cocos2d-x游戏之2048
学习游戏编程是一件非常有趣的事情,在cocos2dx官网找了几个简单的游戏试试手,感觉也不是那么难,首先来看看2048这款游戏吧,很火的原因之一是因为它简单而易操作。网上这位Legendof1991大神很早就写过了,我大部分代码都是根据他的文章来的,但是也有些细节的地方自己修改了,下面就正是进入游戏吧。
先书写一下整个游戏的流程图:
图1 2048简单流程图
一、主场景的创建 |
首先还是新建一个工程,名字随便你怎么取,然后按照老规矩该添加图层就添加图层。先来看下它的头文件:
class HelloWorld : public cocos2d::Layer
{
public: // there's no 'id' in cpp, so we recommend returning the class instance pointer
static cocos2d::Scene* createScene(); // Here's a difference. Method 'init' in cocos2d-x returns bool, instead of returning 'id' in cocos2d-iphone
virtual bool init(); // a selector callback
void menuCloseCallback(cocos2d::Ref* pSender); // implement the "static create()" method manually
CREATE_FUNC(HelloWorld); virtual bool onTouchBegan(Touch *touch, Event *unused_event);
virtual void onTouchEnded(Touch *touch, Event *unused_event); bool doUp();
bool doDown();
bool doLeft();
bool doRight(); //创建卡片函数
void createCard(Size size);
void autoCreateCardNumber();
//判断游戏是否能够继续
void doCheckGameOver();
private:
int firstX,firstY,endX,endY;
CardSprite* cardArray[][];
//游戏得分
int score;
CCLabelTTF *labelTTFScoreName;
CCLabelTTF* labelTTFScoreNumber; }; #endif // __HELLOWORLD_SCENE_H__
其中这两个函数virtual bool onTouchBegan(Touch *touch, Event *unused_event);virtual void onTouchEnded(Touch *touch, Event *unused_event);主要是用来判断触屏滑动的方向。
void HelloWorld::onTouchEnded(Touch *touch, Event *unused_event)
{
Point touchPoint=touch->getLocation();
//touch->getLocationInView();
endX=firstX-touchPoint.x;
endY=firstY-touchPoint.y;
if (abs(endX)>abs(endY))
{
if(endX+>)
{
//向左
doLeft();
}
else
{
//向右
doRight();
}
}
else
{
if(endY+>)
{
//向下
doDown();
}
else
{
//向上
doUp();
}
}
}
这段代码通过世界坐标和窗口坐标之间的差值来判断的,经过测试可行。具体的原理他也没有说明。
二、卡片的创建 |
卡片我们需要新建一个卡片类来实现,类中我们需要设置一些初始化动作,我把他放在下面这个函数中。
CardSprite* CardSprite::createCardSprite(int numbers,int width,int height,float CardSpriteX,float CardSpriteY)
{
//CardSprite *enemy=new CardSprite();
CardSprite* enemy=CardSprite::create();
//CardSprite* enemy=new CardSprite(); if (enemy&&enemy->init())
{
//enemy->autorelease(); //自动释放,这种写法比较好,如果没有初始化好的话也可以安全删除
enemy->enemyInit(numbers,width,height,CardSpriteX,CardSpriteY);
enemy->retain(); //记得release
return enemy;
}
CC_SAFE_DELETE(enemy); //安全释放
return NULL;
}
其中我们需要注意的地方是如果你用create函数之后,需要retain一次,不需要用了则要release,原文博客中用的是这两句:CardSprite *enemy=new CardSprite();enemy->autorelease();他这样处理的好处就是内存由内存池自动管理了。
三、算法分析 |
每个游戏核心都是算法处理。2048也不例外,它的核心思想是每行每列遇到相同的数字则一个乘以2,另一个卡片变成0,例如我们向左滑动的时候代码可以这样写,时间复杂度o(N3),其它三个方向的算法思路也是一样的。
bool HelloWorld::doLeft()
{
bool isdo = false;
for (int y = ; y < ; y++)
{
for (int x = ; x < ; x++)
{ for (int x1 = x + ; x1 < ; x1++)
{
if (cardArray[x1][y]->getNumbers() > )
{
if (cardArray[x][y]->getNumbers() <= )
{
cardArray[x][y]->setNumbers(cardArray[x1][y]->getNumbers());
cardArray[x1][y]->setNumbers(); x--; //这里不会发生溢出,原来已经x1++了。
isdo = true;
}else if(cardArray[x][y]->getNumbers() == cardArray[x1][y]->getNumbers())
{
cardArray[x][y]->setNumbers(cardArray[x][y]->getNumbers()*);
cardArray[x1][y]->setNumbers();
score+=cardArray[x][y]->getNumbers();
labelTTFScoreNumber->setString(String::createWithFormat("%i",score)->getCString());
isdo = true;
}
break;
}
}
}
}
return isdo;
}
至于当你的卡片消除之后,主层中多于两个卡片空位时,你需要添加两张卡片填充空位,至于位置也是随机分布的,它采用递归的方式寻找没有数字的卡片。来看段代码:
void HelloWorld::autoCreateCardNumber()
{
int i=CCRANDOM_0_1()*; //随机生成数字0-4
int j=CCRANDOM_0_1()*; //随机生成数字
if (cardArray[i][j]->getNumbers()>)
{ //有数字则递归调用直到有空白的地方为止
autoCreateCardNumber();
}
else
{
cardArray[i][j]->setNumbers(CCRANDOM_0_1()*<?:); //乘以10之后看是否小于1,出现2或者4,这里就是卡片出现的概率问题了
} }
四、总结 |
整个游戏的难点大概就是这些吧,至于其他一些细节的地方大家可以看他的原文,这个游戏主要涉及到的难点就是卡片的消除及消除之后如何再把数字随机的添加到卡片上。下期任务是写一个简单版的打飞机游戏。望诸君共勉!
作者:曹麒文
出处:http://www.cnblogs.com/master-image/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面
cocos2d-x游戏之2048的更多相关文章
- [LeetCode] Flip Game 翻转游戏之二
You are playing the following Flip Game with your friend: Given a string that contains only these tw ...
- [LeetCode] Jump Game II 跳跃游戏之二
Given an array of non-negative integers, you are initially positioned at the first index of the arra ...
- 猜字符游戏之java
package days06; //需求......,问题,为什么要用do{}while???import java.util.Scanner;public class RepeatOfGussing ...
- 从腾讯QQ升级游戏之“快速加入游戏”功能的实现缺陷看C/S之间如何正确分配相关协作
转载:http://space.itpub.net/17007506/viewspace-615570 笔者在闲暇时,偶尔会登录腾讯QQGame玩玩升级游戏.这确实是一款非常优秀的软件作品,腾讯的开发 ...
- 键盘游戏之canvas--用OO方式写
虽然写的不是很好,但 解释权以及版权仍然归13东倍所有! <!DOCTYPE HTML> <html> <head> <title>canvas-00 ...
- [Swift]LeetCode294. 翻转游戏之 II $ Flip Game II
You are playing the following Flip Game with your friend: Given a string that contains only these tw ...
- [LeetCode] Flip Game II 翻转游戏之二
You are playing the following Flip Game with your friend: Given a string that contains only these tw ...
- html5游戏之Box2d物理引擎集成
前面两章我们已经研究了如何使用Box2d来模拟游戏世界,这一章就把所有的东西拼凑在一起,最终完成我们的游戏. 一.定义物体 典型的物体: {type:'ground',name:'dirt',x:50 ...
- Unity2D 小游戏之 RocketMouse
这个小游戏源自这里.这几天闲时捡了点 Unity(很久没有摸它了),顺手将这个小游戏移植到了 Unity5.5.0,除了 Parallax Scrolling 还有点小问题外,其它功能全部完整.部分代 ...
随机推荐
- Linux下的hosts文件和network文件区别
Linux下的hosts文件和network文件区别 Linux下有两种与计算机名相关的配置文件 1.hosts文件,路径:/etc/hosts,此文间是在网络上使用的, 用于解析计算机名 ...
- PHP删除目录下的空目录
function rm_empty_dir($path){ if(is_dir($path) && ($handle = opendir($path))!==false){ ...
- gitflow工作流简介
gitflow工作流是一种依赖于Git版本管理工具,按特定规范对项目开发.测试.上线流程进行管理的工作方式.它是一种为实现规范化管理的约定,它明确了各个分支的意义,使整个团队的分工协作更加和谐明晰. ...
- Navicat安装教程、建表教程
1.安装教程: 转自:https://www.jianshu.com/p/5f693b4c9468 2.使用教程(建表操作): https://jingyan.baidu.com/article/e6 ...
- Windows任务计划创建计划,定时执行PowerShell命令
[环境介绍] 操作系统:Windows Server 2012 R2,64位操作系统 PowerShell版本:PowerShell 1.0 脚本位置:C:\BackUp.ps1 启动目录:C:\Wi ...
- TortoiseGit安装简单介绍和使用
首先,你必须有会装软件的技能和一个看得懂英语的眼睛.然后保证Git也装好了 他提供了中文版的安装包哦 安装过程尽量选择默认就行,先装上面那个啊,语言包最后装. 语言配置 因为以前装过,所以...路径是 ...
- Lintcode 摊平嵌套的列表
/** * // This is the interface that allows for creating nested lists. * // You should not implement ...
- 线段树 区间更新(更新区间[x,y]的值,再求任意区间[x,y]的和)
#1078 : 线段树的区间修改 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 对于小Ho表现出的对线段树的理解,小Hi表示挺满意的,但是满意就够了么?于是小Hi将问题 ...
- day25 网络编程之socket sc架构
1. 为什么要学习socket? socket就是网络通信的工具,任何一门语言都有socket,他不是任何一个语言的专有名词,而是大家通过自己的程序与其他电脑进行网络通信的时候都用它. 2. 客户 ...
- jinkens + svn 把代码更新到本地在运行。(方法比较笨,只是想实现自己的想法。把代码更新下来在运行。)
jinkens + svn 把代码更新到本地在运行.