碰撞 detection/player 运动物理
Collision detection/player movement physics
我无法理解和解决我遇到的问题。我有一个碰撞图,如果一个元素是 1,它应该触发我的碰撞检测功能,它确实如此。我很确定我的问题存在于我如何控制我的角色移动但我无法弄清楚如何解决它。如果我撞到了墙,即使我将 player.vx
设置为 0
,我仍然可以穿过它。所以然后我添加了 player.x = cell.x - cell.w
但是对所有边都这样做会导致角色四处乱扔,具体取决于在我的路由 table.
中首先调用哪一边
我也尝试了很多不同的方法来增加我的播放器的速度以防止不必要的穿透。
这是我的玩家代码
let friction = 0.9;
let gravity = 2;
let size = 32;
//player
class Player {
constructor() {
this.x = 256;
this.y = 96;
this.w = 32;
this.h = 32;
this.vx = 0;
this.vy = 0;
this.oldX = this.x;
this.oldY = this.y;
this.jumping = false;
}
draw() {
ctx.fillStyle = 'green';
ctx.fillRect(this.x, this.y, this.w, this.h)
}
update() {
this.oldX = this.x;
this.oldY = this.y;
if (controller.right) {this.vx += 1}
if (controller.left) {this.vx -= 1}
if (controller.up && !this.jumping) {this.vy -= 10; this.player = true}
if (controller.down) {this.vy += 1}
this.x += this.vx;
this.y += this.vy;
this.vx *= friction;
this.vy *= friction;
this.vy += gravity;
this.draw();
}
}
let player = new Player();
和 Codepen 可以更轻松地提供帮助 https://codepen.io/jfirestorm44/pen/GRrjXGE?editors=0010
提前致谢
编辑:如果有人发现这个,我在下面的评论中留下了一个新的 CodePen,其中包含一个完全重写的工作示例。
好的,我想我明白了
首先,看起来 leftCollision()
和 rightCollision()
函数的名称混淆了。
这两个函数中的 if
条件语句在我看来都是正确的,因此我决定通过将 oldX
值分配给它来拒绝新的 x
值:
function rightCollision(obj, cell) {
if (obj.x + obj.w >= cell.x && obj.oldX < obj.x) {
obj.vx = 0;
obj.x = obj.oldX; // <-- like this
}
};
我是如何进行调试的
- 专注于一个方向。我选择右移
- 注意到它仅在按下左箭头键后才检测到左侧碰撞
- 在 RightCollision() 中打印玩家和单元格坐标并注意到
x
和 oldX
'seemed' 对我来说是正确的
- 通过将
oldX
值分配给它来拒绝新的 x
值。
我无法理解和解决我遇到的问题。我有一个碰撞图,如果一个元素是 1,它应该触发我的碰撞检测功能,它确实如此。我很确定我的问题存在于我如何控制我的角色移动但我无法弄清楚如何解决它。如果我撞到了墙,即使我将 player.vx
设置为 0
,我仍然可以穿过它。所以然后我添加了 player.x = cell.x - cell.w
但是对所有边都这样做会导致角色四处乱扔,具体取决于在我的路由 table.
我也尝试了很多不同的方法来增加我的播放器的速度以防止不必要的穿透。
这是我的玩家代码
let friction = 0.9;
let gravity = 2;
let size = 32;
//player
class Player {
constructor() {
this.x = 256;
this.y = 96;
this.w = 32;
this.h = 32;
this.vx = 0;
this.vy = 0;
this.oldX = this.x;
this.oldY = this.y;
this.jumping = false;
}
draw() {
ctx.fillStyle = 'green';
ctx.fillRect(this.x, this.y, this.w, this.h)
}
update() {
this.oldX = this.x;
this.oldY = this.y;
if (controller.right) {this.vx += 1}
if (controller.left) {this.vx -= 1}
if (controller.up && !this.jumping) {this.vy -= 10; this.player = true}
if (controller.down) {this.vy += 1}
this.x += this.vx;
this.y += this.vy;
this.vx *= friction;
this.vy *= friction;
this.vy += gravity;
this.draw();
}
}
let player = new Player();
和 Codepen 可以更轻松地提供帮助 https://codepen.io/jfirestorm44/pen/GRrjXGE?editors=0010
提前致谢
编辑:如果有人发现这个,我在下面的评论中留下了一个新的 CodePen,其中包含一个完全重写的工作示例。
好的,我想我明白了
首先,看起来 leftCollision()
和 rightCollision()
函数的名称混淆了。
这两个函数中的 if
条件语句在我看来都是正确的,因此我决定通过将 oldX
值分配给它来拒绝新的 x
值:
function rightCollision(obj, cell) {
if (obj.x + obj.w >= cell.x && obj.oldX < obj.x) {
obj.vx = 0;
obj.x = obj.oldX; // <-- like this
}
};
我是如何进行调试的
- 专注于一个方向。我选择右移
- 注意到它仅在按下左箭头键后才检测到左侧碰撞
- 在 RightCollision() 中打印玩家和单元格坐标并注意到
x
和oldX
'seemed' 对我来说是正确的 - 通过将
oldX
值分配给它来拒绝新的x
值。