I have a snake game made using JavaScript using Node.js and sockets.
When a food spawns, I want there to be a 21/25 chance it being green, a 3/25 chance of it being red, and a 1/25 chance of it being yellow.
If there is more than 1 food in the array and the player eats a green one, I want it to disappear.
And:
If a player eats a green food, they gain 10 points and another food spawns.
If a player eats a red food, the player gains 50 points and 3 green food spawn.
If the player eats a yellow food, they gain 200 points and 5 green food spawn.
It’s working fine, except for when there’s more than 1 green food on the screen and the player eats one, sometimes several food disappear or sometimes they all disappear.
Why is this happening?
var FoodList = [];
SpawnFood(10, 1); //Spawn a default peice of food
function SpawnFood(Value, Amount) //Add a Food to the board
{
for (var i = 0; i < Amount; i++) {
var j = i;
if (FoodList.length == 0) {
FoodList[j] = new Food(); //If there is no food in the array, spawn one
FoodList[j].init();
FoodList[j].FoodValue = Value;
j++
} else { //if there is food in the array
while (FoodList[j] !== undefined) { //choose the lowest empty place
j++
}
FoodList[j] = new Food(); //And then spawn in
FoodList[j].init();
FoodList[j].FoodValue = Value;
}
}
}
//Collision detection below :
for (var i in SnakeList) //For each instance of snake
{
var snake = SnakeList[i]; //Declare snake as the current snake
for (var j in FoodList) //For each instance of Food
{
if (snake.hasColision(FoodList[j])) //If they have collided
{
snake.addLength(); //Removes the Food and adds length to the current snake
snake.eatFood(FoodList[j]); //Rewards the player with score)
var Value = FoodList[j].FoodValue; //Asking it what score value the food has
delete FoodList[j]; //Deletes that food
var count = 0;
for (var s in FoodList) //For each instance of Food
{
count++;
} //Counts how many peices of food are in the array (.length doesnt work)
if (Value == 10) { //If the player ate a green food
if (count < 1) { //And theres more than 1 food in the array
var RandomNumber = Math.round(Math.random() * (25 - 1) + 1); //Generate a random num
if ((RandomNumber >= 1) && (RandomNumber <= 21)) //common drop, green food
{
SpawnFood(10, 1); //Soawn green food
} else if ((RandomNumber >= 22) && (RandomNumber <= 24)) //rare red
{
SpawnFood(50, 1); //spawn red
} else {
SpawnFood(200, 1); //spawn very rare yellow
}
}
} else if (Value == 50) { //If the player ate a red, spawn 3 green
SpawnFood(10, 3);
} else if (Value == 200) { //If the player ate a yellow, spawn 5 green
SpawnFood(10, 5);
}
}
}
}
Advertisement
Answer
Here is how you should do it: (I don’t know about SnakeList but it should be an array as well, if it’s not then follow the same approach as for FoodList)
var FoodList = [];
SpawnFood(10, 1);
// remove food from index
function removeFood(index){
// cut that element out of the array (Read more about splice)
FoodList.splice(index, 1);
}
// spawn an amount of food by calling spawnOneFood an amount of times
function SpawnFood(Value, Amount) {
for (var i = 0; i < Amount; i++) {
// create a new food
var f = new Food();
f.init();
f.FoodValue = Value;
// add it to FoodList
FoodList.push(f);
}
}
// get random value (it good practice to split diferent logics into diferent function)
function getRandomValue(){
var RandomNumber = Math.round(Math.random() * (25 - 1) + 1);
// no need to check if it's greater than 1 (it is)
if (RandomNumber <= 21)
return 10;
// no need to check if it's greater than 22 (it is)
else if (RandomNumber <= 24)
return 50;
// no need for else (if we are here then the above tests failed) (if you get a yellow food go straight to a casino because you're lucky as hell)
return 200;
}
// SnakeList should be an array too. (for(var i = 0; i < SnakeList.length; i++))
for (var i in SnakeList)
{
var snake = SnakeList[i];
for (var j = 0; j < FoodList.length; j++) //For each instance of Food
{
if (snake.hasColision(FoodList[j]))
{
snake.addLength();
snake.eatFood(FoodList[j]);
var Value = FoodList[j].FoodValue;
removeFood(j);
j--; // removeFood actually shrinks the array so we need to go backwards one step to handle all elements
// This should work now
var count = FoodList.length;
if (Value == 10) {
if (count < 1) {
var randomValue = getRandomValue();
SpawnFood(randomValue, 1);
}
} else if (Value == 50) {
SpawnFood(10, 3);
} else if (Value == 200) { // as I said: LUCKY AS HELL
SpawnFood(10, 5);
}
}
}
}