***************************************转载请注明出处:http://blog.csdn.net/lttree******************************************

不知不觉。都10月5号了,

十一大假期快结束了

不开心啊, 有木有。。!

算了,接着发 2048 吧,这是第五篇了,

也非常快了呀,2048系列。立即就要结束了。

这篇文章主要讲述:

—— 对于游戏相关移动和游戏结束的判定

—— 游戏音效的加入

—— 游戏分数的加入

直接正文:

1. 游戏方向是否能移动 和 游戏结束的判定

这俩为什么放一块呢?

我的方法是在.h建立4个bool变量:是否能向上移动、是否能向下移动、。。。

这样。假设四个方向都不能移动,即为游戏结束了。

为这个判定,单独建立一个函数:

<span style="font-family:Comic Sans MS;">void GameScene::judgeMove()
{
int r , c;
isMoveUp = false;
isMoveDown = false;
isMoveRight = false;
isMoveLeft = false; // 向上能否移动
for( r = 0 ; r < GAME_ROWS - 1 ; ++r )
{
for( c = 0 ; c < GAME_COLS ; ++c )
{
if( map[r+1][c] == 0 )
{
if( map[r][c] != 0 ) { isMoveUp = true; break; }
}
else
{
if( map[r][c] != 0 )
{
if( m_allTiled.at( map[r][c] - 1 ) -> m_number == m_allTiled.at( map[r+1][c] - 1 ) -> m_number )
{ isMoveUp = true; break; }
}
}
}
if( isMoveUp == true ) break;
} // 向下能否移动
for( r = GAME_ROWS-1 ; r > 0 ; --r )
{
for( c = 0 ; c < GAME_COLS ; ++c )
{
if( map[r-1][c] == 0 )
{
if( map[r][c] != 0 )
{ isMoveDown = true; break; }
}
else
{
if( map[r][c] != 0 )
{
if( m_allTiled.at( map[r][c] - 1 ) -> m_number == m_allTiled.at( map[r-1][c] - 1 ) -> m_number )
{ isMoveDown = true; break; }
}
}
}
if( isMoveDown == true ) break;
} // 向左能否移动
for( c = 0 ; c < GAME_COLS-1 ; ++c )
{
for( r = 0 ; r < GAME_ROWS ; ++r )
{
if( map[r][c+1] == 0 )
{
if( map[r][c] != 0 ) { isMoveRight = true; break; }
}
else
{
if( map[r][c] != 0 )
{
if( m_allTiled.at( map[r][c] - 1 ) -> m_number == m_allTiled.at( map[r][c+1] - 1 ) -> m_number )
{ isMoveRight = true; break; }
}
}
}
if( isMoveRight == true ) break;
} // 向右能否移动
for( c = GAME_COLS-1 ; c > 0 ; --c )
{
for( r = 0 ; r < GAME_ROWS ; ++r )
{
if( map[r][c-1] == 0 )
{
if( map[r][c] != 0 ) { isMoveLeft = true; break; }
}
else
{
if( map[r][c] != 0 )
{
if( m_allTiled.at( map[r][c] - 1 ) -> m_number == m_allTiled.at( map[r][c-1] - 1 ) -> m_number )
{ isMoveLeft = true; break; }
}
}
}
if( isMoveLeft == true ) break;
}
}</span>

以是否能向上移动来解析一下这种方法:

从最以下一行第一列到倒数第二行最后一列,进行两层循环:

——首先推断同列的上面那一行,是否为0(即是否是空的格子,没有数字块)

————假设为空,推断这一行是否为空

——————不为空。则能够向上移动

——————为空。则不能移动

————假设不为空,推断本行对应列是否为空

——————为空,则不能移动

——————不为空,推断本行与上一行同列的是否同样

————————同样。则能够移动

————————不同。不能移动

依据前面“——”长短,能够看出,推断等级。

然后,建立游戏结束界面的类~GameOverScene:

<span style="font-family:Comic Sans MS;font-size:12px;">#ifndef __test2048_GameOverScene_H__
#define __test2048_GameOverScene_H__ #include "cocos2d.h" USING_NS_CC; class GameOver: public Layer
{
public:
virtual bool init();
static Scene * createScene();
CREATE_FUNC(GameOver); // 又一次開始游戏 的回调函数
void menuRestartCallback( Ref * pObject );
// 退出 的回调函数
void menuExitCallback( Ref * pObject );
}; #endif</span>

.cpp:

