【问题标题】:Collision detection/player movement physics碰撞检测/玩家运动物理
【发布时间】:2021-03-30 01:04:29
【问题描述】:

我在理解和解决我遇到的问题时遇到了问题。我有一个碰撞图,如果一个元素是 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

提前致谢

编辑:如果有人发现这一点,我在下面的 cmets 中留下了一个新的 CodePen,并带有一个完全重写的工作示例。

【问题讨论】:

    标签: javascript collision-detection game-physics


    【解决方案1】:

    好吧,我想我明白了

    首先,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
        } 
    };
    

    我是如何进行调试的

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

    【讨论】:

    • 这似乎是朝着正确方向迈出的一步。一个问题是,如果我对 Y 也这样做,那么当我穿过盒子顶部时,玩家会振动并缓慢移动。
    • 它解决了您发布的三个问题中的两个。振动与你的 vy 在 update() 函数内被重置有关,所以你的 this.vy = 0 没有达到你期望的效果
    • 看起来你在你的 codepen 中应用了这个解决方案,所以这可能是一个被接受的答案。你觉得@贾斯汀怎么样?
    • 它确实处理了 x 和 y。现在我需要弄清楚其余的。我觉得这应该容易得多。感谢您的帮助。
    • 我走了一条完全不同的路线并尝试了一种新方法。我现在正在计算所有四个边的距离,并用它来辅助瓷砖之间的 CD。我还添加了一个函数来限制与玩家的距离,计算瓷砖以节省性能。它目前设置为 2,我还添加了距离向量以用于可视化目的。这是一个 CodePen codepen.io/jfirestorm44/pen/jOymVKK?editors=0010
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-02-17
    • 1970-01-01
    • 2019-04-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-17
    相关资源
    最近更新 更多