【问题标题】:Why are my angles off but movement works in my 2D, birds-eye view game?为什么我的角度不对,但在我的 2D 鸟瞰游戏中可以进行运动?
【发布时间】:2021-06-16 13:27:24
【问题描述】:

我正在不使用引擎/库的 JS 中创建鸟瞰图 2D 游戏(更多用于学习挑战)。我已经让角色移动与 WASD 一起使用,其中角色将根据他们当前的 direction 前进(W)或后退(S)(A 向左转,D 向右转),但是当我输出角度时(@ 987654334@) 在游戏时间我得到了意想不到的结果。

例如,当玩家面向“向上”并且我按下“W”时,玩家向上移动,得到输出的direction90° - 正如预期的那样。当面向“向下”并按下“S”时,玩家向下移动,direction270° - 正如预期的那样。

但是,当面向左时,我按下“W”,角色确实向左移动但是输出direction,当面向+向右移动,它是 180° - 与我的预期完全相反。

这些是移动我的玩家的功能:

// Turning
    _resetAngle(angle) {
        if (angle >= 360) { return 0 }
        if (angle < 0) { return 359 }
        return angle
    }

    updateDirection(player, keyboardInput) {
        let currentDirection = player.direction
        const turnedLeft = keyboardInput['a']
        const turnedRight = keyboardInput['d']

        if (turnedLeft) { currentDirection -= this.turnAngle }
        if (turnedRight) { currentDirection += this.turnAngle }

        player.setDirection(this._resetAngle(currentDirection))
    }

//Moving
    _calculateNewCoords(movingForward, entity) {
        let newX
        let newY

        // please ignore the code duplication, just testing for now
        if (movingForward) {
            newX = entity.getX() - entity.speed * Math.cos(entity.direction * (Math.PI / 180))
            newY = entity.getY() - entity.speed * Math.sin(entity.direction * (Math.PI / 180))
        }
        else {
            newX = entity.getX() + entity.speed * Math.cos(entity.direction * (Math.PI / 180))
            newY = entity.getY() + entity.speed * Math.sin(entity.direction * (Math.PI / 180))
        }
        return { newX, newY }
    }

    updateCoordinatesByKeyboard(entity, keyboardInput) {
        const movingForward = keyboardInput['w']
        const movingBackwards = keyboardInput['s']

        if ((movingForward && movingBackwards) || !(movingForward || movingBackwards)) { return }
        
        const { newX, newY } = this._calculateNewCoords(movingForward, entity)
        if (this._canMove(entity, newX, newY)) { return entity.setXY(newX, newY) }
    }

这是渲染玩家的部分:

drawCharacter(character, image) {
    const scale = this._getScale(character) // for a 'breathing' effect, makes character grow and shrink

    this.context.setTransform(scale, 0, 0, scale, this.windowDimensions.width / 2, this.windowDimensions.height / 2)
    this.context.rotate(character.direction * Math.PI / 180)
    this.context.drawImage(image, -image.width / 2, -image.height / 2)
}

打印player.direction时的结果:

输出:90(如预期)

输出:180(预计为 0)

输出:270(如预期)

输出:0(预计为 180)

输出:135(预计为 45)

输出:315(预计为 225)

再次重申——玩家按预期移动(即按下 WASD 可使玩家正确转动和移动)——但输出 directions 是出乎意料的,我想解决这个问题,因为将来我想将 NPC 设置为特定角度(即面向 45°)并期望他们面向该方向而无需计算“镜像”方向。

提前感谢您的帮助!

【问题讨论】:

  • setDirection 函数有什么作用?如果您可以创建一个有效的 sn-p,那将会很有用。
  • @AHaworth setDirection 只是设置玩家的方向:setDirection(direction) { this.direction = direction }。我将尝试创建一个独立的 sn-p

标签: javascript html5-canvas trigonometry 2d-games


【解决方案1】:

我不会说你得到的值没有意义 - 它完全相反 - 因为这是我所期望的。所以这更像是一个“装饰性”问题,因为它对于您的其他游戏对象也是一样的。

不过,您可以通过以下方式轻松地将输出重新计算为您想要的值:

output = Math.abs((input + 90) % 360 - 270)

这将使:

90 -> 90

180 -> 0

270 -> 270

0 -> 180

135 -> 45

315 -> 225

【讨论】:

  • 您能解释一下为什么当前的输出对您有意义吗?感谢您的外观修复,但我想了解为什么我没有看到直观上对我有意义的数字
  • 嗯,我不知道从哪里开始,因为我不明白你不明白什么。如果我们顺时针方向,你的角度从 90->180->270->360 (虽然 360 实际上是 0,因为它环绕)。是什么让你认为如果它是 90 -> 0 -> 270 -> 180 更合乎逻辑
  • 我在看一个单位圆,并在想“左边 180 点,右边 0 点” - 但现在你这样说,你是对的,它是关于 转向 离开。天啊。那真好笑。谢谢@obscure!
  • 呵呵,我知道你的意思@Jona - 很高兴我能帮上忙! =)
猜你喜欢
  • 1970-01-01
  • 2014-07-16
  • 1970-01-01
  • 2013-04-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-07-30
相关资源
最近更新 更多