我写了一个html5游戏框架,并试图创建一个2D平台游戏。但是我坚持玩游戏的碰撞检测部分,我的框架包含一个方法为“ intersects”的rect对象。因此,您可以检查rect是否与另一个rect相交,它工作正常,但我不知道如何对这种方法做出反应。我试图将玩家位置设置为最后一个“非碰撞”位置,但是问题是玩家速度偏移,每次玩家速度的和之间存在间隙时。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
我自己再也想不到。
我认为,这不仅是HTML5 / JS游戏的总体上是一个游戏机制问题。我不熟悉HTML5语法,因此您可能必须重写我的代码示例的一些详细信息。另外,我不知道您的代码结构如何;我会认为,无论是球员和块有这样一些功能getX()
,getXSpeed()
,setX()
等等。
当您检测到播放器(或任何其他可移动的对象)与环境块之间的碰撞时,您将需要更新播放器的位置,以便它仅碰触该块而不会拦截它。在执行此操作之前,您需要了解它与方块的碰撞方式:玩家是从上方,从左侧,从右侧还是从底部进入方块?
首先,我们需要玩家的位置。
playerX = player.getX();
playerY = player.getY();
根据播放器的移动方向,您需要添加播放器的宽度和高度,以获取指向播放器移动方向的角的坐标。
if(player.getXSpeed() > 0) {
playerX += player.getWidth();
}
if(player.getYSpeed() > 0) {
playerY += player.getHeight();
}
接下来,您将要获得与玩家先前位置最接近的方块侧面。您可以检查玩家的速度是正还是负,以查明他来自哪一侧。它们一起代表了指向玩家前进方向的角点坐标。
blockX = player.getXSpeed() > 0? block.getX() : block.getX() + block.getWidth();
blockY = player.getYSpeed() > 0? block.getY() : block.getY() + block.getHeight();
现在,我们有了播放器经过的块的垂直边的Y坐标和水平边的X坐标,总共有了两边之间的角坐标。
我创建了一个小图,以防您不明白我们为什么这样做:
黑框表示环境块。橙色框代表玩家的先前位置和当前位置。蓝线代表玩家移动的路径。现在,我们需要检查代表该块角的蓝点是否在该线的上方或下方。这告诉我们玩家是否撞到积木的水平或垂直侧面。
如果玩家击中垂直面,则蓝线的倾斜度将小于从玩家的角到方块的角的倾斜度。就数学而言,这意味着:
(currentPlayerY - previousPlayerY) / (currentPlayerX - previousPlayerX)
小于
(currentPlayerY - blockY) / (currentPlayerX - blockX)
如果这不适用,则玩家将击中积木的水平侧。您的代码将如下所示:
bool verticalSide = abs(player.getYSpeed() / player.getXSpeed()) < abs((playerY / blockY) / (playerX - blockX));
由于我们可以忽略重力,因此我们可以假设玩家的运动是线性的。我们只需要在这条线上的一个点就可以判断玩家来自哪个方向。这意味着无论玩家在上一个游戏周期中走了多远,它(currentPlayerY - previousPlayerY) / (currentPlayerX - previousPlayerX)
都将始终等于player.getYSpeed() / player.getXSpeed()
。请注意,玩家不一定来自左上角,因此我们计算出的倾斜度可能为负。我们使用abs()
编程语言通常提供的数学类函数来获取绝对值,即将所有负值都变为正数。
现在我们知道是要处理水平碰撞还是垂直碰撞,我们可以相应地更新玩家的位置:
if(verticalSide) {
player.setX(player.getXSpeed() > 0? blockX - player.getWidth(): blockX);
player.setXSpeed(0);
} else {
player.setY(player.getYSpeed() > 0? blockY - player.getHeight(): blockY);
player.setYSpeed(0);
}
如果verticalSide
为true,则玩家正在撞块的一侧。现在,我们检查玩家的x速度是否为正,以找出他是来自左侧还是右侧,并更新其位置,以便他刚好碰到障碍物。我们还将他的水平速度设置为0。但是,如果verticalSide
不正确,则玩家将撞到块的顶部或底部,因此我们对y轴执行相同的操作。这应该是您需要的一切。
但我还有另外一条提示:您最可能需要信息,即玩家当前是否正在着地,以确定在按下空格键或任何键时是否可以跳跃。为此,您应该grounded
在播放器类中创建一个布尔字段,该字段在每次移动播放器时都设置为false。在碰撞检查期间,如果玩家正在击中方块的顶部(即verticalSide
isfalse
和player.getYSpeed() > 0
is),请将其再次设置为true true
。如果按下了跳转键,grounded
则true
在触发跳转之前检查是否为。
有趣的是,昨天我遇到了完全相同的问题,我想出了这个解决方案,但只压缩了几行代码,所以我不得不倒退以记住我在这里所做的事情。猜猜我将来应该评论我的代码。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句