Splice function

Hi all,

I’m trying to use the splice function for an array as described here and here but it’s not working in my code. I’ve implemented it on line 161. Does anyone have any insights?

Thanks!

Here’s a link to the code online.

And here’s the code

// Creating a score!
// Adding a score to the game.

let hayley;
let gremlin_Ob = new Array(1); //we're going to start the game with only one zombie now, and add to it over time to make the game increase in difficulty

let playerFrames = new Array(9);
let zombieFrames = new Array(6);

let INTRO = 0;
let RUN_GAME = 1;
let GAME_OVER = 2;
let gameState = INTRO;

let score = 0;
let zombieCount = 1; //create a new variable that keeps track of how many zombies there are


function preload() {
	for (let i = 0; i < playerFrames.length; i++) {
		playerFrames[i] = loadImage("Mplayer-" + i + ".png");
	}
	for (let i = 0; i < zombieFrames.length; i++) {
		zombieFrames[i] = loadImage("zombie-" + i + ".png");
	}
}

function setup() {
	createCanvas(500, 500);
	imageMode(CENTER);
	noCursor();
	hayley = new Player();
	gremlin_Ob[0] = new Zombie(); //instead of creating lots of zombies, we're just creating one by filling the first index in the zombie array
}

function draw() {
	if (gameState == INTRO) intro();
	else if (gameState == RUN_GAME) runGame();
	else if (gameState == GAME_OVER) gameOver();
}





// --------- CLASSES -------------------------------------------------------------------------------------------- //
// --------- PLAYER CLASS ------------------------------------------------------- //
class Player {
	constructor() {
		this.x = 0;
		this.y = 0;
		this.radius = 30;
		this.frame = 0;
		this.flip = 1;
	}
	display() {
		push();
		translate(this.x, this.y);
		scale(this.flip, 1);
		image(playerFrames[this.frame], 0, 0);
		pop();
	}
	move() {
		this.x = mouseX;
		this.y = mouseY;
		if (mouseX > pmouseX) this.flip = 1;
		if (mouseX < pmouseX) this.flip = -1;
		if (frameCount % 4 == 0) this.frame++;
		if (this.frame >= playerFrames.length) this.frame = 0;
	}
}

// --------- ZOMBIE CLASS --------------------------------------------------------//
class Zombie {
	constructor() {
		this.x = random(width);
		this.y = random(height);
		this.speedX = random(-2, 2);
		this.speedY = random(-2, 2);
		this.radius = 30;
		this.frame = 0;

		while (collision(this, hayley) == true) {
			this.x = random(width);
			this.y = random(height);
		}
	}
	display() {
		push();
		translate(this.x, this.y);
		if (this.speedX < 0) scale(-1, 1);
		image(zombieFrames[this.frame], 0, 0);
		pop();
	}
	move() {
		this.x += this.speedX;
		this.y += this.speedY;
		if (this.x < 0 || this.x > width) this.speedX *= -1;
		if (this.y < 0 || this.y > height) this.speedY *= -1;
		if (frameCount % 4 == 0) this.frame++;
		if (this.frame >= zombieFrames.length) this.frame = 0;
	}
}





// --------- GAME STATES ---------------------------------------------------------------------------------------- //
// --------- INTRO STATE ---------- //
function intro() {
	background(255, 0, 0);
	textSize(48);
	textAlign(CENTER, BOTTOM);
	text("ZOMBIE APOCALYPSE", width / 2, height / 2);
	textSize(16);
	text("Click anywhere to start", width / 2, height / 2 + height / 4);
	changeStates();
}

// -------- RUN_GAME STATE ---------- //
function runGame() {
	
	
	
	background(0);
	hayley.move();
	hayley.display();

	for (i = 0; i < gremlin_Ob.length; i++) {
		gremlin_Ob[i].move();
		gremlin_Ob[i].display();
	}

	for (i = 0; i < gremlin_Ob.length; i++) {
		if (collision(gremlin_Ob[i], hayley) == true) {
			gameState = GAME_OVER; // instead of saying 'OUCH!' we now end the game by going to the game over function
		}
	}

	score++;
	drawScore(); 

	if (score % 100 == 0) {	//if the score is a multiple of 100 ...
		gremlin_Ob[zombieCount] = new Zombie(); //... add a zombie
		zombieCount++; //increase the zombieCount by 1
	}
}

