this is my first post! With that in mind, if I need to add anything more than what is below, please let me know. Thank you!
I am currently working to make a platformer game in Javascript where a player can move using arrow keys. Currently, my left and right movements, as well as my player gravity, works. However, when I jump, I am unable to provide smooth jumping movements. originally, I tried simply moving my player's y value higher.
if (up) {
this.y -= 100;
}
However, this makes the player "teleport" upwards, rather than look like an actual jump. To fix this, I reused my gravity code to overcome the gravitational force until a certain limit, making the player look like they are smoothly jumping until they reach a certain height. Below is my code.
if (up) { // This if statement is apart of another function, did not include
this.can_jump = false;
this.jumping = true; this.jump();
}
jump() { // Overcome the gravitational force, but jump force slowly lowers
this.y -= (this.gravity * this.velocity) * 3;
this.gravity -= 0.1;
this.velocity -= 0.1;
this.check();
this.check_jump(this.jumping);
}
check_jump(jumping) {
if (jumping) {
if (this.x < 500) { // While player is less than 500, keep jumping
this.jumping = false;
this.gravity = 2;
this.velocity = 2;
this.can_jump = true;
}
}
}
Additionally, here is the code regarding player collisions and gravity.
gravityEffect() {
this.y += (this.gravity * this.velocity);
this.check();
}
check() {
// Too far up
if (this.y <= 70) { this.y = 70; }
// Too far down
if (this.y >= 600) { this.y = 600; }
// Too far left, teleports to other side
if (this.x < 0) { this.x = 1200; }
// Too far right, teleports to other side
if (this.x > 1200) { this.x = 0; }
}
However, when testing this, my player not only keeps jumping upwards, but also does not do so smoothly (it looks like it is glitching). Here is a link to an mp4 file download (screen recording) showcasing the glitch: https://www.mediafire.com/file/jtqh3lca72vj8nz/%25F0%259D%2590%258C%25F0%259D%2590%25B2_%25F0%259D%2590%2586%25F0%259D%2590%25AB%25F0%259D%2590%259A%25F0%259D%2590%25AF%25F0%259D%2590%25A2%25F0%259D%2590%25AD%25F0%259D%2590%25B2_-_Google_Chrome_2021-04-28_19-59-08.mp4/file
Also, here is a copy of my current code (zipped), if running the program helps: https://www.mediafire.com/file/r5ewoxtb4n57htz/game.zip/file
Please let me know what is wrong. Also, if there is a different or more efficient method of simulating player jumping, please make me aware of it. Thank you for your time.
While trying to keep the code mostly the same I made some changes.
First and formost I changed how you had the controller written. Unless your intention was for the up/down/left/right arguments to stay true then you need a method for them to kick back to false. This controller class will do that.
// Apply classes to empty variables
console.log("Creating player...");
player = new Player();
console.log("Creating world...");
world = new World();
console.log("Creating Controller...")
controller = new Controller();
// Draw canvas with set size
console.log("Creating game screen...");
createCanvas(1000, 750);
}
class Controller {
constructor() {
this.up = false;
this.down = false;
this.right = false;
this.left = false;
let keyEvent = (e) => {
if (e.code === 'ArrowUp') { this.up = e.type === 'keydown' }
if (e.code === 'ArrowRight') { this.right = e.type === 'keydown' }
if (e.code === 'ArrowDown') { this.down = e.type === 'keydown' }
if (e.code === 'ArrowLeft') { this.left = e.type === 'keydown' }
}
window.addEventListener('keydown', keyEvent)
window.addEventListener('keyup', keyEvent)
}
}
Since we changed that we'll have to change the Player Class very slightly. I've set the X and Y velocity to 0 and we'll increment those once a button is pressed. The additional update function will update your X and Y based on that.
Player Class
class Player {
// Setup player attributes
constructor() {
this.x = 100;
this.y = 395;
this.width = 50;
this.height = 50;
this.jumping = false;
this.color = "#ffdb15";
this.gravity = 2;
this.velocityY = 0;
this.velocityX = 0; //changed this from speed
this.points = 0;
}
move() {
// Reverse gravity to upwards, change player's color
if (controller.up && !this.jumping) { this.jumping = true; this.jump(); this.color = this.getRandomColor(true); }
// Reverse gravity to downwards, change player's color
if (controller.down) { this.color = this.getRandomColor(false); }
// Go left
if (controller.left) { this.velocityX -= 1 }
// Go right
if (controller.right) { this.velocityX += 1 }
}
jump() {
this.velocityY -= 35;
}
check() {
// Too far up
if (this.y <= 70) { this.y = 70; }
// Too far down
if (this.y >= 600) { this.y = 600; this.jumping = false } //once collision player can jump again
// Too far left, teleports to other side
if (this.x < 0) { this.x = 1200; }
// Too far right, teleports to other side
if (this.x > 1200) { this.x = 0; }
}
// Get a random player color
getRandomColor(isMoving) {
if ((this.y === 70 || this.y === 600) && isMoving) {
// Explanation: Each color has RGB values from 0 to 255, or 256 total options
// Since colors start from "000000" and go until "FFFFFF", there are ((256^3) - 1) possibilities
// (256^3) - 1 = 16777215
// Use this number, and a random number from Math.Random(), to get a random color
// Idea from: https://css-tricks.com/snippets/javascript/random-hex-color/
this.color = Math.floor(Math.random() * 16777215).toString(16);
return "#" + this.color;
} else { return this.color; }
}
show() {
// Show player
fill(this.color);
strokeWeight(0);
rect(this.x, this.y, this.width, this.height);
}
update() {
this.velocityY += this.gravity;
this.x += this.velocityX;
this.y += this.velocityY;
this.velocityY *= 0.9;
this.velocityX *= 0.9; //provides a sliding slow down once button is released.
this.move();
this.check();
}
}
The draw function is the same but replace gravity with update
function draw() {
world.generate();
player.update();
player.show();
}
This should get you where you want to go with it.