本页面由 Flash 保存计划 从 Internet Archive 存档还原 · 快照 2010-06-11 · 原址 http://space.flash8.net/bbs/thread-405990-1-1.html ← Flash 保存计划
返回列表 回复 发帖

诚心求救,望解答,关于碰撞后位移问题, 只要知道原理就好了。

首先介绍下我做的游戏是坦克大战,都是最简单的方型碰撞,并且只能上下左右移动,不存在斜着移动。
我的问题是:
当坦克与墙体碰撞后,使坦克后移到紧贴着墙的位置
例:  A - >  B   A向B移动
     AB         A与B碰撞了,A保持在B的左面,并紧贴着。
以下是我的废话--------------
我自己的想法:
最开始:
我设定了一个变量记录坦克朝向(比如90度),待碰撞后,根据朝向,控制坦克向 与朝向相反的方向移动,坦克的一半与碰撞物
的一半的距离。
后来我发现这种方法有很大的问题,比如说要制作一个效果,中弹时后退一段距离。这时候就会出现问题。
然后我想了第二种方法
记录坦克 上一步 的坐标跟当前坐标,根据对比得出坦克移动方向,然后位移。
但这种方法很难管理,如果我有多个类,并都使用了Event.ENTER_FRAME 来设定坦克位置,那么就很难记录上一步与下一步的
坐标。因为你很难判定那个类的Event.ENTER_FRAME先执行,除非把所有的内容都写在一个Event.ENTER_FRAME里,但这样不好
管理,也失去了面向对象的优势

大家能告诉我,大家是怎么设定碰撞后位移的方法吗。  我只想知道原理就行,不需要代码。
要勤来闪吧才可以 找到 好东西

搜 [url=space.php?uid=617985]Cl@rke将军[/url]  写的《俯视视角游戏常见碰撞检测方法全解》

http://space.flash8.net/bbs/viewthread.php?tid=390951&highlight=
认真的拜读了一下,貌似里面只提到了  在以方格型式移动的情况下(就是一次移动一个方格),做出碰撞位移。  其它讲解的都碰撞的检测方法。。

我想知道的是  碰撞后  怎么“位移”
例:  A - >  B   A向B移动
     AB         A与B碰撞了,A保持在B的左面,并紧贴着。
我移动一次是1~N个象素,非方格,应该怎么办?
做过坦克大战这样的游戏,但不是很明白你的想法,a是坦克?B是什么?墙面吗?还是其他坦克?A保持在B的左面,并紧贴着。?不会就停着吧?是b被a推着走?想推箱子一样?
a 是坦克

b是墙

a就停在B的左面,B不会被推走,就这样
本帖最后由 迷惘的小强 于 2010-6-12 21:51 编辑

onClipEvent (enterFrame) {
if (Key.isDown(Key.RIGHT)) {
  if (this._x<275) {
   this._x += 4;
  }
}
if (Key.isDown(Key.LEFT)) {
  this._x -= 4;
}
}
键盘左右移动
你先拿你自已的影片要到达的位置,你想要它停的位置,看一下X是多少,然后代码里X就写多少

aaa.fla (24 KB)

标准的坦克大战适用于“数组地图”碰撞检测方法,但是有特殊因素,玩家未必像普通RPG一样每次走满一个格子。
坦克大战的地图非常有规则,每个地图单位均是相同大小的方块。
根据地图形成一个数组,用1来表示墙壁,0来表示通路,假设如下:
var map:Array = [
[1,1,1,1,1,1,1,1,1,1],
[1,0,0,0,0,0,1,0,0,1],
[1,0,0,0,1,1,1,0,0,1],
[1,0,0,0,1,0,0,0,0,1],
[1,0,0,0,1,1,1,1,0,1],
[1,0,0,0,0,0,0,0,0,1],
[1,1,1,1,1,1,1,1,1,1]];
设每个方格的大小都是30x30,左上注册,第一个方格剪辑坐标(0,0)
玩家(player)初始坐标(x=30,y=30),对应map[1][1]位置。下文使用
玩家(player)移动速度是3(10帧走完一格)

玩家每次左移动需要做如下判定(伪码):
if(player.x%30){  //如果坦克横坐标不是30的整数倍,此刻坦克肯定没有紧贴墙壁,无条件批准这次移动
        批准移动;
}else{//否则可能碰到墙壁,需要判断能否移动
    if(player.y%30){//如果坦克纵坐标不是30的整数倍,坦克最多可能碰到两块墙壁
        if(map[int(player.y/30)][player.x/30-1]||map[int(player.y/30)+1][player.x/30-1]){
            禁止移动
        }else{
            批准移动
        }
    }else{//否则坦克只能碰到一块墙壁
        if(map[player.y/30][player.x/30-1]){
            禁止移动
        }else{
            批准移动
        }
    }
}



本帖所有坐标直接用了flash中的坐标计算,
实际制作时为了方便管理和提高效率,可以专门用变量记录坦克当前位置对应数组的哪部分。

使用这个思路一定保证所有除法是整除,不会出现小数,否则会很麻烦。
在线时间不固定。
上文是按照标准坦克大战的基本思路写的,
貌似和楼主帖子信息仍然有出入,
如有不能完成功能,楼主请跟帖。
在线时间不固定。
十分感谢将军的回答

我现在用的的确是hitTestObject方法  先碰撞,然后再移动单位的位置,虽然已经初步达到了目的,但很少的时候会出现一些bug,比如本来在墙的左边,莫名的被弹到了墙的右面,所以感觉这样的方法不太稳定,一但出现问题,就很难挽回。

我这个小游戏的确要比这个稍稍麻烦一些,坦克每次的移动距离是会变化的,坦克有移动速度这个属性,吃了某个物品,会佩戴了某个装备,速度会动态的变化,而且也存在不能整数的时候。

不过我想这个方法应该也能实现,我现在想法还比较模糊,还得再想想。
速度不定的话需要稍事修改了
不过数组地图对“障碍规则,4方向移动”始终是最好的解决方案。

设单位地图方块大小30x30
坦克大小20x20(不能让坦克和方格一样大,不然只要坦克坐标出现小数,所有路口都过不去)
设坦克速度2.25

以向右移动为例。
情况1:
坦克原始坐标x=91,坦克原始右边界x=111
坦克移动后右边界x=113.25
移动前后坦克右边界没有出当前坦克所在格子,不会因这次右移发生可能撞墙的情况
情况2:
坦克原始坐标x=99,坦克原始右边界x=119
坦克移动后右边界x=121.25
右边界到了下一个格子,有可能下一个格子是墙壁,将此移动修改为
先让坦克移动1个单位,坦克右边界从x=119移动到x=120
通过数组地图检测右面是否是墙壁(可能检测2个格,参见#7帖子),如果是,判定到此为止。如果不是,坦克继续移动1.25个单位,右边界到121.25
在线时间不固定。
恩,谢谢将军   

我尝试做做,有问题再请教你哈。
返回列表