博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
cocos2d-x游戏开发系列教程-坦克大战游戏之坦克和地图碰撞的检测下
阅读量:5059 次
发布时间:2019-06-12

本文共 3438 字,大约阅读时间需要 11 分钟。

上篇我们完成了地图的信息获取和碰撞检测,这篇我们整合到程序中。

在这之前我们改造一下Tank类,使它更加模块化,共容易理解:

1.改造后的Tank类声明如下:

class Tank : public CCSprite{public :	Tank();	~Tank();	static Tank* createTankWithTankType(const char* tankTypeName, TileMapInfo* tileMapInfo);	void initTankWithTankType(const char* tankTypeName, TileMapInfo* tileMapInfo);	void command(enumOrder order);	TileMapInfo* mTileMapInfo;};

static Tank* createTankWithTankType(const char* tankTypeName, TileMapInfo* tileMapInfo);

void initTankWithTankType(const char* tankTypeName, TileMapInfo* tileMapInfo);

可以看到这两个函数后面都多了TileMapInfo类的指针。

我们可以在坦克中使用这个指针来检测是否碰撞。

2.我们实现void initTankWithTankType(const char* tankTypeName, TileMapInfo* tileMapInfo);

void Tank::initTankWithTankType(const char* tankTypeName, TileMapInfo* tileMapInfo){	initWithSpriteFrameName(tankTypeName);	mTileMapInfo = tileMapInfo;	//将坦克放入地图层中	mTileMapInfo->getTileMap()->addChild(this);	//缩放到合适大小	CCTMXTiledMap* tmxTileMap = mTileMapInfo->getTileMap();	CCSize tileSize = tmxTileMap->getTileSize();	CCSize tankSize = getContentSize();	//比地图上砖块小一点	setScale((tileSize.height * 2-4) / (tankSize.height));}
上面函数中,我们先把Tank类自己加入了地图层中,这样更方便我们进行一个位置计算。

然后缩放到了比地图上一整个砖块小一点的大小,这样可以正常通过砖块之间的通道。

3.简单的实现static Tank* createTankWithTankType(const char* tankTypeName, TileMapInfo* tileMapInfo);来返回一个Tank实例:

Tank* Tank::createTankWithTankType(const char* tankTypeName, TileMapInfo* tileMapInfo){	CCSpriteFrameCache* pCache = CCSpriteFrameCache::sharedSpriteFrameCache();	pCache->addSpriteFramesWithFile("tank.plist");	Tank* tank = new Tank();	tank->initTankWithTankType(tankTypeName, tileMapInfo);	tank->autorelease();	return tank;}
可以看到我们添加了plist文件,然后从中加载了tankTypeName类型的Tank精灵,然后初始化,最后加入自动释放列表。

4.然后在void command(enumOrder order);函数中,我们在命令控制中加入检测碰撞的函数:

bool Tank::command(enumOrder order){	float stepX = 0.0f;	float stepY = 0.0f;	float fRotation = getRotation();	switch (order)	{	case cmdNothing:		break;	case cmdGoUP:		stepY = 1.0f;		fRotation = 0.0f;		break;	case cmdGoDown:		stepY = -1.0f;		fRotation = 180.0f;		break;	case cmdGoLeft:		stepX = -1.0f;		fRotation = 270.0f;		break;	case cmdGoRight:		stepX = 1.0f;		fRotation = 90.0f;		break;	case cmdFire:		//调用子弹开火		return mBullet->fire();	default:		break;	}	//根据运行方向旋转坦克	setRotation(fRotation);	//检测地图上的碰撞	CCRect rect = this->boundingBox();	if (!mTileMapInfo->collisionTest(CCRectMake(rect.getMinX() + stepX, 		rect.getMinY() + stepY, rect.size.width, rect.size.height)))	{		setPositionX(getPositionX() + stepX);		setPositionY(getPositionY() + stepY);		return true;	}	return false;}

可以看到我们跟之前的Tank类的command函数中多了碰撞检测,

先通过boundingBox获取Tank在地图中的矩形,然后传入移动后的矩形,

通过TileMapInfo类中的collisionTest碰撞函数,来检测是否碰撞,

如果碰撞则不移动,如果没有碰撞则按照stepX和stepY分量进行移动位置。

5.Tank类改造完了,最后我们需要在CityScene中初始化我们的新 TileMapInfo类和Tank类:

bool  CityScene::init(){	CCLayer::init();	//初始化地图信息	TileMapInfo* tileMapInfo = TileMapInfo::createMapInfoWithFile("Round1.tmx");	CCTMXTiledMap* tmxTileMap = tileMapInfo->getTileMap();	this->addChild(tmxTileMap);	//在已有的地图上,创建玩家坦克	mPlayerTank[0] = Tank::createTankWithTankType("player2U.png", tileMapInfo);	//放到地图中初始化位置	CCSize tileSize = tmxTileMap->getTileSize();	CCSize mapSize = tmxTileMap->getContentSize();	mPlayerTank[0]->setPosition(ccp(mapSize.width / 2 - tileSize.width * 3, tileSize.height));	//添加虚拟手柄的显示	mLayerPanel = Panel::create();	addChild(mLayerPanel, 3);	return true;}
可以看到我们先初始化了地图信息,然后通过地图信息创建了一个坦克,并把坦克放到了地图中的初始化位置。

下面我们看看运行后的碰撞效果:

完整源码下载地址:

转载于:https://www.cnblogs.com/niulanshan/p/6175080.html

你可能感兴趣的文章
浅谈C#与数据结构中的哈希表(Hashtable)(上)(没法转载,只能贴在这里啦)
查看>>
Git 的使用
查看>>
原码 反码 补码 移码
查看>>
JS 二维数组 对象数组 对象中的数组
查看>>
转:前端工程与性能优化(下):静态资源管理与模板框架
查看>>
转:Hprose for php(二)——服务器
查看>>
extern static和函数
查看>>
HBase环境搭建
查看>>
拍照、本地图片工具类(兼容至Android7.0)
查看>>
NGUI-使用UILabel呈现图片和不同格式的文字
查看>>
AutoTransformHandler
查看>>
angular5引入sass
查看>>
Gridview 动态指定字段升序,降序排序
查看>>
解决idea maven 编译版本自动回复1.5
查看>>
【转载】基于CodeIgniter框架Restful风格API的Auth验证
查看>>
Java学习--使用 Date 和 SimpleDateFormat 类表示时间
查看>>
vue中 $event 的用法--获取当前父元素,子元素,兄弟元素
查看>>
安装redis服务
查看>>
java中使用OpenOffice
查看>>
css3 同心圆旋转(1)
查看>>