Rectangle class not visibly showing up on canvas - javascript

I'm trying to make a 2D platformer game, so far everything has worked, however now I'm trying to get the platforms I created to move back and forth, so I decided to create a draw() method within my Platform class in order to render the platforms:
var canvas = document.getElementById("ctx");
var ctx = canvas.getContext("2d");
canvas.setAttribute('tabindex', 0);
canvas.focus();
canvas.addEventListener("keydown", movePlayer);
//Maybe I can get a class working?
class Platform {
constructor(x, y, xS, yS, moveBool) {
this.xPos = x;
this.yPos = y;
this.xSize = xS;
this.ySize = yS;
this.moveable = moveBool;
}
draw(ctx) {
ctx.fillStyle = "red";
ctx.fillRect(this.xPos, this.yPos, this.xSsize, this.ySsize);
}
get getX() {
return this.xPos;
}
get getY() {
return this.yPos;
}
get getxSize() {
return this.xSize;
}
get getySize() {
return this.ySize;
}
get getMoveable() {
return this.moveable;
}
set moveRight(speed) {
this.xPos = speed;
}
}
//Platform array:
platformArray = [];
//Vars:
var x_new = 50;
var y_new = 50;
var isJumping = false;
var isColliding = false;
var speed = 5;
var keys = {
up: false,
right: false,
left: false
};
function movePlayer(event) {
switch (event.keyCode) {
//Right key down:
case 39:
keys["right"] = true;
break;
//Left key down:
case 37:
keys["left"] = true;
break;
//Up key down:
case 38:
keys["up"] = true;
isJumping = true;
break;
}
}
function keyUp(event) {
switch (event.keyCode) {
//Up key up:
case 38:
isJumping = false;
keys["up"] = false;
break;
//Right key up:
case 39:
keys["right"] = false;
break;
//Left key up:
case 37:
keys["left"] = false;
break;
}
}
function boundsIntersect(x1, y1, x2, y2) {
if (x1 > x2 - 50 && x1 < x2 + 200 && y1 < y2 && y1 > y2 - 55) {
return true;
}
return false;
}
function update() {
window.requestAnimationFrame(update);
ctx.clearRect(0, 0, 900, 500);
ctx.fillStyle = "black";
ctx.beginPath();
ctx.fillRect(x_new, y_new, 50, 50);
//Draw ground:
ctx.beginPath();
ctx.rect(0, 490, 900, 10);
ctx.fillStyle = "green";
ctx.fill();
//PLayer movement:
if (keys["up"] && !keys["right"] && !keys["left"]) {
y_new -= speed;
} else if (keys["right"] && !keys["up"]) {
x_new += speed;
} else if (keys["left"] && !keys["up"]) {
x_new -= speed;
} else if (keys["up"] && keys["right"]) {
y_new -= speed;
x_new += speed;
} else if (keys["up"] && keys["left"]) {
y_new -= speed;
x_new -= speed;
}
if (y_new < 440 && isJumping == false && isColliding == false) {
y_new += 5;
y_previous = y_new - 5;
}
//Platforms:
platform1 = new Platform(50, 300, 200, 10, true);
platformArray.push(platform1);
platform1.draw(ctx);
platform2 = new Platform(300, 200, 200, 10, false);
platformArray.push(platform2);
platform3 = new Platform(400, 300, 200, 10, false);
platformArray.push(platform3);
//Platform intersections:
platformArray.forEach(function(platform) {
if (boundsIntersect(x_new, y_new, platform.getX, platform.getY) && isJumping == false) {
isColliding = true;
y_new -= 0.5;
} else if (boundsIntersect(x_new, y_new, platform.getX, platform.getY) && isJumping == true) {
isJumping = false;
y_new += 11;
isColliding = true;
} else {
isColliding = false;
}
});
var platSpeed = 2;
//Move platforms:
platformArray.forEach(function(platform) {
if (platform.getMoveable) {
if (platform.getX > 0) {
platform.moveRight = 300;
platform.draw(ctx);
}
}
});
ctx.save();
ctx.restore();
}
window.requestAnimationFrame(update);
update();
canvas {
background: #eee;
}
<!DOCTYPE html>
<html>
<body>
<canvas id="ctx" tabindex=0 width=900 height=500 style="border:1px solid #000000;" onkeypress="movePlayer(event)" onkeyup="keyUp(event)"></canvas>
</body>
</html>
However what happens is, the platforms are there because BoundsIntersect detects them, but they're just not visually showing up and I'm not sure why. Any help is appreciated!

