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

  • 相关阅读:
    .net core + mvc 手撸一个代码生成器
    如何使用VS Code编写Spring Boot (第二弹)
    第五章 .net core该怎么玩
    第四章 .net core做一个简单的登录
    第三章 搭建一个通用的权限管理系统
    第二章 在Linux上部署.net core
    将博客搬至CSDN
    Entity Framework6 with Oracle(可实现code first)
    利用windbg查找dictionary导致IIS占CPU100%案例分析(一)
    VS快捷键以及Reshaper快捷键
  • 原文地址:https://www.cnblogs.com/TreeDream/p/9316101.html
Copyright © 2011-2022 走看看