cocos2d-x游戏开发系列教程-坦克大战游戏之坦克和地图碰撞的检测上
来源:互联网 发布:一对一直播源码 编辑:程序博客网 时间:2024/05/11 20:59
在上篇我们可以控制坦克在地图上任意行走了,
但是实际游戏中遇到墙就应该是无法走动的,这节课我们继续完善程序,
让他能在地图检测到墙壁,而无法通过。
1.我们新建一个TileMapInfo类,来获取地图信息。
class TileMapInfo{public:bool collisionTest(CCRect rect);static TileMapInfo* createMapInfoWithFile(const char* tmxFile);void initMapInfoWithFile(const char* tmxFile);CC_SYNTHESIZE(CCTMXTiledMap*, mTMXTileMap, TileMap);private:CCTMXLayer* mTMXLayers[2];};
可以看到定义中有一个collisionTest碰撞检测函数,
它根据传进来的rect检测是否与地图上的砖块发生了碰撞,
既然要检测碰撞,我们就需要知道地图中砖块的类型。
2.我们还记得Tiled程序吧,他可以制作tmx格式的地图,看下他的截图
可以看到右上边有两个层,layer_0和layer_1,我们分别单独勾选两个层对比看看,注意看下面两个图的区别:
我们可以看到第二个图层里面是草地,我们知道游戏中,坦克行走到草地会被遮挡住,
这样分层两个层,我们可以在第一层和第二层之间绘制坦克达到遮挡效果。
3.我们看截图右下方,看到很多类型的图块,他们在tmx中都以gid的名字保存,
如下图我标出了前面图块的gid值。
如上图所示我们一共有 36 个图块,那么最后一个图块gid值是36。
4,那么我们先定义上面图块的7种类型
//tile类型,草地,钢铁,河流等enum enumTileType{tileNone, tileGrass, tileSteel, tileWall,tileRiver, tileKing };
5.然后我们在定义一个数组,可以通过传进图块的gid值来获取图块类型,对应于上面截图中的图块:
//根据地图中gid获取对应tile的类型static enumTileType gidToTileType[] ={tileNone,tileNone, tileNone, tileGrass, tileGrass, tileSteel, tileSteel, tileNone, tileNone, tileGrass, tileGrass, tileSteel, tileSteel,tileWall, tileWall, tileRiver, tileRiver, tileKing, tileKing,tileWall, tileWall, tileRiver, tileRiver, tileKing, tileKing,tileKing, tileKing, tileNone, tileNone, tileNone, tileNone,tileKing, tileKing, tileNone, tileNone, tileNone, tileNone};
6.然后实现函数void initMapInfoWithFile(const char* tmxFile);,从一个tmx地图文件初始化地图信息:
void TileMapInfo::initMapInfoWithFile(const char* tmxFile){mTMXTileMap = CCTMXTiledMap::create(tmxFile);mTMXLayers[0] = mTMXTileMap->layerNamed("layer_0");mTMXLayers[1] = mTMXTileMap->layerNamed("layer_1");CCSize winSize = CCDirector::sharedDirector()->getWinSize();CCSize mapSize = mTMXTileMap->getContentSize();//缩放地图到合适屏幕大小mTMXTileMap->setScale(winSize.height / mTMXTileMap->getContentSize().height);//将地图放到屏幕中间mTMXTileMap->setPosition(ccp((winSize.width - mapSize.width * mTMXTileMap->getScale()) / 2,(winSize.height - mapSize.height * mTMXTileMap->getScale()) / 2));}
7.然后实现一个静态方法,返回一个TileMapInfo的实例:
TileMapInfo* TileMapInfo::createMapInfoWithFile(const char* tmxFile){TileMapInfo* tileMapInfo = new TileMapInfo();tileMapInfo->initMapInfoWithFile(tmxFile);return tileMapInfo;}
8.最后实现碰撞检测的函数bool TileMapInfo::collisionTest(CCRect rect)
bool TileMapInfo::collisionTest(CCRect rect){int gid = 0;CCSize mapSize = mTMXTileMap->getContentSize();CCSize tileSize = mTMXTileMap->getTileSize();if (rect.getMinX() < 0 || rect.getMaxX() >= mapSize.width ||rect.getMinY() < 0 || rect.getMaxY() >= mapSize.height)return true;//将坦克Y坐标转换为地图上的Y坐标float MinY = mapSize.height - rect.getMinY();float MaxY = mapSize.height - rect.getMaxY();//对坦克四个顶点进行碰撞检测gid = mTMXLayers[0]->tileGIDAt(ccp((int)(rect.getMinX() / tileSize.width), (int)(MinY / tileSize.height)));if (gidToTileType[gid] != tileNone && gidToTileType[gid] != tileGrass)return true;gid = mTMXLayers[0]->tileGIDAt(ccp((int)(rect.getMinX() / tileSize.width), (int)(MaxY / tileSize.height)));if (gidToTileType[gid] != tileNone && gidToTileType[gid] != tileGrass)return true;gid = mTMXLayers[0]->tileGIDAt(ccp((int)(rect.getMaxX() / tileSize.width), (int)(MaxY / tileSize.height)));if (gidToTileType[gid] != tileNone && gidToTileType[gid] != tileGrass)return true;gid = mTMXLayers[0]->tileGIDAt(ccp((int)(rect.getMaxX() / tileSize.width), (int)(MinY / tileSize.height)));if (gidToTileType[gid] != tileNone && gidToTileType[gid] != tileGrass)return true;return false;}可以看到碰撞检测函数比较麻烦,首先判断了传进来的矩形是否在地图中,
然后依次对矩形四个顶点进行碰撞检测,如果矩形进入了除 tileNone和tileGrass之外的区域
说明无法行走了,则返回true来表示碰撞了。
其中我们用到了tileGIDAt函数,他可以从一个tmx中表示的地图坐标获取gid。如下图:
可以看到 tmx 坐标中 3,24 所在的位置是一个tileNone类型的gid。
到这里TileMapInfo类已经完成了,下篇文章对Tank类进行一些修改。
0 0
- cocos2d-x游戏开发系列教程-坦克大战游戏之坦克和地图碰撞的检测上
- cocos2d-x游戏开发系列教程-坦克大战游戏之坦克和地图碰撞的检测下
- cocos2d-x游戏开发系列教程-坦克大战游戏之所有坦克之间的碰撞检测
- cocos2d-x游戏开发系列教程-坦克大战游戏之子弹和地图碰撞
- cocos2d-x游戏开发系列教程-坦克大战游戏之子弹的碰撞检测处理
- cocos2d-x游戏开发系列教程-坦克大战游戏之坦克的显示
- cocos2d-x游戏开发系列教程-坦克大战游戏之敌方坦克AI的编写
- cocos2d-x游戏开发系列教程-坦克大战游戏加载地图的编写
- cocos2d-x游戏开发系列教程-坦克大战游戏之虚拟手柄控制坦克移动
- cocos2d-x游戏开发系列教程-坦克大战游戏关卡选择场景的编写上
- cocos2d-x游戏开发系列教程-坦克大战游戏之虚拟手柄的显示
- cocos2d-x游戏开发系列教程-坦克大战游戏之虚拟手柄的显示
- cocos2d-x游戏开发系列教程-坦克大战游戏启动界面的编写
- cocos2d-x游戏开发系列教程-坦克大战游戏关卡选择场景的编写中
- cocos2d-x游戏开发系列教程-坦克大战游戏关卡选择场景的编写下
- 使用《红孩儿工具箱》开发基于Cocos2d-x的《坦克大战》游戏
- Java开发的游戏之三 坦克大战 完整源代码
- C#开发-----坦克大战游戏
- 分布式数据库 Hbase 的高可用管理和监控
- (基础) class 与 c 语言对比学习-OC+class
- 提交主从表的多个已经修改的数据
- 通过MyEclipse连接Mysql,Oracle数据库
- linux 守护进程实例
- cocos2d-x游戏开发系列教程-坦克大战游戏之坦克和地图碰撞的检测上
- 淘宝技术交流笔记
- ORACLE PL/SQL编程详解之二:PL/SQL块结构和组成元素
- [Windows]_[连接错误fatal error C1047--with an older compiler]
- 2013的回味
- C# DataTable 合并重复字段为一行
- input help
- 数据库课程设计答辩通知(2013年12月)
- js购物车