Your draw function has a typo. You are also calling your update() function twice at the bottom. Here is a version with the platforms fixed. Just bear in mind that your platforms don't seem to work as you might expect. However, I think that warrants a different question.
var canvas = document.getElementById("ctx");
var ctx = canvas.getContext("2d");
canvas.setAttribute('tabindex', 0);
canvas.focus();
canvas.addEventListener("keydown", movePlayer);
//Maybe I can get a class working?
class Platform {
constructor(x, y, xS, yS, moveBool) {
this.xPos = x;
this.yPos = y;
this.xSize = xS;
this.ySize = yS;
this.moveable = moveBool;
}
draw(ctx) {
ctx.fillStyle = "red";
ctx.fillRect(this.xPos, this.yPos, this.xSize, this.ySize);
}
get getX() {
return this.xPos;
}
get getY() {
return this.yPos;
}
get getxSize() {
return this.xSize;
}
get getySize() {
return this.ySize;
}
get getMoveable() {
return this.moveable;
}
set moveRight(speed) {
this.xPos = speed;
}
}
//Platform array:
platformArray = [];
//Vars:
var x_new = 50;
var y_new = 50;
var isJumping = false;
var isColliding = false;
var speed = 5;
var keys = {
up: false,
right: false,
left: false
};
function movePlayer(event) {
switch (event.keyCode) {
//Right key down:
case 39:
keys["right"] = true;
break;
//Left key down:
case 37:
keys["left"] = true;
break;
//Up key down:
case 38:
keys["up"] = true;
isJumping = true;
break;
}
}
function keyUp(event) {
switch (event.keyCode) {
//Up key up:
case 38:
isJumping = false;
keys["up"] = false;
break;
//Right key up:
case 39:
keys["right"] = false;
break;
//Left key up:
case 37:
keys["left"] = false;
break;
}
}
function boundsIntersect(x1, y1, x2, y2) {
if (x1 > x2 - 50 && x1 < x2 + 200 && y1 < y2 && y1 > y2 - 55) {
return true;
}
return false;
}
function update() {
window.requestAnimationFrame(update);
ctx.clearRect(0, 0, 900, 500);
ctx.fillStyle = "black";
ctx.beginPath();
ctx.fillRect(x_new, y_new, 50, 50);
//Draw ground:
ctx.beginPath();
ctx.rect(0, 490, 900, 10);
ctx.fillStyle = "green";
ctx.fill();
//PLayer movement:
if (keys["up"] && !keys["right"] && !keys["left"]) {
y_new -= speed;
} else if (keys["right"] && !keys["up"]) {
x_new += speed;
} else if (keys["left"] && !keys["up"]) {
x_new -= speed;
} else if (keys["up"] && keys["right"]) {
y_new -= speed;
x_new += speed;
} else if (keys["up"] && keys["left"]) {
y_new -= speed;
x_new -= speed;
}
if (y_new < 440 && isJumping == false && isColliding == false) {
y_new += 5;
y_previous = y_new - 5;
}
//Platforms:
platform1 = new Platform(50, 300, 200, 10, true);
platformArray.push(platform1);
platform1.draw(ctx);
platform2 = new Platform(300, 200, 200, 10, false);
platformArray.push(platform2);
platform3 = new Platform(400, 300, 200, 10, false);
platformArray.push(platform3);
//Platform intersections:
platformArray.forEach(function(platform) {
if (boundsIntersect(x_new, y_new, platform.getX, platform.getY) && isJumping == false) {
isColliding = true;
y_new -= 0.5;
} else if (boundsIntersect(x_new, y_new, platform.getX, platform.getY) && isJumping == true) {
isJumping = false;
y_new += 11;
isColliding = true;
} else {
isColliding = false;
}
});
var platSpeed = 2;
//Move platforms:
platformArray.forEach(function(platform) {
if (platform.getMoveable) {
if (platform.getX > 0) {
platform.moveRight = 300;
platform.draw(ctx);
}
}
});
ctx.save();
ctx.restore();
}
window.requestAnimationFrame(update);
canvas {
background: #eee;
}
<!DOCTYPE html>
<html>
<body>
<canvas id="ctx" tabindex=0 width=900 height=500 style="border:1px solid #000000;" onkeypress="movePlayer(event)" onkeyup="keyUp(event)"></canvas>
</body>
</html>

