什么是更有效的碰撞方式?
Posted
技术标签:
【中文标题】什么是更有效的碰撞方式?【英文标题】:What's a more efficient way to do collisions? 【发布时间】:2017-07-10 13:27:17 【问题描述】:这是我的困境
我的游戏舞台周围有 4 堵墙,当玩家撞到这些墙时,我不想为每一堵墙都做一个 if 语句来检查玩家是否撞到了它,所以我创建了一个阵列来固定墙壁,然后检查玩家是否击中它。现在,因为我正在这样做,所以如果玩家击中某物,我将不知道他实际击中了什么,并且如果他击中 [0], [1], [2]
等,我无法在我的数组中进行检查,因为那时我会重新开始检查是否他正在击中特定的墙壁。我不想这样做的原因是为了将来,当我添加更多的障碍、建筑物等时。
所以我的问题是,我怎样才能进行碰撞检查,而不需要对特定对象进行硬编码检查,并提供某种可用于玩家响应的值,例如,如果你撞到顶墙而你可以在不执行上述操作的情况下以某种方式解决此问题,然后使其无法通过或其他方式,
if (main.playerPosKeeper_mc.hitTestObject(this[main.StageCollisions]))
trace("hit");
StageCollisions 是一个数组,其中包含我的所有障碍。
当玩家在 StageCollisions 中击中任何东西时,我不能简单地从他的 y 值或 x 值中减去,因为我不知道他击中了哪个对象,但我也不想对其进行硬编码,以便我检查我是否击中了让我们说最高障碍,因为如果我只是回到制作静态 if else 语句,为什么首先要做一个数组。
^^ 引用这个话题
AS3 - How to Cycle States of Character Animations (moving & stopped)
这一直困扰着我一段时间,因此将不胜感激。这是一个很难形成的问题,因此我可以在必要时澄清要点。
【问题讨论】:
所以你想在循环处理4个边界墙的同时将英雄剪辑保持在某个矩形内? 不一定,我正在做碰撞检查,我很好奇我如何知道玩家正在撞击哪面墙,而不检查我拥有的每一面墙,然后给出适当的命令。我的真正目标是摆脱对特定对象的硬编码碰撞检查,因为如果我让游戏变得更大,我必须对特定对象进行更多检查。我包含的主题来自用户 Vesper 的回复是我一直在努力的,但值得拥有自己的主题。这可能是我想多了,但是是的。 另外,忘了提一下,一旦点击了 dpad 方向,我就会进行碰撞检查,之前我被告知要使用循环,可能是通过使用激活每一帧的事件侦听器,但我认为一种更简单、更有效的方法是仅在您单击 dpad 时进行检查,它会将您移向该方向,检查您是否击中某物,如果您击中某物,则将您向后移动,但后来我得到了上面的问题我不知道我在打什么,而且如果我想添加更多的墙壁和东西,我不想为了将来对特定对象进行硬编码检查。 不确定我能得到你想要的。您可以拥有一组(任意数量)墙壁,并且在循环中您可以找到是否有任何墙壁与英雄发生碰撞,如果有的话,您还可以找到应该归咎于哪一堵墙壁。这就是你想要的吗? 对于 GameDev 堆栈交换来说可能是一个更好的问题。 【参考方案1】:所以我的问题是,如何在不进行硬编码的情况下进行碰撞检查 检查特定对象,并给出某种值 用于玩家响应,例如,如果您击中顶部 墙,您可以在不执行上述操作的情况下以某种方式解决这个问题,然后 让它你不能穿过或其他东西
是的,所以您需要一种执行通用碰撞响应的方法。这可能是一个很大的话题。最简单的方法通常是在移动后检查是否发生碰撞,如果发生碰撞则反转移动。
类似这样的:
function movePlayer(movementX:Number, movementY:Number):void
var originalX:Number = player.x;
var originalY:Number = player.y;
player.x += movementX;
if (checkCollision())
player.x = originalX;
player.y += movementY;
if (checkCollision())
player.y = originalY;
function checkCollision():Boolean
for each (var wall:MovieClip in walls)
if (player.hitTestObject(wall))
return true;
return false;
这样,您可以让checkCollision()
检查 4 面墙或 50 面墙,没关系。它不会让玩家进入它们。
这只是一个起点,它可以通过多种方式分解或改进。
【讨论】:
【参考方案2】:一些琐碎的伪代码供你学习:
private function collisionCheck(h:Sprite):Sprite // pass the hero Sprite into this function and it will return the wall that it hit
for each (b:Sprite in blockArray) // if your array of hit-able objects is called "blockArray"
if (h.hitTtestObject(b)) // check the hero Sprite against all objects in the array
return b;
return null;
然后,在您的代码中的其他地方(可能在您的 gameTick 函数或 gameLoop 函数中,或者您的游戏逻辑在每一帧上重复的任何地方:
private function gameTick():void
var objectHit:Sprite = collisionCheck(_myHero); // this will run the collision check function, and return the sprite that the hero collides with;
if (objectHit != null)
objectHit.alpha = 0.5;
// this will give you a visible representation that your code is indeed working, or not.
当你的英雄没有与任何东西发生碰撞时,这个函数将返回 null。这就是为什么我在尝试对其 alpha 值执行操作之前首先检查 objectHit 是否不为空。当然,除了在项目中更改其 alpha 值之外,您还会做一些其他事情,但这是我经常做的事情(使用 alpha),以快速获得视觉确认事物正在检测它们应该做的事情。
【讨论】:
“当然,除了在项目中更改其 alpha 值之外,您还会做其他事情”——这就是 OP 所要求的。 ;) 不,如果您阅读帖子下方的 OPs cmets,您会发现他只是想知道如何弄清楚他撞到了哪堵墙。他清楚地理解移动、检查、撤消的概念。他似乎只是认为有一种比依次通过数组检查每个对象更好的方法,而实际上并没有,这就是我想要展示的。然后,如果他真的需要知道他击中了什么,我的代码会返回那个。 是的,这确实返回了他击中的对象,但他真正的问题是如何对他击中的对象做一些有意义的事情,而不是为击中的对象编写不同的条件。这个例子根本没有展示如何做到这一点。 这可能是他的目标,但在我阅读时这不是他的问题。每次我参加 ACT 时,阅读理解都是我的最低分,所以也许你是对的 :) 嗨,我很抱歉不清楚我的意图。确实,我想知道我击中了哪个物体,但这是为了让我可以调用正确的响应(如果你没有击中某物,则向上移动,或者保持静止以防止碰撞,或者我能想到的其他任何事情of) 我认为 Aaron 的代码非常符合我的意图,但仍然感谢你们在这方面的帮助。以上是关于什么是更有效的碰撞方式?的主要内容,如果未能解决你的问题,请参考以下文章