前言

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

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

准备工作

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

开始游戏

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

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

1、计时器

int time=;
CCLabelTTF* timelb;//文本框
schedule(schedule_selector(manfor20s::timecount), 1.0f);//每秒执行的计时器 //每秒累加
void manfor20s::timecount(float dt)
{
time= time+;
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/),
pl->getPosition().y - (pl->getContentSize().height/),
pl->getContentSize().width,
pl->getContentSize().height); CCRect win=CCRectMake(,,visibleSize.width,visibleSize.height);
listSpirit=this->getChildren();//获取所有元素
for (int i=listSpirit->count()-;i>=;i--)
{ CCSprite* it=(CCSprite*)listSpirit->objectAtIndex(i);
if(it->getTag()==)//tag为2则为子弹
{
/*
CCSprite *sp = dynamic_cast<CCSprite*>(it); */
CCRect projectileRect = CCRectMake( it->getPosition().x - (it->getContentSize().width/),
it->getPosition().y - (it->getContentSize().height/),
it->getContentSize().width,
it->getContentSize().height);
if ( ccpDistance(it->getPosition(),plane->getPosition())<) //子弹和小鸟圆心点相距小于15则认为碰撞了
{
CCMessageBox("被击中了","alert");
menuCloseCallback();//关闭
break;
}
if(!win.intersectsRect(projectileRect))//如果子弹超出窗体则删除 {
this->removeChild(it);
}
}
} #pragma region 产生弹道 随机生成各个方向的子弹
if(getRand(,)>)//随机因子
{
//get directer
int di =getRand(,);
CCSprite * pu =CCSprite::create("p.png");
pu->setTag();
CCPoint from;
CCPoint to;
switch(di)
{
case ://up to down
{
from=ccp(getRand(,visibleSize.width),visibleSize.height);
to=ccp(getRand(-visibleSize.width,visibleSize.width*),-);
}
break;
case ://down to up
{
from=ccp(getRand(,visibleSize.width),);
to=ccp(getRand(-visibleSize.width,visibleSize.width*),visibleSize.height+);
}
break;
case ://left to right
{
from=ccp(,getRand(,visibleSize.height));
to=ccp(visibleSize.width+,getRand(-visibleSize.height,visibleSize.height*));
}
break;
case ://right to left
{
from=ccp(visibleSize.width,getRand(,visibleSize.height));
to=ccp(-,getRand(-visibleSize.height,visibleSize.height*));
}
break;
default:break;
}
pu->setPosition(from);
this->addChild(pu);
int distance=cocos2d::ccpDistance(from,to);
CCActionInterval *forward = CCMoveTo::create(distance/,to); //moveto 速度控制
pu->runAction(forward);
}
#pragma endregion
} //random
int manfor20s::getRand(int start,int end)
{
float i = CCRANDOM_0_1()*(end-start+)+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 - && location.x < heropos.x + && location.y > heropos.y - && location.y < heropos.y + )
{
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,,true);
visibleSize = CCDirector::sharedDirector()->getVisibleSize();
CCPoint origin = CCDirector::sharedDirector()->getVisibleOrigin();
timelb=CCLabelTTF::create("", "Arial", );
timelb->setPosition(ccp(origin.x+,origin.y +visibleSize.height-));
this->addChild(timelb);
manfor20s::time=; plane=CCSprite::create("bird.png");
plane->setTag();
plane->setPosition(ccp(origin.x+visibleSize.width/,origin.y + visibleSize.height/));
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/),
pl->getPosition().y - (pl->getContentSize().height/),
pl->getContentSize().width,
pl->getContentSize().height); CCRect win=CCRectMake(,,visibleSize.width,visibleSize.height);
listSpirit=this->getChildren();
for (int i=listSpirit->count()-;i>=;i--)
{ CCSprite* it=(CCSprite*)listSpirit->objectAtIndex(i);
if(it->getTag()==)
{
/*
CCSprite *sp = dynamic_cast<CCSprite*>(it); */
CCRect projectileRect = CCRectMake( it->getPosition().x - (it->getContentSize().width/),
it->getPosition().y - (it->getContentSize().height/),
it->getContentSize().width,
it->getContentSize().height);
if ( ccpDistance(it->getPosition(),plane->getPosition())<)
{
CCMessageBox("被击中了","alert");
menuCloseCallback();
break;
}
if(!win.intersectsRect(projectileRect))//delete if over the windows
{
this->removeChild(it);
}
}
} #pragma region 产生弹道
if(getRand(,)>)//随机因子
{
//get directer
int di =getRand(,);
CCSprite * pu =CCSprite::create("p.png");
pu->setTag();
CCPoint from;
CCPoint to;
switch(di)
{
case ://up to down
{
from=ccp(getRand(,visibleSize.width),visibleSize.height);
to=ccp(getRand(-visibleSize.width,visibleSize.width*),-);
}
break;
case ://down to up
{
from=ccp(getRand(,visibleSize.width),);
to=ccp(getRand(-visibleSize.width,visibleSize.width*),visibleSize.height+);
}
break;
case ://left to right
{
from=ccp(,getRand(,visibleSize.height));
to=ccp(visibleSize.width+,getRand(-visibleSize.height,visibleSize.height*));
}
break;
case ://right to left
{
from=ccp(visibleSize.width,getRand(,visibleSize.height));
to=ccp(-,getRand(-visibleSize.height,visibleSize.height*));
}
break;
default:break;
}
pu->setPosition(from);
this->addChild(pu);
int distance=cocos2d::ccpDistance(from,to);
CCActionInterval *forward = CCMoveTo::create(distance/,to); //moveto 速度控制
pu->runAction(forward);
}
#pragma endregion
} void manfor20s::timecount(float dt)
{
manfor20s::time= manfor20s::time+;
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+)+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 / );
// 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 - && location.x < heropos.x + && location.y > heropos.y - && location.y < heropos.y + )
{
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", ); // create a exit botton
CCMenuItemLabel *start_game = CCMenuItemLabel::create(label1, this, menu_selector(MainPage::menustartGame) ); CCLabelTTF *label2 = CCLabelTTF::create("Exit", "Arial", ); // 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)/ ,
origin.y+visibleSize.height/ + start_game->getContentSize().height/));
exit_game->setPosition(ccp((origin.x + visibleSize.width - exit_game->getContentSize().width)/ ,
origin.y+visibleSize.height/ + exit_game->getContentSize().height/-)); // create menu, it's an autorelease object
CCMenu* pMenu = CCMenu::create(start_game,exit_game, NULL);
pMenu->setPosition(CCPointZero);
this->addChild(pMenu, ); //标题
CCLabelTTF* pLabel = CCLabelTTF::create("can you hold 20 sec?", "Arial", ); // position the label on the center of the screen
pLabel->setPosition(ccp(origin.x + visibleSize.width/,
origin.y + visibleSize.height - pLabel->getContentSize().height)); // add the label as a child to this layer
this->addChild(pLabel, ); //背景图片
CCSprite* pSprite = CCSprite::create("background.jpg"); pSprite->setPosition(ccp(visibleSize.width/ + origin.x, visibleSize.height/ + origin.y)); this->addChild(pSprite, ); 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();
#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 / );
// create a scene. it's an autorelease object
CCScene *pScene = manfor20s::scene(); pDirector->replaceScene(pScene);
}

