基于cocos2d tileMap的一个小游戏
2013-08-10 14:31
267 查看
上一篇文章中我们介绍了cocos2d tileMap的一些基本知识,这一节我们基于cocos2d做一个简单的游戏,下载地址:http://download.csdn.net/detail/lennonchan/5903037。
这是一款收集宝石的小游戏,主要任务是指挥鸟在不碰雷德前提下收集所有的宝石,节目如下:
通过右下角的按钮控制鸟的行走方向,也可以通过Windows小键盘区的数字键控制方向。windows上esc键重新开始,Android上menu键重新开始。
为了游戏增加游戏的灵活性,地图是通过程序计算出来的,所以每次初始化的界面可能都不一样。
下来看下代码,我们只看CGameMap类。
CGameMap继承自cocos2d::CCTileMapAtlas,接口很少。
getInstance :获取单例对象
create : 创建一个tileMap,比较重要
getStartPosition: 获取鸟所在的位置
getEndPosition:获取鸟从某一点开始,沿某一方向能走得最远距离。
moveStart: 沿某一方向走一步,并将目标位置的类型返回。
getMapSize: 获取地图大小
isCollectOver:判断地图上的宝石是否收集完毕
我们从create函数看起:
函数有三个参数,宽高和一个随机种子。注意:这里的宽高的单位并不是像素,而是格子,也就是地图会有w*h个cell。
if(seed <= 0)
{
seed = (int)time(NULL);
}
如果随机种子小于0,则用当前时间作为随机种子。
接下来用随机种子生成一个随机状态:
random_state *rs = random_new((char*)&iseed, sizeof(int));
接下来用随机状态和宽高成生一个原始的网格:
char * grid = gengrid(m_Width,m_Height,rs);
文章开头上传的代码中有gengrid的源码,这里不复述。
然后调用私有函数grid2Image将原始数据转为tga格式的图片格式。
releaseMap();其实在这里没什么作用,因为我们没用到tga的解析。
然后调用我们的创建的函数,通过tgainfo初始化一个map,函数原型如下:
将解析tga的过程换成直接赋值:m_pTGAInfo = pInfo;
注:如果朋友们要运行下载的工程,需要将此函数自己复制到CCTileMapAtlas.cpp,再在头文件中声明。
下来看另外一个比较重要的函数:moveStart
用于游戏中移动鸟的位置,参数为移动方向。
首先我们将目标位置标记为鸟所在的位置:
CCPoint pEnd = m_StartPosition;
然后通过移动方向进行坐标计算:
接下来判断目标位置是啥玩意:
ccColor3B r = tileAt(pEnd);
ccColor3B c = r;
分情况判断:
如果是炸弹、宝石、停止或者空白则将鸟移动到当前位置,否则不做处理。
最后返回目标位置的类型return (eMapType)r.r;
游戏先将这么多吧,因为大家可以下到源码,如果有什么问题我们在讨论。
最后说一点tile图片制作时要注意的地方:
图片的第一个cell要空出来,原因看上一篇文章。为了达到网格的效果,每个cell的上下左右各留一个空格的黑色像素。
这是一款收集宝石的小游戏,主要任务是指挥鸟在不碰雷德前提下收集所有的宝石,节目如下:
通过右下角的按钮控制鸟的行走方向,也可以通过Windows小键盘区的数字键控制方向。windows上esc键重新开始,Android上menu键重新开始。
为了游戏增加游戏的灵活性,地图是通过程序计算出来的,所以每次初始化的界面可能都不一样。
下来看下代码,我们只看CGameMap类。
class CGameMap : public cocos2d::CCTileMapAtlas { public: static CGameMap* getInstance(); CGameMap* create(unsigned int width,unsigned int height,int seed = 0); ~CGameMap(); CCPoint getStartPosition(); CCPoint getEndPosition(CCPoint,eDirect); eMapType moveStart(eDirect drct); CCSize getMapSize(); bool isCollectOver(); private: CGameMap(); sImageTGA* grid2Image(char* pGrid); char cFlag2Tile(char cFlag); private: unsigned int m_Width; unsigned int m_Height; unsigned int m_iCollectedGems; unsigned int m_iTotalGems; CCPoint m_StartPosition; ccColor3B m_CurrentType; static CGameMap* m_pInstance; };
CGameMap继承自cocos2d::CCTileMapAtlas,接口很少。
getInstance :获取单例对象
create : 创建一个tileMap,比较重要
getStartPosition: 获取鸟所在的位置
getEndPosition:获取鸟从某一点开始,沿某一方向能走得最远距离。
moveStart: 沿某一方向走一步,并将目标位置的类型返回。
getMapSize: 获取地图大小
isCollectOver:判断地图上的宝石是否收集完毕
我们从create函数看起:
CGameMap* CGameMap::create( unsigned int width,unsigned int height,int seed) { m_Width = width; m_Height = height; m_iTotalGems = 0; if(seed <= 0) { seed = (int)time(NULL); } int iseed = seed; random_state *rs = random_new((char*)&iseed, sizeof(int)); char * grid = gengrid(m_Width,m_Height,rs); sImageTGA* pInfor = grid2Image(grid); releaseMap(); //tgaDestroy(m_pTGAInfo); if (initWithTGAInfo(_TILE_IMG_, pInfor, _TILE_WIDTH_, _TILE_HEIGHT_)) { //autorelease(); } m_CurrentType.r = eBlank; return this; }
函数有三个参数,宽高和一个随机种子。注意:这里的宽高的单位并不是像素,而是格子,也就是地图会有w*h个cell。
if(seed <= 0)
{
seed = (int)time(NULL);
}
如果随机种子小于0,则用当前时间作为随机种子。
接下来用随机种子生成一个随机状态:
random_state *rs = random_new((char*)&iseed, sizeof(int));
接下来用随机状态和宽高成生一个原始的网格:
char * grid = gengrid(m_Width,m_Height,rs);
文章开头上传的代码中有gengrid的源码,这里不复述。
然后调用私有函数grid2Image将原始数据转为tga格式的图片格式。
sImageTGA* CGameMap::grid2Image(char* pGrid) { sImageTGA* pImage = new sImageTGA(); pImage->flipped = 0; pImage->type = 1; pImage->pixelDepth = 24; pImage->width = m_Width; pImage->height = m_Height; pImage->imageData = new unsigned char[m_Width*m_Height*3]; for (int i = 0;i < m_Width; i++) { for (int j = 0;j < m_Height; j++) { pImage->imageData[(j*m_Width+i)*3] = cFlag2Tile(pGrid[i*m_Width+j]); if(pImage->imageData[(j*m_Width+i)*3] == eStart) m_StartPosition = ccp(i,j); else if(pImage->imageData[(j*m_Width+i)*3] == eGem) m_iTotalGems++; pImage->imageData[(j*m_Width+i)*3+1] = 0; pImage->imageData[(j*m_Width+i)*3+2] = 0; } } return pImage; }
releaseMap();其实在这里没什么作用,因为我们没用到tga的解析。
然后调用我们的创建的函数,通过tgainfo初始化一个map,函数原型如下:
bool CCTileMapAtlas::initWithTGAInfo(const char *tile, sImageTGA* pInfo, int tileWidth, int tileHeight) { if(!pInfo) return false; m_pTGAInfo = pInfo; this->calculateItemsToRender(); if( CCAtlasNode::initWithTileFile(tile, tileWidth, tileHeight, m_nItemsToRender) ) { m_pPosToAtlasIndex = new CCDictionary(); this->updateAtlasValues(); this->setContentSize(CCSizeMake((float)(m_pTGAInfo->width*m_uItemWidth), (float)(m_pTGAInfo->height*m_uItemHeight))); return true; } return false; }
将解析tga的过程换成直接赋值:m_pTGAInfo = pInfo;
注:如果朋友们要运行下载的工程,需要将此函数自己复制到CCTileMapAtlas.cpp,再在头文件中声明。
下来看另外一个比较重要的函数:moveStart
eMapType CGameMap::moveStart( eDirect drct ) { if(drct == eNON) return eStart; CCPoint pEnd = m_StartPosition; switch (drct) { case eUp: pEnd.y++; break; case eDown: pEnd.y--; break; case eLeft: pEnd.x--; break; case eRight: pEnd.x++; break; case eUpLeft: pEnd.y++; pEnd.x--; break; case eUpRight: pEnd.y++; pEnd.x++; break; case eDownLeft: pEnd.y--; pEnd.x--; break; case eDownRight: pEnd.y--; pEnd.x++; break; default: break; } if(pEnd.y < 0 || pEnd.y >= m_Height || pEnd.x < 0 || pEnd.x >= m_Width) return eStart; ccColor3B r = tileAt(pEnd); ccColor3B c = r; switch (c.r) { case eMine: case eGem: case eStop: case eBlank: if(m_CurrentType.r == eGem) { m_iCollectedGems++; m_CurrentType.r = eBlank; } setTile(m_CurrentType,m_StartPosition); m_StartPosition = pEnd; m_CurrentType = c; c.r = eStart; setTile(c,m_StartPosition); break; case eStart: case eWall: default: break; } return (eMapType)r.r; }
用于游戏中移动鸟的位置,参数为移动方向。
首先我们将目标位置标记为鸟所在的位置:
CCPoint pEnd = m_StartPosition;
然后通过移动方向进行坐标计算:
switch (drct) { case eUp: pEnd.y++; break; case eDown: pEnd.y--; break; case eLeft: pEnd.x--; break; case eRight: pEnd.x++; break; case eUpLeft: pEnd.y++; pEnd.x--; break; case eUpRight: pEnd.y++; pEnd.x++; break; case eDownLeft: pEnd.y--; pEnd.x--; break; case eDownRight: pEnd.y--; pEnd.x++; break; default: break; }
接下来判断目标位置是啥玩意:
ccColor3B r = tileAt(pEnd);
ccColor3B c = r;
分情况判断:
switch (c.r) { case eMine: case eGem: case eStop: case eBlank: if(m_CurrentType.r == eGem) { m_iCollectedGems++; m_CurrentType.r = eBlank; } setTile(m_CurrentType,m_StartPosition); m_StartPosition = pEnd; m_CurrentType = c; c.r = eStart; setTile(c,m_StartPosition); break; case eStart: case eWall: default: break; }
如果是炸弹、宝石、停止或者空白则将鸟移动到当前位置,否则不做处理。
最后返回目标位置的类型return (eMapType)r.r;
游戏先将这么多吧,因为大家可以下到源码,如果有什么问题我们在讨论。
最后说一点tile图片制作时要注意的地方:
图片的第一个cell要空出来,原因看上一篇文章。为了达到网格的效果,每个cell的上下左右各留一个空格的黑色像素。
相关文章推荐
- 如何制作一个基于Tile的游戏 Cocos2d-x 2.0.4
- 如何制作一个基于Tile的游戏(2) Cocos2d-x 2.0.4
- Cocos2D-X射击小游戏(四)编码2 添加一个精灵
- 如何制作一个基于Tile的游戏(2) Cocos2d-x 2.0.4
- 开源一个基于cocos2d-x的游戏--超级六边形(SuperSector)
- 一个基于Myeclipse开发的Java打地鼠小游戏(Appletcation)
- 用cocos2d 2.1制作一个过河小游戏(3): 船与河岸Sprite设计
- 如何制作一个基于Tile的游戏(2) Cocos2d-x 2.0.4
- 从零开始做一个基于pygame引擎的躲闪小游戏(一)-画矩形、画圆、简单的碰撞检测
- 基于cocos2d开发的android小游戏——採花仙
- [安卓] 12、开源一个基于SurfaceView的飞行射击类小游戏
- 如何制作一个基于Tile的游戏(2) Cocos2d-x 2.0.4
- 一个简单的基于canvas小游戏
- 基于websocket写的一个在线联机小游戏:六子冲棋
- cocos2d-xna 写的一个小游戏demo坦克大战
- 一个cocos2d小游戏
- 如何制作一个基于Tile的游戏 Cocos2d-x 3.0alpha0
- 一个基于cocos2d-x 3.0和Box2d的demo小程序
- 用cocos2d 2.1制作一个过河小游戏(2): 牧师与魔鬼Sprite设计
- 如何制作一个基于Tile的游戏(2) Cocos2d-x 2.0.4