2019独角兽企业重金招聘Python工程师标准>>>

或许有天

我们羡慕和崇拜的人

因为我们的努力

也会来了解我们

说不定

还会成为好友

骨头喜欢这样与哲哲共勉

多少个夜晚

一张长长的书桌上

哲哲在左边认真的做着可爱的独特的手作

骨头在右边噼里啪啦敲着自己真正喜欢的代码

中间的pad放部电影 || 放首歌 || 放段《一席》

这就是我们刚认识时憧憬的日子

所以现在是很幸福了

继续!

昨晚那个游戏已经成功运行在了手机上,接下来,好好看看代码。

AppDelegate.cpp类

常规的东西,设置FPS,设置是否显示FPS,生成菜单场景类Scene,然后让导演类加载第一个场景。

GameMenuScene.cpp类


大部分工作都在init里,设置背景:

[cpp]  view plain copy
  1. CCSize size = CCDirector::sharedDirector()->getWinSize();
  2. //菜单背景
  3. CCSprite* bg = CCSprite::create("MainMenu.png");
  4. bg->setScale(0.5);
  5. bg->setPosition( ccp(size.width/2, size.height/2) );
  6. this->addChild(bg, 0,0);

加载几个按钮,到CCMenu上,然后将CCMenu加载到Scene中

[cpp]  view plain copy
  1. //按钮
  2. CCMenuItemImage *newGameItem = CCMenuItemImage::create("newGameA.png", "newGameB.png",this,menu_selector(GameMenu::menuNewGameCallback));
  3. newGameItem->setScale(0.5);
  4. newGameItem->setPosition(ccp(size.width / 2 + 40,size.height / 2 - 20));
  5. newGameItem->setEnabled(false);
  6. CCMenuItemImage *continueItem = CCMenuItemImage::create("continueA.png", "continueB.png",this,menu_selector(GameMenu::menuContinueCallback));
  7. continueItem->setScale(0.5);
  8. continueItem->setPosition(ccp(size.width / 2 + 40,size.height / 2 - 60));
  9. continueItem->setEnabled(false);
  10. CCMenuItemImage *aboutItem = CCMenuItemImage::create("aboutA.png", "aboutB.png",this,menu_selector(GameMenu::menuAboutCallback));
  11. aboutItem->setScale(0.5);
  12. aboutItem->setPosition(ccp(size.width / 2 + 40,size.height / 2 - 100));
  13. aboutItem->setEnabled(false);
  14. soundItem = CCMenuItemImage::create("sound-on-A.png", "sound-on-B.png",this,menu_selector(GameMenu::menuSoundCallback));
  15. soundItem->setScale(0.5);
  16. soundItem->setEnabled(false);
  17. soundItem->setPosition(ccp(40,40));
  18. CCMenu* mainmenu = CCMenu::create(newGameItem,continueItem,aboutItem,soundItem,NULL);
  19. mainmenu->setPosition(ccp(0,0));
  20. this->addChild(mainmenu,1,3);

初始化背景音乐:

[cpp]  view plain copy
  1. //初始化声音
  2. SimpleAudioEngine::sharedEngine()->preloadBackgroundMusic("background.mp3");
  3. SimpleAudioEngine::sharedEngine()->setBackgroundMusicVolume(0.5);
  4. SimpleAudioEngine::sharedEngine()->playBackgroundMusic("background.mp3");

然后在onEnter方法里,让菜单按钮从无放大至正常大小

[cpp]  view plain copy
  1. void GameMenu::onEnter(){
  2. CCLayer::onEnter();
  3. CCSize size = CCDirector::sharedDirector()->getWinSize();
  4. CCNode* mainmenu = this->getChildByTag(3);
  5. mainmenu->setScale(0);
  6. mainmenu->runAction(CCSequence::create(CCScaleTo::create(0.5,1),CCCallFunc::create(this, callfunc_selector(GameMenu::menuEnter)),NULL));
  7. }

使用getChildByTag()方法取得mainNenu。这也正是为何addChild()时,要加入tag参数了。

[cpp]  view plain copy
  1. CCSequence::create()里,CCScaleTo动作执行完之后,调用GameMenu类的menuEnter方法

然后通过mainmenu->getChildren();方法获取按钮组,遍历一下,设置为可用。

然后紧跟着一些callBack方法,也就是按钮事件

[cpp]  view plain copy
  1. void GameMenu::menuNewGameCallback(CCObject* pSender)
  2. {
  3. CCDirector::sharedDirector()->setDepthTest(true);
  4. CCDirector::sharedDirector()->replaceScene(CCTransitionPageTurn::create(0.5,GameMain::scene(), false));
  5. }

