尊重开发者的劳动成果,转载的时候请务必注明出处:http://blog.csdn.net/haomengzhu/article/details/17383997
<捕鱼达人>回顾
【cocos2d-x IOS游戏开发-捕鱼达人1】内容介绍
<城市跑酷>回顾
【cocos2d-x IOS游戏开发-城市跑酷1】跑酷游戏介绍
上节回顾
Cocos2d-X游戏【泰然网《跑酷》】JS到C++移植7:Gesture Recognizer【手势识别】
这一节中将介绍如何添加一些跑酷游戏的常用的一些控制方式。
在修改runner类之前首先要在Utils.h中添加如下代码
// collision type for chipmunk enum SpriteTag{ SpriteTagRunner, SpriteTagCoin, SpriteTagRock, };
需要定义一个标记chipmunk碰撞检测的枚举类型
打开Runner.cpp,通过添加如下代码来完成RunnerStat的定义:
// define enum for runner status //1.定义一个runner状态的枚举,跑步者有许多状态 enum RunnerStat { RunnerStatRunning, RunnerStatJumpUp, RunnerStatJumpDown, RunnerStatCrouch, RunnerStatIncredible, };
为runner类定义几个新的成员变量
CCSize crouchSize; cpSpace *space; cpBody *body;// current chipmunk body cpShape *shape;// current chipmunk shape static RunnerStat stat;// init with running status CCAction *runningAction; CCAction *jumpUpAction; CCAction *jumpDownAction; CCAction *crouchAction;
当游戏角色蹲下的时候它的形状将会发生改变,下面的代码会记录蹲下时候的大小。 在init()中添加如下代码:
// init crouchSize CCPhysicsSprite *tmpSprite = CCPhysicsSprite::createWithSpriteFrameName("runnerCrouch0.png"); crouchSize = tmpSprite->getContentSize();改变initShape
// start with running shape //7.在initShape里,创建与精灵大小相等的chipmunk形状 initShape("running");
void Runner::initShape(const char* type) { if (shape) { //space.removeShape(this.shape); cpSpaceRemoveShape(space, shape); } if (type == "running") { shape = cpBoxShapeNew(body, runningSize.width - 14, runningSize.height); } else { // crouch shape = cpBoxShapeNew(body, crouchSize.width, crouchSize.height); } //shape = cpBoxShapeNew(body, //runningSize.width, runningSize.height); //shape->setCollisionType(SpriteTag.runner); shape->collision_type = SpriteTagRunner; cpSpaceAddShape(space, shape); }还有initAction()中的三个动画初始化函数:jumpUpAction, jumpDownAction和crouchAction
// init jumpUpAction CCAnimation* animation1; animation1 = CCAnimation::create(); CCSpriteFrame * frame1; // num equal to spriteSheet for (unsigned int i = 0; i < 4; i++) { char str[100] = {0}; sprintf(str, "runnerJumpUp%i.png", i); frame1 = CCSpriteFrameCache::sharedSpriteFrameCache()->spriteFrameByName(str); animation1->addSpriteFrame(frame1); } animation1->setDelayPerUnit(0.2f); jumpUpAction = CCAnimate::create(animation1); jumpUpAction->retain(); // init jumpDownAction CCAnimation* animation2; animation2 = CCAnimation::create(); CCSpriteFrame * frame2; // num equal to spriteSheet for (unsigned int i = 0; i < 2; i++) { char str[100] = {0}; sprintf(str, "runnerJumpDown%i.png", i); frame2 = CCSpriteFrameCache::sharedSpriteFrameCache()->spriteFrameByName(str); animation2->addSpriteFrame(frame); } animation2->setDelayPerUnit(0.2f); jumpDownAction = CCAnimate::create(animation2); jumpDownAction->retain(); // init crouchAction CCAnimation* animation3; animation3 = CCAnimation::create(); CCSpriteFrame * frame3; // num equal to spriteSheet for (unsigned int i = 0; i < 1; i++) { char str[100] = {0}; sprintf(str, "runnerCrouch%i.png", i); frame3 = CCSpriteFrameCache::sharedSpriteFrameCache()->spriteFrameByName(str); animation3->addSpriteFrame(frame3); } animation3->setDelayPerUnit(0.3f); crouchAction = CCAnimate::create(animation3); crouchAction->retain();
void Runner::jump() { if (stat == RunnerStatRunning) { //this.body.applyImpulse(cp.v(0, 250), cp.v(0, 0)); cpVect arg1 = cpv(0, 250); cpVect arg2 = cpv(0, 0); cpBodyApplyImpulse((cpBody*)body , (cpVect)arg1 , (cpVect)arg2); stat = RunnerStatJumpUp; sprite->stopAllActions(); sprite->runAction(jumpUpAction); //播放音效 //audioEngine->playEffect(s_music_jump); } }
只需要给runner的body一个向上的冲力,runner就会跳起来,在将动画换成跳跃动画之前,通过调用sprite->stopAllActions()来停止当前动画。
跳跃的动作可以分为两个部分--上升和下降。可以通过观察body的重心的线速度来检测从上升到下降状态的转换。
如果在Y轴的线速度小于0.1,跳跃的动作正在从上升状态切换到下降状态,这时将精灵的动画切换到jumpDownAction.
如果Y轴的线速度等于0说明精灵的从下降的状态切换到了跑动的状态,这时将精灵动画改成runningAction.
void Runner::step(float dt) { //线速度 cpVect vel = body->v; if (stat == RunnerStatJumpUp) { if (vel.y < 0.1) { stat = RunnerStatJumpDown; sprite->stopAllActions(); sprite->runAction(jumpDownAction); } return; } if (stat == RunnerStatJumpDown) { if (vel.y == 0) { stat = RunnerStatRunning; sprite->stopAllActions(); sprite->runAction(runningAction); } return; } }
void Runner::crouch() { if (stat == RunnerStatRunning) { initShape("crouch"); sprite->stopAllActions(); sprite->runAction(crouchAction); stat = RunnerStatCrouch; // after time turn to running stat scheduleOnce(schedule_selector(Runner::loadNormal), 1.5f); //audioEngine.playEffect(s_music_crouch); } }
scheduleOnce(schedule_selector(Runner::loadNormal), 1.5f);来返回到跑动状态.
loadNormal() 初始化跑动状态下body的shape.可以这样做:
void Runner::loadNormal(float dt) { initShape("running"); sprite->stopAllActions(); sprite->runAction(runningAction); stat = RunnerStatRunning; }
switch (rtn) { case SimpleGesturesUp: CCLOG("Runner::jump"); runner->jump(); break; case SimpleGesturesDown: CCLOG("Runner::crouch"); runner->crouch(); break; case SimpleGesturesNotSupport: case SimpleGesturesError: // try dollar Recognizer // 0:Use Golden Section Search (original) // 1:Use Protractor (faster) #if 0 var result = dollar.Recognize(this.recognizer.getPoints(), 1); CCLOG(result.Name); if (result.Name == "circle") { runner->incredibleHulk(); } #endif CCLOG("not support or error touch,use geometricRecognizer!!"); runner->incredibleHulk(); #if 0 //通过GeometricRecognizer校准 //可以选择屏蔽玩家单击操作 if (p_2dPath.size() < 1){ return ; } RecognitionResult r = geometricRecognizer->recognize(p_2dPath); if((r.name != "Unknown") && (r.score > 0.5)) { runner->incredibleHulk(); //return; } #endif
// runner step, to change animation runner->step(delta);