《C++游戏开发》十八 角色在障碍物中智能行走的实现

原创 2013年09月13日 00:15:49

本系列文章由七十一雾央编写,转载请注明出处。

 http://blog.csdn.net/u011371356/article/details/11621337

作者:七十一雾央 新浪微博:http://weibo.com/1689160943/profile?rightmod=1&wvr=5&mod=personinfo



      

   

     最近一直在忙着写一个游戏,其中融入了RPG元素,有人物的行走与障碍物判定。

      一般而言,当人物行走时碰到障碍物时应该停止不动,就像下面这样

      

 

      这样的实现非常简单,每次移动前判断人物的矩形是否和障碍物相交即可,如果只以向右的方向为例,代码大概可以写成这样

if(行走)
{
switch(方向)
{
case 右:如果当前位置的右边位置是障碍物,则不动,否则将人物移到右边位置
break;  
}
}

      这看起来非常合理,我一开始也是按照这个思路写的,但是当人物处于下面这种情况时,即人物只有一部分碰撞到障碍物的时候

      


      如果仍然像上面那样,障碍物和人物矩形仍然是相交的,所以人物仍然是行走不了的,这在游戏中可以接受,但是看起来总是有一种违和感,为什么我们的人物不能智能一点,在拐角处可以绕过障碍物呢?


      下面是自己的想法和实现,希望可以给新手朋友们参考,也希望路过的高手可以指导下,毕竟自己对游戏了解的不太多。


      在上图的情况中,我们看到人物(就是那只可爱的小狗)向右行走的时候下半部分碰撞到了障碍物,而上半部分没有碰撞到,那么我们希望出现的情况就是小狗先向上行走一点,使得下半部分不再与障碍物碰撞,然后向右行走。如果是上半部分碰撞到障碍物,而下半部分没有碰撞到障碍物,那么小狗应该向下行走一点,再向右行走。

 

      另外,当处于下面这样的情况时

      


      如果小狗向右下方向行走时,那么按照之前的判断,小狗仍然是不会运动的。但是我们想要的效果是小狗向下移动。

 

      那么,我们怎么样实现这个效果呢?

 

      事实上是非常简单的。

 

      实现的思路有两点关键:

      1.将运动方向分解,单独进行x方向和y方向的判断和运动。

      2.障碍判断使用人物矩形的四个顶点进行。

       

      在游戏中我使用了摇杆,那么当是右上方向时,就分解为向右运动和向上运动。在运动分解之后,第二种情况即小狗沿墙向右下方向的移动就自然解决了,此时小狗运动方向被分解为右方向和下方向,有方向上遇到障碍物无法行走,但是下方向是畅通的,那么就会出现小狗向下面移动的效果了。

 

      再回到我们初始提出的问题,现在解决起来就很容易了。

      我们可以很容易的得到小狗矩形的四个顶点,在不同的方向判断中使用不同的点。

      例如:当向右运动时,我们得到右上顶点和右下顶点。

      判断右上顶点和右下顶点是否遇到障碍物,会出现四种情况

             1.右上顶点和右下顶点均是障碍物

                这显示就是不可走的情况

             2.右上顶点和右下顶点均不是障碍物

                这就是可通行的情况

             3.右上顶点是障碍物,右下顶点不是障碍物

                此时人物应该向下运动,然后再向右运动,绕过障碍物

             4.右上顶点不是障碍物,右下顶点是障碍物

               人物应该向上运动,然后向右运动,绕过障碍物

 

       事实上如果我们分解处理xy方向之后,对于3,4种情况下,只需要处理前面一部分运动就可以,即只向上下运动即可,因为游戏中是在不断接受玩家的按键信息,不断的处理位置变化,当玩家按着右键的时候,在y方向上处理了上下运动经过障碍物后,在x方向的处理上自然处于可以运动的状态了,也就形成了绕过障碍物的效果。

 

      有了思路,实现可以向下面这样

 

