尊重开发者的劳动成果,转载的时候请务必注明出处:http://blog.csdn.net/haomengzhu/article/details/17418919
<捕鱼达人>回顾
【cocos2d-x IOS游戏开发-捕鱼达人1】内容介绍
<城市跑酷>回顾
【cocos2d-x IOS游戏开发-城市跑酷1】跑酷游戏介绍
上节回顾
Cocos2d-X游戏【泰然网《跑酷》】JS到C++移植9:Map Loop【地图循环加载】
现在已经可以让游戏角色跑在一个有背景的世界了,但是要完成一个跑酷游戏的话:
还需要两个东西:金币和石头.
当游戏角色碰到了金币,金币将会消失;
但是碰到石头后石头不会消失,当他碰到石头,game over!
除了碰撞处理外它们没有任何区别,让我们从金币开始做吧。
创建一个Coin.cpp的文件并将它添加到VS的项目中,将下面代码添加到里面:
/** Constructor * @param {CCSpriteBatchNode *} * @param {cpSpace *} * @param {ccp} */ Coin::Coin(CCSpriteBatchNode *spriteSheet, cpSpace *space, CCPoint pos) { this->space = NULL; this->sprite = NULL; this->shape = NULL; this->_map = 0;// which map belong to this->space = space; //初始化金币的动画 // init runningAction创建一个空白的序列帧动画信息 CCAnimation* animation = CCAnimation::create(); //CCSpriteFrame对应的就是帧,将CCSpriteFrame添加到CCAnimation生成动画数据, //用CCAnimation生成CCAnimate(就是最终的动画动作),最后可以用CCSprite执行这个动作。 CCSpriteFrame * frame = NULL; // num equal to spriteSheet for (unsigned int i = 0; i < 8; i++) { char str[100] = {0}; sprintf(str, "coin%i.png", i); frame = CCSpriteFrameCache::sharedSpriteFrameCache()->spriteFrameByName(str); animation->addSpriteFrame(frame); } //animation = CCAnimation.create(animFrames, 0.1); animation->setDelayPerUnit(0.1f); //设置动画结束后是否保留动画帧信息 animation->setRestoreOriginalFrame(false); //设置循环播放次数 (-1:无限循环) animation->setLoops(-1); //由这个动画信息创建一个序列帧动画 CCAction *action = CCAnimate::create(animation); //保存这个动画,这行代码retain()将避免CCObject被GC //runningAction = CCRepeatForever::create(CCAnimate::create(animation)); //action->retain(); this->sprite = CCPhysicsSprite::createWithSpriteFrameName("coin0.png"); //金币采取使用静态的body方式来抵消重力 // init physics cpFloat radius = 0.95 * sprite->getContentSize().width / 2; cpBody *body = cpBodyNewStatic(); //body->setPos(pos); body->p = cpv(pos.x, pos.y); sprite->setCPBody(body); this->shape = cpCircleShapeNew(body, radius, cpv(0, 0)); this->shape->collision_type = (SpriteTagCoin); //传感器只是调用碰撞函数,并不会真的产生碰撞 //Sensors only call collision callbacks, and never generate real collisions //shape->setSensor(true); this->shape->sensor = true; cpSpaceAddStaticShape(this->space, this->shape); // Needed for collision //body.setUserData(this); // add sprite to sprite sheet this->sprite->runAction(action); spriteSheet->addChild(this->sprite, 1); }
提一些要点:
1. 生成的石头和金币会通过一个管理类ObjectManager.cpp管理石头和金币;
地图是反复滚动的,金币属于哪个地图,这个值需要在ObjectManager.cpp中进行设置。
2. 初始化金币的动画
3. 金币采取使用静态的body方式来抵消重力
4. 传感器只是调用碰撞函数,并不会真的产生碰撞
5. 在ObjectManager.cpp中要使用removeFromParent来删除已经滚出地图外的元素
接下来是石头,同样的方式创建一个Rock.cpp文件并添加下面的代码:
/** Constructor * @param {CCSpriteBatchNode *} * @param {cpSpace *} * @param {ccp} */ Rock::Rock(CCSpriteBatchNode *spriteSheet, cpSpace *space, CCPoint pos) { this->space = NULL; this->sprite = NULL; this->shape = NULL; this->_map = 0;// which map belong to this->space = space; #if 1 //石头有两个可根据Ycoordinate的值选择的纹理 if (pos.y >= (g_groundHight + Runner::getCrouchContentSize()->height)) { //if (pos.y >= (g_groundHight + Runner::gRunnerCrouchContentSizeHeight)) { this->sprite = CCPhysicsSprite::createWithSpriteFrameName("hathpace.png"); } else { this->sprite = CCPhysicsSprite::createWithSpriteFrameName("rock.png"); } #endif //采取使用静态的body方式来抵消重力 cpBody *body = cpBodyNewStatic(); body->p = cpv(pos.x, pos.y); this->sprite->setCPBody(body); //石头的形状不是circle,而是box this->shape = cpBoxShapeNew(body, this->sprite->getContentSize().width, this->sprite->getContentSize().height); this->shape->collision_type = (SpriteTagRock); //传感器只是调用碰撞函数,并不会真的产生碰撞 //Sensors only call collision callbacks, and never generate real collisions //shape->setSensor(true); this->shape->sensor = true; cpSpaceAddStaticShape(this->space, this->shape); spriteSheet->addChild(this->sprite); // Needed for collision //body.setUserData(this); }
岩石跟金币有以下两个不同点:
1. 石头有两个可根据Ycoordinate的值选择的纹理
2. 石头的形状不是circle,而是box。
现在已经有了金币跟岩石,但是如何将它们添加到游戏中呢?
【跑酷源码素材】资源引用页:http://download.csdn.net/detail/danielzzu/6739365