cocos2d x游戏开发系列教程 坦克大战游戏之坦克和地图碰撞的检测下

本文详细介绍了如何在坦克游戏中实现地图碰撞检测。通过改造Tank类,整合TileMapInfo类,实现了坦克与地图的交互。文章包括Tank类的模块化改造、碰撞检测函数的实现,以及如何在CityScene中初始化地图和坦克。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.youkuaiyun.com/jiangjunshow

也欢迎大家转载本篇文章。分享知识,造福人民,实现我们中华民族伟大复兴!

               

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

在这之前我们改造一下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.0ffloat stepY = 0.0ffloat fRotation = getRotation(); switch (order) { case cmdNothing:  breakcase cmdGoUP:  stepY = 1.0f;  fRotation = 0.0f;  breakcase cmdGoDown:  stepY = -1.0f;  fRotation = 180.0f;  breakcase cmdGoLeft:  stepX = -1.0f;  fRotation = 270.0f;  breakcase cmdGoRight:  stepX = 1.0f;  fRotation = 90.0f;  breakcase 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;}
可以看到我们先初始化了地图信息,然后通过地图信息创建了一个坦克,并把坦克放到了地图中的初始化位置。


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




完整源码下载地址:

http://download.youkuaiyun.com/detail/yincheng01/6756657

           

给我老师的人工智能教程打call!http://blog.youkuaiyun.com/jiangjunshow
这里写图片描述
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值