cocos2dx-是男人就坚持20s 练手项目

前言

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

 

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

准备工作

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

开始游戏

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

cocos2dx-是男人就坚持20s 练手项目cocos2dx-是男人就坚持20s 练手项目

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

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

 下载代码戳这里

 

你可能感兴趣的:(cocos2dx)