zoukankan      html  css  js  c++  java
  • 塔防cocos2d

    塔防游戏,类似于保卫萝卜的一种。

    需要注意的是几点问题是:

    • 游戏地图是瓦片地图,设置特定的标记,用来标记哪些点是地图点,哪些是塔点。
    • 游戏关卡选择:需要在两个cpp文件传参,用的是静态成员变量。
    • 每一关的不同点是地图的不一样,根据关卡使用不同地图,无需写重复的game1.cpp,game2.cpp。
    • 每个塔对于在它范围内的物体进行攻击,一个双重循环。

    展示一下效果吧:

    公司Logo:

    #ifndef __HELLOWORLD_SCENE_H__
    #define __HELLOWORLD_SCENE_H__
    
    #include "cocos2d.h"
    using namespace cocos2d;
    
    class HelloWorld : public cocos2d::CCLayer
    {
    private:
        CCSprite* LG;
    public:
        virtual bool init();  
        void BG();
        
        virtual void registerWithTouchDispatcher(void);
        virtual bool ccTouchBegan(CCTouch *pTouch, CCEvent *pEvent);
        virtual void ccTouchMoved(CCTouch *pTouch, CCEvent *pEvent);
        virtual void ccTouchEnded(CCTouch *pTouch, CCEvent *pEvent);
    
        static cocos2d::CCScene* scene();
    
        void menuCloseCallback(CCObject* pSender);
    
        CREATE_FUNC(HelloWorld);
    };
    
    #endif // __HELLOWORLD_SCENE_H__
    HelloWorldScene.h
    #include "HelloWorldScene.h"
    #include "hall.h"
    
    USING_NS_CC;
    
    CCScene* HelloWorld::scene()
    {
        // 'scene' is an autorelease object
        CCScene *scene = CCScene::create();
        
        // 'layer' is an autorelease object
        HelloWorld *layer = HelloWorld::create();
    
        // add layer as a child to scene
        scene->addChild(layer);
    
        // return the scene
        return scene;
    }
    
    void HelloWorld::BG() {
        CCPoint _center = ccp(1120/2, 640/2);
        CCSprite* bg = CCSprite::create("bg.png");
        this->addChild(bg);
        bg->setPosition(_center);
        LG = CCSprite::create("logo.png");
        this->addChild(LG);
        LG->setPosition(ccp(1120/2,640));
    
        LG->runAction(
            CCMoveTo::create(1,_center)
            );
    
        
    
    }
    
    // on "init" you need to initialize your instance
    bool HelloWorld::init()
    {
    
        if ( !CCLayer::init() )
        {
            return false;
        }
        BG();
    
    
        
        this->setTouchEnabled(true);
        return true;
    }
    
    
    void HelloWorld::menuCloseCallback(CCObject* pSender)
    {
    #if (CC_TARGET_PLATFORM == CC_PLATFORM_WINRT) || (CC_TARGET_PLATFORM == CC_PLATFORM_WP8)
        CCMessageBox("You pressed the close button. Windows Store Apps do not implement a close button.","Alert");
    #else
        CCDirector::sharedDirector()->end();
    #if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
        exit(0);
    #endif
    #endif
    }
    
    void HelloWorld::registerWithTouchDispatcher(void) {
        //参数:作用范围,优先级,是否被吞噬
        CCDirector::sharedDirector()->getTouchDispatcher()->addTargetedDelegate(this,0,true);
    }
    bool HelloWorld::ccTouchBegan(CCTouch *pTouch, CCEvent *pEvent) {
        return true;
    }
    void HelloWorld::ccTouchMoved(CCTouch *pTouch, CCEvent *pEvent) {
    
    }
    void HelloWorld::ccTouchEnded(CCTouch *pTouch, CCEvent *pEvent) {
            // 切换场景
            CCScene* pGameScene = hall::scene();
            pGameScene = CCTransitionFade::create(1.0f,pGameScene);
            CCDirector::sharedDirector()->replaceScene(pGameScene);
    
    }
    HelloWorldScene.cpp

    开始界面(游戏大厅):

    #ifndef _hall_H_
    #endif
    
    #define _hall_H_
    #include "cocos2d.h"
    
    using namespace cocos2d;
    class hall : public CCLayer
    {
    private:
        CCSprite* start;
    public:
        virtual bool init();
        void BG();
        static CCScene* scene();
    
        virtual void registerWithTouchDispatcher(void);
        virtual bool ccTouchBegan(CCTouch *pTouch, CCEvent *pEvent);
        virtual void ccTouchMoved(CCTouch *pTouch, CCEvent *pEvent);
        virtual void ccTouchEnded(CCTouch *pTouch, CCEvent *pEvent);
    
        CREATE_FUNC(hall);
    };
    hall.h
    #include "hall.h"
    #include "Customs.h"
    
    USING_NS_CC;
    
    
    CCScene* hall::scene()
    {
        CCScene* pScene = CCScene::create();
        hall* pLayer = hall::create();
        pScene->addChild(pLayer);
        return pScene;
    }
    
    void hall::BG() {
        CCPoint _center = ccp(1120*0.5f, 640*0.5f);
        CCSprite* bg = CCSprite::create("background/start.png");
        this->addChild(bg);
        bg->setPosition(_center);
        
        
        start = CCSprite::create("start.png");
        this->addChild(start);
        start->setPosition(ccp(1120*0.5f,640*0.5f-150));
        
        CCSprite* fish = CCSprite::create("fish/hall.png");
        this->addChild(fish);
        fish->setScale(0.2f);
        fish->setPosition(ccp(1120,640/2));
    
        fish->runAction(
            CCRepeatForever::create(
                CCSequence::create(
                    CCMoveTo::create(3,ccp(0,640/2)),
                    CCFlipX::create(true),
                    CCMoveTo::create(3,ccp(1120,640/2)),
                    CCFlipX::create(false),
                    NULL
                    )
            )
        );
        
    }
    
    bool hall::init()
    {
        if (!CCLayer::init())
        {
            return true;
        }
        BG();
        this->setTouchEnabled(true);
        return true;
    }
    
    
    void hall::registerWithTouchDispatcher(void) {
        //参数:作用范围,优先级,是否被吞噬
        CCDirector::sharedDirector()->getTouchDispatcher()->addTargetedDelegate(this,0,true);
    }
    bool hall::ccTouchBegan(CCTouch *pTouch, CCEvent *pEvent) {
        CCPoint touchPoint = pTouch->getLocation();
        float minx = start->getPositionX() - 275 / 2.0f;
        float maxx = start->getPositionX() + 275 / 2.0f;
        float miny = start->getPositionY() - 212 / 2.0f;
        float maxy = start->getPositionY() + 212 / 2.0f;
        if(touchPoint.x>minx && touchPoint.x<maxx && touchPoint.y > miny && touchPoint.y < maxy) {
            start->setScale(2.0f);
    
        }
    
        return true;
    }
    void hall::ccTouchMoved(CCTouch *pTouch, CCEvent *pEvent) {
    
    }
    void hall::ccTouchEnded(CCTouch *pTouch, CCEvent *pEvent) {
        // 切换场景
        CCPoint touchPoint = pTouch->getLocation();
        float minx = start->getPositionX() - 275 / 2.0f;
        float maxx = start->getPositionX() + 275 / 2.0f;
        float miny = start->getPositionY() - 212 / 2.0f;
        float maxy = start->getPositionY() + 212 / 2.0f;
        if(touchPoint.x>minx && touchPoint.x<maxx && touchPoint.y > miny && touchPoint.y < maxy) {
            start->setScale(1.0f);
            CCScene* pGameScene = Customs::scene();
            pGameScene = CCTransitionFade::create(1.0f,pGameScene);
            CCDirector::sharedDirector()->replaceScene(pGameScene);
    
        }
        
    }
    hall.cpp

    关卡选择:

    #ifndef _Customs_H_
    #endif
    
    #define _Customs_H_
    #include "cocos2d.h"
    
    using namespace cocos2d;
    class Customs : public CCLayer
    {
    private:
        CCSprite* customs[10];
    public:
        virtual bool init();
        void BG();
        static CCScene* scene();
        static int lv;
    
        virtual void registerWithTouchDispatcher(void);
        virtual bool ccTouchBegan(CCTouch *pTouch, CCEvent *pEvent);
        virtual void ccTouchMoved(CCTouch *pTouch, CCEvent *pEvent);
        virtual void ccTouchEnded(CCTouch *pTouch, CCEvent *pEvent);
    
        CREATE_FUNC(Customs);
    };
    Customs.h
    #include "Customs.h"
    #include "game1.h"
    
    
    USING_NS_CC;
    
    CCScene* Customs::scene()
    {
        CCScene* pScene = CCScene::create();
        Customs* pLayer = Customs::create();
        pScene->addChild(pLayer);
        return pScene;
    }
    
    void Customs::BG() {
        CCPoint _center = ccp(1120/2, 640/2);
        CCSprite* bg = CCSprite::create("choice.png");
        this->addChild(bg);
        bg->setPosition(_center);
        
        
        
        int k=320-150;
        char tmp[50];
        for(int i=0; i<5; i++){
            sprintf(tmp,"customs/%d.png",i+1);
            customs[i] = CCSprite::create(tmp);
            this->addChild(customs[i]);
            customs[i]->setPosition(ccp(k, 420));
            k+=150;
        }
    
    }
    
    int Customs::lv = 1;
    
    bool Customs::init()
    {
        if (!CCLayer::init())
        {
            return true;
        }
        
        BG();
        this->setTouchEnabled(true);
        return true;
    }
    
    
    void Customs::registerWithTouchDispatcher(void) {
        //参数:作用范围,优先级,是否被吞噬
        CCDirector::sharedDirector()->getTouchDispatcher()->addTargetedDelegate(this,0,true);
    }
    bool Customs::ccTouchBegan(CCTouch *pTouch, CCEvent *pEvent) {
    
        return true;
    }
    void Customs::ccTouchMoved(CCTouch *pTouch, CCEvent *pEvent) {
    
    }
    void Customs::ccTouchEnded(CCTouch *pTouch, CCEvent *pEvent) {
        // 切换场景
        
        CCPoint touchPoint = pTouch->getLocation();
    
        for(int i = 0 ; i < 5; i ++) {
            float minx = customs[i]->getPositionX() - 20 / 2.0f;
            float maxx = customs[i]->getPositionX() + 20 / 2.0f;
            float miny = customs[i]->getPositionY() - 40 / 2.0f;
            float maxy = customs[i]->getPositionY() + 40 / 2.0f;
            
    
            if(touchPoint.x>minx && touchPoint.x<maxx && touchPoint.y > miny && touchPoint.y < maxy) {
                customs[i]->setScale(1.6f);
                Customs::lv = i+1;
                CCScene* pGameScene = game1::scene();
                
                pGameScene = CCTransitionFade::create(1.0f,pGameScene);
                CCDirector::sharedDirector()->replaceScene(pGameScene);
    
            }
        }
        
    }
    Customs.cpp

     

     游戏界面:

    #ifndef _game1_H_
    #endif
    
    #define _game1_H_
    #include "cocos2d.h"
    
    using namespace cocos2d;
    using namespace std;
    
    
    
    
    struct WayPoint {
        CCPoint pos;
        int index;
        bool operator < (const WayPoint & rhs) const {
            return index < rhs.index;
        }
    };
    
    //
    struct Cannon {
        CCPoint pos;
        int width,hight;
        bool flag;
        int kind;
    };
    
    //怪物
    struct Monster {
        CCSprite * sp;
        int flag;
    };
    
    
    class game1 : public CCLayer
    {
    private:
        void findPath(CCTMXTiledMap* tmxMap);
        //A关节点
        list<WayPoint> _listPoint_;
        
        //炮塔
        Cannon cannon[50];
        //炮塔个数
        int cnt;
    
        Monster spEnemy[50];
        int cntMonster;
    
        int wave;
        int wave_cnt;
    
        int FlagVic;
        //返回键
        CCSprite * back;
    public:
        virtual bool init();
        static CCScene* scene();
        
        //背景
        void BG();
        //运动序列
        CCSequence* createMoveAction();
        virtual void registerWithTouchDispatcher(void);
        virtual bool ccTouchBegan(CCTouch *pTouch, CCEvent *pEvent);
        virtual void ccTouchMoved(CCTouch *pTouch, CCEvent *pEvent);
        virtual void ccTouchEnded(CCTouch *pTouch, CCEvent *pEvent);
    
        //默认调度器
        //void update(float dt);
        void shoot(float dt);
    
        CREATE_FUNC(game1);
    };
    game1.h
    #include "game1.h"
    #include "Customs.h"
    
    
    USING_NS_CC;
    
    #include "SimpleAudioEngine.h"
    using namespace CocosDenshion;
    
    CCScene* game1::scene()
    {
        CCScene* pScene = CCScene::create();
        game1* pLayer = game1::create();
        pScene->addChild(pLayer);
        return pScene;
    }
    
    void game1::findPath(CCTMXTiledMap* tmxMap) {
        this->cnt = 0;
        CCTMXObjectGroup* object = tmxMap->objectGroupNamed("object");
        CCArray* objectsArray = object->getObjects();
        for(int i = 0; i < (int)objectsArray->count(); i++) {
            // 字典  map  key-value
            CCDictionary* item = (CCDictionary*)objectsArray->objectAtIndex(i);
            CCString* strX = (CCString*)item->valueForKey("x");
            CCString* strY = (CCString*)item->valueForKey("y");
            CCString* strWidth = (CCString*)item->valueForKey("width");
            CCString* strHeight = (CCString*)item->valueForKey("height");
            CCString* strWayPoint = (CCString*)item->valueForKey("waypointA");
            int index = strWayPoint->intValue();
    
            if(index!=0) {
                float x = strX->floatValue()+40;
                float y = strY->floatValue()+40;
                WayPoint wayPoint;
                wayPoint.pos = CCPoint(x,y);
                wayPoint.index = index;
                _listPoint_.push_back(wayPoint);
            }
    
            CCString *strBuild = (CCString*)item->valueForKey("build");
            int build = strBuild->intValue();
            if(build!=0) {
                float x = strX->floatValue()+40;
                float y = strY->floatValue()+40;
                cannon[this->cnt].pos = CCPoint(x,y);
                cannon[this->cnt].width =  strWidth->intValue();
                cannon[this->cnt].hight = strHeight->intValue();
                cannon[this->cnt].flag = false;
                this->cnt++;
            }
    
        }
    
        _listPoint_.sort();
        //放房子
    
        CCSprite* start_Point = CCSprite::create("house/house1.png");
        CCSprite* end_Point = CCSprite::create("house/house2.png");
        this->addChild(start_Point);
        start_Point->setScale(0.2);
        this->addChild(end_Point);
        end_Point->setScale(0.2);
        start_Point->setPosition(_listPoint_.begin()->pos);
        end_Point->setPosition((--_listPoint_.end())->pos);
    }
    
    
    // 创建寻路动作
    CCSequence* game1::createMoveAction()
    {
        // 临时链表
        list<WayPoint> _listPoint = this->_listPoint_;
        // 动作数组
        CCArray* actionArray = CCArray::create();
        while (_listPoint.size() > 1)
        {
            WayPoint frontPoint = _listPoint.front();
            // 删除第一个点
            _listPoint.pop_front();
            // 创建动作
            float speed = 80;
            // 计算两点之间的距离
            WayPoint nextPoint = _listPoint.front();
            float x = (frontPoint.pos.x - nextPoint.pos.x);
            float y = (frontPoint.pos.y - nextPoint.pos.y);
            float dis = sqrt(x*x + y*y);
            float t = dis / speed;
            // 创建动作
            CCMoveTo* moveTo = CCMoveTo::create(t, nextPoint.pos);
            // 将动作添加到数组
            actionArray->addObject(moveTo);
        }
        return CCSequence::create(actionArray);
    }
    
    
    void game1::BG() {
        CCPoint _center = ccp(1120*0.5f,640*0.5f);
        char bgtmp[50];
        sprintf(bgtmp,"background/level%d.png",Customs::lv);
        CCSprite* bg = CCSprite::create(bgtmp);
        this->addChild(bg);
        bg->setPosition(_center);
        //1.创建地图对象
        char tmp[50];
        sprintf(tmp,"tmx/map%d.tmx",Customs::lv);
        CCTMXTiledMap* tmxMap = CCTMXTiledMap::create(tmp);
        //2.绘制地图
        this->addChild(tmxMap);
        findPath(tmxMap);
    
        //音乐
        // 播放背景音乐
        SimpleAudioEngine::sharedEngine()
            ->playBackgroundMusic("music/backgroundmusic1.mp3",true);
        
        back = CCSprite::create("back.png");
        this->addChild(back);
        back->setPosition(ccp(1120-50,640-50));
    
        wave = 5;
        wave_cnt = 3;
        FlagVic = 0;
        
    }
    
    bool game1::init()
    {
        if (!CCLayer::init())
        {
            return true;
        }
        
        BG();
    
        WayPoint wayPoint = _listPoint_.front();
        char fishtmp[50];
        cntMonster = 0;
        for(int j = 0; j < wave; j++) {
            for (int i = 0; i < wave_cnt; i++)
            {
                // 创建一个怪物
                sprintf(fishtmp,"fish/%d.png",(i+j)%12+1);
                spEnemy[cntMonster].sp = CCSprite::create(fishtmp);
                spEnemy[cntMonster].sp->setFlipX(true);
                this->addChild(spEnemy[cntMonster].sp);
                spEnemy[cntMonster].sp->setVisible(false);
                spEnemy[cntMonster].sp->setPosition(wayPoint.pos);
                spEnemy[cntMonster].flag = 10;
                spEnemy[cntMonster].sp->runAction(CCSequence::create(
                    CCDelayTime::create(i*0.8f+j*10),
                    CCShow::create(),
                    createMoveAction(),
                    CCHide::create(),
                    NULL));
                cntMonster++;
            }
        }
    
    
        this->setTouchEnabled(true);
        this->schedule(schedule_selector(game1::shoot),0.5f);
        return true;
    }
    
    
    void game1::registerWithTouchDispatcher(void) {
        //参数:作用范围,优先级,是否被吞噬
        CCDirector::sharedDirector()->getTouchDispatcher()->addTargetedDelegate(this,0,true);
    }
    bool game1::ccTouchBegan(CCTouch *pTouch, CCEvent *pEvent) {
        return true;
    }
    void game1::ccTouchMoved(CCTouch *pTouch, CCEvent *pEvent) {
    
    }
    void game1::ccTouchEnded(CCTouch *pTouch, CCEvent *pEvent) {
        CCPoint touchPoint = pTouch->getLocation();
        
        for(int i = 0; i < this->cnt; i++) {
            CCPoint center = cannon[i].pos;
            int wight = cannon[i].width/2;
            int hight = cannon[i].hight/2;
            if(touchPoint.x>center.x-wight&&touchPoint.x<center.x+wight&&touchPoint.y>center.y-hight&&touchPoint.y<center.y+hight) {
                CCSprite* town = CCSprite::create("cannon.png");
                this->addChild(town);
                town->setScale(0.5);
                town->setPosition(center);
                //标记该炮塔有塔了
                cannon[i].flag = true;
                //音效
                SimpleAudioEngine::sharedEngine()->playEffect("music/di.mp3");
            }
        }
        //返回选择关卡
        float minx = back->getPositionX() - 40;
        float maxx = back->getPositionX() + 40;
        float miny = back->getPositionY() - 40;
        float maxy = back->getPositionY() + 40;
        if(touchPoint.x>minx && touchPoint.x<maxx && touchPoint.y > miny && touchPoint.y < maxy) {
            back->setScale(1.1f);
            CCScene* pGameScene = Customs::scene();
            pGameScene = CCTransitionFade::create(1.0f,pGameScene);
            CCDirector::sharedDirector()->replaceScene(pGameScene);
            FlagVic = 0;
            //关闭背景音乐
            SimpleAudioEngine::sharedEngine()->stopBackgroundMusic(true);
        }
    }
    
    
    void game1::shoot(float dt) {
        
        for(int i = 0; i < cntMonster; i++) {
            if(spEnemy[i].flag) {
            for(int j = 0; j < cnt; j++) {
                if(cannon[j].flag) {
    
                    CCPoint Cannon_center = cannon[j].pos;
                    int hight = cannon[j].hight;
                    int wight = cannon[j].width;
                    //在射程范围内
                    if(cannon[j].pos.getDistance(spEnemy[i].sp->getPosition())<100) {
                        CCSprite* tmp = CCSprite::create("bullet/BulletLizi_0.png");
                        this->addChild(tmp);
                        tmp->setPosition(cannon[j].pos);
                        SimpleAudioEngine::sharedEngine()->playEffect("music/bumm1.mp3");
                        tmp->runAction(CCSequence::create(CCMoveTo::create(0.1f,spEnemy[i].sp->getPosition()),CCHide::create(),NULL
                            ));
                        spEnemy[i].flag--;
                        if(!spEnemy[i].flag) {
                            SimpleAudioEngine::sharedEngine()->playEffect("music/bumm2.mp3");
                            FlagVic++;
                            spEnemy[i].sp->setVisible(false);
                        }
                        if(FlagVic==wave*wave_cnt) {
                            CCSprite* k = CCSprite::create("congratulate.png");
                            this->addChild(k);
                            k->setPosition(ccp(1120/2, 640/2));
                        }
                        //CCLOG("dist = %d",spEnemy[i].sp->getPosition().getDistance(cannon[j].pos));
                    }
                }
            }
        }
        }
    
        
    
    }
    game1.cpp

  • 相关阅读:
    geoserver发布地图服务WMTS
    geoserver发布地图服务WMS
    geoserver安装部署步骤
    arcgis api 3.x for js 入门开发系列十四最近设施点路径分析(附源码下载)
    arcgis api 3.x for js 入门开发系列十三地图最短路径分析(附源码下载)
    cesium 之自定义气泡窗口 infoWindow 后续优化篇(附源码下载)
    arcgis api 3.x for js 入门开发系列十二地图打印GP服务(附源码下载)
    arcgis api 3.x for js 入门开发系列十一地图统计图(附源码下载)
    arcgis api 3.x for js 入门开发系列十叠加 SHP 图层(附源码下载)
    arcgis api 3.x for js入门开发系列九热力图效果(附源码下载)
  • 原文地址:https://www.cnblogs.com/TreeDream/p/9316101.html
Copyright © 2011-2022 走看看