坦克大战实现

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

        #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
添加 多种道具,当打死一坦克时就会有一定概率产生一个道具
    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));

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

运行结果

坦克大战

  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值