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