Related

smooth snake movement in javascript

I was making a snake game. I have a basic game but I wanted to move the snake more smoothly and specially I wanted to turn the direction of the snake more smoothly.
The problem until now is that I have been removing the tail of the snake and adding it to the head for the movement part.
Moving the snake smoothly is rather easy by reducing the interval for calling the draw function and incrementing the x and y values by small amounts but what I am having problem is with turning the snake smoothly,it is exactly where I am lost/confused as to how to do it like done here (only the turning of snake part and not the changing of head when snake gets blocked)
can anyone help out please? here is my code:
let cvs = "";
let ctx = "";
let size = [];
var direction = 'b';
var speed = 200;
//moving lines on arrow click
window.addEventListener("keydown", moveSomething, false);
function moveSomething(e) {
switch (e.keyCode) {
case 37:
//left
if (direction != 'r') {
direction = 'l';
}
break;
case 38:
//up
if (direction != 'b') {
direction = 't';
}
break;
case 39:
//right
if (direction != 'l') {
direction = 'r';
}
break;
case 40:
//bottom
if (direction != 't') {
direction = 'b';
}
break;
}
}
let food = {
x: Math.floor(Math.random() * 220),
y: Math.floor(Math.random() * 400),
s: 20,
draw: function() {
//this if block rounds off the x and y values
if ((this.x % 20) != 0 || (this.y % 20) != 0) {
if ((this.x % 20) != 0) {
let e = this.x % 20;
e = 20 - e;
this.x = this.x + e;
}
if ((this.y % 20) != 0) {
let e = this.y % 20;
e = 20 - e;
this.y = this.y + e;
}
};
ctx.fillStyle = "red";
ctx.fillRect(this.x, this.y, this.s, this.s);
},
newfood: function() {
this.x = Math.floor(Math.random() * 220);
this.y = Math.floor(Math.random() * 400);
this.draw();
}
}
const snake = {
s: 20,
draw: function(x, y) {
ctx.fillStyle = "green";
ctx.fillRect(this.s * x, this.s * y, this.s, this.s);
ctx.strokeStyle = "black";
ctx.strokeRect(this.s * x, this.s * y, this.s, this.s);
},
snakeInit: function() {
for (let i = 8; i >= 4; i--) {
size.push({
x: i,
y: 6
})
}
},
callDraw: function() {
for (let i = 0; i < size.length; i++) {
this.draw(size[i].x, size[i].y);
}
},
move: function() {
var snakeX = size[0].x;
var snakeY = size[0].y;
if (direction == 'r') {
snakeX++;
} else if (direction == 'l') {
snakeX--;
} else if (direction == 't') {
snakeY--;
} else if (direction == 'b') {
snakeY++;
}
//console.log("Inside move1", speed);
if (snakeX == -1 || snakeX == cvs.width / this.s || snakeY == -1 || snakeY == Math.floor(cvs.height / this.s) || this.checkSelfCollision(snakeX, snakeY, size)) {
ctx.clearRect(0, 0, cvs.width, cvs.height);
gameloop = clearInterval(gameloop);
return;
} else {
ctx.clearRect(0, 0, cvs.width, cvs.height);
food.draw();
}
if (snakeX * 20 == food.x && snakeY * 20 == food.y) {
var tail = {
x: snakeX,
y: snakeY
};
food.eaten();
speed += 200;
food.newfood();
} else {
var tail = size.pop();
tail.x = snakeX;
tail.y = snakeY;
}
size.unshift(tail);
for (let i = 0; i < size.length; i++) {
this.draw(size[i].x, size[i].y);
}
},
checkSelfCollision: function(x, y, arr) {
for (let i = 0; i < arr.length; i++) {
if (arr[i].x == x && arr[i].y == y) {
return true;
}
}
return false;
}
}
function loop() {
const cvsL = document.getElementById("snakes");
const ctxL = cvsL.getContext('2d');
cvs = cvsL;
ctx = ctxL;
snake.snakeInit();
snake.callDraw();
food.draw();
gameloop = setInterval(function() {
snake.move();
}, speed);
}
<body onload="loop();">
<canvas id="snakes" width=240px height=420px style="border: 1px solid black;display: block;"></canvas>
</body>

