cocos2dx-是男人就坚持20s 练手项目
发布日期:2021-10-23 14:13:16 浏览次数:9 分类:技术文章

本文共 15196 字,大约阅读时间需要 50 分钟。

前言

前段时间心血来潮看了下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
(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 }//randomint 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
(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 buttonvoid 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 instancebool 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

 下载代码戳

 

转载于:https://www.cnblogs.com/qyzBlog/p/3627592.html

转载地址:https://blog.csdn.net/weixin_30588827/article/details/98943120 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:Spring框架参考手册(4.2.6版本)翻译——第三部分 核心技术 6.9.1 @Required
下一篇:设计模式--装饰器模式

发表评论

最新留言

关注你微信了!
[***.104.42.241]2024年05月03日 19时27分09秒

关于作者

    喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!

推荐文章