Processing Loop - javascript

int objectX = width/2;
int objectY = height/2;
int snelheidY = 1;
int score = 0;
int richting = 1;
int positiebal;
int bal = ellipse(objectX, objectY, 50, 50);
lost = false;
void setup() {
size(400, 400);
positiebal = height/2;
textSize(12);
}
void draw() {
background(0, 0, 0);
ellipse(positiebal, objectY, 50, 50);
if(objectY > 375)
snelheidY = -snelheidY;
if(objectY<25)
snelheidY = -snelheidY;
objectY = objectY + snelheidY;
text("score = " +score,4,10);
if (score < 0)
{ textSize(20);
text("play again",50,50);
noLoop();
lost = true;
textSize = 13;
}
}
void mousePressed() {
int distance = dist(200, objectY, mouseX, mouseY);
if (distance<=25)
//score hoger maken met 1 punt
{ score=score+1;
if (snelheidY < 0)
{ snelheidY = snelheidY -1; }
{ snelheidY = snelheidY+1; }
}
// score met 1 punt lager maken
else
{ score = score - 1;
if (snelheidY > 1)
{ snelheidY = snelheidY -1; }
}
if (lost == true)
{ snelheidY = 1;
score = 0;
positiebal = height/2;
richting = 1;
lost= false;
loop();}
}
I made a loop for the whole process to restart after the score<0, but it doesn't work the second time. The first time it works fine, but the second time it just stops the game without showing the restart text and without restarting.

I wouldn't use loop() and noLoop() for this. Instead, store your state in a set of variables, and use those variables to draw each frame. Here's a simple example:
boolean start = true;
boolean play = false;
boolean end = false;
void draw() {
background(0);
if (start) {
text("start", 20, 20);
} else if (play) {
text("play", 20, 20);
} else if (end) {
text("end", 20, 20);
}
}
void mousePressed() {
if (start) {
start = false;
play = true;
} else if (play) {
play = false;
end = true;
} else if (end) {
end = false;
start = true;
}
}

Related

I am having an issue redrawing some circles onto my html canvas

