学习游戏编程是一件非常有趣的事情,在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的更多相关文章

  1. [LeetCode] Flip Game 翻转游戏之二

    You are playing the following Flip Game with your friend: Given a string that contains only these tw ...

  2. [LeetCode] Jump Game II 跳跃游戏之二

    Given an array of non-negative integers, you are initially positioned at the first index of the arra ...

  3. 猜字符游戏之java

    package days06; //需求......,问题,为什么要用do{}while???import java.util.Scanner;public class RepeatOfGussing ...

  4. 从腾讯QQ升级游戏之“快速加入游戏”功能的实现缺陷看C/S之间如何正确分配相关协作

    转载:http://space.itpub.net/17007506/viewspace-615570 笔者在闲暇时,偶尔会登录腾讯QQGame玩玩升级游戏.这确实是一款非常优秀的软件作品,腾讯的开发 ...

  5. 键盘游戏之canvas--用OO方式写

    虽然写的不是很好,但 解释权以及版权仍然归13东倍所有!  <!DOCTYPE HTML> <html> <head> <title>canvas-00 ...

  6. [Swift]LeetCode294. 翻转游戏之 II $ Flip Game II

    You are playing the following Flip Game with your friend: Given a string that contains only these tw ...

  7. [LeetCode] Flip Game II 翻转游戏之二

    You are playing the following Flip Game with your friend: Given a string that contains only these tw ...

  8. html5游戏之Box2d物理引擎集成

    前面两章我们已经研究了如何使用Box2d来模拟游戏世界,这一章就把所有的东西拼凑在一起,最终完成我们的游戏. 一.定义物体 典型的物体: {type:'ground',name:'dirt',x:50 ...

  9. Unity2D 小游戏之 RocketMouse

    这个小游戏源自这里.这几天闲时捡了点 Unity(很久没有摸它了),顺手将这个小游戏移植到了 Unity5.5.0,除了 Parallax Scrolling 还有点小问题外,其它功能全部完整.部分代 ...

随机推荐

  1. visio 使用技巧汇总

    1.visio中图形旋转任意角度的方法 视图----任务窗格----大小与位置----角度 2.箭头形状 更多形状---流程图----箭头形状 3.汇制虚线框 从基本形状中拖出一个矩形,右击矩形,选择 ...

  2. 老男孩python作业9-简单的商城页面布局

    利用HTML相关知识编写下面的网页: 核心代码如下: <!DOCTYPE html> <html lang="en"> <head> <m ...

  3. 读经典——《CLR via C#》(Jeffrey Richter著) 笔记_引用类型和值类型(二)

    [引用类型和值类型的区别] //引用类型(由于使用了‘class’) class SomeRef { public Int32 x; } //值类型(由于使用了‘struct’) struct Som ...

  4. java 学习原生jdbc

    public class App { public static void main( String[] args ) { //JDBC驱动 String driverName = "com ...

  5. redis 学习字符类型 hash

    > HSET userinfo1 username "king" (integer) > HSET userinfo1 passowor " (integer ...

  6. 删除重复数据,保留一条ID最小的

    SELECT * from TBCITY_Temp where code  in (  select    code    from TBCITY_Temp    group by code  hav ...

  7. hive参数设置

    -- 设置hive的计算引擎为spark set hive.execution.engine=spark; -- 修复分区 set hive.msck.path.validation=ignore; ...

  8. hdu 6288(二分法加精度处理问题)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6288 题意:给出a,b,k,n可满足(n^a)*(⌈log2n⌉)^b<=k ,求最大的n值三个 ...

  9. vue 之 vuex

    Vuex 什么是Vuex?  官方说法:Vuex 是一个专为 Vue.js应用程序开发的状态管理模式.它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化. 个人 ...

  10. error creating bean with name 'defaultvalidator' defined in class path resource

    场景: 1.直接用eclipse 运行没问题(本地用的tomcat是7.0.70): 2.打包发布到服务器运行也没问题(服务器tomcat是8.5.30): 3.将打包发布的放到本地tomcat(7. ...