坦克大战实现

前端之家收集整理的这篇文章主要介绍了坦克大战实现前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

先将常用的函数与头文件,宏定义等写到一个公共类中

#ifndef __Common_H__
    #define __Common_H__
    #include "cocos2d.h"
    #include "SimpleAudioEngine.h"
    #include "cocos-ext.h"
    USING_NS_CC;
    USING_NS_CC_EXT;

    #define winSize CCDirector::sharedDirector()->getWinSize()
    #define TANK_SPEED 2
    #define BULLET_SPEED 4
    #define TANK_CREATE_INTERVAL 3
    #define TANK_SHOOT_INTERVAL 1
    #define TIME_OVER 300
    #define TANK_BOMB "TANK_BOMB"
    class Common
    {
    public:
        enum DIRECTION
        {
            UP,RIGHT,DOWN,LEFT,INVALID_DIR
        };
        enum TileType
        {
            NONE,BLOCK,STEEL,HOME
        };
        enum 
        {
            ZO_LAYER_0=100,ZO_BULLET,ZO_TANK,ZO_LAYER_1,ZO_ITEM,ZO_LAYER_SETUP
        };
        static TileType getTileType(int gid)
        {
            if (gid==5||gid==6||gid==11||gid==12)
            {
                return STEEL;
            }
            if (gid==13||gid==14||gid==19||gid==20)
            {
                return BLOCK;
            }
            if (gid==17||gid==18||gid==23||gid==24)
            {
                return HOME;
            }

             return NONE;

        }
        static CCScene* scene(CCLayer *layer)
        {
            CCScene *s=CCScene::create();
            s->addChild(layer);
            return s;
        }

        static const char* format(int v,const char *prefix="",const char *suffix="")
        {
            static char buf[1024];
            sprintf(buf,"%s%d%s",prefix,v,suffix);
            return buf;
        }

        static void moveNodeX(CCNode *n,int dx)
        {
            n->setPositionX(n->getPositionX()+dx);
        }
        static void moveNodeY(CCNode *n,int dy)
        {
            n->setPositionY(n->getPositionY()+dy);
        }
        static void moveNode(CCNode*n,CCPoint pt)
        {
            moveNodeX(n,pt.x);
            moveNodeY(n,pt.y);
        }

        static const CCPoint Map2PointLB(CCTMXTiledMap *_map,CCPoint ptTile)
        {
            ptTile.y=_map->getMapSize().height-1-ptTile.y;
            return ccp(ptTile.x*_map->getTileSize().width,ptTile.y*_map->getTileSize().height);
        }

        static CCPoint Point2Tile(CCTMXTiledMap *_map,CCPoint ptMap)
        {
            int dx=_map->getTileSize().width;
            int dy=_map->getTileSize().height;
            //CCPoint ptMap=_map->convertToNodeSpace(ptGL);
            int x=ptMap.x/dx;
            int y=ptMap.y/dy;
            y=_map->getMapSize().height-1-y;


            return ccp(x,y);
        }


    };
    #endif

开始界面与选择界面非常简单,可以略过,游戏主界面包含的方法如下

#ifndef __LayerGame_H__
    #define __LayerGame_H__
    #include "Common.h"
    #include "TankFriend.h"
    #include "MenuCtrl.h"
    #include "AI.h"
    #include "LayerSetup.h"
    class Item;

    class LayerGame:public CCLayer
    {
    public:
        //CREATE_FUNC(LayerGame);
        void onExit();
        static LayerGame*create(unsigned int index)
        {
            LayerGame *pRt=new LayerGame();
            if (pRt&&pRt->init(index))
            {
                pRt->autorelease();
                return pRt;
            }else
            {
                delete pRt;
                pRt=NULL;
                return pRt;

            }
        }
        bool init(unsigned int index);
        void update(float);

        CCTMXTiledMap *_map;
        TankFriend *_tankFriend;

        void DirCtrlPress(CCObject*);
        void Shoot(CCObject*);
        void Setup(CCObject*);
        void TimeOut(float);
        void setGodMode(int interval)
        {
            _godMode=true;
            CCDelayTime*delay=CCDelayTime::create(interval);
            CCCallFunc *callFunc=CCCallFunc::create(this,callfunc_selector(LayerGame::unSetGodMode));
            this->runAction(CCSequence::createWithTwoActions(delay,callFunc));
        }
        void unSetGodMode()
        {
            _godMode=false;
        }

        void addItem();
        void eatItem(Item*);
        void eatItemBomb();
        void eatItemSteel();
        void setPause()
        {
            CCDirector::sharedDirector()->pause();
        }
        enum FAILURE_REASON
        {
            TIME_OUT,HOME_DESTORY,TANK_DIE
        };
        static void gameOver(FAILURE_REASON reason);
        CCArray *_bullets;
        CCArray *_items;
        AI *_ai;
        int _victoryCount;
        int _curCount;
        int _index;
        int _life;
        bool _godMode;

    };

    #endif

添加友军坦克

 class TankFriend:public CCSprite { public: CREATE_FUNC(TankFriend); bool init(); CCTMXTiledMap *getMap(); void setTileSize(int tileSize); int _tileSize; void Move(Common::DIRECTION dir); void doMove(); void Turn(Common::DIRECTION dir); bool canMove(Common::DIRECTION dir); Bullet *Shoot(); Common::DIRECTION _dir; int _damage; };

