改写《魔塔》前篇07:碰撞检测(附:前期阶段项目下载)
2013-03-30 16:57
369 查看
前面已经初步实现了勇士在地图内的移动。这一篇我们就 开始加入碰撞检测,让勇士在碰到墙壁之后无法行走,到地图边缘时也不会走出去。
我们先来实现墙壁的碰撞逻辑。大家可以先思考一下,如何判断勇士撞到墙了?相信你已经有了一些思路了:可以在menuCallBackMove方法中判断目标地点的图块类型,如果是墙壁的话,就不让勇士移动。没错,这就是我们将要采用的方法。下面我们看一下如何用代码实现这个逻辑。
(1)先熟悉一下CCTMXLayer中的一个重要方法tileGIDAt(CCPoint tileCoordinate)。此方法可以根据传入的Tilemap坐标,返回坐标位置的图块编号,如果该位置没有图块,则返回0.有了这个方法,就可以方便地判断目标位置是否有墙壁了。现在只需要将勇士的cocos2d-x坐标转换为Tilemap坐标即可。转换方法如下,在计算y坐标时,用最大的y值减去当前y值即可。首先我们在HelloWorldScene.h文件里声明方法tileCoordForPosition,即把“CCPoint
tileCoordForPosition(CCPoint position);”添加到声明方法里即可。然后在.cpp文件的最后添加下面代码。
(2)在HelloWorldScene.h头文件里定义几个碰撞类型:
typedef enum
{
kNone=1,//可以通行
kWall,//墙
kEnemy,//敌人
}CollisionType; //碰撞类型
(3)添加一个方法checkCollision(用于碰撞检测)。注意:在获取图块ID之前,先判断目标位置是否在地图范围内,如果超出了地图范围,则返回kWall类型,阻止勇士移动。首先在HelloWorldScene.h文件添加方法的声明,即“CollisionType checkCollision(CCPoint heroPosition);”。然后在.cpp文件里实现此方法,代码如下:
(4)在menuCallBackMove这个回调方法中调用checkCollision,检测碰撞。如果碰撞类型为墙壁,只需要设置勇士的朝向;如果无障碍,则开始行走。修改menuCallBackMove()函数如下:
现在编译运行程序,控制勇士在地图上行走,当遇到墙的时候,勇士不会再穿墙而过了,而是乖乖地站在原地不动。
最后附上前期阶段项目源码的下载地址:点此下载
我们先来实现墙壁的碰撞逻辑。大家可以先思考一下,如何判断勇士撞到墙了?相信你已经有了一些思路了:可以在menuCallBackMove方法中判断目标地点的图块类型,如果是墙壁的话,就不让勇士移动。没错,这就是我们将要采用的方法。下面我们看一下如何用代码实现这个逻辑。
(1)先熟悉一下CCTMXLayer中的一个重要方法tileGIDAt(CCPoint tileCoordinate)。此方法可以根据传入的Tilemap坐标,返回坐标位置的图块编号,如果该位置没有图块,则返回0.有了这个方法,就可以方便地判断目标位置是否有墙壁了。现在只需要将勇士的cocos2d-x坐标转换为Tilemap坐标即可。转换方法如下,在计算y坐标时,用最大的y值减去当前y值即可。首先我们在HelloWorldScene.h文件里声明方法tileCoordForPosition,即把“CCPoint
tileCoordForPosition(CCPoint position);”添加到声明方法里即可。然后在.cpp文件的最后添加下面代码。
CCPoint HelloWorld::tileCoordForPosition(CCPoint position) { int x=position.x/map->getTileSize().width; int y=(((map->getMapSize().height-1)*map->getTileSize().height)-position.y)/map->getTileSize().height; return ccp(x,y); }
(2)在HelloWorldScene.h头文件里定义几个碰撞类型:
typedef enum
{
kNone=1,//可以通行
kWall,//墙
kEnemy,//敌人
}CollisionType; //碰撞类型
(3)添加一个方法checkCollision(用于碰撞检测)。注意:在获取图块ID之前,先判断目标位置是否在地图范围内,如果超出了地图范围,则返回kWall类型,阻止勇士移动。首先在HelloWorldScene.h文件添加方法的声明,即“CollisionType checkCollision(CCPoint heroPosition);”。然后在.cpp文件里实现此方法,代码如下:
CollisionType HelloWorld::checkCollision(CCPoint heroPosition) { //cocos2d-x坐标转换为Tilemap坐标 CCPoint tileCoord=tileCoordForPosition(heroPosition); //如果勇士坐标超过地图边界,返回kWall类型,阻止其移动 if(heroPosition.x<0||tileCoord.x>map->getMapSize().width-1||tileCoord.y <0||tileCoord.y>map->getMapSize().height-1) return kWall; //获取当前坐标位置的图块ID int tileGid=map->layerNamed("wall")->tileGIDAt(tileCoord); //如果图块ID不为0,表示有墙 if(tileCoord){ return kWall; } //可以通行 return kNone; }
(4)在menuCallBackMove这个回调方法中调用checkCollision,检测碰撞。如果碰撞类型为墙壁,只需要设置勇士的朝向;如果无障碍,则开始行走。修改menuCallBackMove()函数如下:
void HelloWorld::menuCallBackMove(CCObject* pSender) { //正在移动中,不接受新的指令 if (isHeroWalking) return; CCNode *node = (CCNode *) pSender; //按钮的tag就是需要行走的方向 int targetDirection = node->getTag(); //移动的距离 CCPoint moveByPosition; switch(targetDirection) { case kDown: moveByPosition=ccp(0,-32); break; case kLeft: moveByPosition=ccp(-32,0); break; case kRight: moveByPosition=ccp(32,0); break; case kUp: moveByPosition=ccp(0,32); break; } //计算目标坐标,用当前勇士坐标加上移动距离 CCPoint targetPosition = ccpAdd(heroSprite->getPosition(), moveByPosition); //调用checkCollision检测碰撞类型,如果是墙壁,则只需要设置勇士的朝向 if (checkCollision(targetPosition) == kWall) { setFaceDirection((HeroDirection)targetDirection); return; } //利用CCSpawn将行走动画和移动同时执行 CCAction *action = CCSequence::create( CCSpawn::create( CCAnimate::create(walkAnimation[targetDirection]), CCMoveBy::create(0.28f,moveByPosition), NULL), //把方向信息传递给onWalkDone方法 CCCallFuncND::create(this, callfuncND_selector(HelloWorld::onWalkDone), (void*)targetDirection), NULL); //主角执行动作 heroSprite->runAction(action); //人物开始移动,设置标识为true isHeroWalking = true; }
现在编译运行程序,控制勇士在地图上行走,当遇到墙的时候,勇士不会再穿墙而过了,而是乖乖地站在原地不动。
最后附上前期阶段项目源码的下载地址:点此下载
相关文章推荐
- 改写《魔塔》后篇06:传送点及地图切换(附:后期阶段项目下载)
- 改写《魔塔》中篇06:善后工作和注意事项(附:中期阶段项目下载)
- 第一个项目(八)碰撞检测
- cocos2dx打飞机项目笔记六:GameScene类和碰撞检测 boundingbox
- Cocos2d-X 瓦片地图使用的实例项目(包含碰撞检测,移动)
- 在项目前期需求分析阶段,需要编写的文档
- 阶段总结之碰撞检测
- 资源 | 26份机器学习视频资源,涵盖入门->中级->项目的各个阶段!(可直接下载......)
- cocos2dx3.X项目重写(四)添加地板,障碍物和碰撞检测
- 人脸检测和识别 源代码 下载-opencv3+python3.6完整实战项目源代码 识别视频《欢乐颂》中人物
- DateChooser控件发布ASP.NET 2.0新版(我的ASP.NET 2.0控件开发书的第二个阶段项目)[请大家一定注意版本的更新,下载最新版]
- Unity3D学习之(碰撞检测小项目)
- cocos2dx3.X项目重写(四)添加地板,障碍物和碰撞检测
- 使用GameMaker中用于碰撞检测的脚本小记
- git 下载项目操作步骤
- 如何快速查找下载java项目所需jar包
- 高级软件工程2017第6次作业——团队项目:Alpha阶段综合报告
- 爬虫代码实现三:打通爬虫项目的下载、解析、存储流程
- 为大家提供一个完整的Hibernate Annotation项目_源码下载
- 下载项目中的文件