// -------- GAME_OVER STATE ---------- // //we've added content to the game over state
function gameOver() {
	background(0);
	changeStates(); //if the user clicks, they go back into the run game state
	background(0);
	fill(255);
	textAlign(CENTER);
	textSize(48);
	text("GAME OVER!!", width / 2, height / 2); //new text: Game Over!
	
	zombieCount = 1; //reset the zombie counter to 1
	var removed = Zombie.splice(0); //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< NOT WORKING
	
	drawScore(); //the score is drawn but now it's not updated (score++) so that the user can see their final score
}





// --------- OTHER FUNCTIONS ------------------------------------------------------------------------------------- //
// --------- COLLISION ---------- //
function collision(temp_zombie, temp_player) {
	let d = dist(temp_player.x, temp_player.y, temp_zombie.x, temp_zombie.y);
	if (d < temp_player.radius + temp_zombie.radius) {
		return true;
	} else {
		return false;
	}
}

// --------- CHANGE STATES ---------- //
function changeStates() {
	if (mouseIsPressed) {
		if (gameState == INTRO || gameState == GAME_OVER) {
			gameState = RUN_GAME;
		}
	}
}

// --------- DRAW SCORE ---------- //
function drawScore() {
	fill(0, 255, 0);
	textSize(16);
	textAlign(LEFT);
	text(score, 10, 20);
}
3 Likes

when you reset the whole thing just say

gremlin_Ob = new Array(1);

?

Can’t test it here

No, I’m afraid not. I get this error:
mySketch, line 131:Uncaught TypeError: Cannot read property ‘move’ of undefined

var removed = Zombie.splice(0);

  • Zombie is a class constructor not an array!
  • The array you’re storing Zombie instances is gremlin_Ob[].
  • If you just wanna empty a JS array, assign 0 to its length: gremlin_Ob.length = 0;
  • Also, there’s no need for a separate zombieCount, given an array already got a builtin length!
function gameOver() {
  // ...

  gremlin_Ob.length = 0;
  gremlin_Ob.push(new Zombie);

  // ...
}
3 Likes

Thanks GoToLoop :slight_smile: Yes! I gapped on the difference between the Zombie class and the gremlin_Ob[] array. Thanks for seeing that. And I ended up being able to make it just one line (although I kept the zombieCount):

gremlin_Ob.length = 1;
1 Like

It took me some time to find out gremlin_Ob[] was the Zombie array. :timer_clock:

A better descriptive name like zombies[] would’ve surely helped me there. :zombie:

Would there be any time where zombieCount would be diff. to gremlin_Ob[]'s length? :thinking:

1 Like

Thanks for your feedback GoToLoop!

I’ve changed the code to reflect your suggestions. This is the updated code, which removes the zombieCount and renames the player object and the zombie array.

// 10.4
// Creating a score!
// Adding a score to the game.

let playerObject_Kate;
let objectArray_Zombie = new Array(1); //we're going to start the game with only one zombie now, and add to it over time to make the game increase in difficulty

let playerFrames = new Array(9);
let zombieFrames = new Array(6);

let INTRO = 0;
let RUN_GAME = 1;
let GAME_OVER = 2;
let gameState = INTRO;

let score = 0;


function preload() {
  for (let i = 0; i < playerFrames.length; i++) {
    playerFrames[i] = loadImage("Mplayer-" + i + ".png");
  }
  for (let i = 0; i < zombieFrames.length; i++) {
    zombieFrames[i] = loadImage("zombie-" + i + ".png");
  }
}

function setup() {
  createCanvas(500, 500);
  imageMode(CENTER);
  noCursor();
  playerObject_Kate = new PlayerClass();
  objectArray_Zombie[0] = new ZombieClass(); //instead of creating lots of zombies, we're just creating one by filling the first index in the zombie array
}

function draw() {
  if (gameState == INTRO) intro();
  else if (gameState == RUN_GAME) runGame();
  else if (gameState == GAME_OVER) gameOver();
}