添加控制按钮,控制坦克的前进,后退与发射

其中前进,后退是按着一直走,发射子弹是按一下,发射一下

bool MenuCtrl::init()
    {
        CCMenu::init();
        schedule(schedule_selector(MenuCtrl::CheckActive));
        return true;
    }

    void MenuCtrl::CheckActive(float)
    {
        if (this->m_pSelectedItem&&m_eState==kCCMenuStateTrackingTouch)
        {
            m_pSelectedItem->activate();
        }
    }

以上重写了menu方法,使得可以按着按钮一直运动

添加子弹层

class Bullet:public CCSprite
    {
    public:
        CREATE_FUNC(Bullet);
        bool init();

        void setPicture(const char *filename);

        static void CheckBullets(CCTMXTiledMap *_map,CCArray *_bullets);
        int _damage;
    };

敌军坦克由电脑随机生成

敌军坦克类继承友军坦克

bool TankEnemy::init()
{

    CCSprite::initWithFile("tank/armor/armor2U.png");
    _tileSize=0;
    _dir=Common::UP;
    this->setZOrder(Common::ZO_TANK);

    Turn(Common::DOWN);

    return true;
}

随机产生敌军坦克方法

#ifndef __AI_H__
    #define __AI_H__
    #include "Common.h"
    class AI:public CCNode
    {
    public:
        CREATE_FUNC(AI);
        bool init();
        void onExit();
        CCTMXTiledMap *getMap()
        {
            return (CCTMXTiledMap*)getParent();
        }
        //generate enemy tank
        void createTank(float);
        bool _createFlag;
        CCArray *_tanks;
        CCArray *_bullets;
        //move enemy tank
        void moveTank(float);
        //make enemy tank shoot bullet
        void Shoot(float);
        //collision detection
        void update(float);

        bool _pause;
        void pause();
        void resume();

    };
    #endif

添加 多种道具,当打死一坦克时就会有一定概率产生一个道具@H_218_502@
class Item:public CCSprite
    {
    public:
        enum ItemType
        {
            IT_ACTIVE,IT_BOMB,IT_MINTANK,IT_STAR,IT_STEEL,IT_TIMER,IT_COUNT
        };
        CREATE_FUNC(Item);
        bool init();
        void setPosition();
        ItemType _type;
    };

添加控制按钮,产生模态对话框,控制音量与音效

#ifndef __LayerSetup_H__
    #define __LayerSetup_H__
    #include "Common.h"
 class MyCCControlSlider : public CCControlSlider { public: static MyCCControlSlider* create(const char* bgFile,const char* progressFile,const char* thumbFile) { // Prepare background for slider CCSprite *backgroundSprite = CCSprite::create(bgFile); // Prepare progress for slider CCSprite *progressSprite = CCSprite::create(progressFile); // Prepare thumb (menuItem) for slider CCSprite *thumbSprite = CCSprite::create(thumbFile); MyCCControlSlider *pRet = new MyCCControlSlider(); pRet->initWithSprites(backgroundSprite,progressSprite,thumbSprite); pRet->autorelease(); return pRet; } bool ccTouchBegan(CCTouch*t,CCEvent*e) { return CCControlSlider::ccTouchBegan(t,e); } void ccTouchEnded(CCTouch*t,CCEvent*e) { CCControlSlider::ccTouchEnded(t,e); } void ccTouchMoved(CCTouch*t,CCEvent*e) { CCControlSlider::ccTouchMoved(t,e); } void ccTouchCancelled(CCTouch*t,CCEvent*e) { CCControlSlider::ccTouchCancelled(t,e); } }; class LayerSetup:public CCLayer { public: CREATE_FUNC(LayerSetup); bool init(); void ChangeBGVolume(CCObject*,CCControlEvent); void ChangeEffectVolume(CCObject*,CCControlEvent); void Close(CCObject*); bool ccTouchBegan(CCTouch *pTouch,CCEvent *pEvent); void ccTouchEnded(CCTouch *pTouch,CCEvent *pEvent); void ccTouchMoved(CCTouch *pTouch,CCEvent *pEvent); void ccTouchCancelled(CCTouch *pTouch,CCEvent *pEvent); CCMenu *_menu; bool _bMenuItemClicked; MyCCControlSlider* _volumeBG; bool _bVolumeBGClicked; MyCCControlSlider* _volumeEffect; bool _bVolumeEffectClicked; }; #endif // !--

由于CCControlSlider中有些成员变量是保护的,需要将CCControlSlider重写,才可以进行。

注意:当在实现暂停道具的时候,由于要暂停与重启,重启时报错

Run-Time Check Failure #0 - The value of ESP was not properly saved across a function call.  This is usually a result of calling a function declared with one calling convention with a function pointer declared with a different calling convention

原先用//scheduleOnce(schedule_selector(AI::resume),1);来调用resume函数,老是报错,帧循环发生错误,后来改成
CCDelayTime* delay=CCDelayTime::create(5.0f);
CCCallFunc* callFunc = CCCallFunc::create(this,callfunc_selector(AI::resume));
this->runAction(CCSequence::create(delay,callFunc,NULL));

就成功了,原因暂且不明。

运行结果

原文链接:https://www.f2er.com/cocos2dx/340141.html

猜你在找的Cocos2d-x相关文章