JavaScript - 如何与角色和物体发生碰撞?
JavaScript - How to have collision with character and an object?
我正在测试一个简单的游戏,我开始在角色和任何物体之间发生碰撞。我首先通过获取字符的最后位置并将字符坐标更改为它来解决这个问题。我想知道是否还有其他方法可以做到这一点?现在我已经完成了“检测”部分。
//Class Function
iscolliding(object) {
if (this.x < object.x + object.width &&
this.x + this.width > object.x &&
this.y < object.y + object.height &&
this.height + this.y > object.y) {
return true;
} else {
return false;
}
}
//------------------------------------------------------------------
//Is colliding function (returns bool)
if (character.iscolliding(/*Object*/)) {
console.log('working');
}
哪里有 console.log('working')
我在想我接下来要做什么?我如何阻止角色通过 object
?我不想使用 Jquery,只是简单的 javascript>
谢谢 (:
如果您需要更多信息,我很乐意回答下面的任何评论! (:
如果您当前的函数确定它们正在发生碰撞,您将需要调用另一个函数。然后你将设置玩家的 x and/or y 值。因此,如果您从玩家的左侧碰撞到对象的右侧,您可以将 player.x
设置为 object.x + object.w
并将玩家的 velocity.x 设置为 0.
这是一个有效的函数。您可以在我最近回答另一个问题的此处看到它的运行情况。只需转到答案和 运行 片段即可。
下面的 collisionDetection()
与您的不同之处在于,如果任何值为真,则不会发生碰撞,它只是 return。否则有一个,它调用 narrowPhase()
.
function collisionDetection(obj) {
if (player.x + player.w < obj.x ||
player.x > obj.x + obj.w ||
player.y + player.h < obj.y ||
player.y > obj.y + obj.h) {
return
}
narrowPhase(obj);
}
function narrowPhase(obj) {
let playerTop_ObjBottom = Math.abs(player.y - (obj.y + obj.h));
let playerRight_ObjLeft = Math.abs((player.x + player.w) - obj.x);
let playerLeft_ObjRight = Math.abs(player.x - (obj.x + obj.w));
let playerBottom_ObjTop = Math.abs((player.y + player.h) - obj.y);
if ((player.y <= obj.y + obj.h && player.y + player.h > obj.y + obj.h) && (playerTop_ObjBottom < playerRight_ObjLeft && playerTop_ObjBottom < playerLeft_ObjRight)) {
player.y = obj.y + obj.h;
player.vy = 0;
}
if ((player.y + player.h >= obj.y && player.y < obj.y) && (playerBottom_ObjTop < playerRight_ObjLeft && playerBottom_ObjTop < playerLeft_ObjRight)) {
player.y = obj.y - player.h;
player.jumping = false;
player.vy = 0;
}
if ((player.x + player.w >= obj.x && player.x < obj.x) && (playerRight_ObjLeft < playerTop_ObjBottom && playerRight_ObjLeft < playerBottom_ObjTop)) {
player.x = obj.x - player.w;
player.vx = 0;
}
if ((player.x <= obj.x + obj.w && player.x + player.w > obj.x + obj.w) && (playerLeft_ObjRight < playerTop_ObjBottom && playerLeft_ObjRight < playerBottom_ObjTop)) {
player.x = obj.x + obj.w;
player.vx = 0;
}
}
您可以使用多种算法来检查碰撞。当您可以将碰撞的对象简化为矩形时,您使用的那个效果很好。
两个盒子碰撞时总会发生重叠。多少取决于他们移动的速度。检测到碰撞后,您需要决定如何处理这些元素。您可能希望移动这两个元素以使它们不重叠。你可以:
- 将位置重置为碰撞发生前的位置。
- 计算它们碰撞时应该在的位置并调整它们。
第一个解决方案更简单,但如果物体移动得太快,它也不会失败。第二种解决方案更好,但更难实施。特别是如果您稍后决定使用其他几何体来检查碰撞。
你可以在这个项目上看到第一个解决方案的例子:
https://stackblitz.com/edit/js-o8orw3?file=index.js
我已经实现了一个基本的 Vector
class 来处理盒子的移动方式。在动画帧内,我移动两个框并检查碰撞。如果发生这种情况,我会将两个盒子移回碰撞前的位置。您可以更新 SPEED
常量以查看他们最终使用此解决方案有何不同。
然后您可以针对您的游戏所需的行为进行调整。对于一个游戏来说,这个方案应该足够了。
更多信息请参考以下link:
https://developer.mozilla.org/en-US/docs/Games/Techniques/2D_collision_detection
这个来自 Unity,涉及其他一些处理碰撞的方法。除了关于编辑器本身的部分之外的所有内容都可以应用。
https://learn.unity.com/tutorial/physics-best-practices#5c7f8528edbc2a002053b5b4
这个也是一样link:
https://learnopengl.com/In-Practice/2D-Game/Collisions/Collision-detection
我正在测试一个简单的游戏,我开始在角色和任何物体之间发生碰撞。我首先通过获取字符的最后位置并将字符坐标更改为它来解决这个问题。我想知道是否还有其他方法可以做到这一点?现在我已经完成了“检测”部分。
//Class Function
iscolliding(object) {
if (this.x < object.x + object.width &&
this.x + this.width > object.x &&
this.y < object.y + object.height &&
this.height + this.y > object.y) {
return true;
} else {
return false;
}
}
//------------------------------------------------------------------
//Is colliding function (returns bool)
if (character.iscolliding(/*Object*/)) {
console.log('working');
}
哪里有 console.log('working')
我在想我接下来要做什么?我如何阻止角色通过 object
?我不想使用 Jquery,只是简单的 javascript>
谢谢 (:
如果您需要更多信息,我很乐意回答下面的任何评论! (:
如果您当前的函数确定它们正在发生碰撞,您将需要调用另一个函数。然后你将设置玩家的 x and/or y 值。因此,如果您从玩家的左侧碰撞到对象的右侧,您可以将 player.x
设置为 object.x + object.w
并将玩家的 velocity.x 设置为 0.
这是一个有效的函数。您可以在我最近回答另一个问题的此处看到它的运行情况。只需转到答案和 运行 片段即可。
下面的 collisionDetection()
与您的不同之处在于,如果任何值为真,则不会发生碰撞,它只是 return。否则有一个,它调用 narrowPhase()
.
function collisionDetection(obj) {
if (player.x + player.w < obj.x ||
player.x > obj.x + obj.w ||
player.y + player.h < obj.y ||
player.y > obj.y + obj.h) {
return
}
narrowPhase(obj);
}
function narrowPhase(obj) {
let playerTop_ObjBottom = Math.abs(player.y - (obj.y + obj.h));
let playerRight_ObjLeft = Math.abs((player.x + player.w) - obj.x);
let playerLeft_ObjRight = Math.abs(player.x - (obj.x + obj.w));
let playerBottom_ObjTop = Math.abs((player.y + player.h) - obj.y);
if ((player.y <= obj.y + obj.h && player.y + player.h > obj.y + obj.h) && (playerTop_ObjBottom < playerRight_ObjLeft && playerTop_ObjBottom < playerLeft_ObjRight)) {
player.y = obj.y + obj.h;
player.vy = 0;
}
if ((player.y + player.h >= obj.y && player.y < obj.y) && (playerBottom_ObjTop < playerRight_ObjLeft && playerBottom_ObjTop < playerLeft_ObjRight)) {
player.y = obj.y - player.h;
player.jumping = false;
player.vy = 0;
}
if ((player.x + player.w >= obj.x && player.x < obj.x) && (playerRight_ObjLeft < playerTop_ObjBottom && playerRight_ObjLeft < playerBottom_ObjTop)) {
player.x = obj.x - player.w;
player.vx = 0;
}
if ((player.x <= obj.x + obj.w && player.x + player.w > obj.x + obj.w) && (playerLeft_ObjRight < playerTop_ObjBottom && playerLeft_ObjRight < playerBottom_ObjTop)) {
player.x = obj.x + obj.w;
player.vx = 0;
}
}
您可以使用多种算法来检查碰撞。当您可以将碰撞的对象简化为矩形时,您使用的那个效果很好。
两个盒子碰撞时总会发生重叠。多少取决于他们移动的速度。检测到碰撞后,您需要决定如何处理这些元素。您可能希望移动这两个元素以使它们不重叠。你可以:
- 将位置重置为碰撞发生前的位置。
- 计算它们碰撞时应该在的位置并调整它们。
第一个解决方案更简单,但如果物体移动得太快,它也不会失败。第二种解决方案更好,但更难实施。特别是如果您稍后决定使用其他几何体来检查碰撞。
你可以在这个项目上看到第一个解决方案的例子:
https://stackblitz.com/edit/js-o8orw3?file=index.js
我已经实现了一个基本的 Vector
class 来处理盒子的移动方式。在动画帧内,我移动两个框并检查碰撞。如果发生这种情况,我会将两个盒子移回碰撞前的位置。您可以更新 SPEED
常量以查看他们最终使用此解决方案有何不同。
然后您可以针对您的游戏所需的行为进行调整。对于一个游戏来说,这个方案应该足够了。
更多信息请参考以下link:
https://developer.mozilla.org/en-US/docs/Games/Techniques/2D_collision_detection
这个来自 Unity,涉及其他一些处理碰撞的方法。除了关于编辑器本身的部分之外的所有内容都可以应用。
https://learn.unity.com/tutorial/physics-best-practices#5c7f8528edbc2a002053b5b4
这个也是一样link:
https://learnopengl.com/In-Practice/2D-Game/Collisions/Collision-detection