cocos2d-x的初步学习二十二之模仿微信打飞机
发布日期:2022-02-08 18:03:28 浏览次数:22 分类:技术文章

本文共 15645 字,大约阅读时间需要 52 分钟。

最近有人用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;        };
GameScene.cpp

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);
在cpp中具体实现函数

//手指移动飞机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,这样就添加完了子弹:

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);};
EnemyPlane.cpp

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
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); } } }
在上面中,我们制作了不同类型的飞机,它们各有自己的特点,设置他们出现的时间,然后我们在update函数中增加

this->addEnemyPlane();        this->moveEnemyPlane();
OK,这样就有敌人的飞机啦。。。。。。。

。。。。。。。。。。。。未完。。。。

OK。。。。我们继续,接下来,我们要考虑碰撞检测了,我的飞机子弹打出来,让打中敌人的飞机,并且显示相应的分数。这里碰撞检测,我们要知道,什么跟什么碰撞了,这里很简单,飞机的子弹跟敌人的飞机有个碰撞,敌人的飞机跟我的飞机有个碰撞,目前是这么多,当然后面还有。上代码

在GameSence.h中

void collisionDetection();    void enemyPlaneBlowupAnimation(EnemyPlane *enemyPlane);        void hitAnimationToFoePlane(EnemyPlane *enemyPlane);        void blowupEnd(CCObject *object);        //得分    int scoreInt;
GameSence.cpp

//碰撞检测void GameLayer::collisionDetection(){    //子弹所在的矩形区域    CCRect bulletRect=bullet->boundingBox();    //敌人飞机的数组    // CCARRAY_FOREACH(<#__array__#>, <#__object__#>)    for (int i=0; i
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(); } }}
上面中,我们定义了一个碰撞检测的函数collisionDetection,通过intersectsRect函数来判断子弹的矩形区域是否在敌人飞机的矩形区域内,打一下少一滴血,当血小于等于0时,就触发我们的飞机爆炸效果,并且移除死亡的飞机,设置分数显示,否则打击的时候,有打击动画。大体的逻辑就是这样。。。。。

。。。。。。。。。。未完。。。。。。。。。。。。。。。。。。。。。。。。

转载地址:https://blog.csdn.net/kuloveyouwei/article/details/11022901 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:JS与OC交互
下一篇:cocos2d-x的初步学习二十三之模仿微信打飞机二

发表评论

最新留言

第一次来,支持一个
[***.219.124.196]2024年04月13日 01时30分41秒