最后是控制背景音乐的方法

[cpp]  view plain copy
  1. void GameMenu::menuSoundCallback(CCObject* pSender)
  2. {
  3. //设置声音
  4. if(! issound){
  5. soundItem->setNormalImage(CCSprite::create("sound-on-A.png"));
  6. soundItem->setDisabledImage(CCSprite::create("sound-on-B.png"));
  7. SimpleAudioEngine::sharedEngine()->playBackgroundMusic("background.mp3", true);
  8. issound = true;
  9. }else{
  10. soundItem->setNormalImage(CCSprite::create("sound-off-A.png"));
  11. soundItem->setDisabledImage(CCSprite::create("sound-off-B.png"));
  12. SimpleAudioEngine::sharedEngine()->stopBackgroundMusic();
  13. issound = false;
  14. }
  15. }

再来看看关于界GameAboutScene.cpp


【插一句:setDepthTest:设置深度测试——可以用于自动处理遮挡关系】

这个类里,在init方法中贴几个CCSprite,加一个CCMenuItemImage及点击事件即可。没什么特别的。

GameObjStar.cpp星星类


本身继承自CCNode,有一个设置是否可见的方法

[cpp]  view plain copy
  1. void GameObjStar::set_visable(bool var){
  2. _visable = var;
  3. this->setVisible(var);
  4. }

在onEnter方法中初始化一下:缩放至一半大小,设置是否可见,设置尺寸。

[cpp]  view plain copy
  1. void GameObjStar::onEnter(){
  2. CCNode::onEnter();
  3. //星星初始化
  4. this->setContentSize(CCSizeMake(36.5,35.5));
  5. CCSprite* star = CCSprite::create("star.png");
  6. star->setScale(0.5);
  7. _visable = true;
  8. addChild(star,1);
  9. }

GameMark.cpp分数类


也是继承自CCNode,同样在onEnter方法里初始化,前面的socre是一个固定的CCSprite,后面是5个CCSprite,根据每个位数来动态修改图片

[cpp]  view plain copy
  1. void GameMark::onEnter()
  2. {
  3. CCNode::onEnter();
  4. CCSize size = CCDirector::sharedDirector()->getWinSize();
  5. this->setContentSize(size);
  6. // bits = CCArray::create(5);
  7. bits=new CCArray(5);
  8. CCSprite *title= CCSprite::create("score.png");
  9. title->setPosition(ccp(size.width/2 + 120,size.height - 15));
  10. title->setScale(0.5);
  11. addChild(title);
  12. for(int i = 0;i < 5;i ++){
  13. CCSprite * shu = CCSprite::create("shu.png");
  14. ui = shu->getTexture();
  15. shu->setScale(0.5);
  16. shu->setTextureRect(CCRectMake(234,0,26,31));
  17. shu->setPosition(ccp(size.width - 15 - i * 15,size.height - 15));
  18. bits->addObject(shu);
  19. addChild(shu);
  20. }
  21. bits->retain();
  22. mark = 0;
  23. }

bits->retain();// 应该是防止数组被回收

下面是按位设置数字,这种自定义rect的舒适化CCSprite的方式是第一次出现,其他的没什么了。

[cpp]  view plain copy
  1. setTextureRect(CCRectMake((temp - 1) * 26,0,26,31));
