Hi, there. I’ve been trying to create a javascript game while loosely following the freeCodeCamp tutorial here: https://www.youtube.com/watch?v=w-OKdSHRlfA
I can’t figure out why my character is jerking when I press the right or left arrow key(instead of traveling smoothly). This may be a lot to ask someone to look at, but I would greatly appreciate any feedback or help.
P.S. I have all my coding in one file as of right now, but am planning to split it up later.
<html>
<head>
<link href="https://fonts.googleapis.com/css?family=Emilys+Candy|Fredericka+the+Great&display=swap" rel="stylesheet">
<style>
canvas{
border: 1px solid black;
margin:10px;
}
/*
Everything Below is for the Whole Site
*/
#container{
width:80%;
padding:10px;
margin:auto;
background:#d1e0fe;
}
body{
background:url("chocoBG.jpg");
}
/* Navigation */
#navi{
font-size:16pt;
padding:10px;
width:80%;
margin:auto;
text-shadow: 0px 0px 10px black;
font-family: 'Emilys Candy', cursive;
}
#navi, #navi a{
color:white;
font-weight:bold;
}
#navi a, .tab{
font-size:14pt;
padding-left:30px;
text-decoration:none;
}
</style>
</head>
<body>
<div id="navi">Sugar World<a href="">Some Link</a>
<a href="">Some Link</a>
<a href="">Some Link</a>
<a href="">Some Link</a>
</div>
<div id="container">
<center><canvas id="screen"></canvas></center>
</div>
<script>
//polyfill
(function() {
var requestAnimationFrame = window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame || window.msRequestAnimationFrame;
window.requestAnimationFrame = requestAnimationFrame;
})();
let canvas = document.getElementById("screen");
let ctx = canvas.getContext("2d");
let width = 600;
let height = 500,
keys = [];
canvas.width = width;
canvas.height = height;
/////////////
//Game //
/////////////
Game = function(){
this.world = {
gravity:0.3,
friction: 0.9
}
this.player = {
x : width/2,
y : height - 156,
posx : 0,
width : 50,
height : 84,
velx: 0,
vely: 0.3,
frameSets: {
bounce: [0, 1, 2 ,3 , 4],
turnLeft: [5, 6, 7, 8, 9, 10],
idleLeft: [11],
runRight: [12, 13, 14, 15, 16, 17],
runLeft: [18, 19, 20, 21, 22, 23],
jump: [1],
idleRight: [11]
} ,
jumping:false,
getBottom: function() { return this.y + this.height; },
getLeft: function() { return this.x; },
getRight: function() { return this.x + this.width; },
getTop: function() { return this.y; },
setBottom: function(y) { this.y = y - this.height; },
setLeft: function(x) { this.x = x; },
setRight: function(x) { this.x = x - this.width; },
setTop: function(y) { this.y = y; }
}
//source_x, source_y
this.sFramesArr = [[0, 0],[50, 0],[100, 0],[150, 0], [200, 0], // Bounce Anim
[0, 84],[50, 84],[100, 84],[150, 84], [200, 84],[0, 168], // Turn left Anim
[50, 168], //Left Static
[100, 168],[150, 168], [200, 168], [0, 252],[50, 252],[100, 252], //RunRight
[200, 252], [0, 336], [50, 336], [100, 336], [150, 336], //RunLeft
[200, 336], [0, 420]
]
let frame = 0;
let delay = 15 * (this.player.velx + 1);
let count = 0;
this.animate = function (fset){
if (frame >= game.player.frameSets[fset].length){
frame = 0;
}
ctx.fillStyle = "#7599df";
ctx.fillRect(0,0,width,height);
display.drawBg(game.player.velx, 0)
display.drawChar(display.squishy.image, game.sFramesArr[game.player.frameSets[fset][frame]][0], game.sFramesArr[game.player.frameSets[fset][frame]][1], game.player.x, game.player.y, game.player.width, game.player.height);
while (count > delay){
count = 0;
frame ++;
};
count++;
}
this.level1 = [
"x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x",
"x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x",
"x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x",
"x", "x", "x", "x", "x", "x", "x", "x", "r", "x", "x", "p", "x", "x", "x", "x", "x", "x", "a", "s", "s", "s", "d", "x",
"x", "x", "x", "x", "x", "x", "x", "x", "g", "x", "b", "g", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x",
"x", "a", "s", "s", "s", "s", "d", "x", "g", "x", "g", "g", "x", "x", "a", "s", "s", "d", "x", "x", "x", "x", "x", "x",
"x", "x", "x", "x", "x", "x", "x", "x", "g", "x", "g", "g", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x"
];
this.keys = function (type, keycode) {
this.down = type == "keydown" ? true : false;
switch(keycode){
case 37:
this.moveLeft();
break; //left
case 38:
this.jump();
break;
case 39:
this.moveRight();
break; //right
}
}
this.moveLeft = function(){
this.player.velx += 5;
}
this.moveRight = function(){
this.player.velx -= 5;
}
this.jump = function (){
if (!this.player.jumping){
this.player.vely -= 10;
}
this.player.jumping = true;
}
this.collider = {
collidePlatformTop: function (tileTop, character){
if (game.player.getBottom() > tileTop){
game.player.setBottom(tileTop - 0.01);
game.player.vely = 0;
}
}
}
}
/////////////
//Display //
/////////////
Display = function(){
this.squishy = new Display.Squishy();
this.map = new Display.Map();
this.drawChar = function (image, source_x, source_y, destination_x, destination_y, width, height){
ctx.drawImage(image, source_x, source_y, width, height, Math.round(destination_x), Math.round(destination_y), width, height);
}
this.drawMap = function(map, columns) {
}
this.drawSquishy = function(image, source_x, source_y, destination_x, destination_y, width, height) {
ctx.drawImage(image, source_x, source_y, width, height, Math.round(destination_x), Math.round(destination_y), width, height);
}
this.drawBg = function(x, y){
ctx.drawImage(display.map.image, 0, 0, 420, 336, 0 + (game.player.posx/3), 0 + y, 720, 600); //Mountain
ctx.drawImage(display.map.image, 420, 168, 252, 84,300 + game.player.posx, 160 + y, 252, 84); //Cloud
this.drawBridge(4, 40 + game.player.posx, 410);
}
this.drawBridge = function(width, x, y){
ctx.drawImage(display.map.image, 672, 84, 84, 84, x, y, 84, 84);
for (let i = 1; i < width; i++){
ctx.drawImage(display.map.image, 672, 0, 84, 84, x + (84 * i), y, 84, 84);
}
ctx.drawImage(display.map.image, 672 + 84, 0, 84, 84, x + width * 84, y, 84, 84);
}
this.clear = function(){
ctx.fillStyle = "#7599df";
}
this.gameOver = function() {
ctx.fillStyle = "black";
ctx.fillRect(0, 0, width, height);
ctx.fillStyle = "white";
ctx.font = "75px Fredericka the Great";
ctx.fillText("Game Over", 100, height/2);
}
}
Display.Squishy = function(){
this.image = new Image();
this.height = 84;
this.width = 50;
this.columns = 5;
}
Display.Map = function(columns, tile_size){
this.image = new Image();
this.columns = columns;
this.tile_size = tile_size;
}
/////////////
//Load Things//
/////////////
let display = new Display();
let game = new Game();
window.addEventListener("load", () => update());
display.squishy.image.addEventListener("load", function(event) {
update();
window.addEventListener("keydown", keys);
window.addEventListener("keyup", keys);
}, { once:true });
display.map.image.src = "BGsheet.png";
display.squishy.image.src = "squishy.png";
function update(){
//Draw Box
ctx.fillStyle = "#7599df";
ctx.fillRect(0,0,width,height);
display.drawBg(0, 0); //image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight
game.animate("bounce");
requestAnimationFrame(update);
//Move Player Left and Right
if (game.player.velx > 0.09){
ctx.fillStyle = "#7599df";
ctx.fillRect(0,0,width,height);
display.drawBg(game.player.velx, 0)
game.animate("runLeft");
}
if (game.player.velx < -0.09){
game.animate("runRight");
}
//Jump
if (game.player.vely < 0){
game.animate("jump");
}
//Friction and Gravity
game.player.y += game.player.vely;
game.player.posx += game.player.velx;
game.player.velx *= game.world.friction;
game.player.vely += game.world.gravity;
if (game.player.y > height){
display.gameOver()
game.player.vely = 0;
game.player.y = 630;
}
//Collide
if ( game.player.getBottom() > 423 && game.player.getBottom() < 630)
{
game.collider.collidePlatformTop(423, game.player);
game.player.vely = 0;
game.player.jumping = false;
};
}
keys = function(event) {
game.keys(event.type, event.keyCode);
};
</script>
</body>
</html>