I am making a snake game, in html, css, and js. It is been working good to me, then i noticed that when i pause the game, the canva seems to move, and the snake collsiion with the left and bottom border is not working correctly, can you help me find my error
let score = 0;
let gameOver = false;
let isPaused = false;
const appleImg = new Image();
appleImg.src = "apple.png";
let snakeHeadImg = new Image();
snakeHeadImg.src = "snakeHead.png";
let startTime = Date.now();
let speed = 75;
let eatingSound = new Audio("Coin.wav");
let deathSound = new Audio("Death.wav");
let bgMusic = document.getElementById("bg-music");
bgMusic.play();
// Get the canvas element
const canvas = document.getElementById("game-canvas");
// Set the canvas dimensions
canvas.width = 400;
canvas.height = 400;
// Get the canvas context
const ctx = canvas.getContext("2d");
// Initialize snake
let snake = [{x: 200, y: 200}];
// Initialize food
let food = {x: Math.floor(Math.random() * (canvas.width - 20)), y: Math.floor(Math.random() * (canvas.width - 20))};
// Initialize snake direction
let direction = "right";
// Draw the score
function drawScore() {
document.getElementById("score").innerHTML = "Score: " + score;
}
// Draw the snake
function drawSnake() {
ctx.fillStyle = "#f1fa8c";
for (let i = 0; i < snake.length; i++) {
if (i === 0) {
// Save the current canvas state
ctx.save();
// Translate the canvas to the position of the snake head
ctx.translate(snake[i].x + 5, snake[i].y + 5);
// Rotate the canvas based on the snake's direction
switch (direction) {
case 'down':
ctx.rotate(180 * Math.PI/180);
break;
case 'right':
ctx.rotate(90 * Math.PI/180);
break;
case 'left':
ctx.rotate(-90 * Math.PI/180);
break;
}
// Draw the head of the snake using the image
ctx.drawImage(snakeHeadImg, -5, -5, 10, 10);
// Restore the canvas state
ctx.restore();
} else {
// Draw the rest of the snake using rectangles
ctx.fillRect(snake[i].x, snake[i].y, 10, 10);
}
}
}
// Draw the food
function drawFood() {
ctx.drawImage(appleImg, food.x, food.y, 15, 15);
}
// Move the snake
function moveSnake() {
let head = {x: snake[0].x, y: snake[0].y};
if (direction === "right") {
head.x += 10;
} else if (direction === "left") {
head.x -= 10;
} else if (direction === "up") {
head.y -= 10;
} else if (direction === "down") {
head.y += 10;
}
snake.unshift(head);
snake.pop();
}
// Clear the canvas
function clearCanvas() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
}
// Check for collision between the snake itself
function checkSelfCollision() {
for (let i = 1; i < snake.length; i++) {
if (snake[i].x === snake[0].x && snake[i].y === snake[0].y) {
gameOver = true;
// play the death sound
bgMusic.currentTime = 0;
bgMusic.pause();
deathSound.currentTime = 0;
deathSound.play();
break;
}
}
}
// Check for collision between snake and food
function checkCollision() {
if (Math.abs(snake[0].x - food.x) <= 15 && Math.abs(snake[0].y - food.y) <= 15) {
food = {x: Math.floor(Math.random() * canvas.width), y: Math.floor(Math.random() * canvas.height)};
score++;
snake.push({x: snake[snake.length-1].x, y: snake[snake.length-1].y});
// play the eating sound
eatingSound.currentTime = 0;
eatingSound.play();
}
}
// Check for collision between snake and border
function checkBorderCollision() {
if (snake[0].x < 0 || snake[0].x > canvas.width || snake[0].y < 0 || snake[0].y > canvas.height) {
gameOver = true;
// play the death sound
bgMusic.currentTime = 0;
bgMusic.pause();
deathSound.currentTime = 0;
deathSound.play();
}
}
document.addEventListener("keydown", event => {
if (event.code === "Space") {
if(isPaused) {
isPaused = false;
gameLoop();
}
else if(!gameOver) {
isPaused = true;
}
}
});
const pauseButton = document.getElementById("pause");
pauseButton.addEventListener("click", handlePauseClick);
function handlePauseClick(event) {
if (event.target.id === "pause") {
if(isPaused) {
isPaused = false;
gameLoop();
}
else if(!gameOver) {
isPaused = true;
}
}
}
// Show game over screen
function showGameOverScreen() {
ctx.fillStyle = "rgba(0, 0, 0, 0.4)";
ctx.fillRect(0, 0, canvas.width, canvas.height);
ctx.font = "30px Arial";
ctx.fillStyle = "white";
ctx.textAlign = "center";
ctx.fillText("Game Over", canvas.width / 2, canvas.height / 2 - 50);
ctx.fillText("Score: " + score, canvas.width / 2, canvas.height / 2);
ctx.font = "20px Arial";
ctx.fillText("Press 'R' to restart", canvas.width / 2, canvas.height / 2 + 50);
ctx.fillText("Press 'Q' to quit", canvas.width / 2, canvas.height / 2 + 80);
}
// Main game loop
function gameLoop() {
if(isPaused) {
ctx.fillStyle = "rgba(0, 0, 0, 0.4)";
ctx.fillRect(0, 0, canvas.width, canvas.height);
ctx.font = "30px Arial";
ctx.fillStyle = "white";
ctx.textAlign = "center";
ctx.fillText("Game Paused", canvas.width/2, canvas.height/2);
ctx.fillText("Press space to continue", canvas.width/2, canvas.height/2+30);
return;
} else {
bgMusic.play();
clearCanvas();
drawScore();
drawFood();
drawSnake();
moveSnake();
checkSelfCollision();
checkCollision();
checkBorderCollision();
if (gameOver) {
showGameOverScreen();
return;
}
let elapsedTime = Date.now() - startTime;
if (elapsedTime > 60000) { // 60 seconds
speed = 60;
}
if (elapsedTime > 120000) { // another 60 seconds
speed = 45;
}
speed = Math.max(speed, 45); // minimum value
setTimeout(gameLoop, speed);
}
}
gameLoop();
// Handle arrow key presses
document.addEventListener("keydown", event => {
if ((event.code === "ArrowRight" || event.code === "KeyD") && direction !== "left") {
direction = "right";
} else if ((event.code === "ArrowLeft" || event.code === "KeyA") && direction !== "right") {
direction = "left";
} else if ((event.code === "ArrowUp" || event.code === "KeyW") && direction !== "down") {
direction = "up";
} else if ((event.code === "ArrowDown" || event.code === "KeyS") && direction !== "up") {
direction = "down";
}
});
const upButton = document.getElementById("up-button");
const leftButton = document.getElementById("left-button");
const downButton = document.getElementById("down-button");
const rightButton = document.getElementById("right-button");
upButton.addEventListener("click", handleButtonClick);
leftButton.addEventListener("click", handleButtonClick);
downButton.addEventListener("click", handleButtonClick);
rightButton.addEventListener("click", handleButtonClick);
function handleButtonClick(event) {
if (event.target.id === "right-button" && direction !== "left") {
direction = "right";
} else if (event.target.id === "left-button" && direction !== "right") {
direction = "left";
} else if (event.target.id === "up-button" && direction !== "down") {
direction = "up";
} else if (event.target.id === "down-button" && direction !== "up") {
direction = "down";
}
}
// Handle restart and quit keys
document.addEventListener("keydown", event => {
if (event.code === "KeyR" && gameOver) {
location.reload();
} else if (event.code === "KeyQ" && gameOver) {
window.close();
}
});
body {
background-color: #1d1f21;
}
#game-canvas {
border: 2px solid #f1fa8c;
font-family: 'Source Sans Pro', sans-serif;
color: #f1fa8c;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
#score{
border: 2px solid #f1fa8c;
font-family: 'Source Sans Pro', sans-serif;
color: #f1fa8c;
position: absolute;
top: 25%;
left: 50%;
padding: 10px;
transform: translate(-50%, -50%);
font-weight: bolder;
box-shadow: 0 0 5px #c5e1a5;
}
#game-title {
font-size: 80px;
font-family: "Futura";
text-align: center;
color: #f1fa8c;
text-shadow: 0 0 10px #c5e1a5, 0 0 20px #c5e1a5, 0 0 30px #c5e1a5, 0 0 40px #c5e1a5, 0 0 50px #c5e1a5, 0 0 60px #c5e1a5;
position: absolute;
top: 10px;
left: 50%;
transform: translate(-50%, -50%);
}
#buttons {
font-family: 'Source Sans Pro', sans-serif;
color: #f1fa8c;
position: absolute;
top: 85%;
left: 50%;
transform: translate(-50%, -50%);
}
.buttons{
font-size: 30px;
height: 60px;
width: 60px;
border: 2px solid #f1fa8c;
background-color: #1d1f21;
color: #f1fa8c;
}
.pauseButton{
position: absolute;
top: 17%;
left: 50%;
transform: translate(-50%, -50%);
font-size: 30px;
height: 60px;
width: auto;
border: 2px solid #f1fa8c;
background-color: #1d1f21;
color: #f1fa8c;
}
<!DOCTYPE html>
<html>
<head>
<title>Snake Game</title>
<link rel="stylesheet" type="text/css" href="style.css">
<audio id="bg-music" src="Snake1.wav" loop></audio>
</head>
<body>
<h1 id="game-title">Snakeee</h1>
<button class="pauseButton" id="pause">Pause</button>
<p id="score"></p>
<canvas id="game-canvas"></canvas>
<div id="buttons">
<center>
<button class="buttons" id="up-button">W</button> <br>
<button class="buttons" id="left-button">A</button>
<button class="buttons" id="down-button">S</button>
<button class="buttons" id="right-button">D</button>
</center>
</div>
<script src="script.js"></script>
</body>
</html>
If you press to run the snipet it wont due to images in the code, so just use any images if you want to run and test it
Related
I am trying to make bullet objects for my HTML game, but they won't get drawn, even though the background (which is drawn the same way before the bullets) works.
<!DOCTYPE html>
<html>
<head>
<title>
Shooter
</title>
<style>
body{
background-color: blue;
}
canvas{
position: absolute;
top: 50px;
left: 50px;
}
h1{
color: yellow;
position: absolute;
top: 0px;
left: 50px;
}
p{
color: red;
position: absolute;
top: 450px;
left: 50px;
}
</style>
</head>
<body onkeydown='getKeyAndMove(event)'>
<h1>
Shooter
</h1>
<canvas width='800' height='400' id='myCanvas'></canvas>
<p>
Use Up and Down to move, Space to shoot. Don't get hit!
</p>
<script>
var start = null;
var playery = 0;
var canvas = document.getElementById("myCanvas");
var ctx = canvas.getContext("2d");
var radius = 1;
var bullets = [null];
var enemies = new Array(null);
function fire(playery, bullets, enemies){
if (bullets[0] === null){
console.log(9)
bullets[0] = {
x:0,
y:playery,
length:50,
height:25,
update: function(enemies){
bullets[0].x += 5;
var maxCount = enemies.length;
/*for (i=0; i<maxCount; i++){
var enemy = enemies[i];
if (enemy.x <= bullets[0].x + bullets[0].length){
if (enemy.x + enemy.length >= bullets[0].x){
if (enemy.y + enemy.height >= bullets[0].y){
if (enemy.y <= bullets[0].y + bulets[0].height){
enemies[i] = null;
bullets[0] = null;
}
}
}
}
}*/
if (bullets[0].x >= 800){
bullets[0] = null;
return;
}
}
};
}
};
function getKeyAndMove(e){
var key_code=e.which||e.keyCode;
switch(key_code){
case 38:
playery -= 5
break;
case 40:
playery += 5
break;
case 32:
console.log(32)
fire(playery, bullets, enemies);
break;
}
};
function step(timestamp){
if (!start) start = timestamp;
var progress = timestamp - start;
ctx.fillStyle = 'white'
ctx.fillRect(0, 0, canvas.width, canvas.height)
ctx.fillStyle = 'rgb(0, 0, 0)'
ctx.fillRect(1, 1, canvas.width - 2, canvas.height - 2)
var i=0;
var j=0;
for (i=0; i < 800; i++){
for (j=0; j < 400; j++){
if (Math.random() > 0.9999) {
ctx.beginPath();
ctx.arc(i, j, radius, 0, 2 * Math.PI, false);
ctx.fillStyle = 'white';
ctx.fill();
ctx.lineWidth = 0;
ctx.strokeStyle = '#FFFFFF';
ctx.stroke();
ctx.closePath();
}
}
}
if (bullets[0] != null){
bullets[0].update(enemies)
console.log(0)
if(bullets[0] != null){
ctx.fillStyle = '#DD0000'
ctx.fillRect(bullets[0].x, bullets[0].y, bullets[0].width, bullets[0].height)
}
}
window.requestAnimationFrame(step)
}
window.requestAnimationFrame(step)
</script>
</body>
</html>
The console shows no errors when I run the code. I have set it to log every frame that there is a bullet, and the log is showing up, the bullet just never appears.
What am I doing wrong?
I accidentally typed width instead of length in line 126. The problem is solved.
I am trying to make a simple JavaScript based game, where the user would move the square around the canvas and dodge elements / squares coming towards it (however this is just a plan, I am far from that point at the moment).
The problem I am experiencing is that whenever I would make my canvas width value bigger than height, it would make the square get stuck after reaching the bottom of the page. There is probably an error / mistake in my code, however I could not seem to spot anything.
The code can be found here or below:
// This code was created in CodePen.io, so some parts of it might not make any sense,
// nor are they gonna be useful outside the CodePen platform. Those parts are however only commented.
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
// character data
var charPositionX = canvas.width / 2;
// Just for the snippet height
var charPositionY = 0;
//var deltaCharPositionX = 10;
//var deltaCharPositionY = 10;
//Removed the init() function, since the elements are loaded.
// start creating elements, first the game environment.
function draw() {
clear();
createRectangleToCoverCanvas();
createChar(charPositionX, charPositionY, 10);
}
function clear() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
}
function createRectangleToCoverCanvas() {
ctx.fillStyle = '#ddd';
ctx.strokeStyle = '#ddd';
ctx.beginPath();
ctx.rect(0, 0, canvas.width, canvas.height);
ctx.fill();
ctx.stroke();
}
// now the character
function createChar(x, y, radius) {
ctx.fillStyle = 'white';
ctx.strokeStyle = 'white';
ctx.beginPath();
ctx.rect(x, y, 32, 32);
ctx.fill();
ctx.stroke();
}
var raf,
direction = {
x: 0,
y: 0
};
// set the speed variable for the character
var speed = 5;
function triggerMoveChar(event) {
switch (event.keyCode) {
// left
case 37:
// update the direction object
direction.x = -speed;
// avoid the scrolling
event.preventDefault();
break;
// up
case 38:
direction.y = -speed;
event.preventDefault();
break;
// right
case 39:
direction.x = speed;
event.preventDefault();
break;
//down
case 40:
direction.y = speed;
event.preventDefault();
break;
}
// if the animation haven't been initiated yet, and the direction is not 0, then do it now
if (!raf && (direction.x || direction.y)) moveChar();
}
function releaseMoveChar(event) {
switch (event.keyCode) {
// left
case 37:
//reset this direction
direction.x = 0;
break;
// up
case 38:
direction.y = 0;
break;
// right
case 39:
direction.x = 0;
break;
//down
case 40:
direction.y = 0;
break;
}
if (!direction.x && !direction.y) {
// if none of the directions is set, stop the animation
cancelAnimationFrame(raf);
raf = undefined;
}
}
function moveChar() {
// declare the animation function
var move = function() {
// update the positions without going out of the screen
if(direction.x){
if(
(charPositionX > 0 && charPositionX < canvas.width-32) ||
(charPositionX <= 0 && direction.x > 0) ||
(charPositionX >= canvas.width-32 && direction.x < 0))
charPositionX += direction.x;
}
if(direction.y){
if((charPositionY > 0 && charPositionY < canvas.height-32) ||
(charPositionY <= 0 && direction.y > 0) ||
(charPositionY >= canvas.width-32 && direction.y < 0))
charPositionY += direction.y;
}
// finally draw ou character
draw();
// update the raf id
raf = requestAnimationFrame(move);
};
// let's go !
raf = requestAnimationFrame(move);
}
draw();
window.addEventListener('keydown', triggerMoveChar, true);
window.addEventListener('keyup', releaseMoveChar, true);
canvas {
margin: auto;
position: absolute;
left: 0;
top: 0;
right: 0;
bottom: 0;
border: 3px solid red;
}
body {
background: #222;
}
.container {
color: #999;
margin: 0;
padding: 10px 0px 20px;
font-family: "Orbitron", "Helvetica", sans-serif;
text-align: center;
font-size: 11px;
line-height: 16px;
}
.container h1 {
margin: 10px 0;
color: red;
font-size: 32px;
min-height: 430px;
}
.container h2 {
margin: 10px 0;
color: #ccc;
font-size: 24px;
min-height: 10px;
}
.container h3 {
margin: 10px 0;
color: #999;
font-size: 18px;
}
<div class="container">
<canvas id="canvas" width="640" height="416"></canvas>
<h1>Project : Simple Game [v0.1alpha]</h1>
<h2>CONTROLS: </h2>
<h3>Arrow Keys </h3>
</div>
I will appreciate any help.
You have a typo on this line
if(direction.y){
if((charPositionY > 0 && charPositionY < canvas.height-32) ||
(charPositionY <= 0 && direction.y > 0) ||
(charPositionY >= canvas.width-32 && direction.y < 0)) // here
charPositionY += direction.y;
}
It should be height not width.
(charPositionY >= canvas.height-32 && direction.y < 0))
im developing a game as a coding exercise and ive come across a bug that i cant find when ever i press the selected button it does not remove the shape and redraw anotheer one it for some reason just keeps the shape on the page and draws a new shae i need it to delete the old shape and redraw a new shape this is how the game should work
enter code here
window.addEventListener("load", function() {
function clear(ctx, width, height) {
}
function drawRandomShape(width, height) {
//ctx.clearRect(0,0, canvas.width, canvas.height)
canvas.style.backgroundColor = 'white';
// var num = Math.floor(Math.random() * 10)
var number = 30;
var countdown = setInterval(function(){
timerSpan.innerHTML = number--;
//console.log(number)
if(number == 0 - 1){
clearInterval(countdown);
}
},1000);
function randomShape(){
var randomNum = Math.floor(Math.random() * 10);
//ctx.clearRect(0,0, canvas.width, canvas.height)
// if(number > 0){
if(randomNum >= 0 && randomNum <= 2){
// ctx.clearRect(0, 0, canvas.width, canvas.height);
var triangle = ctx.beginPath();
triangle += ctx.moveTo(0, 0);
triangle += ctx.lineTo(90, 90);
triangle += ctx.lineTo(0, 90);
triangle += ctx.closePath();
triangle += ctx.fillStyle = "red";
triangle += ctx.fill();
document.addEventListener('keyup', function shape(e){
if(e.keyCode == 37){
triangle += ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
document.removeEventListener('keyup', shape);
randomShape();
}
});
}else if(randomNum > 2 && randomNum <= 4){
// ctx.clearRect(0,0, canvas.width, canvas.height);
var blackTriangle = ctx.fillStyle = "black";
blackTriangle += ctx.beginPath();
blackTriangle += ctx.moveTo(0,0);
blackTriangle += ctx.lineTo(90, 90);
blackTriangle += ctx.lineTo(0, 90);
blackTriangle += ctx.fill();
document.addEventListener('keyup', function shape(e){
if(e.keyCode == 38){
blackTriangle += ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
document.removeEventListener('keyup', shape);
randomShape();
}
});
}else if(randomNum >= 4 && randomNum <= 6){
//ctx.clearRect(0, 0, canvas.width, canvas.height);
var redSquare = ctx.fillStyle = 'black';
redSquare += ctx.rect(200, 100, 90, 90)
redSquare += ctx.fill();
document.addEventListener('keyup', function shape(e){
if(e.keyCode == 39){
redSquare += ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
randomShape()
}
});
}else if(randomNum > 6 && randomNum < 10){
//ctx.clearRect(0,0, canvas.width, canvas.height);
var whiteSquare = ctx.rect(50,70,90,90);
whiteSquare += ctx.fillStyle = 'red';
whiteSquare += ctx.fill();
document.addEventListener('keyup', function shape(e) {
if(e.keyCode == 40){
whiteSquare += ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
document.removeEventListener('keyup', shape);
randomShape();
}
});
}
console.log(randomNum)
//};
}
randomShape();
}
//}, 1000);
function drawGameStartText(width, height ,score) {
width = 170;
height = 350;
ctx.fillStyle = 'White';
ctx.font = '30px Verdana'
ctx.fillText('Press space bar to start a new game' , width , height);
}
function restartGame(ctx, width, height){
}
var canvas = document.getElementById("shapes-game"),
height = canvas.scrollHeight,
width = canvas.scrollWidth,
gameOn = false,
expectedKey = undefined,
ctx = canvas.getContext('2d'),
// white triangle = up, red square = down,
// red triangle = left, white square = right
expectedKeysMap = {white0: 38, red1: 40, red0: 37, white1: 39};
timerSpan = document.getElementById("time-remaining");
scoreSpan = document.getElementById("score-val"),
seconds = 3;
// intervalId;
document.addEventListener("keyup", function(e) {
e.preventDefault();
if(e.keyCode == 32){
drawRandomShape();
}
});
drawGameStartText()
})
body {
padding-bottom: 50px;
}
#shapes-game {
border: 4px solid grey;
background-color: black;
}
.canvas-container {
padding: 10px;
}
.canvas-container, #shapes-game {
height: 750px;
width: 800px;
}
.scores {
padding: 10px;
text-align: center;
}
.legend {
padding-top: 15px;
}
.legend-contents {
text-align: left;
padding-left: 30px;
}
.triangle-bottomleft-red {
width: 0;
height: 0;
border-bottom: 50px solid red;
border-right: 50px solid transparent;
}
.triangle-bottomleft-black {
width: 0;
height: 0;
border-bottom: 54px solid black;
border-right: 58px solid transparent;
}
.triangle-inner-white {
position: relative;
top: 2px;
left: 2px;
width: 0;
height: 0;
border-bottom: 50px solid white;
border-right: 50px solid transparent;
}
.triangle-left {
width: 0;
height: 0;
border-top: 23px solid transparent;
border-bottom: 23px solid transparent;
border-right: 23px solid red;
}
.inner-triangle {
position: relative;
top: -20px;
left: 2px;
width: 0;
height: 0;
border-top: 20px solid transparent;
border-bottom: 20px solid transparent;
border-right: 20px solid blue;
}
.red-square {
width: 50px;
height: 50px;
background-color: red;
}
.white-square {
width: 50px;
height: 50px;
background-color: white;
border-style: solid;
border-width: 1px;
}
<!DOCTYPE html>
<html>
<head>
<title>Shapes!!</title>
<link rel="stylesheet" type="text/css" href="vendor/bootstrap.min.css">
<link rel="stylesheet" type="text/css" href="styles.css">
<script type="text/javascript" src="vendor/jquery-1.12.4.min.js"></script>
<script type="text/javascript" src="vendor/bootstrap.min.js"></script>
<script type="text/javascript" src="index.js"></script>
</head>
<body>
<div class="container">
<div class="col-xs-10 canvas-container">
<canvas id="shapes-game" height="750" width="800"></canvas>
</div>
<div class="col-xs-2 scores">
<h1>Score</h1>
<h3><span id="score-val">0</span></h3>
<h1>Timer</h1>
<h3><span id="time-remaining">30</span></h3>
<div class="legend">
<h1>Legend</h1>
<div class="legend-contents">
<div class="triangle-bottomleft-red">
</div>
<h4>Left</h4>
<div class="white-square">
</div>
<h4>Right</h4>
<div class="triangle-bottomleft-black">
<div class="triangle-inner-white"></div>
</div>
<h4>Up</h4>
<div class="red-square">
</div>
<h4>Down</h4>
</div>
</div>
</div>
</div>
</body>
</html>
There are a zillion things wrong with your code.
First of why are you doing
var blackTriangle = ctx.fillStyle = "black";
blackTriangle += ctx.beginPath();
As it does absolutely nothing.
Create one key handler and handle everything in that rather than
document.addEventListener('keyup', function shape(e){
if(e.keyCode == 39){
redSquare += ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
randomShape()
}
});
You are just creating a pile of key handlers.
If you want to track shapes you are drawing create an array for each shape
const shapes = {
whiteSquares : [],
redSquares : [],
whiteTriangle : [],
redTriangle: [],
};
then when you add the shape add it to the appropriate array
if(randomNum <= 2){
ctx.beginPath();
ctx.lineTo(0, 0);
ctx.lineTo(90, 90);
ctx.lineTo(0, 90);
ctx.closePath();
ctx.fillStyle = "red";
ctx.fill();
shapes.redTriangle.push([0,0]); // store the top left of the triangle
}
Then you can clear it in the key handler
var gameStarted = false;
const keyNames = {
space : 32,
left : 37;
up : 38,
right : 39,
down : 40,
}
// only one key handler needed.
document.addEventListener('keyup', e => {
if(gameStarted === false && e.keyCode === keyNames.space) {
gameStarted = true;
drawRandomShape();
}else if(e.keyCode === keyNames.left) {
if(shapes.redTriangle.length > 0){
var pos = shapes.redTriangle.shift(); // remove the bottom item in the array
ctx.clearRect(pos[0],pos[1],90,90); // clear that position
randomShape(); // create anothe shape.
}
}else if(e.keyCode === keyNames.right) {
if(shapes.whiteSquares.length > 0){
// same as above
}
}else if(e.keyCode === keyNames.up) {
if(shapes.whiteTriangle.length > 0){
// same as above
}
}else if(e.keyCode === keyNames.down) {
if(shapes.redSquares.length > 0){
// same as above
}
}
}
Dont over complicate conditional statements.
You have
var randomNum = Math.floor(Math.random() * 10);
if(randomNum >= 0 && randomNum <= 2){
// do stuff
}else if(randomNum > 2 && randomNum <= 4){
// do stuff
}else if(randomNum >= 4 && randomNum <= 6){
// do stuff
}else if(randomNum > 6 && randomNum < 10){
// do stuff
}
is the same as
var randomNum = Math.floor(Math.random() * 10);
if (randomNum <= 2) {
// do stuff
} else if(randomNum <= 4) {
// do stuff
} else if(randomNum <= 6) {
// do stuff
} else {
// do stuff
}
I'm trying to center a p5.js script in the middle of a page. I tried wrapping it with a div, and centering that, but it doesn't work
<body>
<div id="game"><script src="snakegame.js" type="text/javascript"></script></div>
<div id="score_wrap"><h1 class="score">SCORE: <div id="score"></div></h1></div>
<div id="hscore_wrap"><h1 class="score">HI-SCORE: <div id="hiscore"></div></h1></div>
</body>
This is what I tried to do
#game {
width: 900px;
height: 900px;
position: absolute;
top:0;
bottom: 0;
left: 0;
right: 0;
margin: auto;
}
.score {
font-family: "Bungee", sans-serif;
float: left;
color: #fff;
}
#score_wrap {
float: left;
}
#hscore_wrap {
float: right;
}
body {
background-color : #1048a3;
}
THIS IS INSIDE snakegame.js:
var s;
var scl = 20;
var food;
var pkeyCode = '';
// MAIN CODE FOR THE GAME
function setup() {
frameRate(9);
createCanvas(600, 600);
s = new Snake();
pickLocation();
}
function pickLocation () {
var cols = floor(width/scl);
var rows = floor(height/scl);
food = createVector(floor(random(cols)), floor(random(rows)));
food.mult(scl);
}
function draw() {
background(51);
s.update();
s.show();
if(s.eat(food)) {
s.score += 1;
if(s.score >= s.hiscore) s.hiscore = s.score;
pickLocation();
}
fill(255, 40, 100);
rect(food.x, food.y, scl, scl);
}
function keyPressed() {
if(keyCode === UP_ARROW && pkeyCode != 'DOWN_ARROW'){
s.dir(0, -1);
pkeyCode = 'UP_ARROW';
} else if (keyCode === DOWN_ARROW && pkeyCode != 'UP_ARROW'){
s.dir(0, 1);
pkeyCode = 'DOWN_ARROW';
} else if (keyCode === RIGHT_ARROW && pkeyCode != 'LEFT_ARROW'){
s.dir(1, 0);
pkeyCode = 'RIGHT_ARROW';
} else if (keyCode === LEFT_ARROW && pkeyCode != 'RIGHT_ARROW'){
s.dir(-1, 0);
pkeyCode = 'LEFT_ARROW';
} /* else if (keyCode === ENTER){
console.log('Cheating');
s.total++;
s.score++;
} */
}
// FUNCTIONS RELATING TO THE SNAKE, AND SNAKE PARTS ARE DEFINED HERE
function Snake() {
this.score = 0;
this.hiscore = 0;
this.x = 20;
this.y = 20;
this.xspeed = 1;
this.yspeed = 0;
this.total = 0;
this.tail = [];
this.dir = function(x, y) {
this.xspeed = x;
this.yspeed = y;
}
this.eat = function(pos) {
var d = dist(this.x, this.y, pos.x, pos.y);
if(d < 1) {
this.total++;
return true;
}
else {
return false;
}
}
this.dying = function() {
this.total = 0;
this.tail = [];
this.score = 0;
this.x = scl*3;
this.y = scl*3;
}
this.death = function() {
for (var i = 0; i < this.tail.length; i++) {
var pos = this.tail[i];
var d = dist(this.x, this.y, pos.x, pos.y);
if (d < 1) {
this.dying();
}
}
if(this.x >= width || this.y >= height) {
this.dying();
} else if (this.x < 0 || this.y < 0) {
this.dying();
}
}
this.update = function() {
for (var i = 0; i < this.tail.length - 1; i++) {
this.tail[i] = this.tail[i + 1];
}
this.tail[this.total - 1] = createVector(this.x, this.y);
this.x += this.xspeed*scl;
this.y += this.yspeed*scl;
s.death();
this.x = constrain(this.x, 0, width-scl);
this.y = constrain(this.y, 0, height-scl);
}
this.show = function() {
fill(200, 255, 200);
for (var i = 0; i < this.total; i++){
rect(this.tail[i].x, this.tail[i].y, scl, scl);
}
fill(255, 255, 255);
rect(this.x, this.y, scl, scl);
document.getElementById("score").innerHTML = this.score;
document.getElementById("hiscore").innerHTML = this.hiscore;
}
}
Sorry for the awful formatting, I'm new here
is this what you mean?
I put a border around it so you can see it as the js file is not loaded here
I also wrapped the score comments in a div so that they play nice on wider screens
#game {
width: 900px;
height: 900px;
max-width: 100%;
margin: 0 auto;
border: 1px solid white;
}
.scorecontainer {
max-width: 900px;
margin: 0 auto
}
.score {
font-family: "Bungee", sans-serif;
color: #fff;
}
#score {
float: left;
}
#hiscore {
float: right;
}
body {
background-color: #1048a3;
}
<body>
<div id="game">
<script src="snakegame.js" type="text/javascript"></script>
</div>
<div class="scorecontainer score">
<h1 id="score">SCORE: </h1>
<h1 id="hiscore">HI-SCORE: </h1>
</div>
</body>
I am having issues trying to place an image as an object for an "asteroid avoidance" game. I was able to get the game itself to work based on what was written in my book "Foundation: HTML5 Canvas for Games and Entertainment". I want to go one step beyond what was written in the book. I want to replace the triangle shaped ship with that of an image. However, I am unable to figure out where to put the code for this.draw. My professor showed us a way to do it. When I try to implement it into my code it doesn't want to work properly. May I ask for some advice on how to place the image as the ship?
Here is my working code from the book, before I made any this.draw edits:(http://jsbin.com/tukejopofo/1/)
$(document).ready(function() {
var canvas = $("#gameCanvas");
var context = canvas.get(0).getContext("2d");
//canvas dimensions
var canvasWidth = canvas.width();
var canvasHeight = canvas.height();
var playGame;
var asteroids;
var numAsteroids;
var player;
var score;
var scoreTimeout;
var arrowUp = 38;
var arrowRight = 39;
var arrowDown = 40;
var arrowLeft = 37;
//game UI
var ui = $("#gameUI");
var uiIntro = $("#gameIntro");
var uiStats = $("#gameStats");
var uiComplete = $("#gameComplete");
var uiPlay = $("#gamePlay");
var uiReset = $(".gameReset");
var uiScore = $(".gameScore");
var soundBackground = $("#gameSoundBackground").get(0);
var soundThrust = $("#gameSoundThrust").get(0);
var soundDeath = $("#gameSoundDeath").get(0);
var Asteroid = function(x, y, radius, vX) {
this.x = x;
this.y = y;
this.radius = radius;
this.vX = vX;
};
var Player = function(x, y) {
this.x = x;
this.y = y;
this.width = 24;
this.height = 24;
this.halfWidth = this.width / 2;
this.halfHeight = this.height / 2;
this.flameLength1 = 20;
this.flameLength2 = 20;
this.vX = 0;
this.vY = 0;
this.moveRight = false;
this.moveUp = false;
this.moveDown = false;
this.moveLeft = false;
};
//Reset and start the game
function startGame() {
//Reset game stats
uiScore.html("0");
uiStats.show();
//set up initial game settings
playGame = false;
asteroids = new Array();
numAsteroids = 10;
score = 0;
player = new Player(150, canvasHeight / 2, 50, 50);
for (var i = 0; i < numAsteroids; i++) {
var radius = 5 + (Math.random() * 10);
var x = canvasWidth + radius + Math.floor(Math.random() * canvasWidth);
var y = Math.floor(Math.random() * canvasHeight);
var vX = -5 - (Math.random() * 5);
asteroids.push(new Asteroid(x, y, radius, vX));
};
$(window).keydown(function(e) {
var keyCode = e.keyCode;
if (!playGame) {
playGame = true;
soundBackground.currentTime = 0;
soundBackground.play();
animate();
timer();
};
if (keyCode == arrowRight) {
player.moveRight = true;
if (soundThrust.paused) {
soundThrust.currentTime = 0;
soundThrust.play();
}
} else if (keyCode == arrowLeft) {
player.moveLeft = true;
} else if (keyCode == arrowUp) {
player.moveUp = true;
} else if (keyCode == arrowDown) {
player.moveDown = true;
}
});
$(window).keyup(function(e) {
var keyCode = e.keyCode;
if (!playGame) {
playGame = true;
animate();
};
if (keyCode == arrowRight) {
player.moveRight = false;
if (keyCode == arrowRight) {
player.moveRight = false;
soundThrust.pause();
}
} else if (keyCode == arrowUp) {
player.moveUp = false;
} else if (keyCode == arrowDown) {
player.moveDown = false;
} else if (keyCode == arrowLeft) {
player.moveLeft = false;
}
});
//start the animation loop
animate();
};
//initialize the game environment
function init() {
uiStats.hide();
uiComplete.hide();
uiPlay.click(function(e) {
e.preventDefault();
uiIntro.hide();
startGame();
});
uiReset.click(function(e) {
e.preventDefault();
uiComplete.hide();
$(window).unbind("keyup");
$(window).unbind("keydown");
soundThrust.pause();
soundBackground.pause();
clearTimeout(scoreTimeout);
startGame();
});
};
function timer() {
if (playGame) {
scoreTimeout = setTimeout(function() {
uiScore.html(++score);
if (score % 5 == 0) {
numAsteroids += 5;
}
timer();
}, 1000);
};
};
//Animation loop that does all the fun stuff
function animate() {
//Clear
context.clearRect(0, 0, canvasWidth, canvasHeight);
var asteroidsLength = asteroids.length;
for (var i = 0; i < asteroidsLength; i++) {
var tmpAsteroid = asteroids[i];
tmpAsteroid.x += tmpAsteroid.vX;
if (tmpAsteroid.x + tmpAsteroid.radius < 0) { //creates bounderies to prevent player from leaving the canvas
tmpAsteroid.radius = 5 + (Math.random() * 10);
tmpAsteroid.x = canvasWidth + tmpAsteroid.radius;
tmpAsteroid.y = Math.floor(Math.random() * canvasHeight);
tmpAsteroid.vX = -5 - (Math.random() * 5);
}
var dX = player.x - tmpAsteroid.x;
var dY = player.y - tmpAsteroid.y;
var distance = Math.sqrt((dX * dX) + (dY * dY));
if (distance < player.halfWidth + tmpAsteroid.radius) { //checks for collision
soundThrust.pause()
soundDeath.currentTime = 0;
soundDeath.play();
//Game over
playGame = false;
clearTimeout(scoreTimeout);
uiStats.hide();
uiComplete.show();
soundBackground.pause();
$(window).unbind("keyup"); //unbinds keys to stop player movement at the end of the game
$(window).unbind("keydown");
};
context.fillStyle = "rgb(255, 255, 255)";
context.beginPath();
context.arc(tmpAsteroid.x, tmpAsteroid.y, tmpAsteroid.radius, 0, Math.PI * 2, true);
context.fill();
};
player.vX = 0;
player.vY = 0;
if (player.moveRight) {
player.vX = 3;
};
if (player.moveLeft) {
player.vX = -3;
};
if (player.moveUp) {
player.vY = -3;
};
if (player.moveDown) {
player.vY = 3;
};
player.x += player.vX;
player.y += player.vY;
if (player.x - player.halfWidth < 20) {
player.x = 20 + player.halfWidth;
} else if (player.x + player.halfWidth > canvasWidth - 20) {
player.x = canvasWidth - 20 - player.halfWidth;
}
if (player.y - player.halfHeight < 20) {
player.y = 20 + player.halfHeight;
} else if (player.y + player.halfHeight > canvasHeight - 20) {
player.y = canvasHeight - 20 - player.halfHeight;
}
if (player.moveRight) {
context.save();
context.translate(player.x - player.halfWidth, player.y);
if (player.flameLength1 == 20) {
player.flameLength1 = 15;
(player.flameLength2 == 20)
player.flameLength2 = 15;
} else {
player.flameLength1 = 20;
player.flameLength2 = 20;
};
context.fillStyle = "orange";
context.beginPath();
context.moveTo(0, -12);
context.lineTo(-player.flameLength1, -7);
context.lineTo(0, -5);
context.closePath();
context.fill();
context.fillStyle = "orange";
context.beginPath();
context.moveTo(0, 12);
context.lineTo(-player.flameLength2, 7);
context.lineTo(0, 5);
context.closePath();
context.fill();
context.restore();
};
//draw ship
context.fillStyle = "rgb(255, 0, 0)";
context.beginPath();
context.moveTo(player.x + player.halfWidth, player.y);
context.lineTo(player.x - player.halfWidth, player.y - player.halfHeight);
context.lineTo(player.x - player.halfWidth, player.y + player.halfHeight);
context.closePath();
context.fill();
while (asteroids.length < numAsteroids) { //adds asteroids as the difficulty increases
var radius = 5 + (Math.random() * 10)
var x = Math.floor(Math.random() * canvasWidth) + canvasWidth + radius;
var y = Math.floor(Math.random() * canvasHeight);
var vX = -5 - (Math.random() * 5);
asteroids.push(new Asteroid(x, y, radius, vX));
}
if (playGame) {
//run the animation loop again in 33 milliseconds
setTimeout(animate, 24);
};
};
init();
});
* {
margin: 0;
padding: 0;
}
html,
body {
height: 100%;
width: 100%;
}
canvas {
display: block;
}
body {
background: #000;
color: #fff;
font-family: Verdana, Arial, sans-serif;
font-size: 18px;
}
h1 {
font-size: 30px;
}
h6 {
font-size: 15px;
}
p {
margin: 0 20px;
}
a {
color: #fff;
text-decoration: none;
}
a:hover {
text-decoration: underline;
}
a.button {
background: #185da8;
border-radius: 5px;
display: block;
font-size: 30px;
margin: 40px 0 0 350px;
padding: 10px;
width: 200px;
text-align: center;
}
a.button:hover {
background: #2488f5;
color: #fff;
text-decoration: none;
}
#game {
height: 600px;
left: 50%;
margin: -250px 0 0 -500px;
position: relative;
top: 50%;
width: 980px;
}
#gameCanvas {
background: #001022;
border: 5px solid green;
background-image: url(../images/space.jpg);
background-position: center top;
background-repeat: no-repeat;
background-size: cover;
}
#gameUI {
height: 600px;
position: absolute;
width: 980px;
}
#gameIntro,
#gameComplete {
background: rgba(0, 0, 0, 0.5);
margin: 100px 0 0 10px;
padding: 40px 0;
text-align: center;
}
#gameStats {
font-size: 14px;
margin: 20px 0;
}
#gameStats .gameReset {
margin: 20px 20px 0 0;
position: absolute;
right: 0;
top: 0;
}
<body>
<div id="game">
<div id="gameUI">
<div id="gameIntro">
<h1>Debris Fields of Spiral Galaxy</h1>
<h6>A <i>Galaxy Smuggler's Run</i> Game</h6>
<hr>
<p>You are Captain Amadaeus delivering goods to a dependent planet on the other side of a debris field</p>
<p>Click <i>"Play"</i> and then press any key to start.</p>
<p><a id="gamePlay" class="button" href="">Play!</a>
</p>
</div>
<div id="gameStats">
<p><b>Time: </b><span class="gameScore"></span> seconds</p>
<p><a class="gameReset" href="">Reset</a>
</p>
</div>
<div id="gameComplete">
<h1>Game Over!</h1>
<p>You survived for <span class="gameScore"></span> seconds.</p>
<p>Would you like to give it another go?</p>
<p><a class="gameReset button" href="">Play Again?</a>
</p>
</div>
</div>
<canvas id="gameCanvas" width="980" height="600">
</canvas>
<audio id="gameSoundBackground" loop>
<source src="sounds/background.ogg">
<source src="sounds/background.mp3">
</audio>
<audio id="gameSoundThrust" loop>
<source src="sounds/thrust.ogg">
<source src="sounds/thrust.mp3">
</audio>
<audio id="gameSoundDeath">
<source src="sounds/death.ogg">
<source src="sounds/death.mp3">
</audio>
</div>
</body>
and here is my Professor's code for drawing an image:(http://jsbin.com/rapayufafe/1/)
// JS file for the ship
function Ship() {
this.x = 100;
this.y = 100;
this.color = "yellow";
this.fillStyle = "white";
this.vx = 0;
this.vy = 0;
this.ax = 1;
this.ay = 1;
//function "move" that will add velocity to the position of the ship
this.move = function() {
this.x += this.vx;
this.y += this.vy;
}//end move function
//draw the ship
this.draw=function () {
//ship var
var imageObj = new Image();
imageObj.src = "images/ship.png";
//save the current state of the canvas
context.save();
//moving the point of origin (0,0) to the ships x and y coordinates
context.translate(this.x,this.y);
context.lineStyle = this.color;
context.fillStyle = this.fillStyle;
/*context.beginPath();
context.moveTo(25,0);
context.lineTo(-25,25)
context.lineTo(-25,-25)*/
//draw ship
context.drawImage(imageObj,-25,-25,50,50);
context.closePath();
context.stroke();
context.fill();
context.restore();
}//end of draw ship
}//end ship function
/*var asteroidsLength = asteroids.length;
for (var i = 0; i < asteroidsLength; i++) {
var tmpAsteroid = asteroids[i];
context.fillStyle = "gray";
context.beginPath();
context.arc(tmpAsteroid.x, tmpAsteroid.y, tmpAsteroid.radius, 0, Math.PI*2, true);
context.closePath();
context.fill();
};*/
As you can see in your starting code, you have a section looking like this:
//draw ship
context.fillStyle = "rgb(255, 0, 0)";
context.beginPath();
context.moveTo(player.x + player.halfWidth, player.y);
context.lineTo(player.x - player.halfWidth, player.y - player.halfHeight);
context.lineTo(player.x - player.halfWidth, player.y + player.halfHeight);
context.closePath();
context.fill();
Just replace that code with the code for drawing an image.
var imageObj = new Image();
imageObj.src = "images/ship.png";
context.drawImage(imageObj,player.x,player.y);
Although, I'd recommend declaring the imageObj and setting the source at the top of your code where you declare the rest of your variables so that you don't load the image every time you want to draw the ship.