<span style="font-family:Comic Sans MS;font-size:14px;">#include "GameOverScene.h"
#include "GameDefine.h"
#include "GameScene.h" Scene * GameOver::createScene()
{
auto scene = Scene::create();
auto * layer = GameOver::create(); scene -> addChild( layer ); return scene;
} bool GameOver::init()
{
if( !Layer::init() )
{
return false;
} // 又一次開始游戏
auto restartItem = MenuItemFont::create(" Restart ",CC_CALLBACK_1(GameOver::menuRestartCallback,this));
restartItem -> setPosition( Point( GAME_SCREEN_WIDTH/2,GAME_SCREEN_HEIGHT/2)); // 退出游戏
auto exit = MenuItemFont::create(" Exit ",CC_CALLBACK_1(GameOver::menuExitCallback,this));
exit -> setPosition( Point( GAME_SCREEN_WIDTH/2,GAME_SCREEN_HEIGHT/3 )); auto menu = Menu::create(restartItem,exit,NULL);
menu -> setPosition(Point::ZERO);
this -> addChild(menu); return true;
} void GameOver::menuRestartCallback(Ref * pObject)
{
auto scene = GameScene::createScene();
Director::getInstance() -> replaceScene(CCTransitionProgressRadialCCW::create(1,scene));
} void GameOver::menuExitCallback(Ref * pObject)
{
Director::getInstance()->end();
}</span><span style="font-size:18px;">
</span>

Ok,游戏结束界面已经搞定,能够改一下AppDelegate.cpp ,让游戏直接进入 GameOver界面,看看什么样子:

游戏结束界面,就是这样子的~

做到这里。你们会不会 非常嫌弃,卧XXXX,这么丑。

好吧,是非常丑,

可是,这系列教程主要是,说明怎样开发一款 2048 。

详细自己做的东东,能够自己DIY的~

选择一个自己喜欢的背景图片,选择图片button神马的,

包装一下,就相当美丽啦~

但这些的前提是,要会怎么做2048,要知道 ,我想增加什么。应该在哪里改变什么,加什么。

而这系列教程,就是在说明。2048的制作及解析~

废话不多说。继续下去,要将GameScene中 moveAllTiled函数改变一下啦~:

<span style="font-family:Comic Sans MS;font-size:14px;">void GameScene::moveAllTiled( MOVE_DIR dir )
{
// 推断 并 移动全部块 消除
judgeMove(); // 假设上下左右都不能移动,则游戏结束~
if( !isMoveLeft && !isMoveRight && !isMoveUp && !isMoveDown )
{
auto * scene = Scene::create();
GameOver * layer = GameOver::create();
scene -> addChild( layer ); Director::sharedDirector() -> replaceScene(CCTransitionFadeDown::create(1.5f,scene)); } // 依据方向移动,可是要先推断能否够向那个方向移动
switch ( dir )
{
case MOVE_DIR::UP:
if( !isMoveUp ) return;
moveUp();
break;
case MOVE_DIR::DOWN:
if( !isMoveDown ) return;
moveDown();
break;
case MOVE_DIR::LEFT:
if( !isMoveLeft ) return;
moveLeft();
break;
case MOVE_DIR::RIGHT:
if( !isMoveRight ) return;
moveRight();
break;
default: break;
} // 产生新块
newNumberTiled();
}</span>

对于,游戏结束方面,到这里就结束啦~

2.加入音效

对于2048,我认为还是不要加入背景音乐了。非常突兀的感觉的说,

我仅仅是简单加了两个音效,假设有数字合并。一个成功的小音效。

假设没有数字合并,则是滑动的音效。

当然。先把对应文件放到Resource目录下。并在VS2012中加入现有项。加入进来,

然后在程序中,也须要进行载入。

我选择是在主界面跳到游戏界面之前,进行载入:

<span style="font-family:Comic Sans MS;font-size:14px;">// 载入音效
SimpleAudioEngine::getInstance() -> preloadEffect("move.wav");
SimpleAudioEngine::getInstance() -> preloadEffect("move1.wav");</span>

当然,之前要加入音效的头文件:

<span style="font-family:Comic Sans MS;font-size:14px;">#include "SimpleAudioEngine.h"

using namespace CocosDenshion;</span>

然后。在游戏移动全部块函数中。加入声音播放:

如今。头文件加入两个bool变量:

<span style="font-family:Comic Sans MS;font-size:14px;">	// 播放哪个音乐
bool m_sound_clear;</span>

GameScene.cpp——moveAllTiled:

