canvas keyPress movement - broken - javascript

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 ++;
}
}

Related

How to make Javascript function call happen after pauses

I am building a simple game in using HTML5 Canvas/Javascript. However, the game will be passed Javascript functions (js injected into the browser). The code passed will be to move the character ie. "moveRight(); moveRight(); moveUp();".
Currently, i have the character moving, however for "moveRight(); moveRight();", the character teleports itself to its new position. I would like the character to moveRight and then take a pause before moving right again.
function right(){
window.setTimeout(function() {
character.x += 30;
}, 2000);
}
How can I accomplish something like this. I tried using a timeout, but it did not help me much.
Thanks,
The best way to approach this would be to use requestAnimationFrame, and use a counter for when the player is able to move.
setInterval won't work for this situation, since you need to acknowledge cases where the player moves the other way around, or when the player cancels the movement.
It's hard to understand your current logic without more code, but below you will find an approach to a grid based movement.
const c = document.getElementById('canvas');
c.width = window.innerWidth;
c.height = window.innerHeight;
const ctx = c.getContext('2d');
// player delay for movement
const playerMovementDelay = 2;
const tileSize = 32;
// player starting position
const myPlayer = {x: 1, y: 1, h: 1, w: 1};
let pkl = 0, pkr = 0, pku = 0, pkd = 0;
let pvelx = 0, pvely = 0;
let movementCountdown = 0;
function render() {
// player logic
movementCountdown -= 0.16;
const deltax = pkr + pkl;
const deltay = pkd + pku;
if (movementCountdown <= 0 && (deltax != 0 || deltay != 0)) {
movementCountdown = playerMovementDelay;
pvelx = deltax;
pvely = deltay;
}
const speed = 1;
myPlayer.x += pvelx * speed;
myPlayer.y -= pvely * speed;
pvelx = pvely = 0;
ctx.clearRect(0, 0, c.width, c.height);
// player render
ctx.fillStyle = '#FFD9B3';
ctx.fillRect(myPlayer.x * tileSize, myPlayer.y * tileSize, myPlayer.w * tileSize, myPlayer.h * tileSize);
window.requestAnimationFrame(render);
}
window.addEventListener('keydown', e => {
if (e.key == 'ArrowRight') {
pkr = 1;
e.preventDefault();
} else if (e.key == 'ArrowLeft') {
pkl = -1;
e.preventDefault();
}
if (e.key == 'ArrowUp') {
pku = 1;
e.preventDefault();
} else if (e.key == 'ArrowDown') {
pkd = -1;
e.preventDefault();
}
});
window.addEventListener('keyup', e => {
if (e.key == 'ArrowRight') {
pkr = 0;
} else if (e.key == 'ArrowLeft') {
pkl = 0;
}
if (e.key == 'ArrowUp') {
pku = 0;
} else if (e.key == 'ArrowDown') {
pkd = 0;
}
});
window.requestAnimationFrame(render);
body, html {
margin: 0;
}
<canvas id="canvas"></canvas>
You can use setInterval for the same.
var rightCount = 1;
var moveRight = function () {
rightCount++;
character.x += 30;
}
var move = function () {
setInterval(function () {
if (rightCount < 2) {
moveRight();
}
}, 2000)
}
move();

Moving an image on a canvas with arrow keys

I'm trying to get a block I've called "Sword" to move up and down when using the arrow keys, I have event listeners and handlers but for some reason they're just not talking to each other and I dunno why.
Here is the HTML, it's very simple, just draws a canvas to use.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>17013455_assignment_2</title>
</head>
<body>
<canvas id="canvas"></canvas>
<script src="17013455_ass2_task1.js"></script>
</html>
This is the Javascript, the canvas has a background drawn on, and the "sword" is drawn as a box, my key handlers should move the sword on the Y axis depending on the sword's height and it's space in the Y axix.
window.onload=function () {
var canvas = document.getElementById("canvas");
var gc = canvas.getContext("2d");
canvas.width = 640;
canvas.height = 448;
gc.clearRect(0, 0, canvas.width, canvas.height);
var background = new Image();
background.src = "https://i.imgur.com/9mPYXqC.png";
//sword dimentions
var swordHeight = 50;
var swordWidth = 25;
var swordX = 50;
var swordY = 220;
//controls for player
var upPressed = false;
var downPressed = false;
if (downPressed && swordY < canvas.height - swordHeight) {
swordY += 10;
}
else if (upPressed && swordY > 0) {
swordY -= 10;
}
function keyUpHandler(e) {
if (e.keyCode === 38) {
upPressed = false;
}
else if (e.keyCode === 40) {
downPressed = false;
}
}
function drawSword() {
/*Make a box to represent a sword until sprites are used*/
gc.beginPath();
gc.rect(swordX, swordY, swordWidth, swordHeight);
gc.fillStyle = "#000000";
gc.fill();
gc.closePath();
}
function keyDownHandler(e) {
if (e.keyCode === 38) {
upPressed = true;
}
else if (e.keyCode === 40) {
downPressed = true;
}
}
function render() {
background.onload = function () {
gc.drawImage(background, 0, 0)};
drawSword();
}
document.addEventListener("keydown", keyDownHandler, "false");
document.addEventListener("keyup", keyUpHandler, "false");
render();
setInterval(render, 10);
};
Move this part of code
if (downPressed && swordY < canvas.height - swordHeight) {
swordY += 10;
}
else if (upPressed && swordY > 0) {
swordY -= 10;
}
to render() function.
Your function should look like this:
function render() {
if (downPressed && swordY < canvas.height - swordHeight) {
swordY += 10;
}
else if (upPressed && swordY > 0) {
swordY -= 10;
}
gc.drawImage(background, 0, 0)};
drawSword();
}
and this part
background.onload = function () {
gc.drawImage(background, 0, 0)};
to window.onload = function(){} scope

Javascript game - cannot read "y" property of undefined

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.

javascript jumping character not working

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

Drawing an arc in java script but it doesn't appear

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.

Categories