I am having a lot of different issues while coding player jumping for my game. Sometimes when the player hits the jump key the jump is delayed and/or doesn't jump to the heigh it usually does. I am trying to implement a method where the longer the user holds down the jump key the higher they go.
I want the player to jump 4 blocks on max height(80) and 1 block(20) for min height(1 block is 20 units).
Player.update is called on every game tick(60 times a sec)
class Player {
constructor(x, y) {
this.x = x;
this.y = y;
this.dy = 0;
this.helper = [];
this.intervals = [];
this.canJump = true;
this.jump = false;
this.jumptime = new Date();
this.moveFrame = 0;
this.direction = 0; // 0 -> left, 1 -> right
this.state = 0; // 0 -> still, 1 -> walking, 2 -> jump, 3 -> fall
this.addListeners();
this.update = this.update.bind(this);
this.collision = this.collision.bind(this);
}
draw() {
GUI.drawImageCrop(Kingdoms.images.knight[['still', 'walk', 'jump', 'fall'][this.state]][this.direction], this.x, this.y, 16, 36, this.state === 1 ? (Math.floor(this.moveFrame/5)%4)*16 : 0, 0, 16, 36, 1);
}
addListeners() {
window.addEventListener('keydown', this.keydown.bind(this));
window.addEventListener('keyup', this.keyup.bind(this));
}
removeListeners() {
window.removeEventListener('keydown', this.keydown.bind(this));
window.removeEventListener('keyup', this.keyup.bind(this));
}
keyLoop(e) {
switch(e.keyCode) {
case 65:
case 65:
if (this.collision(this.x-4, this.y) === true) {
this.moveFrame++;
this.direction = 0;
if (this.dy === 0) this.state = 1;
this.x -= 4;
}
break;
case 68:
if (this.collision(this.x+4, this.y) === true) {
this.moveFrame ++;
this.direction = 1;
if (this.dy === 0) this.state = 1;
this.x += 4;
}
break;
case 87:
if (this.canJump && this.dy === 0) {
this.jump = true;
this.dy = -3.5;
this.jumptime = new Date();
this.canJump = false;
}
break;
}
}
keyStart(e) {
}
update() {
var data = this.collision(this.x, this.y+this.dy);
if (data === true) { // required because objects count as true also :(
this.state = this.dy === 0 ? this.state : (this.dy < 0 ? 2 : 3);
this.y += this.dy;
if (this.jump && Date.now()-this.jumptime.getTime() > 100 && Date.now()-this.jumptime.getTime() < 300) this.dy -= (-Math.pow(((Date.now()-this.jumptime.getTime())-100)/100-1.732, 2)+1)*.4;
if (this.dy < 20) this.dy += .3;
} else if (this.dy < 0) {
this.canJump = true;
this.dy = 0;
this.y = data.y*20+20;
} else if (this.dy > 0) {
this.y = data.y*20-36;
this.dy = 0;
this.canJump = true;
}
}
collision(x, y) {
var l = 0;
while (l<World.room.c.length) {
var cx = World.room.c[l].x*20;
var cy = World.room.c[l].y*20;
if ((x > cx || x+16 > cx) && (x < cx+20 || x+16 < cx+20) && (y > cy || y+36 > cy) && (y < cy+20 || y+36 < cy+20)) return World.room.c[l];
l++;
}
return true;
}
keydown(e) {
e.preventDefault();
if (this.helper[e.keyCode] !== 'pressed') {
this.keyStart(e);
this.keyLoop(e);
this.intervals[e.keyCode] = setInterval(this.keyLoop.bind(this), 30, e);
this.helper[e.keyCode] = 'pressed';
}
}
keyup(e) {
e.preventDefault();
if ((e.keyCode === 65 || e.keyCode === 68) && this.state === 1) this.state = 0;
if (e.keyCode === 87) this.jump = false;
clearInterval(this.intervals[e.keyCode]);
this.helper[e.keyCode] = false;
}
}
```