cocos2d-x 旅程开始--(实现瓦片地图中的碰撞检测)


       转眼隔了一天了,昨天搞了整整一下午加一晚上,楞是没搞定小坦克跟砖头的碰撞检测,带着个问题睡觉甚是难受啊!还好今天弄成功了,不过感觉程序不怎么稳定啊。而且发现自己写的东西让我重写一遍的话我肯定写不出来,还要继续学习啊!

上次的进度

           实现了坦克的移动,昨天把程序优化了一下,能整合在一起的就整合在一个函数里了。而且对碰到屏幕边缘的情况进行了检测。之前的代码都是部分代码,今天试试把代码整个贴上去。

这两天的进度

           打这么多汉字,自个都看不进去,直接上代码:

/实现移动///
void HelloWorld::moveTank()
{
	//初始化所需数据
	origPo = player_1->getPosition();       //先得到主角player_1的初始坐标备用
	newPo = ccp(0, 0);                //初始化目标坐标,主角移动的新坐标就是它
	xPo = newPo;                  //主角的锚点为(0.5f,0.5f),xPo是真正的检测位置,真正的检测位置应该在坦克外面

	if (boolleft==true)           //向左移动的话
	{
		player_1->setRotation(-90);          //坦克转向左侧
		newPo = origPo - ccp(10, 0);         //设定坦克移动的目的坐标
		newPo.x = newPo.x > 30 ? newPo.x : 30;      //越界判断

		xPo = newPo + ccp(-30, 0);           //设定检测位置
		xPo.x = xPo.x < 30 ? 30 : xPo.x;    //越界判断
	}
	else if (boolright==true)
	{
		player_1->setRotation(90);
		newPo = origPo + ccp(10, 0);
		newPo.x = newPo.x < MAP_WIDTH - 30 ? newPo.x : MAP_WIDTH - 30;      //MAP_WIDTH为定义的宏,地图宽度

		xPo = newPo + ccp(22, 0);
		xPo.x = xPo.x > MAP_WIDTH - 30 ? MAP_WIDTH - 30 : xPo.x;
	}
	else if (boolup==true)
	{
		player_1->setRotation(0);
		newPo = origPo + ccp(0, 10);
		newPo.y = newPo.y < MAP_HEIGHT - 30 ? newPo.y : MAP_HEIGHT - 30;

		xPo = newPo + ccp(0, 30);
		xPo.y = xPo.y > MAP_HEIGHT - 30 ? MAP_HEIGHT - 30 : xPo.y;
	}
	else if (booldown==true)
	{
		player_1->setRotation(180);
		newPo = origPo - ccp(0, 10);
		newPo.y = newPo.y >30 ? newPo.y : 30;

		xPo = newPo + ccp(0, -22);
		xPo.y = xPo.y < 30 ? 30 : xPo.y;
	}
        //实现碰撞检测
	this->collide("layer_1");                        //检测layer_1图层,这层只有砖块     
	float distancePo = origPo.getDistance(player_1->getPosition());    //计算前后是否移动,得出移动距离           
	if (!distancePo == 0)             //如果移动了,就说明这时候砖块层没有碰撞,而且已经设定了新的position                                            
	{                                                                                
		player_1->setPosition(origPo);             //把position改回来,不让它移动
                collide("layer_2");           //检测layer_2层这层只有铁块               
	}
}

 
 
 collide函数实现碰撞检测: 
void HelloWorld::collide(CCString stringx)
{
	const char *str = "";                      //定义一个char用来改变检测的图层
	if (stringx.compare("layer_1")==0)           //判断是哪个图层
	{
		str = "layer_1";
	}
	else if (stringx.compare("layer_2")==0)
	{
		str = "layer_2";
	}
		
	CCPoint xPo_1; CCPoint xPo_2;            //初始化两个新的检测位置

	if (boolleft)
	{
		xPo_1 = xPo + ccp(0, -25);       //向左移动的话分别检测原检测位置上下两个新的位置
		xPo_2 = xPo + ccp(0, 25);
	}
	else if (boolright)
	{
		xPo_1 = xPo + ccp(0, -25);
		xPo_2 = xPo + ccp(0, 25);
	}
	else if (booldown)
	{
		xPo_1 = xPo + ccp(-25, 0);
		xPo_2 = xPo + ccp(25, 0);
	}
	else if (boolup)
	{
		xPo_1 = xPo + ccp(-25, 0);
		xPo_2 = xPo + ccp(25, 0);
	}
	CCTMXLayer* wallLayer = tank_war->layerNamed(str);            //得到需要检测的图层

	CCPoint m_1 = this->changePositionToMap(xPo_1);
	int tag_1 = wallLayer->tileGIDAt(m_1);

	CCPoint m_2 = this->changePositionToMap(xPo_2);
	int tag_2 = wallLayer->tileGIDAt(m_2);

	CCPoint m = this->changePositionToMap(xPo);                  //将浮点位置坐标转化为TileMap特有的块坐标系统
	int wallTag = wallLayer->tileGIDAt(m);                       //获得地图块上的ID

	if (wallTag == 0)                                            
	{
		if (tag_1 == 0)
		{
			if (tag_2 == 0)           //只有三个检测位置都没有阻挡才能移动
			{
				player_1->setPosition(newPo);
			}
		}
		return;
	}
}
需要把浮点型的检测位置坐标转换为TileMap特有的地图块坐标系统,转换坐标的函数:
CCPoint HelloWorld::changePositionToMap(CCPoint po)
{
	CCPoint mapPosition;
	mapPosition.x = (int)(po.x / 30);
	mapPosition.y = (int)((MAP_HEIGHT - po.y) / 30);
	return mapPosition;
}
说明:由于前面设定的移动距离为10,就会出现这种情况,检测点xPo没有砖块,可以向前移动,而砖块在左侧却与坦克出现碰撞,这时候就会出现部分的穿墙现象,所以需要设定两个新的检测点xPo_1与xPo_2用来检测是否发生了这种状况。


今天就先这样吧,接下来要实现坦克开炮,加上敌人,开始界面等等,还有好多没实现的,一步一步来!休息休息,去跑步,洗澡,睡觉...哦,祝老爸父亲节快乐...

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值