最近有人用2d写了模仿微信的打飞机,我参考了下,用2dx来重新写下,我们一步步来,先整理好整个项目的框架,还有逻辑。我们先写一个有开始菜单的界面,
HelloWorldScene.h:
class HelloWorld : public cocos2d::CCLayer { public: // Method 'init' in cocos2d-x returns bool, instead of 'id' in cocos2d-iphone (an object pointer) virtual bool init(); // there's no 'id' in cpp, so we recommend to return the class instance pointer static cocos2d::CCScene* scene(); // a selector callback void menuCloseCallback(CCObject* pSender); // preprocessor macro for "static create()" constructor ( node() deprecated ) CREATE_FUNC(HelloWorld); void initData(); void startGame(); }
HelloWorldScene.cpp:
bool HelloWorld::init() { ////////////////////////////// // 1. super init first if ( !CCLayer::init() ) { return false; } this->initData(); CCSprite *bgSprite = CCSprite::createWithSpriteFrameName("background_2.png"); bgSprite->setPosition(ccp(wSize.width/2, wSize.height/2)); this->addChild(bgSprite, 0); CCSprite *logoSprite = CCSprite::create("BurstAircraftLogo-hd.png"); logoSprite->setPosition(ccp(wSize.width/2, wSize.height/2+100)); this->addChild(logoSprite, 0); CCMenuItemFont *startItem=CCMenuItemFont::create("开始游戏", this,menu_selector(HelloWorld::startGame)); startItem->setPosition(ccp(wSize.width/2, wSize.height/2-200)); startItem->setFontSizeObj(55); startItem->setFontNameObj("Georgia-Bold"); CCMenu *pMenu = CCMenu::create(startItem, NULL); pMenu->setPosition(CCPointZero); this->addChild(pMenu, 1); return true; } void HelloWorld::initData() { CCSpriteFrameCache *frameCache=CCSpriteFrameCache::sharedSpriteFrameCache(); frameCache->addSpriteFramesWithFile("gameArts-hd.plist"); } //开始游戏 void HelloWorld::startGame() { CCScene *scene=CCScene::create(); GameLayer *layer=GameLayer::create(); scene->addChild(layer); //跳跃式动画 CCDirector::sharedDirector()->replaceScene(CCTransitionJumpZoom::create(1.2f, scene)); }
我们看下游戏界面
GameScene.h:
class GameLayer : public cocos2d::CCLayer { public: virtual bool init(); static cocos2d::CCScene* scene(); CREATE_FUNC(GameLayer); private: void initUI(); void initData(); void scrollBg(); void update(float t); cocos2d::CCSprite *bgSprite1; cocos2d::CCSprite *bgSprite2; int bgHeight; cocos2d::CCSprite *playSprite; };
bool GameLayer::init() { if ( !CCLayer::init() ) { return false; } this->initData(); this->initUI(); //系统的刷新 this->scheduleUpdate(); return true; } void GameLayer::initData() { //背景音乐 SimpleAudioEngine::sharedEngine()->playBackgroundMusic("game_music.mp3",true); bgHeight=480; } void GameLayer::initUI() { //背景 bgSprite1=CCSprite::createWithSpriteFrameName("background_2.png"); //锚点 bgSprite1->setAnchorPoint(ccp(0.5, 0)); bgSprite1->setPosition(ccp(320, 0)); this->addChild(bgSprite1, 0); bgSprite2=CCSprite::createWithSpriteFrameName("background_2.png"); bgSprite2->setAnchorPoint(ccp(0.5, 0)); bgSprite2->setPosition(ccp(320, bgHeight-1)); this->addChild(bgSprite2, 0); //玩家 playSprite=CCSprite::createWithSpriteFrameName("hero_fly_1.png"); playSprite->setPosition(ccp(300, 200)); this->addChild(playSprite, 3); //自身动画 CCArray *array=CCArray::create(); for (int i=1; i<3; i++) { CCString *string=CCString::createWithFormat("hero_fly_%d.png",i); CCSpriteFrame *frame=CCSpriteFrameCache::sharedSpriteFrameCache()->spriteFrameByName(string->getCString()); array->addObject(frame); } CCAnimation *animation=CCAnimation::createWithSpriteFrames(array,0.1); CCAnimate *animate=CCAnimate::create(animation); CCRepeatForever *ac1=CCRepeatForever::create(animate); playSprite->runAction(ac1); } //循环滚动背景 void GameLayer::scrollBg() { bgHeight--; if (bgHeight<=0) { bgHeight=480; } bgSprite1->setPosition(ccp(bgSprite1->getPosition().x, bgHeight-480)); bgSprite2->setPosition(ccp(bgSprite2->getPosition().x, bgHeight-1)); } //刷新 void GameLayer::update(float t) { this->scrollBg(); }
在上面中,我们初始化了一些数据,精灵,设置滚动的背景,当然,我们需要一步步来实现,得想好逻辑,这个功能实现了,然后接下去该实现什么,然后直到完善。。。。
OK,我们继续。。。。。
接下来我们要让我们的飞机跟随我们的手指移动,简单点,我们就用layer的触摸事件来实现,设置setTouchEnabled为true就可以了,
在GameScene.cpp的initData函数中增加
this->setTouchEnabled(true);并且在GameScene类的头文件中重写touch事件
virtual void ccTouchesMoved(cocos2d::CCSet *pTouches, cocos2d::CCEvent *pEven);
//手指移动飞机 void GameLayer::ccTouchesMoved(CCSet *pTouches,CCEvent *pEven) { CCSetIterator it = pTouches->begin(); CCTouch* touch = (CCTouch*)(* it); CCPoint curLocation = CCDirector::sharedDirector()->convertToGL(touch->getLocationInView()); //前一个点的坐标 CCPoint oldLocation=touch->getPreviousLocation(); CCPoint translation=ccpSub(curLocation, oldLocation); // CCLOG("%f",translation.y); //相减,得到偏移量 playSprite->setPosition(this->boundLayerPos(translation)); } CCPoint GameLayer::boundLayerPos(CCPoint newPos) { CCPoint point=newPos; point.x=playSprite->getPosition().x+newPos.x; point.y=playSprite->getPosition().y+newPos.y; if (point.x>=286*2) { point.x = 286*2; }else if (point.x<=33*2) { point.x = 33*2; } if (point.y >=wSize.height-50*2) { point.y = wSize.height-50*2; }else if (point.y <= 43*2) { point.y = 43*2; } return point; }
这样飞机就可以随着手指的移动而移动了。。。。。
然后我们增加发射子弹的功能,因为子弹是自动发射的,不需要通过发射按钮来发射子弹,所以这时候,你可以考虑就只创建一颗子弹精灵来实现,
我们在GameScene.cpp中增加新函数
//制造子弹 void GameLayer::madeBullet() { bullet=CCSprite::createWithSpriteFrameName("bullet1.png"); this->addChild(bullet, 1); //音效 // SimpleAudioEngine::sharedEngine()->playEffect("bullet.mp3"); } //重置子弹 void GameLayer::resetBullet() { bulletSpeed = (wSize.height - (playSprite->getPosition().y + 50))/15; if (bulletSpeed<5) { bulletSpeed=5; } bullet->setPosition(ccp(playSprite->getPosition().x, playSprite->getPosition().y+50)); } //开火 void GameLayer::firingBullets() { bullet->setPosition(ccp(bullet->getPosition().x, bullet->getPosition().y+bulletSpeed)); if (bullet->getPosition().y > wSize.height - 20) { this->resetBullet(); } }
在update(float t)函数中,我们增加函数
this->firingBullets();
OK,现在飞机可以移动,并且可以发射子弹,那么现在,我们需要加入敌人的飞机。。。。。。。
我们定义一个类继承CCSprite
上代码:
EnemyPlane.h
//敌人的飞机 class EnemyPlane :public cocos2d::CCSprite { public: //飞机的种类 int planeType; //飞机的血量 int hp; //飞机的速度s int speed; EnemyPlane(); ~EnemyPlane(); static EnemyPlane* createWithSpriteFrameName(const char *spriteFrameName); };
using namespace cocos2d; using namespace CocosDenshion; EnemyPlane::EnemyPlane() { } EnemyPlane::~EnemyPlane() { } EnemyPlane* EnemyPlane::createWithSpriteFrameName(const char *spriteFrameName) { EnemyPlane* pSprite = new EnemyPlane; if (pSprite && pSprite->initWithSpriteFrameName(spriteFrameName)) { pSprite->autorelease(); return pSprite; } CC_SAFE_DELETE(pSprite); return NULL; }
//添加飞机 void GameLayer::addEnemyPlane() { smallPlaneTime++; mediumPlaneTime ++; bigPlaneTime ++; if (smallPlaneTime > 60) { EnemyPlane *smallPlane=this->makeSmallPlane(); this->addChild(smallPlane, 3); planeArray->addObject(smallPlane); smallPlaneTime = 0; } if (mediumPlaneTime > 400) { EnemyPlane *mediumPlane=this->makeMediumPlane(); this->addChild(mediumPlane, 3); planeArray->addObject(mediumPlane); mediumPlaneTime = 0; } if (bigPlaneTime > 700) { EnemyPlane *bigPlane=this->makeBigPlane(); this->addChild(bigPlane, 3); planeArray->addObject(bigPlane); bigPlaneTime = 0; } } //制造小飞机 EnemyPlane* GameLayer::makeSmallPlane() { EnemyPlane *smallPlane=EnemyPlane::createWithSpriteFrameName("enemy1_fly_1.png"); smallPlane->setPosition(ccp(arc4random()%290+17, 960)); smallPlane->planeType=1; smallPlane->hp=1; smallPlane->speed=arc4random()%4+2; return smallPlane; } //制造中等飞机 EnemyPlane* GameLayer::makeMediumPlane() { EnemyPlane *mediumPlane=EnemyPlane::createWithSpriteFrameName("enemy3_fly_1.png"); mediumPlane->setPosition(ccp(arc4random()%280+23, 960)); mediumPlane->planeType=3; mediumPlane->hp=15; mediumPlane->speed=arc4random()%3+2; return mediumPlane; } //制造大飞机 EnemyPlane* GameLayer::makeBigPlane() { //大飞机有浆的动画 CCArray *array=CCArray::create(); for (int i=1; i<=2; i++) { CCString *string=CCString::createWithFormat("enemy2_fly_%i.png",i); CCSpriteFrame *frame=CCSpriteFrameCache::sharedSpriteFrameCache()->spriteFrameByName(string->getCString()); array->addObject(frame); } CCAnimation *animation=CCAnimation::createWithSpriteFrames(array,0.1); CCAnimate *animate=CCAnimate::create(animation); CCRepeatForever *ac1=CCRepeatForever::create(animate); EnemyPlane *bigPlane=EnemyPlane::createWithSpriteFrameName("enemy2_fly_1.png"); bigPlane->setPosition(ccp(arc4random()%210+55, 1200)); bigPlane->planeType=2; bigPlane->hp=25; bigPlane->speed=arc4random()%2+2; bigPlane->runAction(ac1); array->removeAllObjects(); return bigPlane; } //移动飞机 void GameLayer::moveEnemyPlane() { for (int i=0;i<planeArray->count();i++) { EnemyPlane *tmpPlane=(EnemyPlane *)planeArray->objectAtIndex(i); tmpPlane->setPosition(ccp(tmpPlane->getPosition().x,tmpPlane->getPosition().y - tmpPlane->speed)); if (tmpPlane->getPosition().y<(-75*2)) { planeArray->removeObject(tmpPlane); tmpPlane->removeFromParentAndCleanup(false); } } }
this->addEnemyPlane(); this->moveEnemyPlane();
。。。。。。。。。。。。未完。。。。
OK。。。。我们继续,接下来,我们要考虑碰撞检测了,我的飞机子弹打出来,让打中敌人的飞机,并且显示相应的分数。这里碰撞检测,我们要知道,什么跟什么碰撞了,这里很简单,飞机的子弹跟敌人的飞机有个碰撞,敌人的飞机跟我的飞机有个碰撞,目前是这么多,当然后面还有。上代码
在GameSence.h中
void collisionDetection(); void enemyPlaneBlowupAnimation(EnemyPlane *enemyPlane); void hitAnimationToFoePlane(EnemyPlane *enemyPlane); void blowupEnd(CCObject *object); //得分 int scoreInt;
//碰撞检测 void GameLayer::collisionDetection() { //子弹所在的矩形区域 CCRect bulletRect=bullet->boundingBox(); //敌人飞机的数组 // CCARRAY_FOREACH(<#__array__#>, <#__object__#>) for (int i=0; i<planeArray->count(); i++) { EnemyPlane *enemyPlane=(EnemyPlane *)planeArray->objectAtIndex(i); //矩形和矩形 if (bulletRect.intersectsRect(enemyPlane->boundingBox())) { //碰到飞机了,子弹要消失,所以这里重置 this->resetBullet(); enemyPlane->hp=enemyPlane->hp-1; if (enemyPlane->hp<=0) { this->enemyPlaneBlowupAnimation(enemyPlane); planeArray->removeObject(enemyPlane); } else { this->hitAnimationToFoePlane(enemyPlane); } } } } //敌人飞机爆炸效果 void GameLayer::enemyPlaneBlowupAnimation(EnemyPlane *enemyPlane) { int animationNum = 0; //动画帧数跟相应的分数 if (enemyPlane->planeType == 1) { animationNum = 4; scoreInt += 2000; } if (enemyPlane->planeType == 3) { animationNum = 4; scoreInt += 10000; } if (enemyPlane->planeType == 2) { animationNum = 7; scoreInt += 40000; } CCString *string=CCString::createWithFormat("%i",scoreInt); scoreLabel->setString(string->getCString()); //停止所以动画 enemyPlane->stopAllActions(); //动画效果 CCArray *array=CCArray::create(); for (int i=1; i<=animationNum; i++) { CCString *string=CCString::createWithFormat("enemy%i_blowup_%i.png",enemyPlane->planeType,i); CCSpriteFrame *frame=CCSpriteFrameCache::sharedSpriteFrameCache()->spriteFrameByName(string->getCString()); array->addObject(frame); } CCAnimation *animation=CCAnimation::createWithSpriteFrames(array,0.1); CCAnimate *animate=CCAnimate::create(animation); CCSequence *seq=CCSequence::create(animate,CCCallFuncN::create(this, callfuncN_selector(GameLayer::blowupEnd)),NULL); enemyPlane->runAction(seq); array->removeAllObjects(); if (enemyPlane->planeType == 3) { // SimpleAudioEngine::sharedEngine()->playEffect("enemy1_down.mp3"); } else if (enemyPlane->planeType == 2) { // SimpleAudioEngine::sharedEngine()->playEffect("enemy2_down.mp3"); } else if (enemyPlane->planeType == 1) { // SimpleAudioEngine::sharedEngine()->playEffect("enemy3_down.mp3"); } } //动画结束后的处理 void GameLayer::blowupEnd(CCObject *object) { EnemyPlane *enemyPlane=(EnemyPlane *)object; enemyPlane->removeFromParentAndCleanup(false); } //飞机被击打的动画 void GameLayer::hitAnimationToFoePlane(EnemyPlane *enemyPlane) { //中等飞机 if (enemyPlane->planeType==3) { if (enemyPlane->hp==13) { CCArray *array=CCArray::create(); for (int i=1; i<=2; i++) { CCString *string=CCString::createWithFormat("enemy3_hit_%i.png",i); CCSpriteFrame *frame=CCSpriteFrameCache::sharedSpriteFrameCache()->spriteFrameByName(string->getCString()); array->addObject(frame); } CCAnimation *animation=CCAnimation::createWithSpriteFrames(array,0.1); CCAnimate *animate=CCAnimate::create(animation); CCRepeatForever *ac1=CCRepeatForever::create(animate); enemyPlane->runAction(ac1); array->removeAllObjects(); } } //大飞机 else if (enemyPlane->planeType==2) { if (enemyPlane->hp==20) { CCArray *array=CCArray::create(); for (int i=1; i<=1; i++) { CCString *string=CCString::createWithFormat("enemy2_hit_%i.png",i); CCSpriteFrame *frame=CCSpriteFrameCache::sharedSpriteFrameCache()->spriteFrameByName(string->getCString()); array->addObject(frame); } CCAnimation *animation=CCAnimation::createWithSpriteFrames(array,0.1); CCAnimate *animate=CCAnimate::create(animation); CCRepeatForever *ac1=CCRepeatForever::create(animate); enemyPlane->runAction(ac1); array->removeAllObjects(); } } }
。。。。。。。。。。未完。。。。。。。。。。。。。。。。。。。。。。。。