菜单页.cpp

下载代码戳这里

最新文章

  1. 如何判断ios设备中是否安装了某款应用
  2. Any changes made by a writer will not be seen by other users of the database until the changes have been completed
  3. 手机操控全站仪安卓版 测量员.app
  4. [转]VS2010中水晶报表安装应用及实例
  5. mysql概要(七)表字段管理,字段的增删改
  6. [转载]char * 和char []的区别---之第二篇
  7. TOP 10 BEST LINUX GAMES RELEASED IN 2016
  8. OpenJudge 2694 逆波兰表达式
  9. saveFileDialog
  10. (转)HiddenField控件的使用
  11. 认识input输入框的placeholder属性
  12. Ubuntu更改hosts档
  13. 前端菜鸟学习之DOM事件处理
  14. 技能提升丨Seacms 8.7版本SQL注入分析
  15. vue-cli中安装方法
  16. python语言学习---3
  17. Android ListView的item背景色设置以及item点击无响应等相关问题
  18. opencv源码学习: getGaussianKernel( 高斯核);
  19. 解决远程连接mysql很慢的方法
  20. “AS3.0高级动画编程”学习:第四章 寻路(AStar/A星/A*)算法 (下)

热门文章

  1. C# 继承实现父类方法、重写、重载
  2. Junit测试Spring应用Dubbo测试框架之-Excel 工具类
  3. 学java得这样学,学习确实也得这样
  4. 【转】Android之Adapter用法总结
  5. 下载论坛源码GBK UTF8 BIG5分别是什么意思
  6. ios 程序发布使用xcode工具Application Loader 正在通过ITUNES STORE进行鉴定错误
  7. android4.4系统永不锁屏
  8. 算法笔记_166:算法提高 金属采集(Java)
  9. 关于苹果开发证书失效的解决方式(2016年2月14日Failed to locate or generate matching signing assets)
  10. SQL外键约束