[cpp]  view plain copy
  1. void GameMark::addnumber(int var){
  2. //按位设置数字
  3. mark += var;
  4. int temp = mark % 10;
  5. if(temp > 0){
  6. ((CCSprite *)bits->objectAtIndex(0))->setTexture(ui);
  7. ((CCSprite *)bits->objectAtIndex(0))->setTextureRect(CCRectMake((temp - 1) * 26,0,26,31));
  8. }else{
  9. ((CCSprite *)bits->objectAtIndex(0))->setTexture(ui);
  10. ((CCSprite *)bits->objectAtIndex(0))->setTextureRect(CCRectMake(234,0,26,31));
  11. }
  12. temp = (mark % 100) / 10;
  13. if(temp > 0){
  14. ((CCSprite *)bits->objectAtIndex(0))->setTexture(ui);
  15. ((CCSprite *)bits->objectAtIndex(1))->setTextureRect(CCRectMake((temp - 1) * 26,0,26,31));
  16. }else{
  17. ((CCSprite *)bits->objectAtIndex(0))->setTexture(ui);
  18. ((CCSprite *)bits->objectAtIndex(1))->setTextureRect(CCRectMake(234,0,26,31));
  19. }
  20. temp = (mark % 1000) / 100;

再来看下萝莉类GameObjHero.cpp


首先在void GameObjHero::onEnter()方法里初始化。

接受触摸:

pDirector->getTouchDispatcher()->addTargetedDelegate(this, 0, true);
初始化萝莉:

[cpp]  view plain copy
  1. mainsprite = CCSprite::create("s_1.png");
  2. //动画
  3. CCAnimation * animation = CCAnimation::create();
  4. animation->addSpriteFrameWithFileName("s_1.png");
  5. animation->addSpriteFrameWithFileName("s_2.png");
  6. animation->addSpriteFrameWithFileName("s_3.png");
  7. animation->addSpriteFrameWithFileName("s_4.png");
  8. animation->addSpriteFrameWithFileName("s_5.png");
  9. animation->addSpriteFrameWithFileName("s_6.png");
  10. animation->setDelayPerUnit(0.1f);
  11. animation->setRestoreOriginalFrame(true);
  12. //运行奔跑动画
  13. mainsprite->runAction(CCRepeatForever::create(CCAnimate::create(animation)));

上面这种添加动画的方式,是骨头第一次遇到。

首先创建CCAnimation,然后设置每一帧的图片,然后设置每帧的延迟时间,设置播放完动画后是否回到第一帧。

然后是构造一个循环播放的CCRepeatForever动画,添加到精灵上。

里面有个设置状态方法:

[cpp]  view plain copy
  1. switch(state){
  2. case 1://跳跃
  3. this->stopAllActions();
  4. mainsprite->stopAllActions();
  5. mainsprite->setTexture(jump);
  6. this->runAction(CCSequence::create(CCJumpBy::create(2.5,ccp(0,0),100,1),CCCallFunc::create(this, callfunc_selector(GameObjHero::jumpend)),NULL));
  7. break;
  8. case 2://受伤
  9. this->stopAllActions();
  10. mainsprite->stopAllActions();
  11. mainsprite->setTexture(hurt);
  12. this->runAction(CCSequence::create(CCBlink::create(3, 10),CCCallFunc::create(this, callfunc_selector(GameObjHero::hurtend)),NULL));
  13. ((GameMain *)this->getParent())->setover();
  14. break;

跳跃,则运行CCJumpBy动画,受伤则运行CCBlink动画,就是一闪一闪的,并且在动画结束分别调用相应的方法。

然后是GameObjMap.cpp地图类


[cpp]  view plain copy
  1. void GameObjMap::bg1change(){
  2. //运动出屏幕重设位置,运动
  3. CCSprite * bg = (CCSprite *)this->getChildByTag(0);
  4. bg->setPosition(ccp(480,320));
  5. bg->runAction(CCSequence::create(CCMoveBy::create(4,ccp(-960,0)),CCCallFunc::create(this, callfunc_selector(GameObjMap::bg1change)),NULL));
  6. for(int i = 0;i < 5;i ++){
  7. ((GameObjStar *)stars1->objectAtIndex(i))->set_visable(true);
  8. }
  9. }
  10. void GameObjMap::bg2change(){
  11. //运动出屏幕重设位置,运动
  12. CCSprite * bg = (CCSprite *)this->getChildByTag(1);
  13. bg->setPosition(ccp(480,320));
  14. bg->runAction(CCSequence::create(CCMoveBy::create(4,ccp(-960,0)),CCCallFunc::create(this, callfunc_selector(GameObjMap::bg2change)),NULL));
  15. for(int i = 0;i < 5;i ++){
  16. ((GameObjStar *)stars2->objectAtIndex(i))->set_visable(true);
  17. }
  18. }

楼上两个方法作用是背景循环,callfunc_selector方法调用的是对方,一对好机油!

[cpp]  view plain copy
  1. bg1->runAction(CCSequence::create(CCMoveBy::create(2,ccp(-480,0)),CCCallFunc::create(this, callfunc_selector(GameObjMap::bg1change)),NULL));
  2. bg2->runAction(CCSequence::create(CCMoveBy::create(4,ccp(-960,0)),CCCallFunc::create(this, callfunc_selector(GameObjMap::bg2change)),NULL));

其实整个背景地图的宽度是两倍的可视屏幕宽度,即480*2=960,这样的地图有两套,两套地图的动画在第一次运行时正好差半个周期,而且是互相调用,呈现出来的效果就是一直循环下去。恩,懂了。
然后在两套地图上绘制植物、草地等元素。

最后是核心逻辑类:GameMainScene.cpp

首先在初始化方法里,把游戏的所有元素都实例化一下,比如萝莉,比如地图,比如分数星星等。

最主要的循环方法:

[cpp]  view plain copy
  1. scheduleUpdate();
  2. void GameMain::update(float time){}

在update里面判断是否跟星星相撞,

[cpp]  view plain copy
  1. bool GameMain::isCollion(CCPoint p1,CCPoint p2,int w1,int h1,int w2,int h2){
  2. if(abs(p1.x - p2.x) < w1 + w2 && abs(p1.y - p2.y) < h1 + h2){
  3. return true;
  4. }
  5. return false;
  6. };

判断是否是掉落状态:

[cpp]  view plain copy
  1. void GameMain::isherodrop(){
  2. CCPoint p1 = (map->getChildByTag(0))->getPosition();
  3. CCPoint p2 = (map->getChildByTag(1))->getPosition();
  4. int temp;
  5. if(p1.x <= 100 && (p1.x + 480) >= 100){
  6. temp = (100 - p1.x) / 64;
  7. if(bg1shu[temp] == -1){
  8. hero->setState(2);
  9. }
  10. }else{
  11. temp = (100 - p2.x) / 64;
  12. if(bg2shu[temp] == -1){
  13. hero->setState(2);
  14. }
  15. }
  16. }

上面方法比较难懂,大意就是根据当前地图的x值位置,来取得主角所站的位置有没有石头,没有的话即掉落。

[cpp]  view plain copy
  1. temp = (100 - p1.x) / 64;

100是因为萝莉站在x=100的位置,所以要得到萝莉所在位置是否为空,即

[cpp]  view plain copy
  1. bg2shu[temp] == -1

地图是这样添加的

//星星,植物等大图素的添加
    for(int i = 0;i < 7;i ++){   //960/8=120

也就是说在960像素宽度的背景图上,可以放8个宽度等于120的元素。

static const short bg1shu[] = {-1,1,0,2,-1,1,2,3};
static const short bg2shu[] = {3,3,-1,3,-1,3,3,-1};

然后根据 数组的值来放置元素,-1时为空。

本篇完结   点此下载

http://download.csdn.net/detail/iamlazybone/6632923

好了,《萝莉快跑》的例子到此算是消化了大部分了。

看3遍不如自己动手敲1遍,赶紧去噼里啪啦一下吧:)

大家晚安。

------------------- 飞船起飞--------------------

Cocos2dx游戏开发系列笔记10:解刨《战神传说》

Cocos2dx游戏开发系列笔记9:android手机上运行《战神传说》,并解决横竖屏即分辨率自适应

Cocos2dx游戏开发系列笔记8:开搞一个射击游戏《战神传说》//就个打飞机的

Cocos2dx游戏开发系列笔记7:一个简单的跑酷游戏《萝莉快跑》的消化(附下载)

Cocos2dx游戏开发系列笔记6:怎样让《萝莉快跑》的例子运行在vs和手机上

Cocos2dx游戏开发系列笔记5:继续润色《忍者飞镖射幽灵》

Cocos2dx游戏开发系列笔记4:怎样新加一个Scene类?

Cocos2dx游戏开发系列笔记3:牛刀小试->忍者飞镖射幽灵的Demo

Cocos2dx游戏开发系列笔记2:一个刚创建的cocos2dx中的demo里都有什么

Cocos2dx游戏开发系列笔记1:一个崭新的开始,cocos2dx2.2+ndkr9+Cygwin

-------- 飞船降落--------------------

最后,骨头介绍一下陪在身边的哲哲(右边就是低调的哲哲)

哲哲,小名 YIYI ,手工爱好者,文艺范,手艺人,《YiYiの妙舍》创始人,很有自己想法。

转载于:https://my.oschina.net/kaiyuan/blog/182673

Cocos2dx游戏开发系列笔记7:一个简单的跑酷游戏《萝莉快跑》的消化(附下载)...相关推荐

  1. Cocos2dx游戏开发系列笔记7:一个简单的跑酷游戏《萝莉快跑》的消化(附下载)

    懒骨头(http://blog.csdn.net/iamlazybone  QQ124774397 青岛 ) 或许有天 我们羡慕和崇拜的人 因为我们的努力 也会来了解我们 说不定 还会成为好友 骨头喜 ...

  2. Cocos2dx游戏开发系列笔记8:开搞一个射击游戏《战神传说》//就个打飞机的

    2019独角兽企业重金招聘Python工程师标准>>> 又是一个愉快的夜晚 还是那张长长的工作桌 哲哲在左边做一个香云纱手包 骨头在这里噼里啪啦的解刨 pad里放着<赢在中国& ...

  3. Cocos2dx游戏开发系列笔记6:怎样让《萝莉快跑》的例子运行在vs和手机上

    2019独角兽企业重金招聘Python工程师标准>>> 感谢听D同学赞助的Demo. 那怎样让它运行在vs中呢: 1 使用cocos2d-x-2.2\tools\project-cr ...

  4. Cocos2dx游戏开发系列笔记3:牛刀小试-忍者飞镖射幽灵的Demo

    2019独角兽企业重金招聘Python工程师标准>>> 就是这个例子,应该很简单,主要用到的有:精灵的移动,触摸,碰撞检测. 赶紧搞定,待会还要陪哲哲来几局爱消除. 首先在Scene ...

  5. Cocos2dx游戏开发系列笔记5:继续润色《忍者飞镖射幽灵》

    2019独角兽企业重金招聘Python工程师标准>>> 周末了,哲哲在旁边看<爸爸去哪>,骨头继续玩cocos2dx, 首先,如果你新加了CPP和H文件,记得修改项目目录 ...

  6. Cocos2dx游戏开发系列笔记5:继续润色《忍者飞镖射幽灵》(VS2013快捷键)

    懒骨头(http://blog.csdn.net/iamlazybone  QQ124774397 青岛 ) 周末了,哲哲在旁边看<爸爸去哪>,骨头继续玩cocos2dx, 源码下载 ht ...

  7. Cocos2dx游戏开发系列笔记9:android手机上运行《战神传说》,并解决横竖屏即分辨率自适应问题

    转载:http://blog.csdn.net/iamlazybone/article/details/17191539 懒骨头(http://blog.csdn.net/iamlazybone  Q ...

  8. Cocos2dx游戏开发系列笔记10:解刨《战神传说》

    2019独角兽企业重金招聘Python工程师标准>>> 有点困了,从桌子换到床上,刚要开敲,豆瓣电台传来的传来奇怪的歌声"马的-马的-" 看看歌词,应该是&quo ...

  9. Cocos2dx游戏开发系列笔记11:解刨《战神传说》完结篇

    懒骨头(http://blog.csdn.net/iamlazybone QQ:124774397 ) 两点: 1 感谢 net19880504 同学,在上篇提到:想让骨头继续写<战神传说> ...

最新文章

  1. CSS中实现DIV容器垂直居中
  2. QT的QFileDialog类的使用
  3. java字符函数_java字符串函数用法汇总
  4. uniapp ios时间戳获取不到_2折甩卖、货架被抢空…青岛这家大超市要关门,开业不到两年!停业时间戳...
  5. java 模拟登陆 post_Java开发网 - 高手帮忙啊 (如何用java模拟post方式进行登陆论坛?)...
  6. ffmpeg 2.6.3在Linux下的编译
  7. MySQL中的LIMIT 关键字
  8. stuiod3t-2019030.dmg下载及studio3t macOS Cracking教程
  9. Tumblr,instapaper分享
  10. 快快网络融合CDN是什么
  11. 如何把自己打造成为一名金领架构师-前言
  12. oracle如何获取xml节点,oracle解析xml,带命令空间的节点获取
  13. VR眼镜连接android设备,如何将VR眼镜的屏幕投影到计算机或电视上?
  14. 购物车模块redis和mysql_redis解决购物车的问题
  15. 大数据产业到底是机遇还是陷阱?
  16. HDLBits练习(三)多路复用器,算术电路,卡诺图电路
  17. 合成大西瓜之抱歉~ 我只有大西瓜和刀剑神域~!!
  18. Android Canvas 缩放(Scale)
  19. 《成为沃伦·巴菲特》笔记与感想
  20. 小程序关注公众号组件<official-account ></official-account>的使用方法

热门文章

  1. html5 多点触控 缩放,WebBrowser禁用触摸缩放
  2. Python代码及其依赖环境打包成exe程序,发给别人双击即可运行程序,无需安装python和python依赖包
  3. python matplotlib中误差棒图
  4. freemaker 导出自动分页word文档
  5. google使用方法及技巧
  6. 密码就快要彻底消失了,没有人怀念它
  7. HTML5面试题及答案
  8. JAVA社区团购系统计算机毕业设计Mybatis+系统+数据库+调试部署
  9. ASP.NET Core 中简单Session登录校验
  10. ArcGIS如何获取地理要素的几何属性