<span style="font-family:Comic Sans MS;font-size:12px;">void GameScene::moveAllTiled( MOVE_DIR dir )
{
// 推断 并 移动全部块 消除
judgeMove(); // 假设上下左右都不能移动,则游戏结束~
if( !isMoveLeft && !isMoveRight && !isMoveUp && !isMoveDown )
{
auto * scene = Scene::create();
GameOver * layer = GameOver::create();
scene -> addChild( layer ); Director::sharedDirector() -> replaceScene(CCTransitionFadeDown::create(1.5f,scene)); }
</span>
<span style="font-family:Comic Sans MS;font-size:12px;"><span style="white-space:pre">	</span>m_sound_clear = false;</span>
<span style="font-family:Comic Sans MS;font-size:12px;">	// 依据方向移动。可是要先推断能否够向那个方向移动
switch ( dir )
{
case MOVE_DIR::UP:
if( !isMoveUp ) return;
moveUp();
break;
case MOVE_DIR::DOWN:
if( !isMoveDown ) return;
moveDown();
break;
case MOVE_DIR::LEFT:
if( !isMoveLeft ) return;
moveLeft();
break;
case MOVE_DIR::RIGHT:
if( !isMoveRight ) return;
moveRight();
break;
default: break;
} // 播放音乐
if( m_sound_clear )
{
SimpleAudioEngine::getInstance() -> playEffect("move.wav");
}
else
{
SimpleAudioEngine::getInstance() -> playEffect("move1.wav");
} // 产生新块
newNumberTiled();
}</span>

然后,在对应移动函数中。要设置m_sound_clear的值:

就是在moveUp,moveDown,moveLeft,moveRight对应位置。进行设置

在数字合并的推断语句下(推断numNow==numObj处),进行:

m_sound_clear = true;

Ok,我们能够执行。感受一下啦~

假设对于,音效,还有什么疑问,能够看我之前写的文章,专门说音效的博文:戳我~

接下来。就是关于分数的设置啦~

3.分数的加入

首先,在游戏界面,头文件设置。整型的分数变量

然后在初始化函数设定分数的位置:

GameScene.cpp——init:

<span style="font-family:Comic Sans MS;font-size:12px;">	TTFConfig config("HelloKitty.ttf",40);

	// 分数
score = 0;
auto labelScore = Label::createWithTTF(config, "Score : 0 ");
labelScore -> setPosition( Point(GAME_SCREEN_WIDTH/2,GAME_SCREEN_HEIGHT - 1.5*labelScore->getContentSize().height));
this->addChild(labelScore);
labelScore -> setTag(105);</span>

我们分数的添加是,每合成一个新数字,加上所生成的数字,

比方两个2生成了一个4。则分数+4。

两个512 生成了一个 1024,则分数+1024,

所以,分数改变的位置 和 设置音乐的位置一样,

由于仅仅有合成成功的时候,分数才会添加:

<span style="font-family:Comic Sans MS;font-size:14px;">if( numNow == numObj )
{
m_sound_clear = true;
score += numObj * 2;</span>

然后,还要在移动全部块以后,更新分数:

GameScene.cpp——moveAllTiled:

<span style="font-family:Comic Sans MS;font-size:14px;">// 分数更新
Label *labelScore = (Label *)this -> getChildByTag(105);
labelScore -> setString( StringUtils::format(" Score : %d ",score));</span>

好的啦~。~ 分数也更新完了。

执行一下。看看效果~

正常执行哟~

嘿嘿。第五篇就到这里了。

下一篇就是终于章了

安卓平台移植~

这系列真的要结束了呢

第五篇代码:http://pan.baidu.com/s/1mgHWcyO

***************************************转载请注明出处:http://blog.csdn.net/lttree********************************************

cocos2d-x 3.2 之 2048 —— 第五篇的更多相关文章

  1. 【Python五篇慢慢弹】快速上手学python

    快速上手学python 作者:白宁超 2016年10月4日19:59:39 摘要:python语言俨然不算新技术,七八年前甚至更早已有很多人研习,只是没有现在流行罢了.之所以当下如此盛行,我想肯定是多 ...

  2. 【Python五篇慢慢弹】数据结构看python

    数据结构看python 作者:白宁超 2016年10月9日14:04:47 摘要:继<快速上手学python>一文之后,笔者又将python官方文档认真学习下.官方给出的pythondoc ...

  3. 【Python五篇慢慢弹(3)】函数修行知python

    函数修行知python 作者:白宁超 2016年10月9日21:51:52 摘要:继<快速上手学python>一文之后,笔者又将python官方文档认真学习下.官方给出的pythondoc ...

  4. 【Python五篇慢慢弹(4)】模块异常谈python

    模块异常谈python 作者:白宁超 2016年10月10日12:08:31 摘要:继<快速上手学python>一文之后,笔者又将python官方文档认真学习下.官方给出的pythondo ...

  5. 【Python五篇慢慢弹(5)】类的继承案例解析,python相关知识延伸

    类的继承案例解析,python相关知识延伸 作者:白宁超 2016年10月10日22:36:57 摘要:继<快速上手学python>一文之后,笔者又将python官方文档认真学习下.官方给 ...

  6. 解剖SQLSERVER 第十五篇 SQLSERVER存储过程的源文本存放在哪里?(译)

    解剖SQLSERVER 第十五篇  SQLSERVER存储过程的源文本存放在哪里?(译) http://improve.dk/where-does-sql-server-store-the-sourc ...

  7. 解剖SQLSERVER 第五篇 OrcaMDF里读取Bits类型数据(译)

    解剖SQLSERVER 第五篇  OrcaMDF里读取Bits类型数据(译) http://improve.dk/reading-bits-in-orcamdf/ Bits类型的存储跟SQLSERVE ...

  8. 前端工程师技能之photoshop巧用系列第五篇——雪碧图

    × 目录 [1]定义 [2]应用场景 [3]合并[4]实现[5]维护 前面的话 前面已经介绍过,描述性图片最终要合并为雪碧图.本文是photoshop巧用系列第五篇——雪碧图 定义 css雪碧图(sp ...

  9. Python之路【第十五篇】:Web框架

    Python之路[第十五篇]:Web框架   Web框架本质 众所周知,对于所有的Web应用,本质上其实就是一个socket服务端,用户的浏览器其实就是一个socket客户端. 1 2 3 4 5 6 ...

随机推荐

  1. 谷歌浏览器(chrome) —— 扩展应用程序

    工具的使用--谷歌浏览器(chrome) (二) 1. 设置和下载方法 右上角菜单按钮 ⇒ 更多工具(more tools) ⇒ 扩展(Extensions) 打开该页面之后,会首先进入扩展(已安装应 ...

  2. React 16 服务端渲染的新特性

    React 16 服务端渲染的新特性 React 16 中关于服务端渲染的新特性 快速介绍React 16 服务端渲染的新特性,包括数组.性能.流等 React 16 终于来了!

  3. JDK和Cglib实现动态代理实例及优缺点分析

    Spring AOP使用的核心技术是动态代理,说到动态代理就不得不和设计模式中的代理模式联系起来,通过代理模式我们可以对目标类进行功能增强,在某个方法的执行前后增加一些操作,例如计算方法执行效率.打印 ...

  4. 有关Gradle Network is unreachable: connect的报错

    项目Gradle   Errer:Network is unreachable: connect 同时还有as的 报错 Internal HTTP server disabled: Cannot st ...

  5. java加密解密算法位运算

    一.实例说明 本实例通过位运算的异或运算符 “ ^ ” 把字符串与一个指定的值进行异或运算,从而改变每个字符串中字符的值,这样就可以得到一个加密后的字符串.当把加密后的字符串作为程序输入内容,异或运算 ...

  6. mysql组复制集群简介

    mysql组复制集群拓扑: 环境: centos6.5 mysql5.7.19 一.组复制搭建: 配置hosts文件 再三台服务器上分别启动一个mysql实例,共三个. 参考配置文件如下: serve ...

  7. Python中用绘图库绘制一条蟒蛇

    一..构思设计蟒蛇的长度颜色等 首先,我们来构思一个简单的蟒蛇.让它的颜色为黄色,形状为一条正在爬行的蟒蛇. 二..准备绘图库 Python中有一个绘图库叫turtle我们先引入它. import t ...

  8. http请求后台报406错误

    1.springMVC的项目,通过浏览器访问后台方法遇到了报406的错误,找了很多原因,最终发现是因为缺少spring-mvc的json配置. 2.添加依赖:jackson-databind.jack ...

  9. 理解Faster-RCNN 中的Anchor

    先上图看一下Faster R-CNN操作流程:  图片说明:Faster R-CNN=Fast R-CNN+RPN,其中Fast R-CNN结构不变:RPN负责生成proposals,配合最后一层的f ...

  10. 动态规划——Buyer

    题目链接 题目描述 哆啦A梦班级举办个party,当然吃的东西必不可少,哆啦A梦负责采购任务,他得到了一份清单,上面注明不同食品的受欢迎程度,哆啦A梦需要用一定的价钱尽可能达到的更大的受欢迎程度!例如 ...