// --------- CLASSES -------------------------------------------------------------------------------------------- //
// --------- PLAYER CLASS ------------------------------------------------------- //
class PlayerClass {
  constructor() {
    this.x = 0;
    this.y = 0;
    this.radius = 30;
    this.frame = 0;
    this.flip = 1;
  }
  display() {
    push();
    translate(this.x, this.y);
    scale(this.flip, 1);
    image(playerFrames[this.frame], 0, 0);
    pop();
  }
  move() {
    this.x = mouseX;
    this.y = mouseY;
    if (mouseX > pmouseX) this.flip = 1;
    if (mouseX < pmouseX) this.flip = -1;
    if (frameCount % 4 == 0) this.frame++;
    if (this.frame >= playerFrames.length) this.frame = 0;
  }
}

// --------- ZOMBIE CLASS --------------------------------------------------------//
class ZombieClass {
  constructor() {
    this.x = random(width);
    this.y = random(height);
    this.speedX = random(-2, 2);
    this.speedY = random(-2, 2);
    this.radius = 30;
    this.frame = 0;

    while (collision(this, playerObject_Kate) == true) {
      this.x = random(width);
      this.y = random(height);
    }
  }
  display() {
    push();
    translate(this.x, this.y);
    if (this.speedX < 0) scale(-1, 1);
    image(zombieFrames[this.frame], 0, 0);
    pop();
  }
  move() {
    this.x += this.speedX;
    this.y += this.speedY;
    if (this.x < 0 || this.x > width) this.speedX *= -1;
    if (this.y < 0 || this.y > height) this.speedY *= -1;
    if (frameCount % 4 == 0) this.frame++;
    if (this.frame >= zombieFrames.length) this.frame = 0;
  }
}





// --------- GAME STATES ---------------------------------------------------------------------------------------- //
// --------- INTRO STATE ---------- //
function intro() {
  background(255, 0, 0);
  textSize(48);
  textAlign(CENTER, BOTTOM);
  text("ZOMBIE APOCALYPSE", width / 2, height / 2);
  textSize(16);
  text("Click anywhere to start", width / 2, height / 2 + height / 4);
  changeStates();
}

// -------- RUN_GAME STATE ---------- //
function runGame() {
  background(0);
  playerObject_Kate.move();
  playerObject_Kate.display();

  for (i = 0; i < objectArray_Zombie.length; i++) {
    objectArray_Zombie[i].move();
    objectArray_Zombie[i].display();
  }

  for (i = 0; i < objectArray_Zombie.length; i++) {
    if (collision(objectArray_Zombie[i], playerObject_Kate) == true) {
      gameState = GAME_OVER; // instead of saying 'OUCH!' we now end the game by going to the game over function
    }
  }

  score++;
  drawScore();

  if (score % 100 == 0) { //if the score is a multiple of 100 ...
    objectArray_Zombie[objectArray_Zombie.length] = new ZombieClass(); //... add a zombie
  }
}

// -------- GAME_OVER STATE ---------- // //we've added content to the game over state
function gameOver() {
  background(0);
  changeStates(); //if the user clicks, they go back into the run game state
  background(0);
  fill(255);
  textAlign(CENTER);
  textSize(48);
  text("GAME OVER!!", width / 2, height / 2); //new text: Game Over!

  zombieCount = 1; //reset the zombie counter to 1
  objectArray_Zombie.length = 1; //reset the length of the objectArray_Zombie array to 1 (now there will just be one index in the Zombie object again)
  drawScore(); //the score is drawn (but not updated with score++) so that the user can see their final score
}





// --------- OTHER FUNCTIONS ------------------------------------------------------------------------------------- //
// --------- COLLISION ---------- //
function collision(tempZombieObject, tempPlayerObject) {
  let d = dist(tempPlayerObject.x, tempPlayerObject.y, tempZombieObject.x, tempZombieObject.y);
  if (d < tempPlayerObject.radius + tempZombieObject.radius) {
    return true;
  } else {
    return false;
  }
}

// --------- CHANGE STATES ---------- //
function changeStates() {
  if (mouseIsPressed) {
    if (gameState == INTRO || gameState == GAME_OVER) {
      gameState = RUN_GAME;
      score = 0; //reset the score to 0
    }
  }
}

// --------- DRAW SCORE ---------- //
function drawScore() {
  fill(0, 255, 0);
  textSize(16);
  textAlign(LEFT);
  text(score, 10, 20);
}
1 Like