How to reset javascript game when popup window is closed

This snake style game is opened in a popup when you click a button on a page, then you are given a start screen and instructions, you click start to begin the game, and when you lose it displays your score and some text, if you close the popup and reopen it, it still shows the score rather than the start screen.
How do I make it reset when the popup is closed?
jQuery(document).ready(function($) {
$("#canvas").addClass("displayNone");
$("#lose").addClass("displayNone");
$("#post").removeClass("displayNone");
$("#controls").removeClass("displayNone");
$('#play').on('click', function() {
$('#playdiv').addClass('show-game');
})
var canvas = $("#canvas")[0];;
var ctx = canvas.getContext("2d");
var w = $("#canvas").width();
var h = $("#canvas").height();
var cw = 10;
var d;
var food;
var score;
var snake_array;
$("#score").addClass("displayNone");
$("#start").click(function() {
$("#start").addClass("displayNone");
$("#lose").addClass("displayNone");
$("#post").addClass("displayNone");
$("#canvas").removeClass("displayNone");
init();
})
var keys = [];
window.addEventListener("keydown",
function(e) {
keys[e.keyCode] = true;
switch (e.keyCode) {
case 37:
case 39:
case 38:
case 40:
case 32:
e.preventDefault();
break;
default:
break;
}
},
false);
window.addEventListener('keyup',
function(e) {
keys[e.keyCode] = false;
},
false);
// was here
function init() {
d = "right";
create_snake();
create_food();
score = 0;
if (typeof game_loop != "undefined") clearInterval(game_loop);
game_loop = setInterval(paint, 90);
}
// init();
function create_snake() {
var length = 5;
snake_array = [];
for (var i = length - 1; i >= 0; i--) {
snake_array.push({
x: i,
y: 0
});
}
}
function create_food() {
food = {
x: Math.round(Math.random() * (w - cw) / cw),
y: Math.round(Math.random() * (h - cw) / cw),
};
}
function paint() {
ctx.fillStyle = "white";
ctx.fillRect(0, 0, w, h);
ctx.strokeStyle = "black";
ctx.strokeRect(0, 0, w, h);
var nx = snake_array[0].x;
var ny = snake_array[0].y;
if (d == "right") nx++;
else if (d == "left") nx--;
else if (d == "up") ny--;
else if (d == "down") ny++;
if (nx == -1 || nx == w / cw || ny == -1 || ny == h / cw || check_collision(nx, ny, snake_array)) {
document.querySelector('#score').innerText = 'Your score: ' + score;
$("#score").removeClass("displayNone");
$("#lose").removeClass("displayNone");
$("#start").removeClass("displayNone");
$("#canvas").addClass("displayNone");
//init();
return;
}
if (nx == food.x && ny == food.y) {
var tail = {
x: nx,
y: ny
};
score++;
create_food();
} else {
var tail = snake_array.pop();
tail.x = nx;
tail.y = ny;
}
snake_array.unshift(tail);
for (var i = 0; i < snake_array.length; i++) {
var c = snake_array[i];
paint_cell(c.x, c.y);
}
paint_cell(food.x, food.y);
var score_text = "Score: " + score;
ctx.fillText(score_text, 5, h - 5);
}
function paint_cell(x, y) {
ctx.fillStyle = "pink";
ctx.fillRect(x * cw, y * cw, cw, cw);
ctx.strokeStyle = "red";
ctx.strokeRect(x * cw, y * cw, cw, cw);
}
function check_collision(x, y, array) {
for (var i = 0; i < array.length; i++) {
if (array[i].x == x && array[i].y == y) return true;
}
return false;
}
$(document).keydown(function(e) {
var key = e.which;
if (key == "37" && d != "right") d = "left";
else if (key == "38" && d != "down") d = "up";
else if (key == "39" && d != "left") d = "right";
else if (key == "40" && d != "up") d = "down";
})
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div> unknown HTML please post it here</div>
Seems like you never clean setInterval on exit. Please try to clearInterval. Attach to the window, not local valriable.
const window.timerId = setInterval(init, 9000)
// On init
if (window.game_loop != "undefined") clearInterval(game_loop);
window.game_loop = setInterval(paint, 90);

Continuously drawing rectangles in JavaScript canvas slows the program after a few seconds

Right now I'm trying to make a simple 2D platformer in JavaScript canvas. This is what I have so far:
<!DOCTYPE html>
<html>
<body>
<style>
canvas{
background: #eee;
}
</style>
<canvas id="ctx" tabindex=0 width=900 height=500 style="border:1px solid #000000;" onkeypress="movePlayer(event)" onkeyup="keyUp(event)"></canvas>
<script>
var canvas = document.getElementById("ctx");
var ctx = canvas.getContext("2d");
canvas.setAttribute('tabindex', 0);
canvas.focus();
canvas.addEventListener("keydown", movePlayer);
//Maybe I can get a class working?
function Platform(x,y,xSize,ySize){
this.xPos = x;
this.yPos = y;
ctx.fillStyle = "red";
ctx.fillRect(x,y,xSize,ySize);
this.getX = function(){
return this.xPos;
};
this.getY = function(){
return this.yPos;
};
this.getxSize = function(){
return this.xSize;
};
this.getySize = function(){
return this.ySize;
};
}
//Function arrays?
platformArray = [];
//Too many vars smh:
var x_previous = 50;
var y_previous = 50;
var x_new = 50;
var y_new = 50;
var isJumping = false;
var isColliding = false;
var right = false;
var left = false;
var up = false;
var down = false;
var speed = 5;
function movePlayer(event) {
switch(event.keyCode){
//Right
case 39:
right = true;
break;
//Left
case 37:
left = true;
break;
//Up
case 38:
isJumping = true;
up = true;
break;
}
}
function keyUp(event){
switch(event.keyCode){
//Up key up:
case 38:
isJumping = false;
up = false;
break;
//Right key up:
case 39:
right = false;
break;
//Left key up:
case 37:
left = false;
break;
//Down key up:
case 40:
down = false;
break;
}
}
setInterval(update,1);
setTimeout(update,1)
function boundsIntersect(x1,y1,x2,y2){
if(x1 > x2-20 && x1 < x2+200 && y1 < y2 && y1 > y2-55){
return true;
}
return false;
}
function update(){
ctx.clearRect(0,0,900,500)
ctx.fillStyle = "black";
ctx.beginPath();
ctx.fillRect(x_new,y_new,50,50);
//Draw ground:
ctx.beginPath();
ctx.rect(0,490,900,10);
ctx.fillStyle = "green";
ctx.fill();
if(right == true){
x_new+=speed;
x_previous=x_new-speed;
} else if(left == true){
x_new-=speed;
x_previous=x_new-speed;
} else if(down == true){
y_new+=speed;
y_previous=y_new-speed;
} else if(up == true){
y_new-=speed;
y_previous=y_new-speed;
}
if(y_new < 440 && isJumping == false && isColliding == false){
y_new+=5;
y_previous=y_new-5;
}
//Platforms:
platform1 = new Platform(50,300,200,10);
platformArray.push(platform1);
platform2 = new Platform(300,200,200,10);
platformArray.push(platform2);
platform3 = new Platform(400,300,200,10);
platformArray.push(platform3);
//Platform intersections:
platformArray.forEach(function(platform){
if(boundsIntersect(x_new,y_new,platform.getX(), platform.getY()) && isJumping == false){
isColliding = true;
y_new -= 0.5;
} else if(boundsIntersect(x_new,y_new,platform.getX(), platform.getY()) && isJumping == true){
isJumping = false;
y_new += 10;
isColliding = true;
} else {
isColliding = false;
}
});
ctx.save();
ctx.restore();
}
update();
</script>
</body>
</html>
The program runs just fine up until right around the 20sec mark, then it starts to run slower and slower until it just barely moves the player anymore.
I've tried every possible solution I've found online, but nothing seems to work. Any help is appreciated!
Instead of using window.interval to redraw the frames, use window.requestAnimationFrame. There is an example there how to use it.
What you're doing is trying to redraw the frames every 1/1000 of second, which is way too fast anyway.
What window.requestAnimationFrame does is it smartly requests new frames to redraw as needed, in order to maintain a smooth animation.

Why is my canvas not clearing?

This is my first year in programming and I'm having problems clearing my gEnemies canvas.
$(document).ready(function() {
initStars(600);
});
var FPS = 60;
width = 300;
height = 400;
var gBackground = document.getElementById("canvas_background").getContext("2d");
var gPlayer = document.getElementById("canvas_player").getContext("2d");
var gEnemies = document.getElementById("canvas_enemies").getContext("2d");
var GUI = document.getElementById("canvas_ui").getContext("2d");
var bullets = [];
var enemies = [];
var shootTimer = 0;
var maxShootTimer = 15;
var Key = {
up: false,
down: false,
left: false,
right: false
};
var player = {
width: 16,
height: 16,
x: (width / 2) - 8,
speed: 3,
y: height - 20,
canShoot: true,
render: function() {
gPlayer.fillStyle="aqua";
gPlayer.fillRect(this.x,this.y,this.width,this.height);
},
tick: function() {
if(Key.left && this.x > 0) this.x -= this.speed;
if(Key.right && this.x < width - 20) this.x += this.speed;
if(Key.space && this.canShoot) {
this.canShoot = false;
bullets.push(new Bullet(this.x,this.y - 4));
bullets.push(new Bullet(this.x + this.width,this.y - 4));
shootTimer = maxShootTimer;
}
}
};
stars = [];
addEventListener("keydown", function(e) {
var keyCode = (e.keyCode) ? e.keyCode : e.which;
switch(keyCode) {
case 38: // up
Key.up = true;
break;
case 40: // down
Key.down = true;
break;
case 37: // left
Key.left = true;
break;
case 39: // right
Key.right = true;
break;
case 32: //spacebar
Key.space = true;
break;
}
}, false);
addEventListener("keyup", function(e) {
var keyCode = (e.keyCode) ? e.keyCode : e.which;
switch(keyCode) {
case 38: // up
Key.up = false;
break;
case 40: // down
Key.down = false;
break;
case 37: // left
Key.left = false;
break;
case 39: // right
Key.right = false;
break;
case 32: //spacebar
Key.space = false;
break;
}
}, false);
function collision(obj1,obj2) {
return (
obj1.x < obj2.x+obj2.width &&
obj1.x + obj1.width > obj2.x &&
obj1.y < obj2.y+obj2.height &&
obj1.y + obj1.height > obj2.y
);
}
function Star(x,y) {
this.x = x;
this.y = y;
this.size = Math.random() * 2.5;
this.render = function() {
gBackground.fillStyle = "white";
gBackground.fillRect(this.x,this.y,this.size,this.size)
};
this.tick = function() {
this.y++;
}
}
function createStars(amount) {
for(i=0;i<amount;i ++) {
stars.push(new Star(Math.random() * width, -5));
}
}
function initStars(amount) {
for(i=0;i<amount;i++) {
stars.push(new Star(Math.random()*width,Math.random()*height));
}
}
function Bullet(x,y) {
this.x = x;
this.y = y;
this.width = 2;
this.height = 12;
this.speed = 5;
this.render = function() {
gPlayer.fillStyle = "red";
gPlayer.fillRect(this.x,this.y,this.width,this.height);
};
this.tick = function() {
if(this.y < -this.height) {
var index = bullets.indexOf(this);
bullets.splice(index,1);
}
this.y-=this.speed;
};
}
function Enemy(x,y) {
this.x = x;
this.y = y;
this.width = 16;
this.height = 16;
this.speed = 0.5;
this.render = function() {
gEnemies.fillStyle = "red";
gEnemies.fillRect(this.x,this.y,this.width,this.height);
};
this.tick = function() {
this.y += this.speed;
}
}
function render() {
gBackground.clearRect(0,0,width,height);
gPlayer.clearRect(0,0,width,height);
gEnemies.clearRect(0,0,this.width,this.height);
player.render();
for(x=0;x<8;x++) {
for(y=0;y<8;y++) {
enemies.push(new Enemy(x,y));
}
}
for(i in enemies) enemies[i].render();
for(i in stars) {
stars[i].render();
}
for(i in bullets) bullets[i].render();
}
function tick() {
createStars(1);
player.tick();
for(i in enemies) enemies[i].tick();
for(i in stars) stars[i].tick();
for(i in bullets) bullets[i].tick();
if(shootTimer <= 0) player.canShoot = true;
shootTimer--;
}
setInterval(function() {
render();
tick();
}, 1000/FPS );
canvas {
position: absolute;
top: 0;
left: 0;
}
#canvas_background {
background: black;
}
<!DOCTYPE html>
<html>
<head>
<title> Game </title>
</head>
<body>
<canvas id='canvas_background' width='300' height='400'></canvas>
<canvas id='canvas_player' width='300' height='400'></canvas>
<canvas id='canvas_enemies' width='300' height='400'></canvas>
<canvas id='canvas_ui' width='300' height='400'></canvas>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.2/jquery.min.js"></script>
</body>
</html>
Everything is working properly. I can move the square and shoot bullets. However, the enemies canvas is not clearing properly.
To be clear, this is how I'm trying to clear the Enemies Canvas:
gEnemies.clearRect(0,0,width,height);
Why is the Enemies Canvas not clearing?
It is clearing. The problem is you keep creating 64 new enemies every time you render:
for(x=0;x<8;x++) {
for(y=0;y<8;y++) {
enemies.push(new Enemy(x,y));
}
}
Add this line to your render function and you'll see what I mean:
console.log('enemies='+enemies.length);

A Javascript and Canvas "engine", that is in need of collision detection

So, I have a little "move around and stuff" engine, which is very primative at the moment.
Every so often (timer based) another pixel (5x5) will appear on the screen - if you intersect with that pixel, I would like to fire an event. (To be fair, that pixel (5x5) needs to be a hella-lot bigger :/ ).
So, here is my JSFiddle (for you fiddlers):
http://jsfiddle.net/neuroflux/q9APG/
And here is my javascript for the canvas:
var canvas, ctx;
var pixX = 0; //positions
var pixY = 0;
var endX = 0;
var endY = 0;
var youX = 5; //sizes
var youY = 5;
var dis = 1; //timings
var p = 0;
window.onload = function() {
init();
}
function init() {
canvas = document.getElementById('main');
ctx = canvas.getContext('2d');
setInterval(loop,40);
var pixTimer = Math.floor((Math.random() * 1000) * 10) + 1;
setInterval(addPixel, pixTimer);
document.addEventListener('keydown',function(e) {
runMove(e);
});
}
function addPixel() {
pX = Math.floor(Math.random() * 800) + 1;
pY = Math.floor(Math.random() * 600) + 1;
p++;
}
function loop() {
ctx.clearRect(0,0,canvas.width,canvas.height);
ctx.fillRect(pixX,pixY,youX,youY);
ctx.fillText(pixX + ':' + pixY, 5, 500);
if (p > 0) {
for (var a = 0; a <= p; a++) {
ctx.fillRect(pX,pY,5,5);
}
}
}
function runMove(e) {
var canvas = document.getElementById('main');
ky = e.keyCode;
switch(ky) {
case 37:
endX = endX - dis;
if (pixX == endX) {
} else {
if (pixX >= 0 && pixX < canvas.width) {
moveleft = setInterval(ml,10);
function ml() { pixX--; }
} else {
pixX = 0;
}
}
return false;
case 38:
endY = endY - dis;
if (pixY == endY) {
} else {
if (pixY >= 0 && pixY < canvas.height) {
moveup = setInterval(mu,10);
function mu() { pixY--; }
}
}
return false;
case 39:
endX = endX + dis;
if (pixX == endX) {
} else {
if (pixX >= 0 && pixX < canvas.width) {
moveright = setInterval(mr,10);
function mr() { pixX++; }
}
}
return false;
case 40:
endY = endY + dis;
if (pixY == endY) {
} else {
if (pixY >= 0 && pixY < canvas.height) {
movedown = setInterval(md,10);
function md() { pixY++; }
}
}
return false;
case 80:
growing = setInterval(grow,100);
clearInterval(shrinking);
function grow() {
youX = youX + dis;
youY = youY + dis;
}
return false;
case 73:
clearInterval(shrinking);
clearInterval(growing);
return false;
case 79:
shrinking = setInterval(shrink,100);
clearInterval(growing);
function shrink() {
youX = youX - dis;
youY = youY - dis;
}
return false;
default:
return false;
}
}
I have already tried this, but got issues :( (nothing would fire):
JSFiddle: http://jsfiddle.net/neuroflux/uF5kj/
Canvas Code:
var canvas, ctx;
var pixX = 0; //positions
var pixY = 0;
var endX = 0;
var endY = 0;
var youX = 5; //sizes
var youY = 5;
var dis = 1; //timings
var p = 0;
var pixel = new Array();
window.onload = function() {
init();
}
function init() {
canvas = document.getElementById('main');
ctx = canvas.getContext('2d');
setInterval(loop,40);
var pixTimer = Math.floor((Math.random() * 1000) * 10) + 1;
setInterval(addPixel, pixTimer);
document.addEventListener('keydown',function(e) {
runMove(e);
});
}
function addPixel() {
pX = Math.floor(Math.random() * 800) + 1;
pY = Math.floor(Math.random() * 600) + 1;
p++;
}
function loop() {
ctx.clearRect(0,0,canvas.width,canvas.height);
var bgImg = new Image();
bgImg.src = 'bg.png';
ctx.drawImage(bgImg,0,0,800,600);
ctx.fillRect(pixX,pixY,youX,youY);
ctx.fillText(pixX + ':' + pixY, 5, 500);
if (p > 0) {
for (var a = 0; a <= p; a++) {
pixel[a] = ctx.fillRect(pX,pY,5,5);
}
}
}
function checkIntersections() {
for (var x = 0; x < pixel.length; x++) {
if (pixX == pixel[x].x) { alert(0) }
}
}
function runMove(e) {
var canvas = document.getElementById('main');
ky = e.keyCode;
switch(ky) {
case 37:
endX = endX - dis;
if (pixX == endX) {
} else {
if (pixX >= 0 && pixX < canvas.width) {
moveleft = setInterval(ml,10);
function ml() { pixX--; }
} else {
pixX = 0;
}
}
return false;
case 38:
endY = endY - dis;
if (pixY == endY) {
} else {
if (pixY >= 0 && pixY < canvas.height) {
moveup = setInterval(mu,10);
function mu() { pixY--; }
}
}
checkIntersections();
return false;
case 39:
endX = endX + dis;
if (pixX == endX) {
} else {
if (pixX >= 0 && pixX < canvas.width) {
moveright = setInterval(mr,10);
function mr() { pixX++; }
}
}
checkIntersections();
return false;
case 40:
endY = endY + dis;
if (pixY == endY) {
} else {
if (pixY >= 0 && pixY < canvas.height) {
movedown = setInterval(md,10);
function md() { pixY++; }
}
}
checkIntersections();
return false;
case 80:
growing = setInterval(grow,100);
clearInterval(shrinking);
function grow() {
youX = youX + dis;
youY = youY + dis;
}
checkIntersections();
return false;
case 73:
clearInterval(shrinking);
clearInterval(growing);
return false;
case 79:
shrinking = setInterval(shrink,100);
clearInterval(growing);
function shrink() {
youX = youX - dis;
youY = youY - dis;
}
return false;
default:
return false;
}
}
Wait, so all you want is a function to see if two rectangles intersect?
Here's a bulletproof function for you:
// returns true if there is any overlap
// params: x,y,w,h of two rectangles
function intersects(x1, y1, w1, h1, x2, y2, w2, h2) {
if (w2 !== Infinity && w1 !== Infinity) {
w2 += x2;
w1 += x1;
if (isNaN(w1) || isNaN(w2) || x2 > w1 || x1 > w2) return false;
}
if (y2 !== Infinity && h1 !== Infinity) {
h2 += y2;
h1 += y1;
if (isNaN(h1) || isNaN(y2) || y2 > h1 || y1 > h2) return false;
}
return true;
}
You'd be better off with circles, since the distance can more easily be calculated (fixed radius). Say you set radius to 10, then if distance < 20 they are inside each other, i.e. there is collison.
// Pythagoras theorem to calculate distance between 2 points
function does_collide(x1, y1, x2, y2) {
return Math.sqrt((x2-x1)*(x2-x1) + (y2-y1)*(y2-y1)) < 20;
}
Each time, calculate distance between user / object:
if(does_collide(pixX, pixY, pX, pY)) {
ctx.fillText('collison!#', 0, 10);
collison = true;
} else {
collison = false;
}
At any time, the collison variable can be used for checking whether there is collison.
You can draw a circle using:
ctx.beginPath();
ctx.arc(x, y, r, 0, 2 * Math.PI);
ctx.fill();
http://jsfiddle.net/q9APG/4/

Categories