zoukankan      html  css  js  c++  java
  • cocos2dx-是男人就坚持20s 练手项目

    前言

    前段时间心血来潮看了下app游戏方面的东西

    ,对比了下各种技术和市场招聘情况,赶脚cocos2dx在2D游戏方向还算是大有所为,遂找了几个基础教程看看了解了解。并附上一个简单demo作为成果

    准备工作

    环境搭建倒是重头戏,相关教程也比较多,我直接转个给大家参考吧(安装教程戳这里)。

    开始游戏

    找了个经典游戏是男人就坚持20秒,相信大家都接触过,游戏逻辑比较简单不外乎控制飞机躲避子弹,这里就山寨它吧

    可以看到组成部分只有计时器,子弹和小鸟(为什么选小鸟呢,因为圆形图标做碰撞检测比较简单,本来用飞机的,但是飞机的空白地方不好处理,简单实例就用简单的方法吧)

    1、计时器

    int time=0;
    CCLabelTTF* timelb;//文本框
    schedule(schedule_selector(manfor20s::timecount), 1.0f);//每秒执行的计时器
    
    //每秒累加
    void  manfor20s::timecount(float dt)
    {
        time= time+1;
        CCString* ns=CCString::createWithFormat("%d", manfor20s::time);
        timelb->setString(ns->getCString()  );
    }
    计时器逻辑

    2、子弹的生成和碰撞检测

    CCArray* listSpirit;//获取页面上所有元素的容器
    CCSprite* plane;//小鸟
    schedule(schedule_selector(manfor20s::update));//每一帧执行
    
    
    void  manfor20s::update(float dt)
    {  
        CCSprite *pl =  plane ;  
        CCRect targetRect = CCRectMake(  
            pl->getPosition().x - (pl->getContentSize().width/2),  
            pl->getPosition().y - (pl->getContentSize().height/2),  
            pl->getContentSize().width,  
            pl->getContentSize().height); 
         
        CCRect win=CCRectMake(0,0,visibleSize.width,visibleSize.height);
        listSpirit=this->getChildren();//获取所有元素
        for (int i=listSpirit->count()-1;i>=0;i--)
        {
            
            CCSprite* it=(CCSprite*)listSpirit->objectAtIndex(i);
            if(it->getTag()==2)//tag为2则为子弹
            {
          /*
                CCSprite *sp = dynamic_cast<CCSprite*>(it);  */
                CCRect projectileRect = CCRectMake( it->getPosition().x - (it->getContentSize().width/2),  
                    it->getPosition().y - (it->getContentSize().height/2),  
                    it->getContentSize().width,  
                    it->getContentSize().height);
                if ( ccpDistance(it->getPosition(),plane->getPosition())<15)  //子弹和小鸟圆心点相距小于15则认为碰撞了
                {  
                    CCMessageBox("被击中了","alert");
                    menuCloseCallback();//关闭
                    break;
                }  
                 if(!win.intersectsRect(projectileRect))//如果子弹超出窗体则删除             {
                    this->removeChild(it);  
                 }
            }
        }
        
    
        #pragma region 产生弹道 随机生成各个方向的子弹
        if(getRand(1,10)>8)//随机因子
        {
            //get directer
            int di =getRand(0,3);
            CCSprite * pu =CCSprite::create("p.png");  
            pu->setTag(2);
            CCPoint from;
            CCPoint to;
            switch(di)
            {
                case 0://up to down 
                    {
                        from=ccp(getRand(0,visibleSize.width),visibleSize.height);
                        to=ccp(getRand(-visibleSize.width,visibleSize.width*2),-10);  
                    } 
                    break;
                case 1://down to up
                    {
                        from=ccp(getRand(0,visibleSize.width),0);
                        to=ccp(getRand(-visibleSize.width,visibleSize.width*2),visibleSize.height+10);
                    }
                    break;
                case 2://left to right
                    {
                        from=ccp(0,getRand(0,visibleSize.height)); 
                        to=ccp(visibleSize.width+10,getRand(-visibleSize.height,visibleSize.height*2));
                    } 
                    break;
                case 3://right to left
                    {
                        from=ccp(visibleSize.width,getRand(0,visibleSize.height));  
                        to=ccp(-10,getRand(-visibleSize.height,visibleSize.height*2));
                    } 
                    break;
                default:break;
            }
            pu->setPosition(from);
            this->addChild(pu);
            int distance=cocos2d::ccpDistance(from,to);
            CCActionInterval *forward = CCMoveTo::create(distance/50,to);  //moveto 速度控制
            pu->runAction(forward);   
        }
        #pragma endregion 
    }
    
    //random
    int manfor20s::getRand(int start,int end)  
    {  
        float i = CCRANDOM_0_1()*(end-start+1)+start;  //get random from start to end
        return (int)i;  
    }  
    子弹的生成和碰撞检测

    3、小鸟的移动

    bool manfor20s::ccTouchBegan(CCTouch * touch,CCEvent* event)
    {
        CCPoint heropos = plane->getPosition();
        CCPoint location = touch->getLocationInView();
        location = CCDirector::sharedDirector()->convertToGL(location);
        if (location.x > heropos.x - 24 && location.x < heropos.x + 24 && location.y > heropos.y - 24 && location.y < heropos.y + 24)
        {
            isControl = true;
            deltax = location.x - heropos.x;
            deltay = location.y - heropos.y;
        }
        return true;
    }
    
    
    
    void manfor20s::ccTouchMoved(CCTouch * touch,CCEvent* event)
    {
        if (isControl)
        {
            CCPoint location = touch->getLocationInView();
            location = CCDirector::sharedDirector()->convertToGL(location);
            float x = location.x - deltax;
            float y = location.y - deltay;
            plane->setPosition(ccp(x,y));
        }
    }
    
    void manfor20s::ccTouchEnded(CCTouch * touch, CCEvent * event)
    {
        isControl = false;
    }
    小鸟的移动

    大体逻辑就是这样,第一次做c++项目,分不清::   .  ->的概念,幸好项目比较小问题不大,希望有机会能接触高大上一点的项目做做,哈哈,不知道怎么传代码,就吧.h文件和.cpp文件都贴上来吧

    #ifndef __manfor20s_SCENE_H__
    #define __manfor20s_SCENE_H__
     
    #include "cocos2d.h"
     
    
    class manfor20s:public cocos2d::CCLayer
    {
    
    public: 
        virtual bool init();  
    
        // there's no 'id' in cpp, so we recommend returning the class instance pointer
        static cocos2d::CCScene* scene();
    
        // a selector callback
        void menuCloseCallback();
         
        // implement the "static node()" method manually
        CREATE_FUNC(manfor20s);
        void  timecount(float dt);
        void update(float dt);
        int getRand(int start,int end) ; 
        int time;
        bool isControl;
        int deltax;
        int deltay;
         
        
    
        //触屏响应重写这三个方法
        virtual bool ccTouchBegan(cocos2d::CCTouch* touch, cocos2d::CCEvent* event);//按下
        virtual void ccTouchMoved(cocos2d::CCTouch* touch, cocos2d::CCEvent* event);//拖动
        virtual void ccTouchEnded(cocos2d::CCTouch* touch, cocos2d::CCEvent* event);//松开
    };
    
    #endif
    游戏页.h
    #include "manfor20s.h" 
    #include "MainPage.h"
    USING_NS_CC; 
    CCLabelTTF* timelb;
    CCSize visibleSize; 
    CCArray* listSpirit;
    CCSprite* plane;
    CCScene* manfor20s::scene(){
        CCScene *scene = CCScene::create(); 
        manfor20s *layer = manfor20s::create(); 
        scene->addChild(layer); 
        return scene;
    }
    
     
    bool manfor20s::init()
    {
        if ( !CCLayer::init() )
        {
            return false;
        }
        this->setTouchEnabled(true);
         CCDirector::sharedDirector()->getTouchDispatcher()->addTargetedDelegate(this,0,true);
        visibleSize = CCDirector::sharedDirector()->getVisibleSize();
        CCPoint origin = CCDirector::sharedDirector()->getVisibleOrigin(); 
        timelb=CCLabelTTF::create("0",  "Arial", 20);
        timelb->setPosition(ccp(origin.x+10,origin.y +visibleSize.height-20));
        this->addChild(timelb);   
        manfor20s::time=0;
      
        plane=CCSprite::create("bird.png"); 
        plane->setTag(1);
        plane->setPosition(ccp(origin.x+visibleSize.width/2,origin.y + visibleSize.height/2));
        this->addChild(plane);
         
        schedule(schedule_selector(manfor20s::update));
        schedule(schedule_selector(manfor20s::timecount), 1.0f);
         
        return true;
    }
    
     
    void  manfor20s::update(float dt)
    {  
        CCSprite *pl =  plane ;  
        CCRect targetRect = CCRectMake(  
            pl->getPosition().x - (pl->getContentSize().width/2),  
            pl->getPosition().y - (pl->getContentSize().height/2),  
            pl->getContentSize().width,  
            pl->getContentSize().height); 
         
        CCRect win=CCRectMake(0,0,visibleSize.width,visibleSize.height);
        listSpirit=this->getChildren();
        for (int i=listSpirit->count()-1;i>=0;i--)
        {
            
            CCSprite* it=(CCSprite*)listSpirit->objectAtIndex(i);
            if(it->getTag()==2)
            {
          /*
                CCSprite *sp = dynamic_cast<CCSprite*>(it);  */
                CCRect projectileRect = CCRectMake( it->getPosition().x - (it->getContentSize().width/2),  
                    it->getPosition().y - (it->getContentSize().height/2),  
                    it->getContentSize().width,  
                    it->getContentSize().height);
                if ( ccpDistance(it->getPosition(),plane->getPosition())<15)  
                {  
                    CCMessageBox("被击中了","alert");
                    menuCloseCallback();
                    break;
                }  
                 if(!win.intersectsRect(projectileRect))//delete if over the windows
                 {
                    this->removeChild(it);  
                 }
            }
        }
        
    
        #pragma region 产生弹道 
        if(getRand(1,10)>8)//随机因子
        {
            //get directer
            int di =getRand(0,3);
            CCSprite * pu =CCSprite::create("p.png");  
            pu->setTag(2);
            CCPoint from;
            CCPoint to;
            switch(di)
            {
                case 0://up to down 
                    {
                        from=ccp(getRand(0,visibleSize.width),visibleSize.height);
                        to=ccp(getRand(-visibleSize.width,visibleSize.width*2),-10);  
                    } 
                    break;
                case 1://down to up
                    {
                        from=ccp(getRand(0,visibleSize.width),0);
                        to=ccp(getRand(-visibleSize.width,visibleSize.width*2),visibleSize.height+10);
                    }
                    break;
                case 2://left to right
                    {
                        from=ccp(0,getRand(0,visibleSize.height)); 
                        to=ccp(visibleSize.width+10,getRand(-visibleSize.height,visibleSize.height*2));
                    } 
                    break;
                case 3://right to left
                    {
                        from=ccp(visibleSize.width,getRand(0,visibleSize.height));  
                        to=ccp(-10,getRand(-visibleSize.height,visibleSize.height*2));
                    } 
                    break;
                default:break;
            }
            pu->setPosition(from);
            this->addChild(pu);
            int distance=cocos2d::ccpDistance(from,to);
            CCActionInterval *forward = CCMoveTo::create(distance/50,to);  //moveto 速度控制
            pu->runAction(forward);   
        }
        #pragma endregion 
    }
    
    
    void  manfor20s::timecount(float dt)
    {
        manfor20s::time= manfor20s::time+1;
        CCString* ns=CCString::createWithFormat("%d", manfor20s::time);
        timelb->setString(ns->getCString()  );
    }
    
    
    int manfor20s::getRand(int start,int end)  
    {  
        float i = CCRANDOM_0_1()*(end-start+1)+start;  //get random from start to end
        return (int)i;  
    }  
    
    //close button
    void manfor20s::menuCloseCallback()
    {
        this->removeAllChildren();
        this->unscheduleAllSelectors();  
        CCDirector* pDirector = CCDirector::sharedDirector(); 
        CCEGLView* pEGLView = CCEGLView::sharedOpenGLView(); 
        pDirector->setOpenGLView(pEGLView); 
        // turn on display FPS
        pDirector->setDisplayStats(true);
    
        // set FPS. the default value is 1.0/60 if you don't call this
        pDirector->setAnimationInterval(1.0 / 60);
        // create a scene. it's an autorelease object
        CCScene *pScene = MainPage::scene(); 
    
        pDirector->replaceScene(pScene);
    }
    
    
     
    bool manfor20s::ccTouchBegan(CCTouch * touch,CCEvent* event)
    {
        CCPoint heropos = plane->getPosition();
        CCPoint location = touch->getLocationInView();
        location = CCDirector::sharedDirector()->convertToGL(location);
        if (location.x > heropos.x - 24 && location.x < heropos.x + 24 && location.y > heropos.y - 24 && location.y < heropos.y + 24)
        {
            isControl = true;
            deltax = location.x - heropos.x;
            deltay = location.y - heropos.y;
        }
        return true;
    }
    
    
    
    void manfor20s::ccTouchMoved(CCTouch * touch,CCEvent* event)
    {
        if (isControl)
        {
            CCPoint location = touch->getLocationInView();
            location = CCDirector::sharedDirector()->convertToGL(location);
            float x = location.x - deltax;
            float y = location.y - deltay;
            plane->setPosition(ccp(x,y));
        }
    }
    
    void manfor20s::ccTouchEnded(CCTouch * touch, CCEvent * event)
    {
        isControl = false;
    }
    
    
    
     
    游戏页.cpp
    #ifndef __MainPage_SCENE_H__
    #define __MainPage_SCENE_H__
    
    #include "cocos2d.h"
    
    class MainPage : public cocos2d::CCLayer
    {
    public:
        // Here's a difference. Method 'init' in cocos2d-x returns bool, instead of returning 'id' in cocos2d-iphone
        virtual bool init();  
    
        // there's no 'id' in cpp, so we recommend returning the class instance pointer
        static cocos2d::CCScene* scene();
        
        // a selector callback
        void menuCloseCallback(CCObject* pSender);
    
        // a selector callback
        void menustartGame(CCObject* pSender);
        
        // implement the "static node()" method manually
        CREATE_FUNC(MainPage);
    };
    
    #endif // __HELLOWORLD_SCENE_H__
    菜单页.h
    #include "MainPage.h"
    #include "manfor20s.h"
    USING_NS_CC;
    
    CCScene* MainPage::scene()
    {
        // 'scene' is an autorelease object
        CCScene *scene = CCScene::create();
        
        // 'layer' is an autorelease object
        MainPage *layer = MainPage::create();
    
        // add layer as a child to scene
        scene->addChild(layer);
    
        // return the scene
        return scene;
    }
    
    // on "init" you need to initialize your instance
    bool MainPage::init()
    {
        //////////////////////////////
        // 1. super init first
        if ( !CCLayer::init() )
        {
            return false;
        }
        //获取原始尺寸
        CCSize visibleSize = CCDirector::sharedDirector()->getVisibleSize();
    
        CCPoint origin = CCDirector::sharedDirector()->getVisibleOrigin();
    
        //开始和退出按钮
        CCLabelTTF *label1 = CCLabelTTF::create("Start",  "Arial", 20); // create a exit botton  
        CCMenuItemLabel *start_game = CCMenuItemLabel::create(label1, this, menu_selector(MainPage::menustartGame) );  
    
        CCLabelTTF *label2 = CCLabelTTF::create("Exit",  "Arial", 20); // create a exit botton  
        CCMenuItemLabel *exit_game = CCMenuItemLabel::create(label2, this, menu_selector(MainPage::menuCloseCallback) );  
      
        start_game->setPosition(ccp((origin.x + visibleSize.width - start_game->getContentSize().width)/2 ,
            origin.y+visibleSize.height/2 + start_game->getContentSize().height/2));
        exit_game->setPosition(ccp((origin.x + visibleSize.width - exit_game->getContentSize().width)/2 ,
                                    origin.y+visibleSize.height/2 + exit_game->getContentSize().height/2-50));
    
        // create menu, it's an autorelease object
        CCMenu* pMenu = CCMenu::create(start_game,exit_game, NULL);
        pMenu->setPosition(CCPointZero);
        this->addChild(pMenu, 1);
    
      
        //标题
        CCLabelTTF* pLabel = CCLabelTTF::create("can you hold 20 sec?", "Arial", 28);
        
        // position the label on the center of the screen
        pLabel->setPosition(ccp(origin.x + visibleSize.width/2,
                                origin.y + visibleSize.height - pLabel->getContentSize().height));
    
        // add the label as a child to this layer
        this->addChild(pLabel, 1);
    
       //背景图片
        CCSprite* pSprite = CCSprite::create("background.jpg");
         
        pSprite->setPosition(ccp(visibleSize.width/2 + origin.x, visibleSize.height/2 + origin.y));
         
        this->addChild(pSprite, 0);
        
        return true;
    }
    
    
    void MainPage::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 MainPage::menustartGame(CCObject* psender)
    {
        CCDirector* pDirector = CCDirector::sharedDirector(); 
        CCEGLView* pEGLView = CCEGLView::sharedOpenGLView();
    
        pDirector->setOpenGLView(pEGLView);
    
        // turn on display FPS
        pDirector->setDisplayStats(true);
    
        // set FPS. the default value is 1.0/60 if you don't call this
        pDirector->setAnimationInterval(1.0 / 60);
        // create a scene. it's an autorelease object
        CCScene *pScene = manfor20s::scene(); 
         
        pDirector->replaceScene(pScene);
    }
    菜单页.cpp

     下载代码戳这里

  • 相关阅读:
    ext表格范例
    基于对象的EXT组件间通信
    hibernate自定义生成主健
    Amcharts
    ExtJS之面向对象编程基本知识
    在Ext里写大应用 (翻译:米米饭)
    EXT表单常用验证
    JPA 复合主键
    PowerDesign15常用技巧
    spring security和EXT
  • 原文地址:https://www.cnblogs.com/qyzBlog/p/3627592.html
Copyright © 2011-2022 走看看