Diagonal move not working and issue on left-longPress/right simultaneous
But on double keypress the ship goes crazy!
$(document).bind('keydown', function(e) {
var box = $("#plane"),
left = 37,
up = 38,
right = 39,
down = 40
if (e.keyCode == left) {
box.animate({left: "-=5000"},3000);
}
if (e.keyCode == up) {
box.animate({top: "-=5000"},3000);
}
if (e.keyCode == right) {
box.animate({left:"+=5000"},3000);
}
if (e.keyCode == down) {
box.animate({top: "+=5000"},3000);
}
});
$(document).bind('keyup', function() {
$('#plane').stop();
});
In game development it's best to create a wrapper around the keyboard.
Such wrapper should implement the following:
Event.preventDefault()
to prevent the browser doing default stuff (like i.e. page scrolling on arrow keys)keydown
event is not an Event.repeat
Event.key
Event.key
)To fix the diagonal player movement, you can do it in wo ways, using an angle of rotation, or move the player diagonally by 1 / Math.sqrt(2)
(approximately ~ 0.7071
) distance. In the following example I'll use angles (in radians):
const player = {
el: document.querySelector("#player"),
x: 100, y: 50,
dirX: 0, dirY: 0,
velX: 0, velY: 0,
power: 2, angle: 0,
move() {
if (this.dirX || this.dirY) {
this.angle = Math.atan2(this.dirY, this.dirX);
this.velX = Math.cos(this.angle) * this.power;
this.velY = Math.sin(this.angle) * this.power;
this.x += this.velX;
this.y += this.velY;
this.dirX = this.dirY = 0; // Reset directions
}
this.el.style.translate = `${this.x}px ${this.y}px`;
this.el.style.rotate = `${this.angle}rad`;
}
};
const keyboard = {
actions: new Map(Object.entries({
ArrowLeft () { player.dirX = -1; },
ArrowRight () { player.dirX = 1; },
ArrowUp () { player.dirY = -1; },
ArrowDown () { player.dirY = 1; },
// add more key actions here
})),
keys: new Set(),
handle(evt) {
if (evt.repeat || !this.actions.has(evt.key)) return;
evt.preventDefault();
this.keys[evt.type === "keydown" ? "add" : "delete"](evt.key);
},
callActions() {
for (let key of this.keys) this.actions.get(key)();
}
};
addEventListener("keydown", (evt) => keyboard.handle(evt));
addEventListener("keyup", (evt) => keyboard.handle(evt));
const engine = () => {
keyboard.callActions();
player.move();
requestAnimationFrame(engine);
};
engine();
#player{
position: absolute;
left: 0; top: 0;
width: 20px; height: 20px;
background: #0bf; border-radius: 50%;
}
Click here to focus and use arrow keys to move:
<div id="player">→</div>