switch(方向)
{
case 右:if(情况1)
不作处理
else(情况2)
到达该位置,即x增加
else(情况3)
向下运动,即y增加
else(情况4)
向上运动,即y减少
break;
case
……
}

       实现中可以用switch –case处理方向。但是写完后就会发现大量的代码都是一样的,所以我是使用了数组,分xy方向分解,依次进行xy方向判断,将上下左右分别添加了另外分解的一个方向,设为不可通行,通过数组下标处理不同的情况,看起来代码就不累赘了。用switch-case语句最大的好处就是代码很清晰,很容易看明白,缺点是重复代码。用数组后代码很简洁,但是语义不是那么清晰,有时过会自己就会混淆,囧。

C++游戏系列1-角色类

【项目-游戏中的角色类】(1)基于下面设计的游戏中角色类,补充完整需要的成员函数,使角色能一定的规则行动或改变状态。下面代码中包含的是最基本的要求,可以根据你的设计进行扩充。class Role { ...
  • sxhelijian
  • sxhelijian
  • 2016年03月27日 20:23
  • 2366

【Visual C++】游戏开发笔记十六 讲解一个完整的回合制游戏demo

本系列文章由zhmxy555编写,转载请注明出处。文章链接  http://blog.csdn.net/zhmxy555/article/details/7447864作者:毛星云    邮箱: ha...
  • zhmxy555
  • zhmxy555
  • 2012年04月11日 03:10
  • 100560

MFC小游戏,背景位图,用键盘上的上下左右控制人物的走动,不出现闪烁效果

  • 2009年08月07日 19:02
  • 4.21MB
  • 下载

《C++游戏开发》十八 角色在障碍物中智能行走的实现

最近一直在忙着写一个游戏,其中融入了RPG元素,有人物的行走与障碍物判定。       一般而言,当人物行走时碰到障碍物时应该停止不动,就像下面这样                这样的实现非常简单,...
  • u011371356
  • u011371356
  • 2013年09月13日 00:15
  • 13419

HTML5小游戏研究(一):canvas初探,雏形:方块跳跃障碍

前几天玩了一个HTML5小游戏(http://www.lessmilk.com/game/box-jump/),很有意思,但不支持手机。想着学习一下前端知识和JS,决定仿制一个。先做个会动的方块由于没...
  • twoByte
  • twoByte
  • 2016年07月14日 16:37
  • 1236

Unity3D游戏开发之跑酷游戏项目讲解

一、游戏策划      游戏采用2D界面,角色从左到右奔跑,在路段中随机生成障碍物和金币,玩家需要使用跳跃功能躲开障碍物,在游戏中玩家收集的金币数目越多,奔跑的距离越长,玩家的得分就越高。我们最...
  • wave_1102
  • wave_1102
  • 2015年06月29日 18:00
  • 4065

【Android游戏开发之四】Android 游戏框架(一个游戏角色在屏幕行走的demo)

Himi  原创, 转载请注明! 谢谢。   原文地址: http://blog.csdn.net/xiaominghimi/archive/2010/12/21/6090631.aspx 各位童...
  • java886o
  • java886o
  • 2011年10月11日 13:37
  • 269

【Android游戏开发之四】基础的Android 游戏框架(一个游戏角色在屏幕行走的demo)

本站文章均为 李华明Himi 原创,转载务必在明显处注明:(作者新浪微博: @李华明Himi )  转载自【黑米GameDev街区】 原文链接: http://www.himigame.com/...
  • lcl_sysu
  • lcl_sysu
  • 2015年12月08日 21:03
  • 251

【Visual C++】游戏开发五十 浅墨DirectX教程十八 雪花飞扬:实现唯美的粒子系统

本系列文章由zhmxy555(毛星云)编写,转载请注明出处。   文章链接:http://blog.csdn.net/zhmxy555/article/details/8744805 作者:毛星云(浅...
  • zhmxy555
  • zhmxy555
  • 2013年04月01日 02:24
  • 29035

【Visual C++】游戏开发五十 浅墨DirectX教程十八 雪花飞扬:实现唯美的粒子系统

本篇文章中,我们将一起探讨三维游戏中粒子系统的方方面面,首先对粒子系统的基本概念特性做一个全面的认知,然后我们依旧是把粒子系统封装在一个C++类中,模拟了三维游戏中唯美的雪花飞扬的景象,让我们之前的综...
  • true11false
  • true11false
  • 2014年07月25日 22:54
  • 1221
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:《C++游戏开发》十八 角色在障碍物中智能行走的实现
举报原因:
原因补充:

(最多只允许输入30个字)