I am currently developing a 2D birds-eye view game in JavaScript without using any engine or library, mainly for the learning experience. I have successfully implemented character movement using WASD keys, where the character moves forwards (W) or backwards (S) based on their current direction
(A turns left, D turns right). However, I am encountering unexpected results when I output the angles (direction
) during gameplay.
For instance, when the player is facing "up" and I press "W", the player moves up, and the output direction
is 90°
- which is expected. When facing "down" and I press "S", the player moves down, and the direction is 270°
as expected.
But, when facing left and moving forward with "W", the character does move left but the output direction
is 0°
. Similarly, when facing right and moving forward, the output direction
is 180°
, which is the opposite of my expectations.
The functions responsible for player movement are as follows:
// 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) }
}
This is the section that renders the players:
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)
}
When printing player.direction
, here are the results:
Output: 90
(as expected)
https://i.sstatic.net/7ZCvV.png
Output: 180
(expect it to be 0)
https://i.sstatic.net/sO8g2.png
Output: 270
(as expected)
https://i.sstatic.net/ClVbr.png
Output: 0
(expect it to be 180)
https://i.sstatic.net/wzmeE.png
Output: 135
(expect it to be 45)
https://i.sstatic.net/YtndF.png
Output: 315
(expect it to be 225)
https://i.sstatic.net/1CPWC.png
To summarize, the player movements work correctly, but the output direction
s are not as expected. I would like to address this issue because I plan to set NPCs at specific angles in the future and anticipate them facing the correct direction without needing to calculate the 'mirror' direction.
Thank you in advance for any assistance!