I need some help writing a gameplay loop for my Space Invaders clone. I have it partially working, but for whatever reason the second level only spawns 1 ship instead of the 20 I have coded. I cannot figure out why the level progresses but it doesn’t load the way it should. Should I be recalling the setup function for each level perhaps? Here’s my code
Main Loop:
boolean left, right, up;
boolean space;
Player p;
Spaceships [] s;
Projectile [] proj;
int nextProjectile;
Timer firingTimer;
float spacing = 75;
float x = 100;
float y = 100;
int score = 0;
int finalScore;
int highScore;
int level;
int noOfShips = 10;
int shipCount = noOfShips;
void setup(){
size(680, 680);
p = new Player();
s = new Spaceships[noOfShips];
for(int k = 0; k < s.length; k++){
s[k] = new Spaceships(x);
x += spacing;
if(x >= width && y >= 100){
y += spacing;
x = 50;
}
}
left = false;
right = false;
space = false;
proj = new Projectile[5];
for(int l = 0; l < proj.length; l++){
proj[l] = new Projectile(150 + l * 50, 550);
}
nextProjectile = 0;
level = 0;
firingTimer = new Timer(200);
firingTimer.start();
}
void draw(){
background(0, 0, 0);
switch(level){
case 0:
startScreen();
break;
case 1:
invadersGame(1);
break;
case 2:
invadersGame(2);
break;
}
}
void startScreen(){
background(0);
textAlign(CENTER);
textSize(120);
text("INVADERS", width/2, height/2);
textSize(70);
text("PRESS SPACE \nTO BEGIN", width/2, 450);
}
void invadersGame(int lv){
switch(lv){
case 1:
noOfShips = 10;
break;
case 2:
noOfShips = 20;
break;
}
noStroke();
fill(255);
textSize(12);
text("SCORE: " + score, 50, 50);
text("LEVEL: " + level, 150, 50);
text("AMMO: ", 90, 550);
text("SHIP COUNT :" + shipCount, 250, 50);
if(space){
if(firingTimer.complete()){
proj[nextProjectile].fire(p.x + p.w/9, p.y + p.h/2, p.facing);
nextProjectile = (nextProjectile + 1)%proj.length;
firingTimer.start();
}
}
for(int i = 0; i < proj.length; i++){
proj[i].update();
for(int j = 0; j < s.length; j++){
if(intersect(proj[i], s[j]) && !s[j].dead){
//fill(0, 0, 255);
//rect(0, 0, width, height);
proj[i].reset();
s[j].destroy();
shipCount -= 1;
if(shipCount == 0){
//j = 0;
level++;
println("Level Up");
levelUp();
s[j].reset();
}
}
}
proj[i].display();
}
p.update();
p.display();
for(int k = 0; k < s.length; k++){
if(!s[k].dead){
s[k].move();
}
s[k].update();
s[k].display();
if(intersect(p, s[k]) && !s[k].dead){
//fill(255, 0, 0, 50);
// rect(0, 0, width, height);
}
}
}
void levelUp(){
for(int m = 0; m < s.length; m++){
if(s[m].dead){
s[m].dead = false;
s[m].move();
}
s[m].update();
s[m].display();
}
}
boolean intersect(Player b1, Spaceships b2){
//Distance on x axis
float distX = abs((b1.x + b1.w/2) - (b2.x + b2.w/2));
//distance on y axis
float distY = abs((b1.y + b1.h/2) - (b2.y + b2.w/2));
//what is the combined half widths
float combinedHW = b1.w/2 + b2.w/2;
//what is the combined half heights
float combinedHH = b1.h/2 + b2.h/2;
//Check for x axis collision
if(distX < combinedHW){
//check on y axis
if(distY < combinedHH){
//we collided
println("YIPPIE");
return true;
}
}
return false;
}
boolean intersect(Projectile b1, Spaceships b2){
//Distance on x axis
float distX = abs((b1.x + b1.w/2) - (b2.x + b2.w/2));
//distance on y axis
float distY = abs((b1.y + b1.h/2) - (b2.y + b2.w/2));
//what is the combined half widths
float combinedHW = b1.w/2 + b2.w/2;
//what is the combined half heights
float combinedHH = b1.h/2 + b2.h/2;
//Check for x axis collision
if(distX < combinedHW){
//check on y axis
if(distY < combinedHH){
//we collided
println("YIPPIE");
return true;
}
}
return false;
}
void keyPressed(){
switch(keyCode){
case 37:
left = true;
break;
case 38:
up = true;
break;
case 39:
right = true;
break;
case 32:
space = true;
if(level == 0){
level++;
}
break;
}
}
void keyReleased(){
switch(keyCode){
case 37:
left = false;
break;
case 38:
up = false;
break;
case 39:
right = false;
break;
case 32:
space = false;
break;
}
}
Player Class:
class Player{
float x, y, w, h;
float speedX, maxSpeed;
String facing;
Player(){
x = width/2;
y = 600;
w = 22;
h = 44;
maxSpeed = 5;
speedX = 0;
facing = "up";
}
void update(){
if(left){
speedX = -maxSpeed;
}
if(right){
speedX = maxSpeed;
}
if((!left && !right) || (left && right)){
speedX = 0;
}
checkBounds();
PVector v = new PVector();
v.x = speedX;
x += v.x;
}
void display(){
fill(0, 0, 255);
rect(x, y - 10, w / 1.5, h + 5);
rect(x, y, w * 2, h);
}
void checkBounds(){
if(x > width){
x = -w;
}
if(x < -w){
x = width;
}
}
}
Projectile Class:
class Projectile{
float x, y, w, h, vx, vy, startingX, startingY;
float speed;
boolean inMotion;
Projectile(float sx, float sy){
startingX = sx;
startingY = sy;
x = sx;
y = sy;
w = 10;
h = 15;
vx = 0;
vy = 0;
speed = 10;
inMotion = false;
}
void update(){
x += vx;
y += vy;
checkBounds();
}
void display(){
fill(255);
rect(x, y, w, h);
}
void fire(float newX, float newY, String facing){
x = newX;
y = newY;
if(!inMotion){
switch(facing){
case "up":
vx = 0;
vy = -speed;
w = 10;
h = 20;
break;
}
inMotion = true;
}
}
void reset(){
x = startingX;
y = startingY;
vx = 0;
vy = 0;
inMotion = false;
}
void checkBounds(){
if(x < -w || x > width || y < -h || y > height){
reset();
}
}
}
Spaceships Class:
class Spaceships{
float x;
float y;
float w;
float h;
float vx;
float vy;
float speed;
float shipSize;
color c;
boolean dead;
int storedTime = 0;
boolean levelComplete;
Spaceships(float tempX){
x = tempX;
y = 100;
w = 50;
h = 25;
vx = 0;
vy = 0;
speed = random(1, 2);
dead = false;
}
void move(){
x = x + speed;
if(x > width){
//x = x - -speed;
//x -= -speed;
speed = -speed;
y += 100;
}else if(x < 0){
speed = -speed;
y += 100;
}else if(y > height - 100){
y = height - 100;
}
}
void update(){
x += vx;
y += vy;
//checkBounds();
}
void display(){
float offset = shipSize / 4;
ellipseMode(CENTER);
rectMode(CENTER);
strokeWeight(2);
stroke(0);
fill(170);
ellipse(x, y - 10, w / 2, h / 2);
ellipse(x, y, w, h /2 +3);
stroke(0);
fill(50, 100, 100);
ellipse(x, y, w/4, h/4);
ellipse(x + offset + 15, y, w/5, h/5);
ellipse(x - offset - 15, y, w/4, h / 4);
}
void destroy(){
vx = 0;
vy = 0;
x = -1000;
dead = true;
score += 100;
}
void reset(){
x = 100;
y = 100;
vx = 0;
vy = 0;
dead = false;
speed = random(1, 2);
//inMotion = false;
}
void checkBounds(){
if(x < 0 || x > width){
//reset();
x = -speed;
}
}
}
Timer Class:
class Timer{
int startTime;
int interval;
Timer(int timeInterval){
interval = timeInterval;
}
void start(){
startTime = millis();
}
boolean complete(){
int elapsedTime = millis() - startTime;
if(elapsedTime > interval){
return true;
}else{
return false;
}
}
}
If someone could please let me know what I am doing wrong I would greatly appreciate it!
Thanks in advance,
-Mellie