碰撞检测/玩家运动物理 好吧,我想我明白了我是如何调试这个的

问题描述

我在理解和解决我遇到的问题时遇到了问题。我有一个碰撞贴图,如果一个元素是 1,它应该触发我的碰撞检测功能,它确实如此。我很确定我的问题存在于我如何控制我的角色运动,但我不知道如何解决它。即使我将 player.vx 设置为 0,如果我撞到一堵墙,我仍然可以穿过它。然后我添加player.x = cell.x - cell.w,但对所有方面都这样做会导致角色被抛出,具体取决于路由表中哪一方首先被调用

我还尝试了许多增加播放器速度的变体,以防止不必要的穿透。

这是我的玩家代码

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,其中包含一个完全重写的工作示例。

解决方法

好吧,我想我明白了

enter image description here

首先,看起来 leftCollision()rightCollision() 函数的名称混淆了。

这两个函数中的 if 条件语句在我看来都是正确的,因此我决定通过为它分配 x 值来拒绝新的 oldX 值:

function rightCollision(obj,cell) {
    if (obj.x + obj.w >= cell.x && obj.oldX < obj.x) {
        obj.vx = 0;
        obj.x = obj.oldX;    // <-- like this
    } 
};

我是如何调试这个的

  1. 专注于一个方向。我选择向右移动
  2. 注意到它只有在按下左箭头键后才会检测到左碰撞
  3. 在 RightCollision() 中打印了播放器和单元格坐标,并注意到 xoldX 对我来说“似乎”是正确的
  4. 通过为其分配 x 值拒绝了新的 oldX 值。