在这一步,我们主要是把主角加入到游戏场景中来,并且让它跑动,这里的跑动,实际上也就是执行一组动画,让其看起来像是在跑动,而且相对屏幕的位置也不会改变
我们会定义一个主角类:Runner,而这一步就要用到 帧动画 的创建和使用等知识点。
对于Runner,我的设计思路如下:
1.主角有一个动作集合,包括跑动,跳起来,以及蹲下。那么就有不同的帧动画,那么这里借鉴到 晓风残月前辈的方法,将帧动画打包命名,之后根据动作名来执行动作
2.主角需要绑定刚体,并且在不同的动作下的刚体大小不同
3.我们给主角设定一个状态,那么根据状态,就能知道执行动作和刚体
反正在这一步主要是看
那么上马:Runner.h
#ifndef __Runner__H__ #define __Runner__H__ #include "cocos2d.h" enum runnerState{ running, jumpUp, jumpDown, crouch }; class Runner : public cocos2d::Node{ public: virtual bool init(); CREATE_FUNC(Runner); //初始化 action 集合 void initActionSet(cocos2d::SpriteFrameCache* frameCache); //根据动作名称执行动作 void doAction(const char* actionName);// void initBody();//初始化物理刚体 runnerState getState(){ return m_state;};//获取当前的状态,后面要用到 cocos2d::Size getRunJumpSize(){ return run_jumpSize;};//获取不同时候的SIze cocos2d::Size getCrouchSize() { return crouchSize;}; void Run(); private: // 需要一个主要的精灵执行动作 cocos2d::Sprite* m_runner; // 不同的动作需要不同的刚体大小 cocos2d::Size run_jumpSize;//跑和跳的大小一样 cocos2d::Size crouchSize;//蹲下来的大小 runnerState m_state; };/**/ #endif
这里的刚体Size只有两个,因为跑的时候和跳起来的时候的精灵大小是差不多的,那么处于这两个状态的的刚体绑定大小可以一样,然后下蹲的时候的Size就不同
Runner.cpp
#include "Runner.h" USING_NS_CC; bool Runner::init(){ //加载图片到缓存池 auto frameCache = SpriteFrameCache::getInstance(); frameCache->addSpriteFramesWithFile("parkour.plist","parkour.png"); m_runner = Sprite::createWithSpriteFrameName("runner0.png"); run_jumpSize = m_runner->getContentSize(); crouchSize = Sprite::createWithSpriteFrameName("runnerCrouch0.png")->getContentSize(); this->addChild(m_runner); initActionSet(frameCache);//初始化动作集合 m_state = running; initBody(); return true; } void Runner::initActionSet(SpriteFrameCache* frameCache){ SpriteFrame* frame = NULL; //3.0中改用vector 而不是用Array Vector<SpriteFrame*>frameVector; /* 1.----------------加载跑动的Animation-----------------*/ for(int i = 0; i <= 7; i ++) { //从缓存池中加载精灵到Vector frame = frameCache->spriteFrameByName(String::createWithFormat("runner%d.png",i)->getCString()); frameVector.pushBack(frame); } //用vector里面的SpriteFrame列表创建Animation 以及设置一些参数 auto run_animation = Animation::createWithSpriteFrames(frameVector,0.1f,-1); //将跑动的 Animation 取名为 running AnimationCache::getInstance()->addAnimation(run_animation,"running"); } void Runner::doAction(const char* actionName){ auto animation = AnimationCache::getInstance()->animationByName(actionName); auto action = Animate::create(animation); m_runner->runAction(action); } void Runner::initBody(){ //根据不同状态设置不同刚体大小 Size bodySize; if(m_state == crouch){ bodySize = crouchSize; } else{ bodySize = run_jumpSize; } //创建runner的刚体 auto runerBody = PhysicsBody::createBox(bodySize,PHYSICSBODY_MATERIAL_DEFAULT); //绑定刚体 this->setPhysicsBody(runerBody); } void Runner::Run(){ m_state = running; initBody(); doAction("running"); }
在init
函数里面我们做了一些事:
1.先把图片加载到缓存池,初始化主精灵,和两个Size,以及当前状态
这里的图片实际上是一张整合了很多小图片的集合,不同的图片有不同纹理,那么集合到同一图片中纹理就相同的,那么同一纹理的图片,我们就可以减少渲染批次,3.0中的渲染好像是自动处理的,看了一篇文章,说是不推荐使用那个SpriteBachNode啦,然后说得也比较抽象,我这里也不特别解释,有好的教程麻烦推荐,谢谢
2.我们初始化了动作集合,这一步当中,我们只初始化跑动的帧动画
在initActionSet函数当中,我都有详细注释
doAction函数中,我们可以根据传入的参数动作名称来执行动作,也就是在initActionSet 当中给动作取名字的那里
initBody函数当中,根据不同的状态,我们就给主角绑定不同大小的刚体,关于重复setPhysicsBody,你可能会有疑问,本来有一个刚体,换了一个状态,又设定一个刚体可以吗?答案是可以的,我们可以查看源码
void Node::setPhysicsBody(PhysicsBody* body) { /*省略*/ if (_physicsBody != nullptr) { PhysicsWorld* world = _physicsBody->getWorld(); _physicsBody->removeFromWorld(); _physicsBody->_node = nullptr; _physicsBody->release(); if (world != nullptr && body != nullptr) { world->addBody(body); } } _physicsBody = body; if (body != nullptr) { Node* parent = getParent(); Point pos = parent != nullptr ? parent->convertToWorldSpace(getPosition()) : getPosition(); _physicsBody->setPosition(pos); _physicsBody->setRotation(getRotation()); } }
这里我们可以看到,它会判断_physicsBody(也就是Node的刚体)是不是为空,如有已有刚体,会先删除,然后重新绑定
好啦,到这里主角类以及初步设置完啦,我们在PlayScene.h 中加入一个成员变量 Runner* m_runner;
然后在PlayScene.cpp 的init函数中对 m_runner初始化:
m_runner = Runner::create(); m_runner->setPosition(runner_posX,ground_hight+m_runner->getRunJumpSize().height/2); m_runner->Run(); this->addChild(m_runner);
那么这里的runner_posX 就是在 ground_hight 下面定义的一个宏,也就是主角的X坐标位置,我这里定义 80
OK运行测试如图:
如果你把那些资源都放在Resouce 文件下了,还能听到背景音乐
这里我也有一个问题,就是有的人可以插入动态的那种图片,比较好的演示了运行结果,用QQ好像不能对这个屏幕进行截取动态图,求方法推荐
下面我们就加入PlayScene的背景,以及地图无限滚动,让主角看起来更像是跑动 ,同时也为主角的Jump跳跃动作以及Crouch下蹲动作的执行做准备
个人愚昧观点,欢迎指正与讨论
cocos2d-x 3.0游戏实例学习笔记 《跑酷》 第三步---主角开跑&同时带着刚体