cocos2d-x路~使得第一个字游戏(一个)
前言
去年的回忆。另外,在第三、他们开发了他们的第一场比赛四月,它是游戏。所以我决定走上独立开发的道路上。了。第一款游戏达到它应有的盈利水平。然而这款游戏开发后的时间里。都没再取得还有一款令自己惬意的作品。
直到今年的三、四月,我使用cocos2d-x开发出我的第一款文字游戏。
自从使用cocos2d-x后。发现自己爱上了这个引擎。
它也许还不够强大和完好。可是使用它。能够体验编码的乐趣。还能够为我重拾C++这门技术(究竟对C++有多么的执着啊),还能增进NDK和JNI的学习。恰恰满足我各种各样的追求。
这个第一款文字游戏。名字我取作Anagram Puzzle。事实上这款游戏是參照RayWenderlich上的这篇教程来改写的。教程里使用的是iOS的UIKit编写。虽说原理相通。可是在改写过程中还是遇到不少折腾的地方。因为初次编写cocos2d-x游戏。所以错误难免百出,希望阅读者们高抬贵手,点到即止……废话不多说,立即開始coco2d-x之道~怎样制作第一款文字游戏!
Anagram简单介绍
Anagram是一种把单词或短语的字母顺序打乱,又一次排列后变成一个新单词或短语的游戏。
比如,单词cinema能够又一次排列成iceman。游戏中就要求玩家进行你所提供单词或短语的又一次排列。完毕游戏的画面会如图所看到的:
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdTAxMTc4MTgzNA==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="">
在开发这个游戏过程中,会接触到下面这些知识:
- MVC型的游戏结构
- 怎样从文件配置载入级别
- 载入第三方字体
- 简单使用音乐音效
- 分离HUD层与游戏层
- 手势拖动及动画
- Particle的效果
首先最重要的当然是使用命令行来创建cocos2d-xproject,当然也有其它方法也能够创建project。可是我觉得掌握命令行来创建是必须的基本功。
创建方法能够在这里找到。创建完毕后各个平台的project目录都有了。我们的主要project目录是proj.android和proj.ios两个。
整个开发过程,我使用Mac OS来开发,所以编码是在XCode上进行,而Androidproject的编译则使用命令行,具体教程能够參考这里。
建立好project后,先把所需的资源文件复制到Resource目录中。打开Xcodeproject,眼下Resource目录下还是原来的资源文件,通过右击Resource目录 -> Add Files to ...,把资源文件都加到project里。编辑后project会如图
1)载入级别配置文件
打开level1.plist,能够看到里面内容
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdTAxMTc4MTgzNA==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="">
有三个最顶端的key,各自是:
pointsPerTile: 每一个单词填对后获得的分数。
timeToSolve: 解决这一关的时间(秒)。
anagrams: 是题目的列表,包括两个item。各自是原始的短语以及最后要拼出的短语。
level文件的介绍就到此为止。以下開始编写Level类,在Level.h中加入以下内容
class Level:public CCObject{
public:
static Level * levelWithNum(int levelNum); public:
int mPointPerTile;
int mTimeToSovle;
CCArray * pAnagrams;
};
当中,三个变量相应level文件中的三个最顶端的item。另一个初始化函数。是给外部调用初始化level文件。
如今。打开Level.cpp。实现levelWithNum函数
Level * Level::levelWithNum(int levelNum){
char fileName[50];
char fullPath[150];
sprintf(fileName,"level%d.plist",levelNum);
CCFileUtils::sharedFileUtils()->fullPathFromRelativeFile(fileName,fullPath);
CCDictionary * pListDict = CCDictionary::createWithContentsOfFile(fileName); if(pListDict == NULL){
CCLog("level config not found");
} Level * l = new Level();
CCString * tempStr;
tempStr = dynamic_cast<CCString*>(pListDict->objectForKey("pointsPerTile"));
l->mPointPerTile = tempStr->intValue();
tempStr = dynamic_cast<CCString*>(pListDict->objectForKey("timeToSolve"));
l->mTimeToSovle = tempStr->intValue();
l->pAnagrams = dynamic_cast<CCArray*>(pListDict->objectForKey("anagrams"));
l->pAnagrams->retain(); return l;
}
这里首先用CCDictionary读出level文件里数值,然后就是读取出相应key里的值,并存储起来。
如今。打开主界面文件。默认是HelloWorldScene类,可是我改写成MainScene,当中MainScene.h是这种
class MainScene : public cocos2d::CCLayer
{
public:
~MainScene();
// 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(); // implement the "static node()" method manually
CREATE_FUNC(MainScene);
private:
Level * pLevel;
};
可见。添加了Level变量。在MainScene.cpp中的init函数。编写
pLevel = Level::levelWithNum(1);
当然。这里能够通过CCLog来打印出pLevel里的内容来看看。会得到如图所看到的
在MainScene里加入个新的函数
void dealRandomAnagram();
详细实现要这样
void MainScene::dealRandomAnagram(){
Common::random(0, pLevel->pAnagrams->count() - 1);
int randomIndex = Common::random(0, pLevel->pAnagrams->count() - 1); CCAssert((randomIndex >= 0 && randomIndex < pLevel->pAnagrams->count()),"error random index!"); CCArray * anagram = (CCArray*)pLevel->pAnagrams->objectAtIndex(randomIndex); CCString * ana1 = (CCString*)anagram->objectAtIndex(0);
CCString * ana2 = (CCString*)anagram->objectAtIndex(1); int ana1len = ana1->length();
int ana2len = ana2->length();
}
Common::random是我自己编写的。生成两个数值之间的随机数
int Common::random(int s,int e){
float i = CCRANDOM_0_1()*(e-s+1)+s;
return (int)i;
}
这样就把初始状态的短语和终于状态的短语获取到了,把dealRandomAnagram函数加入到MainScene的init函数里。
pLevel = Level::levelWithNum(1);
dealRandomAnagram();
2)创建单词的View
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdTAxMTc4MTgzNA==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="">
在project中新增一个继承于CCNode的类,名字叫做TileView,在TileView.h中加入下面代码
public:
static TileView * initWithLetter(const char * l,float sideLen); private:
CCSprite * pSprite;
char mLetter;
bool mIsMatch;
当中initWithLetter是初始化函数,pSprite是显示的精灵。mLetter是相应的字母。mIsMatch表示结果是否已经配对上(就是找到字母所应该在的位置)。
在TileView.cpp里。加入下面代码
#include "TileView.h" TileView * TileView::initWithLetter(const char * l, float sideLen){
TileView * tile = new TileView();
CCSprite * bg = CCSprite::create("tile.png");
tile->addChild(bg);
tile->pSprite = bg;
float scale = sideLen / bg->getContentSize().width;
bg->setScale(scale); char chLetter[2];
sprintf(chLetter,"%c",l[0] - 32);
CCLabelTTF * letter = CCLabelTTF::create(chLetter,"Arial",75 * scale);
letter->setColor(ccWHITE);
tile->addChild(letter); tile->mIsMatch = false;
tile->mLetter = chLetter[0]; return tile;
}
函数中,首先的是创建一个以tile.png为图案的精灵。然后创建图案上的字母
接下来就要在界面中显示出来了。在MainScene中加入
private:
Level * pLevel;
CCArray * pTiles;
CCArray * pTargets;
pTiles是TileView的数组,pTargets是TargetView的数组,当中TileView是放在底部给出的短语的各个单词,TargetView是目标短语的各个单词。在MainScene.cpp的dealRandomAnagram函数中继续加入代码
int ana1len = ana1->length();
int ana2len = ana2->length(); float tileSide = ceilf( Common::getCameraWith()*0.9 / (float)std::max(ana1len, ana2len) ) - kTileMargin; float xOffset = (Common::getCameraWith() - std::max(ana1len,ana2len) * (tileSide + kTileMargin)) / 2;
xOffset += tileSide/2;
此时,開始计算各个TileView的位置。
首先,比較得出原始短语和目标短语中长度最长的。然后算出各个View所需的宽度tileSide,以及各个View之间的间隔xOffset
对了,不要忘了定义全局的空隙
#define kTileMargin 20
接着,就要创建我们的TileView了
pTiles = CCArray::createWithCapacity(ana1len); const char * ana1Letter = ana1->getCString();
for(int i = 0;i < ana1len; i++){
char letter[3];
sprintf(letter,"%c",ana1Letter[i]); if(letter[0] != ' '){
TileView * tile = TileView::initWithLetter(letter,tileSide);
tile->setPosition(ccp(xOffset + i * (tileSide + kTileMargin),Common::getCameraHeight() / 4));
this->addChild(tile);
pTiles->addObject(tile);
}
}
pTiles->retain();
创建方法比較简单。可是要注意的是,原始短语中能够会有空字符。空字符的地方须要留空。如图所看到的
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdTAxMTc4MTgzNA==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="">
3)单词View优化
方方正正的TileView看着有些拘谨,以下进行一些优化来让它们生动一些。
在TileView中加入randomize函数
void TileView::randomize(){
float rotation = Common::random(0,50) /(float)100 - 0.2;
this->setRotation(rotation * 10); int yOffset = Common::random(0,10);
this->setPositionY(this->getPositionY() + yOffset);
}
让TileView稍作旋转和偏移,然后在MainScene的dealRandomAnagram函数中的 this->addChild(tile); 语句后加入以下语句
tile->randomize();
4)加入TargetView
有了原始短语,以下就要開始创建目标短语的View了。对照TileView。TargetView要相对简单一些。由于它是固定位置及不须要显示字母。
TargetView.h中加入以下代码:
class TargetView : public CCNode
{
public:
TargetView(void);
~TargetView(void); static TargetView * initWithLetter(const char * l,float sideLen); private:
CCSprite * pSprite;
char mLetter;
bool mIsMatch;
};
与TileView相类似的。一个初始化函数,三个私有变量。
与TileView的是一一相应。
TargetView * TargetView::initWithLetter(const char * l, float sideLen){
TargetView * tile = new TargetView();
CCSprite * bg = CCSprite::create("slot.png");
tile->addChild(bg);
tile->pSprite = bg; float scale = sideLen / bg->getContentSize().width;
bg->setScale(scale); char chLetter[2];
sprintf(chLetter,"%c",l[0] - 32);
/*
CCLabelTTF * letter = CCLabelTTF::create(chLetter,"Arial",78 * scale);
letter->setColor(ccWHITE);
tile->addChild(letter);*/ tile->mIsMatch = false;
tile->mLetter = chLetter[0]; return tile;
}
TargetView的initWithLetter函数中,凝视的语句是为显示一下结果。可是在实际游戏中是不显示TargetView上的字母。
接下来,就要把TargetView显示到场景上了。找到MainScene的dealRandomAnagram方法,在末尾处加入上下面代码
pTargets = CCArray::createWithCapacity(ana2len); const char * ana2Letter = ana2->getCString();
for(int i = 0;i < ana2len; i++){
char letter[3];
sprintf(letter,"%c",ana2Letter[i]); if(letter[0] != ' '){
TargetView * target = TargetView::initWithLetter(letter,tileSide);
target->setPosition(ccp(xOffset + i * (tileSide + kTileMargin),Common::getCameraHeight() / 4 * 3));
this->addChild(target);
pTargets->addObject(target);
}
}
pTargets->retain();
是否可看到TargetView也出来,这里。我们就完毕了AnagramPuzzle的第一部分开发工作,最后上个截图
感觉还不错吧,轻松的把所须要的游戏界面展示出来。
这次接触到cocos2d-x知识还是比較少。主要是如何往主场景中加入内容,如何创建精灵。下一次,我们就要编写一些有点挑战性的东西了。比方怎么拖动精灵,怎么推断是否摆在正确的位置,怎么进行倒计时等等,真正的Code乐趣快要上场!
请听下回分解。
版权声明:本文博客原创文章,博客,未经同意,不得转载。
cocos2d-x路~使得第一个字游戏(一个)的更多相关文章
- Cocos2D将v1.0的tileMap游戏转换到v3.4中一例(一)
大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请告诉我,如果觉得不错请多多支持点赞.谢谢! hopy ;) 首先说一下为什么要转换,这是为了后面的A*寻路算法做准备.由于在 ...
- 喵的Unity游戏开发之路 - 推球:游戏中的物理
很多童鞋没有系统的Unity3D游戏开发基础,也不知道从何开始学.为此我们精选了一套国外优秀的Unity3D游戏开发教程,翻译整理后放送给大家,教您从零开始一步一步掌握Unity3D游戏开发. 本文不 ...
- IOS7学习之路三(UISpriteKit游戏开发SKNode)
ios7新添加了自己的游戏开发框架UISpriteKit ,可以用此做一些2D的小游戏, 今天学习了一下SKNode的知识做一下笔记,以便以后查阅. 1.SKNode继承自UIResponder. 2 ...
- 我的第一篇博文:C++最初的路-经典的小游戏走迷宫
写在开始:这个博客建于大二下学期.2年多的学习,从网上借鉴的大牛经验,代码,指导数不胜数,而其中大部分来自别人的博客,于是期待有一天也能把自己在学习过程中的一些经验拿出来与大家分享. 其实我凝望了C+ ...
- Cocos2D将v1.0的tileMap游戏转换到v3.4中一例(八)
大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请告诉我,如果觉得不错请多多支持点赞.谢谢! hopy ;) 回到Xcode中,新建一个EndLayer类,继承于CCNode ...
- Cocos2D将v1.0的tileMap游戏转换到v3.4中一例(六)
大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请告诉我,如果觉得不错请多多支持点赞.谢谢! hopy ;) 在Xcode中打开MainScene.h文件,在接口中添加2个方 ...
- Cocos2D将v1.0的tileMap游戏转换到v3.4中一例(五)
大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请告诉我,如果觉得不错请多多支持点赞.谢谢! hopy ;) 为了暂时不影响原来的cat移动方法,我们在CatSprite.m ...
- Cocos2D将v1.0的tileMap游戏转换到v3.4中一例(四)
大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请告诉我,如果觉得不错请多多支持点赞.谢谢! hopy ;) 现在打开MainScene.m文件,首先设置实例变量: @imp ...
- 云计算之路-出海记:建一个免费仓库 Amazon RDS for SQL Server
上周由于园子后院起火,不得不调兵回去救火,出海记暂时停更,这周继续更新,"出海记"记录的是我们在 AWS 上建设博客园海外站的历程. 在这一记中记录的是我们基于 AWS 免费套餐( ...
随机推荐
- 一二三(The Seventh Hunan Collegiate Programming Contest)
一二三 你弟弟刚刚学会写英语的一(one).二(two)和三(three).他在纸上写了好些一二三,可惜有些字母写错了.已知每个单词最多有一个字母写错了(单词长度肯定不会错),你能认出他写的啥吗? 输 ...
- POJ 1122 FDNY to the Rescue!
给出某些交叉点的距离,-1 表示无法到达. 然后给出火灾发生点 和 附近的消防局位置. 排列消防局 的 时间 与路径. 反向建图,以火灾出发点为起点做一次SPFA. #include<cstd ...
- bash学习之环境变量
1.查看系统存在的环境变量env 和 export env命令:查看环境变量 [CJP@CJP ~]$ env HOSTNAME=CJP SHELL=/bin/bash HISTSIZE=1000 U ...
- C# 开发Chrome内核浏览器(WebKit.net)
原文地址:http://www.cnblogs.com/linyijia/p/4045333.html
- linux kickstart 自动安装
最近很多业务系统都是linux lnmp平台安装,反复的安装让人觉得很苦恼,仔细钻研了下kickstart .这里环境是red hat linux 5.8 32位,系统盘中的软件包里包含有kickst ...
- This application failed to start because it could not find or load the Qt platform plugin "xcb".
linux根据系统Qt5未安装编译的程序Qt在该系统下进行下面的错误会报: This application failed to start because it could not find or ...
- Spring Data Redis—Pub/Sub(附Web项目源码) (转)
一.发布和订阅机制 当一个客户端通过 PUBLISH 命令向订阅者发送信息的时候,我们称这个客户端为发布者(publisher). 而当一个客户端使用 SUBSCRIBE 或者 PSUBSCRIBE ...
- 教你pomeloclient包libpomelo增加cocos2d-x 3.0工程(Windows、Android、IOS平台)
Windows平台 操作系统:Windows7(64-bit) VS版本号:2013 Cocos2d-x版本号:3.0 project路径:E:\cocos2d-prj\ 1.从github下载lib ...
- 从零开始学Xamarin.Forms(二) 环境搭建、创建项目
原文:从零开始学Xamarin.Forms(二) 环境搭建.创建项目 一.环境搭建 Windows下环境搭建: 1.下载并安装jdk.Android SDK和NDK,当然还需要 VS2013 ...
- TCP header
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvc3Vzc2VyNDM=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA ...