I'm just trying to animate a jump in canvas, but I don't think I got the math formula properly, instead of doing a sine wave kind of motion, it just instantly telports, with no animation, any help would be great thanks.
var ctx = new CtxScene(500, 500, '1px solid black').create()
, player = {
x: 0,
y: 0,
moving: false,
dir: undefined
};
var i = 0;
(function draw() {
setTimeout(function() {
requestAnimationFrame(draw);
checkDir();
update();
}, 1000 / 60);
})();
document.onkeydown = function(e) {
if (e.which === 37) {
player.moving = true;
player.dir = 'left';
}
if (e.which === 39) {
player.moving = true;
player.dir = 'right';
}
if (e.which === 38) {
player.moving = true;
player.dir = 'up';
}
if (e.which === 40) {
player.moving = true;
player.dir = 'down';
}
if (e.which === 32) {
player.moving = true;
player.dir = 'jump';
}
console.log(e.which);
}
document.onkeyup = function(e) {
player.moving = false;
}
function update() {
ctx.clearRect(0, 0, 500, 500);
ctx.fillStyle = '#00A';
ctx.fillRect(player.x, player.y, 100, 100)
}
function checkDir() {
if (player.moving) {
if (player.dir === 'left') {
player.x -=5;
} else if (player.dir === 'right') {
player.x += 5;
} else if (player.dir === 'up') {
player.y -= 5;
} else if (player.dir === 'down') {
player.y += 5;
} else if (player.dir === 'jump') {
player.y = 100 * Math.sin(5*Math.PI/200);
}
}
}
the math is a few lines from the bottom (I'm almost 100% sure it's wrong)
Ok so the easiest way to do this is to use physics, really really basic physics. Give your character a gravity force and at least a velocity in the Y direction, similar to this:
player.gravity= 0.92;
var characterUpdate= function(){
player.y+=player.velocityY;
player.velocityY+=player.gravity;
}
This will cause the player to constantly want to go downward (gravity) and you increase the velocityY to counter act this during a jump. You'll want to set some bounds to avoid the character going off the screen for now, something like:
if (player.y+player.height >= ctx.height) {
player.y=ctx.height-player.height;
}
The added benefit of this method is that it takes care of any falls you might plan on including later.
Related
I created a ball and some Javascript code that is supposed to make it move. But my code isn't working and I don't know why. Could someone please look over my code and help me out.
Code
var canvas = document.getElementById("myCanvas");
var ctx = canvas.getContext("2d");
var xPos = canvas.width/2;
var yPos = canvas.height-30;
var ballRadius = 10;
var leftPressed = false;
var rightPressed = false;
var upPressed = false;
var downPressed = false;
function drawBall() {
ctx.beginPath();
ctx.arc(xPos, yPos, ballRadius, 0, Math.PI*2, false);
ctx.fillStyle = "#0095DD";
ctx.fill();
ctx.closePath();
}
function draw() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
drawBall();
}
setInterval(draw, 10);
document.addEventListener("keydown", keyDownHandler, false);
document.addEventListener("keyup", keyUpHandler, false);
function keyDownHandler(e) {
if(e.keyCode == 37) {
leftPressed = true;
}
else if(e.keyCode == 39) {
rightPressed = true;
}
else if(e.keyCode == 38) {
upPressed == true;
}
else if(e.keyCode == 40) {
downPressed = true;
}
}
function keyUpHandler(e) {
if(e.keyCode == 37) {
leftPressed = false;
}
else if(e.keyCode == 39) {
rightPressed = false;
}
else if(e.keyCode == 38) {
upPressed == false;
}
else if(e.keyCode == 40) {
downPressed = false;
}
}
if(leftPressed = true) {
xPos -= 7;
} else if(rightPressed = true) {
xPos += 7;
} else if(upPressed = true) {
yPos -= 7;
} else if(downPressed = true) {
yPos += 7;
}
* { padding: 0; margin: 0; }
canvas { background: #eee; display: block; margin: 0 auto; }
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Breakout</title>
<style>
* { padding: 0; margin: 0; }
canvas { background: #eee; display: block; margin: 0 auto; }
</style>
</head>
<body>
<canvas id="myCanvas" width="480" height="320"></canvas>
<script src="gameJS.js"></script>
</body>
</html>
You're only updating the boolean values during keypress. You're not updating the position dynamically. Your position update code runs first during load and that's it.
To move during keypress, you need to update the position during each keypress and you need to draw the ball.
var canvas = document.getElementById("myCanvas");
var ctx = canvas.getContext("2d");
var xPos = canvas.width/2;
var yPos = canvas.height-30;
var ballRadius = 10;
var leftPressed = false;
var rightPressed = false;
var upPressed = false;
var downPressed = false;
function drawBall() {
ctx.beginPath();
ctx.arc(xPos, yPos, ballRadius, 0, Math.PI*2, false);
ctx.fillStyle = "#0095DD";
ctx.fill();
ctx.closePath();
}
function draw() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
drawBall();
}
setInterval(draw, 10);
document.addEventListener("keydown", keyDownHandler, false);
//document.addEventListener("keyup", keyUpHandler, false);
function keyDownHandler(e) {
if(e.keyCode == 37) {
xPos -= 7;
//draw the ball with new position
}
else if(e.keyCode == 39) {
xPos += 7;
//draw the ball with new position
}
else if(e.keyCode == 38) {
yPos -= 7;
//draw the ball with new position
}
else if(e.keyCode == 40) {
yPos += 7;
//draw the ball with new position
}
}
* { padding: 0; margin: 0; }
canvas { background: #eee; display: block; margin: 0 auto; }
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Breakout</title>
<style>
* { padding: 0; margin: 0; }
canvas { background: #eee; display: block; margin: 0 auto; }
</style>
</head>
<body>
<canvas id="myCanvas" width="480" height="320"></canvas>
<script src="gameJS.js"></script>
</body>
</html>
You are using assignment operators (single equal signs) in your check for keypresses, rather than comparator operators (double equal signs). Essentially, you're saying that they should equal true, rather than checking if they are true:
if (leftPressed = true) {}
else if (rightPressed = true) {}
else if (upPressed = true) {}
else if (downPressed = true) {}
These should be written as:
if (leftPressed == true) {}
else if (rightPressed == true) {}
else if (upPressed == true) {}
else if (downPressed == true) {}
Having said that, you don't need to make use of these four variables at all, and can instead simply modify the positions directly on checking against the keyCode values:
if (e.keyCode == 37) {
xPos -= 7;
}
Hope this helps! :)
There are a few errors in your code.
In your up/down key handlers you compare the value of upPressed instead of setting it.
e.g.
upPressed == true;
should be
upPressed = true;
In your if conditions at the end, you set the value instead of comparing.
e.g.
if(leftPressed = true)
should be
if(leftPressed)
I've moved the ball position code into the moveBall function and called that when the key handler is called so that the position is updated on key press.
This is the fixed version.
var canvas = document.getElementById("myCanvas");
var ctx = canvas.getContext("2d");
var xPos = canvas.width / 2;
var yPos = canvas.height - 30;
var ballRadius = 10;
var leftPressed = false;
var rightPressed = false;
var upPressed = false;
var downPressed = false;
function drawBall() {
ctx.beginPath();
ctx.arc(xPos, yPos, ballRadius, 0, Math.PI * 2, false);
ctx.fillStyle = "#0095DD";
ctx.fill();
ctx.closePath();
}
function draw() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
drawBall();
}
setInterval(draw, 10);
document.addEventListener("keydown", keyDownHandler, false);
function keyDownHandler(e) {
leftPressed = false;
rightPressed = false;
upPressed = false;
downPressed = false;
if (e.keyCode == 37) {
leftPressed = true;
} else if (e.keyCode == 39) {
rightPressed = true;
} else if (e.keyCode == 38) {
upPressed = true;
} else if (e.keyCode == 40) {
downPressed = true;
}
moveBall();
}
function moveBall() {
if (leftPressed) {
xPos -= 7;
} else if (rightPressed) {
xPos += 7;
} else if (upPressed) {
yPos -= 7;
} else if (downPressed) {
yPos += 7;
}
}
* {
padding: 0;
margin: 0;
}
canvas {
background: #eee;
display: block;
margin: 0 auto;
}
<canvas id="myCanvas" width="480" height="320"></canvas>
Since keyDownHandler is called whenever a keydown event occurs, you'll want to move your position variables updating code to within that function, and you can remove the keyDownHandler as it doesn't do anything in this example:
function keyDownHandler(e) {
//left
if(e.keyCode === 37){
xPos -= 7
}
//right
else if (e.keyCode === 39) {
xPos += 7
}
//up
else if (e.keyCode === 38) {
yPos -= 7
}
//down
else if (e.keyCode === 40) {
yPos += 7
}
}
In addition, you can make your code slightly more readable with a switch statement rather than cascading else if
function keyDownHandler(e) {
switch(e.keyCode){
case 37: //left
xPos -= 7
break;
case 39: //right
xPos += 7
break;
case 38: //up
yPos -= 7
break;
case 40: //down
yPos += 7
break;
}
}
Note: as Obsidian Age correctly pointed out, you are using assignment operators and not comparison operators in your update code, so you might want to double check that in the future. In my example I used the triple equal === operator because it checks both type and value, which is recommended in JavaScript. See W3Schools reference for JavaScript Operators
Just update your javascript as below will do the trick.
var canvas = document.getElementById("myCanvas");
var ctx = canvas.getContext("2d");
var xPos = canvas.width/2;
var yPos = canvas.height-30;
var ballRadius = 20;
var leftPressed = false;
var rightPressed = false;
var upPressed = false;
var downPressed = false;
function drawBall() {
ctx.beginPath();
ctx.arc(xPos, yPos, ballRadius, 0, Math.PI*2, false);
ctx.fillStyle = "#0095DD";
ctx.fill();
ctx.closePath();
}
function draw() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
if(leftPressed == true) {
xPos -= 7;
}
else if(rightPressed == true) {
xPos += 7;
}
else if(upPressed == true) {
yPos -= 7;
}
else if(downPressed == true) {
yPos += 7;
}
drawBall();
}
function keyDownHandler(e) {
var keyCode = e.keyCode;
if(keyCode == 37) {
leftPressed = true;
}
else if(keyCode == 39) {
rightPressed = true;
}
else if(keyCode == 38) {
upPressed = true;
}
else if(keyCode == 40) {
downPressed = true;
}
}
function keyUpHandler(e) {
var keyCode = e.keyCode;
if(keyCode == 37) {
leftPressed = false;
}
else if(keyCode == 39) {
rightPressed = false;
}
else if(keyCode == 38) {
upPressed = false;
}
else if(keyCode == 40) {
downPressed = false;
}
}
Use assignment operator = instead of comparison operator == for upPressed variable within keyUpHandler and keyDownHandler methods.
Don't set leftPressed, rightPressed, upPressed and downPressed values using by = operator within if...else conditions. Use comparison operator or logical values directly instead.
Update xPos and yPos values each time before drawBall method calling.
The working code below.
var canvas = document.getElementById("myCanvas");
var ctx = canvas.getContext("2d");
var xPos = canvas.width / 2;
var yPos = canvas.height - 30;
var ballRadius = 10;
var leftPressed = false;
var rightPressed = false;
var upPressed = false;
var downPressed = false;
function drawBall() {
ctx.beginPath();
ctx.arc(xPos, yPos, ballRadius, 0, Math.PI * 2, false);
ctx.fillStyle = "#0095DD";
ctx.fill();
ctx.closePath();
}
function draw() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
SetPos();
drawBall();
}
setInterval(draw, 10);
document.addEventListener("keydown", keyDownHandler, false);
document.addEventListener("keyup", keyUpHandler, false);
function keyDownHandler(e) {
if (e.keyCode == 37) {
leftPressed = true;
} else if (e.keyCode == 39) {
rightPressed = true;
} else if (e.keyCode == 38) {
upPressed = true;
} else if (e.keyCode == 40) {
downPressed = true;
}
}
function keyUpHandler(e) {
if (e.keyCode == 37) {
leftPressed = false;
} else if (e.keyCode == 39) {
rightPressed = false;
} else if (e.keyCode == 38) {
upPressed = false;
} else if (e.keyCode == 40) {
downPressed = false;
}
}
function SetPos() {
if (leftPressed) {
xPos -= 7;
} else if (rightPressed) {
xPos += 7;
} else if (upPressed) {
yPos -= 7;
} else if (downPressed) {
yPos += 7;
}
}
* {
padding: 0;
margin: 0;
}
canvas {
background: #eee;
display: block;
margin: 0 auto;
}
<canvas id="myCanvas" width="480" height="320"></canvas>
So I was making this game today, and everything works perfectly, but sometimes this error shows up. I know what it means, and I've had it before, but this time it makes no sense. The game works perfectly fine, but sometimes when the bullet collides with the enemy the game freezes. I don't even know what to try anymore. Btw, if the error doesn't show up right away, just keep playing. Here's the code:
<html>
<head>
<title>Space shooter</title>
<style>
* {
margin:0;
}
canvas {
background: url("http://www.ufointernationalproject.com/wp-content/uploads/2017/03/space-03.jpg");
}
</style>
</head>
<body>
<canvas id="canvas" width="1350" height="630"></canvas>
<script>
var ctx = document.getElementById("canvas").getContext("2d"),
lastShot = Date.now(),
fireRate = 120,
bullets = [],
enemies = [],
enemySpeed = 1.5,
bulletSpeed = 20,
player = {
x: 600,
y: 250,
leftPressed: false,
rightPressed: false,
upPressed: false,
downPressed: false,
spacePressed: false,
speed: 5
};
var playerImage = new Image();
playerImage.src = "https://3.bp.blogspot.com/-jGC08Dy0zg8/U405cNq1-MI/AAAAAAAABqU/38d5rmV1S8Y/s1600/redfighter0006.png";
var enemyImage = new Image();
enemyImage.src = "https://a.fsdn.com/con/app/proj/partartspace/screenshots/Spaceship14.png/1";
function spawnEnemes() {
enemies.push({
x:Math.floor(Math.random() * 1250) + 1,
y:-100
})
}
setInterval(spawnEnemes, 500);
function draw() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.drawImage(playerImage, player.x,player.y, 100, 100);
if (player.leftPressed) {
player.x -= player.speed;
}
if (player.rightPressed) {
player.x += player.speed;
}
if (player.upPressed) {
player.y -= player.speed;
}
if (player.downPressed) {
player.y += player.speed;
}
if (player.spacePressed && Date.now() - lastShot > fireRate) {
bullets.push({
x: player.x+50,
y: player.y
});
lastShot = Date.now();
}
bullets.forEach(function(bullet){
ctx.beginPath();
ctx.arc(bullet.x, bullet.y, 5, 0, 2 * Math.PI);
ctx.fillStyle = "red";
ctx.fill();
bullet.y -= bulletSpeed;
});
enemies.forEach(function(enemy){
ctx.drawImage(enemyImage, enemy.x, enemy.y, 100,100);
enemy.y += enemySpeed;
});
for (var enemy = 0; enemy < enemies.length; enemy ++){
if(player.x < enemies[enemy].x + 80 &&
player.x + 80 > enemies[enemy].x &&
player.y < enemies[enemy].y + 65 &&
player.y + 100 > enemies[enemy].y)
{
document.location.reload();
}
for (var bullet = 0; bullet < bullets.length; bullet ++) {
if(bullets[bullet].y < enemies[enemy].y + 70 &&
bullets[bullet].y > enemies[enemy].y &&
bullets[bullet].x < enemies[enemy].x + 100 &&
bullets[bullet].x > enemies[enemy].x)
{
bullets.splice(bullet, 1);
enemies.splice(enemy, 1);
}
}
}
requestAnimationFrame(draw);
}
draw();
document.body.addEventListener("keydown", function(e) {
if (e.keyCode === 37) {
player.leftPressed = true;
}
else if (e.keyCode === 39) {
player.rightPressed = true;
}
else if (e.keyCode === 38) {
player.upPressed = true;
}
else if (e.keyCode === 40) {
player.downPressed = true;
}
else if (e.keyCode === 32) {
player.spacePressed = true;
}
});
document.body.addEventListener("keyup", function(e) {
if (e.keyCode === 37) {
player.leftPressed = false;
}
else if (e.keyCode === 39) {
player.rightPressed = false;
}
else if (e.keyCode === 38) {
player.upPressed = false;
}
else if (e.keyCode === 40) {
player.downPressed = false;
}
else if (e.keyCode === 32) {
player.spacePressed = false;
}
});
</script>
</body>
</html>
The problem seems to be when you splice. As you don't exit the loops, you end up accessing invalid positions after a removal.
I'm having a few issues with my code. Can't get my cube to jump. Take a look at my code and let me know if you can help please.
My left, right and duck abilities all currently work at desired level, but I cannot get my cube to jump. I've been trying for three days and can't find anything online. My javascript is embedded within a tag in a html page.
var canvas = document.getElementById("gameCanvas");
var ctx = canvas.getContext("2d");
var coinRad = 8;
var coinX = 40;
var coinY = 80;
var x = 20;
var y = 510;
var w = 30;
var h = 50;
var rightPressed = false;
var leftPressed = false;
var ducked = false;
var jumping = false;
document.addEventListener("keydown", keyDownHandler, false);
document.addEventListener("keyup", keyUpHandler, false);
function keyDownHandler(e) {
if (e.keyCode == 39) {
rightPressed = true;
} else if (e.keyCode == 37) {
leftPressed = true;
} else if (e.keyCode == 40) {
ducked = true;
} else if (e.keycode == 32) {
jumping = true;
}
}
function keyUpHandler(e) {
if (e.keyCode == 39) {
rightPressed = false;
} else if (e.keyCode == 37) {
leftPressed = false;
} else if (e.keyCode == 40) {
ducked = false;
} else if (e.keycode == 32) {
jumping = false;
}
}
function drawCube() {
ctx.beginPath();
ctx.rect(x, y, w, h);
ctx.fillStyle = "Green";
ctx.fill();
ctx.closePath();
}
function run() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
if (leftPressed) {
if (x > 0) {
x -= 2.5;
}
} else if (rightPressed) {
if (x < canvas.width - w) {
x += 2.5;
}
}
if (jumping) {
y -= 10;
h -= 10;
}
if (ducked) {
y = 535;
h = 25;
} else {
y = 510;
h = 50;
}
drawCube();
}
setInterval(run, 10);
<canvas id="gameCanvas"></canvas>
Additionally, your keyCode check is improperly capitalized for the jumping condition.
else if (e.keyCode == 40) {
ducked = false;
} else if (e.keycode == 32) { //should be keyCode
jumping = false;
}
because when the run method end, you do this.
if (jumping) {
y -= 10;
h -= 10;
}
if (ducked) {
y = 535;
h = 25;
} else {
y = 510;
h = 50;
}
even if you change the values from Y and H, their values always change to 510 and 50 respectively, because the else in ducked condition.
Remove this else or find another logic to do the same
My keyPress movement seems to be broken, if I press arr.up/down twice then it gets broken and I can't move the element back. And the element doesn't even stop when I stop holding the arr.up/down, why?
rocket = new Image();
x = 50;
y = 185;
score = 0;
velY = 0;
speed = 2;
y += velY;
ctx.drawImage(rocket, x, y);
if(e.keyCode == 38) {
if(velY < speed) {
velY --;
}
}
if(e.keyCode == 40) {
if(velY < speed) {
velY ++;
}
}
Preview: http://game.stranger.tk/
I would have edited your code however your game via your link isn't working :(. I hope this code example I have provided helps you out.
jsFiddle : https://jsfiddle.net/w1z2c1cq/
javascript
var c = document.getElementById('myCanvas');
var ctx = c.getContext('2d');
var rocket = function()
{
this.Sprite = new Image();
this.Sprite.src = "https://encrypted-tbn1.gstatic.com/images?q=tbn:ANd9GcS9zafp1ezdR2lSAxTdjZYe_nPhe6VeKKmAuK-GzWQCSs395WkzNA";
this.XPos = 100;
this.YPos = 100;
}
var player = new rocket();
setInterval(function()
{
ctx.fillRect(0,0,400,400);
ctx.drawImage(player.Sprite, player.XPos, player.YPos);
}, 3);
window.addEventListener("keydown", function(e){
// Left key
if(e.keyCode === 37) {
player.XPos -= 5;
}
// Right key
if(e.keyCode === 39) {
player.XPos += 5;
}
// Up key
if(e.keyCode === 38) {
player.YPos -= 5;
}
// Down key
if(e.keyCode === 40) {
player.YPos += 5;
}
});
Also in your code you are checking this same if statement for up and down if(velY < speed)
try
// Up
if(e.keyCode == 38) {
if(velY < speed) {
velY --;
}
}
// Down
if(e.keyCode == 40) {
if(velY > -speed) {
velY ++;
}
}
I'm working on a simple html/js project to get a box moving in a canvas that can shoot a ball. I got the box moving but I cant get the ball to appear. The program makes it to the drawBall() and moveBall()(Tested using alerts) functions but they don't do anything. I've been working on this the past hour and so and I just can't get it to work. Here's my javascript code that moves the box and should draw a ball whenever the spacebar is released.
function init() {
//canvas = document.getElementById('canvas');
context = $('#canvas')[0].getContext('2d');
WIDTH = $('#canvas').width();
HEIGHT = $('#canvas').height();
block_x = WIDTH / 2;
block_y = HEIGHT / 2;
setInterval('draw()', 25);
}
function clearCanvas() {
context.clearRect(0,0,WIDTH,HEIGHT);
}
function draw() {
clearCanvas();
if(shotBall)
{
drawBall();
moveBall();
}
if (rightKey) block_x += 5;
else if (leftKey) block_x -= 5;
if (upKey) block_y -= 5;
else if (downKey) block_y += 5;
if (block_x <= 0) block_x = 0;
if ((block_x + block_w) >= WIDTH) block_x = WIDTH - block_w;
if (block_y <= 0) block_y = 0;
if ((block_y + block_h) >= HEIGHT) block_y = HEIGHT - block_h;
context.fillRect(block_x, block_y, block_w, block_h);
}
function drawBall() {
context.beginPath();
context.arc(ball_x, ball_y, ball_radius, 0, Math.PI * 2, false);
}
function moveBall() {
ball_y += 1;
ball_x -= 1;
}
function onKeyDown(evt) {
if (evt.keyCode == 68) rightKey = true;
else if (evt.keyCode == 65) leftKey = true;
if (evt.keyCode == 87) upKey = true;
else if (evt.keyCode == 83) downKey = true;
}
function onKeyUp(evt) {
if (evt.keyCode == 68) rightKey = false;
else if (evt.keyCode == 65) leftKey = false;
if (evt.keyCode == 87) upKey = false;
else if (evt.keyCode == 83) downKey = false;
if(evt.keyCode == 32) createBall();
}
function createBall()
{
ball_x = block_x + (block_w / 2);
ball_y = block_y + (block_y / 2);
radius = 20;
shotBall = true;
}
$(document).keydown(onKeyDown);
$(document).keyup(onKeyUp);
When I tried your code
the problem that I can see is that you haven't initialized the block_w, and block_h and the ball_radius variables, because these values are seems to be undefined as I see in firebug tool.
So you have to make sure that you have defined and initialized every variable that you use.
Also You have to make sure that you are calling every function that you have defined.
When I put values manually in the context.arc(23, 34, 45, 0, Math.PI*2, false); function
then it works fine for me.
So make sure you have defined and initialized every variable.