I am using a basic html canvas to create a simple game using javascript, but I am having an issue while trying to redraw my window. I have created a redraw_window function that I call whenever i want a new frame to show on the screen, but when I try to call the redraw_window function from this location on line 151, it does not work. The screen does not update. Any ideas why?
const c = canvas.getContext("2d")
canvas.width = innerWidth
canvas.height = innerHeight
const random = (min, max) => Math.floor(Math.random() * (max - min)) + min;
class Light {
constructor(pos,vel){
this.pos = pos
this.vel = vel
}
move(){
if (this.pos == 0){
this.vel = 1
}
if(this.pos == 9){
this.vel = -1
}
this.pos += this.vel
}
}
function is_not_in(val,list){
for (var i = 0; i < list.length; i++){
if (list[i] == val){
return false
}
}
return true
}
function clear_window(){
c.clearRect(0,0,canvas.width,canvas.height)
}
function sleep(milliseconds) {
const date = Date.now();
let currentDate = null;
do {
currentDate = Date.now();
} while (currentDate - date < milliseconds);
}
function redraw_window(pos){
c.font = "80px serif"
//let board = [1,1,1,1,1,1,1,1,1,1]
positions = [canvas.width/2-450,canvas.width/2-350,canvas.width/2-250,canvas.width/2-150,canvas.width/2-50,canvas.width/2+50,canvas.width/2+150,canvas.width/2+250,canvas.width/2+350,canvas.width/2+450,]
//board[light.pos] = 0
clear_window()
c.fillStyle = "black"
//c.fillText(board.toString(),canvas.width/2-c.measureText(board.toString()).width/2,canvas.height/2)
//c.fillText("Troy likes big hairy black balls",canvas.width/2-c.measureText("Troy likes big hairy black balls").width/2,canvas.height/2+80)
for (var i = 0; i < positions.length; i++) {
let radius = 20
if (pos != i){
c.beginPath()
c.arc(positions[i],canvas.height/2,radius,0,Math.PI * 2,false)
c.fillStyle = "black"
c.fill()
}
if (pos == i){
c.beginPath()
c.arc(positions[i],canvas.height/2,radius,0,Math.PI * 2,false)
c.fillStyle = "green"
c.fill()
}
}
}
function choose(choices) {
var index = Math.floor(Math.random() * choices.length);
return choices[index];
}
function win_animation(){
redraw_window(null)
sleep(300)
redraw_window(light.pos)
sleep(300)
redraw_window(null)
sleep(300)
redraw_window(light.pos)
}
var light = new Light(random(0,9),choose([-1,1]))
function main(){
var FPS = 60
var SPEED = 0.5
var COOLDOWN = FPS * 0.25
var SCORE_TO_WIN = 5
var right_player_points = 0
var left_player_points = 0
var frame = 0
var right_player_cooldown = 0
var left_player_cooldown = 0
var keys_pressed = []
var right_player_key = "ShiftRight"
var left_player_key = "ShiftLeft"
var right_player_cooldown = 0
var left_player_cooldown = 0
var playing = true
//handles cooldown and keys pressed list
window.addEventListener("keydown",(event)=>{
if (event.code == right_player_key && is_not_in(right_player_key,keys_pressed)){
if (right_player_cooldown == 0){
right_player_cooldown = COOLDOWN
keys_pressed.push(event.code)
}
}
if (event.code == left_player_key && is_not_in(left_player_key,keys_pressed)){
if (left_player_cooldown == 0){
left_player_cooldown = COOLDOWN
keys_pressed.push(event.code)
}
}
})
//runs fps times per second
var run = setInterval(run,1000 / FPS)
function run(){
frame += 1
if (left_player_cooldown > 0){
left_player_cooldown -= 1
}
if (right_player_cooldown > 0){
right_player_cooldown -= 1
}
//runs SPEED times per second
if (frame >= FPS * SPEED){
frame = 0
if (!is_not_in(right_player_key,keys_pressed) && light.pos == 9){
right_player_points += 1
**VVV THIS IS WHERE I AM HAVING MY ISSUE VVV**
redraw_window(null);
alert("right player:" + right_player_points.toString())
if (right_player_points >= SCORE_TO_WIN){
alert("right player Wins")
right_player_points = 0
left_player_points = 0
light = new Light(random(0,9),choose([-1,1]))
}
}
if (!is_not_in(left_player_key,keys_pressed) && light.pos == 0){
left_player_points += 1
light = new Light(random(0,9),choose([-1,1]))
alert("left player:" + left_player_points.toString())
if (left_player_points >= SCORE_TO_WIN){
alert("left player wins")
left_player_points = 0
right_player_points = 0
}
}
light.move()
redraw_window(light.pos)
keys_pressed = []
}
}
}
main() ```
The main issue I can see here is that you have a variable and a function both named run. The setInterval call is being overwritten with the function definition. I recommend you rename the variable run to runInterval.
Change
var run = setInterval(run, 1000 / FPS)
to
var runInterval = setInterval(run, 1000 / FPS)
See if that helps.

Make movement more smooth on Java Script Game | JavaScript Canvas

I am working on very simple java script game. there's a falling random object (trash) and another object for catch the falling object (trash bin). everything seems fine but i wanted to make the movement of the trash bin more smooth. Do you have any idea to fix this? Thanks in Advance
this is my code
window.onload = function(){
var canvas = document.getElementById("canvas");
var context = canvas.getContext("2d");
var canvasBack = document.getElementById("backgroundCanvas");
var contextBack = canvasBack.getContext("2d");
var timer;
//mengatur hiscore
var hiscore = 0;
//Background image, musik and arrays musik.
var background = new Image();
background.src = 'assets/bgw2.jpg';
var catchSounds = [];
var catchSoundCounter = 0;
for(var i = 0; i < 5; i++)
{
var catchSound = new Audio();
catchSound.src = 'Audio/bleep.wav';
catchSounds.push(catchSound);
}
var music = new Audio();
music.src = 'Audio/MarimbaBoy.wav';
music.loop = true;
var smashSounds = [];
var smashCounter = 0;
for(var i = 0; i < 5; i++)
{
var smash = new Audio();
smash.src = 'Audio/smash.mp3';
smashSounds.push(smash);
}
var player;
var fruits = [];
var numberOfFruits = 15;
//Player constructor
function Player()
{
this.gameOver = false;
this.score = 0;
this.fruitsCollected = 0;
this.fruitsMissed = 0;
this.playerWidth = 150;
this.playerHeight = 90;
this.playerSpeed = 10;
this.x = canvas.width / 2;
this.y = canvas.height - this.playerHeight;
this.playerImage = new Image();
this.playerImage.src = 'assets/binn.png';
//Draws the player
this.render = function()
{
context.drawImage(this.playerImage, this.x, this.y);
}
//Moves the player left
this.moveLeft = function()
{
if(this.x > 0)
{
this.x -= this.playerSpeed;
}
}
//Moves the player right
this.moveRight = function()
{
if(this.x < canvas.width - this.playerWidth)
{
this.x += this.playerSpeed;
}
}
}
//Fruit constructor
function Fruit()
{
this.fruitNumber = Math.floor(Math.random() * 5);
this.fruitType = "";
this.fruitScore = 0;
this.fruitWidth = 50;
this.fruitHeight = 50;
this.fruitImage = new Image();
this.fruitSpeed = Math.floor(Math.random() * 2 + 1);
this.x = Math.random() * (canvas.width - this.fruitWidth);
this.y = Math.random() * -canvas.height - this.fruitHeight;
//Creates a different kind of fruit depending on the fruit number
//which is generated randomly
this.chooseFruit = function()
{
if(this.fruitNumber == 0)
{
this.fruitType = "pisang";
this.fruitScore = 5 * this.fruitSpeed;
this.fruitImage.src = 'assets/pisang.png';
}
else if(this.fruitNumber == 1)
{
this.fruitType = "rubbish";
this.fruitScore = 10 * this.fruitSpeed;
this.fruitImage.src = 'assets/rubbish.png';
}
else if(this.fruitNumber == 2)
{
this.fruitType = "botol";
this.fruitScore = 15 * this.fruitSpeed;
this.fruitImage.src = 'assets/botol.png';
}
else if(this.fruitNumber == 3)
{
this.fruitType = "coke";
this.fruitScore = 20 * this.fruitSpeed;
this.fruitImage.src = 'assets/coke.png';
}
else if(this.fruitNumber == 4)
{
this.fruitType = "apple";
this.fruitScore = 25 * this.fruitSpeed;
this.fruitImage.src = 'assets/apple.png';
}
else if(this.fruitNumber == 5)
{
this.fruitType = "papikra";
this.fruitScore = 30 * this.fruitSpeed;
this.fruitImage.src = 'assets/papikra.png';
}
}
//Makes the fruit descend.
//While falling checks if the fruit has been caught by the player
//Or if it hit the floor.
this.fall = function()
{
if(this.y < canvas.height - this.fruitHeight)
{
this.y += this.fruitSpeed;
}
else
{
smashSounds[smashCounter].play();
if(smashCounter == 4)
{
smashCounter = 0;
}
else
{
smashCounter++;
}
player.fruitsMissed += 1;
this.changeState();
this.chooseFruit();
}
this.checkIfCaught();
}
//Checks if the fruit has been caught by the player
//If it is caught, the player score and fruit counter is increased, and
//the current fruit changes its state and becomes a different fruit.
this.checkIfCaught = function()
{
if(this.y >= player.y)
{
if((this.x > player.x && this.x < (player.x + player.playerWidth)) ||
(this.x + this.fruitWidth > player.x && this.x + this.fruitWidth < (player.x + player.playerWidth)))
{
catchSounds[catchSoundCounter].play();
if(catchSoundCounter == 4)
{
catchSoundCounter = 0;
}
else
{
catchSoundCounter++;
}
player.score += this.fruitScore;
player.fruitsCollected += 1;
this.changeState();
this.chooseFruit();
}
}
}
//Randomly updates the fruit speed, fruit number, which defines the type of fruit
//And also changes its x and y position on the canvas.
this.changeState = function()
{
this.fruitNumber = Math.floor(Math.random() * 5);
this.fruitSpeed = Math.floor(Math.random() * 2 + 1);
this.x = Math.random() * (canvas.width - this.fruitWidth);
this.y = Math.random() * -canvas.height - this.fruitHeight;
}
//Draws the fruit.
this.render = function()
{
context.drawImage(this.fruitImage, this.x, this.y);
}
}
//Adds controls. Left arrow to move left, right arrow to move right.
//ENTER to restart only works at the game over screen.
window.addEventListener("keydown", function(e){
e.preventDefault();
if(e.keyCode == 37)
{
player.moveLeft();
}
else if(e.keyCode == 39)
{
player.moveRight();
}
else if(e.keyCode == 13 && player.gameOver == true)
{
main();
window.clearTimeout(timer);
}
});
main();
//Fills an array of fruits, creates a player and starts the game
function main()
{
contextBack.font = "bold 20px Dominique";
contextBack.fillStyle = "WHITE";
player = new Player();
fruits = [];
for(var i = 0; i < numberOfFruits; i++)
{
var fruit = new Fruit();
fruit.chooseFruit();
fruits.push(fruit);
}
startGame();
}
function startGame()
{
updateGame();
window.requestAnimationFrame(drawGame);
}
//Checks for gameOver and makes each fruit in the array fall down.
function updateGame()
{
music.play();
if(player.fruitsMissed >= 10)
{
player.gameOver = true;
}
for(var j = 0; j < fruits.length; j++)
{
fruits[j].fall();
}
timer = window.setTimeout(updateGame, 30);
}
//Draws the player and fruits on the screen as well as info in the HUD.
function drawGame()
{
if(player.gameOver == false)
{
context.clearRect(0, 0, canvas.width, canvas.height);
contextBack.clearRect(0, 0, canvasBack.width, canvasBack.height);
contextBack.drawImage(background, 0, 0);
player.render();
for(var j = 0; j < fruits.length; j++)
{
fruits[j].render();
}
contextBack.fillText("SCORE: " + player.score, 30, 50);
contextBack.fillText("HIGHEST SCORE: " + hiscore, 140, 50);
contextBack.fillText("FRUIT CAUGHT: " + player.fruitsCollected, 320, 50);
contextBack.fillText("FRUIT MISSED: " + player.fruitsMissed, 490, 50);
}
else
{
//Different screen for game over.
for(var i = 0; i < numberOfFruits; i++)
{
console.log("Speed was" + fruits[fruits.length - 1].fruitSpeed);
fruits.pop();
}
if(hiscore < player.score)
{
hiscore = player.score;
contextBack.fillText("NEW HI SCORE: " + hiscore, (canvas.width / 2) - 80, canvas.height / 2);
}
contextBack.fillText("PRESS ENTER TO RESTART", (canvas.width / 2) - 100, canvas.height / 2 + 50);
context.clearRect(0, 0, canvas.width, canvas.height);
}
window.requestAnimationFrame(drawGame);
}
}
First of all, just use one requestAnimationFrame and no other setTimeout code. These can start to run out of sync with each other and it's hard to pause them all when the player wants to pause the game.
Instead, use a counter instead of timeout.
let fruitCounter = 0
function drawGame() {
// all your draw code here
...
// every 60 frames drop a new fruit
fruitCounter++
if(fruitCounter > 60){
fruitCounter = 0
dropNewFruit()
}
// request the new frame unless its game over
if(!gameOver) {
requestAnimationFrame(drawGame)
}
}
Also, if you use keyboard events like this, it will always be choppy because there is a delay when typing on the keyboard (just press a letter for a long time in a text field, you will see that it takes a while until more letters appear)
You can fix this by setting a variable once a key gets pressed.
window.addEventListener("keydown", function(e){
if(e.keyCode == 37){
moveLeft = 1
}
}
window.addEventListener("keyup", function(e){
if(e.keyCode == 37){
moveLeft = 0
}
}
Then, you can use that variable in your animation code
function drawGame() {
// all your draw code here
player.x += moveLeft
// request the new frame unless its game over
if(!gameOver) {
requestAnimationFrame(drawGame)
}
}
These are just a few tips! This has always worked for me when I build a javascript game.

Javascript not counting past 9

So I have this problem where I get my score to update, and then it turns the span text to the next number, but it always seems to stop at 9. I tried adding in more 0s into my original span text, but it just doesn't seem to want to go past 9. If anyone could help me fix this, it would greatly be appreciated.
EDIT: Here is where the problem likely lies:
let currentScore = document.getElementById('currentScore').value = score;
and
checkScore();
I don't really know how to shorten this further, but give pointers to what specifically is causing the problem.
<html>
<head>
</head>
<body onload ="checkScore">
<script>
</script>
<p><span style="color:red">Your</span> <span style="color:orange">current</span> <span style="color:gold">High</span> <span style="color:green">Score</span> <span style="color:blue">is:</span>
<span id="SCORES" style="color:purple">0</span>
<input id="currentScore" type="hidden">
<script>
var cookie;
function setCookie(cname,cvalue,exdays) {
var d = new Date();
d.setTime(d.getTime() + (exdays*365*7*24*60*60*1000));
var expires = "expires=" + d.toGMTString();
cookie = encodeURI(cname + "=" + cvalue + ";" + expires + ";path=/");
}
function getCookie(cname) {
var name = cname + "=";
var decodedCookie = decodeURIComponent(cookie);
var ca = decodedCookie.split(';');
for(var i = 0; i < ca.length; i++) {
var c = ca[i];
while (c.charAt(0) == ' ') {
c = c.substring(1);
}
if (c.indexOf(name) == 0) {
return c.substring(name.length, c.length);
}
}
return "";
}
function checkScore() {
// get current score
let currentScore = document.getElementById('currentScore').value;
//get high score from the "cookie"
let highScore = getCookie('highscore');
// if current score is bigger then high score - set new high score and update cookie
if (highScore < currentScore) {
highScore = currentScore;
setCookie("highscore", highScore, 365);
}
// update DOM
document.getElementById("SCORES").innerHTML = highScore;
}
// set inital cookie for this example to work
setCookie("highscore", -1, 365);
var
COLS = 26,
ROWS = 26,
EMPTY = 0,
SNAKE = 1,
FRUIT = 2,
LEFT = 0,
UP = 1,
RIGHT = 2,
DOWN = 3,
KEY_LEFT = 65,
KEY_UP = 87,
KEY_RIGHT = 68,
KEY_DOWN = 83,
canvas,
ctx,
keystate,
frames,
score;
currentScore;
grid = {
width: null,
height: null,
_grid: null,
init: function(d, c, r) {
this.width = c;
this.height = r;
this._grid = [];
for (var x=0; x < c; x++) {
this._grid.push([]);
for (var y=0; y < r; y++) {
this._grid[x].push(d);
}
}
},
set: function(val, x, y) {
this._grid[x][y] = val;
},
get: function(x, y) {
return this._grid[x][y];
}
}
snake = {
direction: null,
last: null,
_queue: null,
init: function(d, x, y) {
this.direction = d;
this._queue = [];
this.insert(x, y);
},
insert: function(x, y) {
this._queue.unshift({x:x, y:y});
this.last = this._queue[0];
},
remove: function() {
return this._queue.pop();
}
};
function setFood() {
var empty = [];
for (var x=0; x < grid.width; x++) {
for (var y=0; y < grid.height; y++) {
if (grid.get(x, y) === EMPTY) {
empty.push({x:x, y:y});
}
}
}
var randpos = empty[Math.round(Math.random()*(empty.length - 1))];
grid.set(FRUIT, randpos.x, randpos.y);
}
function main() {
canvas = document.createElement("canvas");
canvas.width = COLS*20;
canvas.height = ROWS*20;
ctx = canvas.getContext("2d");
document.body.appendChild(canvas);
ctx.font = "18px Helvetica";
frames = 0;
keystate = {};
document.addEventListener("keydown", function(evt) {
keystate[evt.keyCode] = true;
});
document.addEventListener("keyup", function(evt) {
delete keystate[evt.keyCode];
});
init();
loop();
}
function init() {
score = 0;
currentScore = 0;
grid.init(EMPTY, COLS, ROWS);
var sp = {x:Math.floor(COLS/2), y:ROWS-1};
snake.init(UP, sp.x, sp.y);
grid.set(SNAKE, sp.x, sp.y);
setFood();
}
function loop() {
update();
draw();
window.requestAnimationFrame(loop, canvas);
}
function update() {
frames++;
if (keystate[KEY_LEFT] && snake.direction !== RIGHT) {
snake.direction = LEFT;
}
if (keystate[KEY_UP] && snake.direction !== DOWN) {
snake.direction = UP;
}
if (keystate[KEY_RIGHT] && snake.direction !== LEFT) {
snake.direction = RIGHT;
}
if (keystate[KEY_DOWN] && snake.direction !== UP) {
snake.direction = DOWN;
}
if (frames%5 === 0) {
var nx = snake.last.x;
var ny = snake.last.y;
switch (snake.direction) {
case LEFT:
nx--;
break;
case UP:
ny--;
break;
case RIGHT:
nx++;
break;
case DOWN:
ny++;
break;
}
if (0 > nx || nx > grid.width-1 ||
0 > ny || ny > grid.height-1 ||
grid.get(nx, ny) === SNAKE
) {
return init();
}
if (grid.get(nx, ny) === FRUIT) {
score++;
let currentScore = document.getElementById('currentScore').value = score;
checkScore();
setFood();
} else {
var tail = snake.remove();
grid.set(EMPTY, tail.x, tail.y);
}
grid.set(SNAKE, nx, ny);
snake.insert(nx, ny);
}
}
function draw() {
var tw = canvas.width/grid.width;
var th = canvas.height/grid.height;
for (var x=0; x < grid.width; x++) {
for (var y=0; y < grid.height; y++) {
switch (grid.get(x, y)) {
case EMPTY:
ctx.fillStyle = "#000";
break;
case SNAKE:
ctx.fillStyle = "#4aa024";
break;
case FRUIT:
ctx.fillStyle = "#f00";
break;
}
ctx.fillRect(x*tw, y*th, tw, th);
}
}
ctx.fillStyle = "#49c2ff";
ctx.fillText("SCORE: " + score, 10, canvas.height-10);
}
main();
</script>
</body>
</html>
I am not sure why you are updating currentScore input it is a hidden input. I changed all document.getElementById('currentScore') selectors to document.getElementById('SCORES') because span is where you are actually showing the highscore.
I will post on why it was stopping at 9 with your previous code soon.
<html>
<head>
</head>
<body onload ="checkScore">
<script>
</script>
<p><span style="color:red">Your</span> <span style="color:orange">current</span> <span style="color:gold">High</span> <span style="color:green">Score</span> <span style="color:blue">is:</span>
<span id="SCORES" style="color:purple">0</span>
<input id="currentScore" type="hidden">
<script>
var cookie;
function setCookie(cname,cvalue,exdays) {
var d = new Date();
d.setTime(d.getTime() + (exdays*365*7*24*60*60*1000));
var expires = "expires=" + d.toGMTString();
cookie = encodeURI(cname + "=" + cvalue + ";" + expires + ";path=/");
}
function getCookie(cname) {
var name = cname + "=";
var decodedCookie = decodeURIComponent(cookie);
var ca = decodedCookie.split(';');
for(var i = 0; i < ca.length; i++) {
var c = ca[i];
while (c.charAt(0) == ' ') {
c = c.substring(1);
}
if (c.indexOf(name) == 0) {
return c.substring(name.length, c.length);
}
}
return "";
}
function checkScore() {
// get current score
let currentScore = parseInt(document.getElementById('SCORES').innerHTML);
//get high score from the "cookie"
let highScore = getCookie('highscore');
// if current score is bigger then high score - set new high score and update cookie
if (highScore < currentScore) {
highScore = currentScore;
setCookie("highscore", highScore, 365);
}
// update DOM
document.getElementById("SCORES").innerHTML = highScore;
}
// set inital cookie for this example to work
setCookie("highscore", -1, 365);
var
COLS = 26,
ROWS = 26,
EMPTY = 0,
SNAKE = 1,
FRUIT = 2,
LEFT = 0,
UP = 1,
RIGHT = 2,
DOWN = 3,
KEY_LEFT = 65,
KEY_UP = 87,
KEY_RIGHT = 68,
KEY_DOWN = 83,
canvas,
ctx,
keystate,
frames,
score;
currentScore;
grid = {
width: null,
height: null,
_grid: null,
init: function(d, c, r) {
this.width = c;
this.height = r;
this._grid = [];
for (var x=0; x < c; x++) {
this._grid.push([]);
for (var y=0; y < r; y++) {
this._grid[x].push(d);
}
}
},
set: function(val, x, y) {
this._grid[x][y] = val;
},
get: function(x, y) {
return this._grid[x][y];
}
}
snake = {
direction: null,
last: null,
_queue: null,
init: function(d, x, y) {
this.direction = d;
this._queue = [];
this.insert(x, y);
},
insert: function(x, y) {
this._queue.unshift({x:x, y:y});
this.last = this._queue[0];
},
remove: function() {
return this._queue.pop();
}
};
function setFood() {
var empty = [];
for (var x=0; x < grid.width; x++) {
for (var y=0; y < grid.height; y++) {
if (grid.get(x, y) === EMPTY) {
empty.push({x:x, y:y});
}
}
}
var randpos = empty[Math.round(Math.random()*(empty.length - 1))];
grid.set(FRUIT, randpos.x, randpos.y);
}
function main() {
canvas = document.createElement("canvas");
canvas.width = COLS*20;
canvas.height = ROWS*20;
ctx = canvas.getContext("2d");
document.body.appendChild(canvas);
ctx.font = "18px Helvetica";
frames = 0;
keystate = {};
document.addEventListener("keydown", function(evt) {
keystate[evt.keyCode] = true;
});
document.addEventListener("keyup", function(evt) {
delete keystate[evt.keyCode];
});
init();
loop();
}
function init() {
score = 0;
currentScore = 0;
grid.init(EMPTY, COLS, ROWS);
var sp = {x:Math.floor(COLS/2), y:ROWS-1};
snake.init(UP, sp.x, sp.y);
grid.set(SNAKE, sp.x, sp.y);
setFood();
}
function loop() {
update();
draw();
window.requestAnimationFrame(loop, canvas);
}
function update() {
frames++;
if (keystate[KEY_LEFT] && snake.direction !== RIGHT) {
snake.direction = LEFT;
}
if (keystate[KEY_UP] && snake.direction !== DOWN) {
snake.direction = UP;
}
if (keystate[KEY_RIGHT] && snake.direction !== LEFT) {
snake.direction = RIGHT;
}
if (keystate[KEY_DOWN] && snake.direction !== UP) {
snake.direction = DOWN;
}
if (frames%5 === 0) {
var nx = snake.last.x;
var ny = snake.last.y;
switch (snake.direction) {
case LEFT:
nx--;
break;
case UP:
ny--;
break;
case RIGHT:
nx++;
break;
case DOWN:
ny++;
break;
}
if (0 > nx || nx > grid.width-1 ||
0 > ny || ny > grid.height-1 ||
grid.get(nx, ny) === SNAKE
) {
return init();
}
if (grid.get(nx, ny) === FRUIT) {
score++;
let currentScore = document.getElementById('SCORES').innerHTML = score;
checkScore();
setFood();
} else {
var tail = snake.remove();
grid.set(EMPTY, tail.x, tail.y);
}
grid.set(SNAKE, nx, ny);
snake.insert(nx, ny);
}
}
function draw() {
var tw = canvas.width/grid.width;
var th = canvas.height/grid.height;
for (var x=0; x < grid.width; x++) {
for (var y=0; y < grid.height; y++) {
switch (grid.get(x, y)) {
case EMPTY:
ctx.fillStyle = "#000";
break;
case SNAKE:
ctx.fillStyle = "#4aa024";
break;
case FRUIT:
ctx.fillStyle = "#f00";
break;
}
ctx.fillRect(x*tw, y*th, tw, th);
}
}
ctx.fillStyle = "#49c2ff";
ctx.fillText("SCORE: " + score, 10, canvas.height-10);
}
main();
</script>
</body>
</html>

snake game collision with itself

I have made a snake game with processign.js and im trying to make the collision with itself. The problem is that it isnt working as it should.
var screen = 0;
var bg = color(60,150,60);
var snake;
var apple;
var bonus;
var nBonus = 0;
var gameOver = false;
var appleSize = 10;
var applePosX = round(random(10,width-appleSize)/10)*10;
var applePosY = round(random(10,height-appleSize)/10)*10;
var keys = [];
void keyPressed() {
keys[keyCode] = true;
};
void keyReleased() {
keys[keyCode] = false;
};
frameRate(10);
// collision with itself
// -----------------------------------------------------------------------
// ------------------------------- THE SNAKE -----------------------------
var Snake = function(x, y) {
this.x = x;
this.y = y;
this.len = 1;
this.size = 10;
this.snakePosX = 0;
this.snakePosY = 0;
this.points = 0;
this.positions = [];
this.moving = false;
this.apples = 0;
for(var i=0; i<this.len; i++) {
var posX = this.x-i*10;
var posY = this.y;
this.positions[i] = {x:posX, y:posY};
}
};
Snake.prototype.draw = function() {
fill(0);
stroke(255,255,255);
for(var i=0; i<this.positions.length; i++) {
rect(this.positions[i].x, this.positions[i].y, this.size, this.size);
}
};
Snake.prototype.move = function() {
if(gameOver === false) {
if(keys[UP]) {
this.snakePosY = -this.size;
this.snakePosX = 0;
this.moving = true;
}
if(keys[DOWN]) {
this.snakePosY = this.size;
this.snakePosX = 0;
this.moving = true;
}
if(keys[LEFT]) {
this.snakePosX = -this.size;
this.snakePosY = 0;
this.moving = true;
}
if(keys[RIGHT]) {
this.snakePosX = this.size;
this.snakePosY = 0;
this.moving = true;
}
}
if(this.moving == true) {
if(snake.positions.length == 1) {
this.positions[0].x += this.snakePosX;
this.positions[0].y += this.snakePosY;
}
else {
for(var i=1; i<this.positions.length; i++) {
this.positions[i-1].x = this.positions[i].x;
this.positions[i-1].y = this.positions[i].y;
this.positions[i].x += this.snakePosX;
this.positions[i].y += this.snakePosY;
}
}
}
};
Snake.prototype.checkColl = function() {
// collision with itself
if(this.positions.length>1) {
for(var i=0; i<this.positions.length; i++) {
if(this.positions[0].x > 350) {
text('holly crap', 100, 100);
}
}
}
// collision with walls
if(this.positions[0].x > width-this.size || this.positions[0].x < 0 || this.positions[0].y > height-this.size || this.positions[0].y < 0) {
gameOver = true;
gameIsOver();
}
// collision with apples
for(var i=0; i<this.positions.length; i++) {
if(this.positions[i].x >= apple.x && this.positions[i].x+10 <= apple.x+10 && this.positions[i].y >= apple.y && this.positions[i].y+10 <= apple.y+10) {
apple.draw();
this.apples ++;
this.points += 10;
this.positions.unshift({x:apple.x, y:apple.y});
apple.x = round(random(10,width-appleSize)/10)*10;
apple.y = round(random(10,height-appleSize)/10)*10;
if(this.apples > 1 && this.apples % 5 == 0) {
nBonus = 1;
}
}
}
// collision with bonus
if(this.positions[0].x >= bonus.x && this.positions[0].x+10 <= bonus.x+10 && this.positions[0].y >= bonus.y && this.positions[0].y+10 <= bonus.y+10) {
if(this.moving) {
bonus.x = round(random(10,width-appleSize)/10)*10;
bonus.y = round(random(10,height-appleSize)/10)*10;
nBonus = 0;
this.points += 10;
}
}
};
// ------------------------ THE APPLES -----------------------------------
var Apple = function(x, y) {
this.x = x;
this.y = y;
};
Apple.prototype.draw = function() {
fill(255,0,0);
noStroke();
rect(this.x, this.y, appleSize, appleSize);
};
// ------------------------ THE BONUS -----------------------------------
var Bonus = function(x, y) {
this.x = x;
this.y = y;
}
Bonus.prototype.draw = function() {
fill(150,0,0);
stroke(255,255,255)
rect(this.x, this.y, appleSize, appleSize);
};
// -----------------------------------------------------------------------
snake = new Snake(width/2, height/2);
apple = new Apple(applePosX, applePosY);
bonus = new Bonus(width/2, height/2);
// -----------------------------------------------------------------------
void gameIsOver() {
fill(0);
textAlign(CENTER);
text("Game Over\nPress 'S' to play again", width/2, height/2);
textAlign(LEFT);
if(keys[83]) {
screen = 2;
gameOver = false;
}
}
void playGame() {
if(screen === 0) {
if(mouseX >= width/2-50 && mouseY <= width/2+50 && mouseY >= height/2-15 && mouseY <= height/2+15) {
if(mousePressed) {
screen = 1;
}
}
}
}
void makeScreen() {
if(screen === 0) {
textAlign(CENTER);
textSize(30);
text('SNAKE GAME', width/2, 100);
stroke(255,255,255);
noFill();
rectMode(CENTER);
rect(width/2, height/2, 100, 30);
textSize(15);
text('Play', width/2, height/2+5);
textSize(11);
text('By Eskimopest', width/2, height-20);
textAlign(LEFT);
rectMode(LEFT);
playGame();
}
if(screen === 1) {
snake.draw();
snake.move();
snake.checkColl();
apple.draw();
if(nBonus === 1) {
bonus.draw();
}
fill(0);
text('POINTS : '+ snake.points, 10, 20);
text('APPLES : '+ snake.apples, 10, 40);
}
if(screen === 2) {
snake.points = 0;
snake.apples = 0;
snake.x = width/2;
snake.y = height/2;
snake.len = 1;
snake.positions = [{x:snake.x, y:snake.y}];
snake.snakePosX = 0;
snake.snakePosY = 0;
applePosX = round(random(10,width-appleSize)/10)*10;
applePosY = round(random(10,height-appleSize)/10)*10;
screen = 1;
}
}
// -----------------------------------------------------------------------
void draw() {
background(bg);
makeScreen();
for(var i=0; i<snake.positions.length; i++) {
text(i + 'x:'+snake.positions[i].x + ' y:'+snake.positions[i].y, 600, 20+i*10);
}
}
The problem is in snake.prototype.checkColl and I'm trying to make this work but with no results. When I try to make
if(this.positions[0].x = this.positions[i].x)
nothing happens. If anyone could help me I would be very appreciated.
That should be:
if(this.positions[0].x == this.positions[i].x)
Using a single = is doing an assignment. You want to do a comparison, so you need double ==.

How to determine what JavaScript causes a browser crash?

I'm brand new to JavaScript, and have a crashing application. I have no idea what would cause the crash.
Here is the code:
<script>
//constants
var Col = 20, Rows = 20;
var cellHeight = 25;
var cellWidth = 25;
var foodX;
var score;
var foodY;
var Nothing = 0, Snake = 1, Food = 2;
var Left = 37, Up = 38, Right = 39, Down = 40;
var canvas = document.getElementById('snakeCanvas');
var context = canvas.getContext('2d');
var dead = "false";
var snakeDirection = null;
var keystate;
var snake = [];
function start() //this is where we begin the long journey
{
init();
Tick();
}
function init() {
snake = [{ x: 5, y: 5 }];
snakeDirection = null;
score = 0;
document.getElementById("score").innerHTML = "Score: " + score;
setFood();
keystate = null;
}
function Tick() // just liker a timer tick
{
document.addEventListener("keydown", function (evt) {
keystate = evt.keyCode; // checks key presses
});
//document.addEventListener("keyup", function (evt) {
//delete keystate[evt.keyCode];
//});
update(); //after we check for a key press we update alllll the
stuff
setTimeout(Tick, 300);
//}
}
function update()
{
checkKey(); // checks what key has been pressed
for (var i = snake.length-1; i > 0; i--) {
snake[i].y = snake[i-1].y;
snake[i].x = snake[i-1].x
}
switch (snakeDirection) { // keys
case "DOWN":
snake[0].y++;
break;
case "UP":
snake[0].y--;
break;
case "RIGHT":
snake[0].x++;
break;
case "LEFT":
snake[0].x--;
break;
}
draw(); //draws all the stuff like food and snake
checkCollisions(); // self explaintory name
}
function checkKey() //Change the direction of the snake cant go
backwards too
{
if (keystate == Left && snakeDirection != "RIGHT" )
{
snakeDirection = "LEFT";
}
if (keystate == Up && snakeDirection != "DOWN")
{
snakeDirection = "UP";
}
if (keystate == Right && snakeDirection != "LEFT")
{
snakeDirection = "RIGHT";
}
if (keystate == Down && snakeDirection != "UP")
{
snakeDirection = "DOWN";
}
}
function setFood()
{ //WE ARE RUNNING OUT OF FOOD WE NEED NEW PROVISIONS
var next = "true"
do {
foodX = Math.floor((Math.random() * Rows));
foodY = Math.floor((Math.random() * Col));
for (var i = 0; i < snake.length; i++) { // IT SUCKS WHEN I
CANT EAT FOOD BECAUSE ITS ALREADY INSIDE OF ME
if (snake[i].x == foodX && snake[i].y == foodY) {
next = "false"
}
}
}
while (next == "false")
draw(); // Pretty pictures
}
function checkCollisions()
{
for (var i = 1; i < snake.length; i++) { // STOP hitting
yourself
if (snake[0].x == snake[i].x && snake[0].y == snake[i].y) {
init();
}
}
if (snake[0].y < 0 || snake[0].y > Rows || snake[0].x < 0 ||
snake[0].x > Col) // you are forbidon to veture from the canvas
{
init();
}
if (snake[0].x == foodX && snake[0].y == foodY) { //Yummy FOOD EAT
EAT EAT
score++;
document.getElementById("score").innerHTML = "Score: " + score;
setFood();
snake.push({ x: null, y: null }); // I got fatter
}
}
function draw()
{
context.clearRect(0, 0, canvas.width, canvas.height); // clears
canvas
context.fillStyle = "#FF0000"; // pretty colour for the head of
the snake
context.fillRect(snake[0].x * cellWidth, snake[0].y * cellWidth,
cellWidth, cellHeight);
context.fillStyle = "#09F";
for (var i = 1; i < snake.length; i++)
{
context.fillRect(snake[i].x * cellWidth, snake[i].y * cellWidth,
cellWidth, cellHeight);
}
context.fillStyle = "#F90"; // FOOD FOOD FOOD FOOD
context.fillRect(foodX * cellWidth, foodY * cellWidth, cellWidth,
cellHeight);
}
start(); // starts hence the name start
</script>
OK not bad for a beginer if you wrote it all your self.
Your problem is with the keydown event. You are creating a new handler each time you tick. This will lead to a crash. You only need to create the event handler once for the page, it will remain active until you leave the page.
To fix your problem move adding the keyDown listener to just above the function Start, as shown below.
var snake = [];
document.addEventListener("keydown", function (evt) {
keystate = evt.keyCode; // checks key presses
});
function start(){
init();
Tick();
}
Also just a because to me it looks weird. true and false are not strings you dont need to put quotes around them. Though using them as strings still works.
You have
function setFood() { //WE ARE RUNNING OUT OF FOOD WE NEED NEW PROVISIONS
var next = "true"
do {
foodX = Math.floor((Math.random() * Rows));
foodY = Math.floor((Math.random() * Col));
for (var i = 0; i < snake.length; i++) {
if (snake[i].x == foodX && snake[i].y == foodY) {
next = "false"
}
}
} while (next == "false")
draw();
}
would be better written as follows
function setFood() {
var next = true; // removed the qoutes
do {
foodX = Math.floor((Math.random() * Rows));
foodY = Math.floor((Math.random() * Col));
for (var i = 0; i < snake.length; i++) {
if (snake[i].x == foodX && snake[i].y == foodY) {
next = false; // removed the quotes.
// no point continuing the for loop as you know you need to
// reposition the food so use the break token
break; // breaks out of the closest loop
}
}
} while ( !next ) // removed next == "false" and replaced with
// ! next. "!" means "Not". do while next not true
// you have the draw here but you draw every tick so it would be best if
// you removed it as the next draw is less than 1/3 of a second away anyways
// draw(); // removed needless draw
}
Good work. Hope you get a good mark for it.

Categories

Resources