We are about to switch to a new forum software. Until then we have removed the registration on this forum.
Hi, so I have an assignment where I have to create a game. I have succeeded in creating the game but I am having trouble with restarting the game. I currently have it so when you click the screen the game starts and you use the keys to move the character around the screen and when all of the enemies have been removed the game over screen appears but when I try to press a button to go back to the beginning again it does not work? I have tried adding in a restart() function having looked at other entries on the forum but none of those were using a class so it did not work for me. I really need help as this is due in under a week and I have spent several days trying to figure it out.
I am using processing version 3.3.5
The code is shown below:
PFont font;
int Score;
//int ScoreIncrease;
Alien oneAlien;
int numberofStars = 300;
Stars[] theStars = new Stars[numberofStars];
int numberOfEnemies = 2;
Enemy [] theEnemies = new Enemy[numberOfEnemies];
int enemySize = 30;
int enemiesRemaining = numberOfEnemies;
boolean GamePlaying = false;
boolean GameOver = true;
void setup(){
size(1000,800);
font = loadFont("Consolas-BoldItalic-48.vlw");
oneAlien = new Alien (150,150, (int) random(width), (int) random(height));
for(int loop = 0; loop<theStars.length; loop++){
theStars[loop] = new Stars((int) random(width), (int) random(height), 5,5 ,30);
}
for(int loop = 0; loop<theEnemies.length; loop++){
theEnemies[loop] = new Enemy((int) random(width), (int) random(height),enemySize);
}
}//ends setup
void draw(){
background(0);
stroke(0);
//draws the stars for the background
for (int loop = 0; loop<theStars.length;loop++){
theStars[loop].drawStars();
}
//sets what is to be shown on the screen when the game is not in play
if(!GamePlaying){
//print
textFont(font,48);
textAlign(CENTER);
fill(0,250,0);
text("Click the screen to start", width/2, height/2);
}
//sets what is shown when the game is in play
if (GamePlaying) {
text("Score = " + Score, 800,750);
text("Time " + millis(), 150,750);
oneAlien.drawHead();
oneAlien.drawBody();
oneAlien.drawEyes();
oneAlien.drawSpots();
oneAlien.Bounce();
for(int loop = 0; loop < theEnemies.length; loop++) {
theEnemies[loop].display();
}
for(int loop = 0; loop < theEnemies.length; loop++) {
theEnemies[loop].move();
}
for(int loop = 0; loop < theEnemies.length; loop++) {
if(theEnemies[loop].checkForOverlap(oneAlien)) {
theEnemies[loop].Xloc = -100;
theEnemies[loop].Yloc = -100;
int timeBonus = int((20000.0 / millis()) * 15);
Score = Score + 10 +timeBonus;
enemiesRemaining --;
if(enemiesRemaining == 0){
//GameOverScreen();
GameOver = !GameOver;
}
}
}
textSize(48);
fill(255,0,0);
text("Click screen to pause", width/2, height/16);
} //ends Game Playing instructions
if (!GameOver){
background(0);
textSize(64);
fill(0,128,0);
text("You Won!", width/2 ,height/2);
fill(255);
text("Press Enter to play again" , width/2, height/2 + 120);
text("Your score = "+Score, width/2, height/2 +200);
}//ends Game Over instructions
}//ends draw
void restart(){
GameOver = !GameOver;
GamePlaying = !GamePlaying;
Score = 0;
setup();
}//ends restart
void mousePressed(){
//check position
GamePlaying = !GamePlaying;
}//ends mouse Pressed
void keyPressed(){
if (key == CODED) {
if(keyCode ==UP) {
oneAlien.moveUp();
};
if(keyCode ==DOWN) {
oneAlien.moveDown();
};
if(keyCode ==LEFT) {
oneAlien.moveLeft();
};
if(keyCode ==RIGHT){
oneAlien.moveRight();
};
if(keyCode ==ENTER) {
restart();
GameOver = !GamePlaying;
};
}//ends key==coded
}//ends key pressed
///////////first class/////////////
class Alien{
//attributes
int bodyW;
int bodyH;
int bodyXloc;
int bodyYloc;
int headW;
int headH;
int headXloc;
int headYloc;
int spotW;
int spotH;
int spotXloc;
int spotYloc;
int moveBy, moveBy2;
Alien(){
bodyW = 300;
bodyH = 400;
bodyXloc = 450;
bodyYloc = 450;
moveBy = 1;
moveBy2 = 1;
}//end Alien
Alien(int bW, int bH, int xl, int yl){
bodyW = bW;
bodyH = bH;
bodyXloc = xl;
bodyYloc = yl;
moveBy = 5;
moveBy2 = 5;
// do {
// moveBy = (int) random(-5,0);
// moveBy2 = (int) random(-5,5);
// }while (moveBy == 0 || moveBy2 == 0);
}//end
void drawBody(){
fill(66,149,244);
rectMode(CENTER);
rect(bodyXloc, bodyYloc, bodyW, bodyH);
}//end draw body
void drawHead(){
fill(244,158,66);
headW = bodyW / 2;
headH = bodyH / 2;
headXloc = bodyXloc;
headYloc = (bodyYloc - (bodyH / 2) - (headH / 2));
rect(headXloc, headYloc, headW, headH);
}//ends draw head
void drawEyes(){
fill(0);
rect (headXloc, headYloc, (headW/2), (headH/2));
float r = random(255);
float g = random(255);
float b = random(255);
fill(r,g,b);
rect (headXloc, headYloc, (headW/4), (headH/4));
}//end eyes
void drawSpots(){
float r = random(255);
float g = random(255);
float b = random(255);
fill(r,g,b);
spotW = bodyW / 2;
spotH = bodyH / 2;
spotXloc = bodyXloc;
spotYloc = (bodyYloc - (bodyH / 1500) - (spotH / 1500));
ellipse(spotXloc, spotYloc, spotW, spotH);
}//end draw spots
void Bounce(){
//checking when hitting right side
if(bodyXloc >= (width - (bodyW/2))){
//moveBy = moveBy * -1;
bodyXloc = (width - (bodyW/2));
}
//checking when hitting left side
if(bodyXloc <= (0 +(bodyW / 2))){
// moveBy = moveBy * -1;
bodyXloc = (bodyW / 2);
}
//checking when hitting the top of screen
if(bodyYloc >= (height - (bodyH/2))){
// moveBy2 = moveBy2 * -1;
bodyYloc = (height - (bodyH/2));
}
//checking when hitting the bottom of screen
if(bodyYloc <= (0 +(bodyH / 2 +headH))){
//moveBy2 = moveBy2 * -1
bodyYloc = (bodyH / 2 +headH);
}
}//ends bounce
void moveUp(){
bodyYloc = bodyYloc - moveBy2;
}//end moveUp
void moveDown(){
bodyYloc = bodyYloc + moveBy2;
}//ends moveDown
void moveLeft(){
bodyXloc = bodyXloc - moveBy;
}//ends moveLeft
void moveRight(){
bodyXloc = bodyXloc + moveBy;
}//ends moveRight
void move(){
bodyXloc = bodyXloc + moveBy;
bodyYloc = bodyYloc + moveBy2;
}//ends move
}//ends class
///////////starts a new class/////////////
class Enemy{
//attributes
int enemySize;
int Xloc;
int Yloc;
int xSpeed, ySpeed;
Enemy(int Xl, int Yl, int Size) {
Xloc = Xl;
Yloc = Yl;
enemySize = Size;
do{
xSpeed = (int) random(-10,10);
ySpeed = (int) random(-10,10);
}while(xSpeed == 0 || ySpeed == 0);
}//ends
void display(){
fill (255,247,0);
ellipse(Xloc, Yloc, enemySize, enemySize);
}//ends
void move(){
Xloc = Xloc + xSpeed;
Yloc = Yloc + ySpeed;
//checks to make sure that the object will bounce off the top and bottom of the screen
if (Xloc > width - (enemySize / 2) || Xloc < 0 + (enemySize / 2)){
xSpeed = xSpeed * -1;
}
//makes sure that the enemy bounces on the sides of the screen
if (Yloc > height - (enemySize / 2) || Yloc < 0 + (enemySize / 2)){
ySpeed = ySpeed * -1;
}
}//ends
boolean checkForOverlap(Alien oneAlien){
//System.out.println("Alien x is " +Xloc);
//System.out.println("Alien y is " +Yloc);
//System.out.println("Enemy x is " +oneAlien.bodyXloc);
//System.out.println("Enemy y is " +oneAlien.bodyXloc);
int alienX = oneAlien.bodyXloc;
int alienY = oneAlien.bodyYloc;
int distanceApart = (int) dist(Xloc, Yloc, alienX, alienY);
//System.out.println(distanceApart);
if (distanceApart >(enemySize / 2) + (oneAlien.bodyW / 2) + (oneAlien.headW)){
// System.out.println("Miss");
return false;
}
else {
// System.out.println("Crash");
return true;
}
}//end check for overlap
}//ends class
////////////starts last class/////////////
class Stars{
int starX;
int starY;
int starSize;
int starWidth;
int starHeight;
Stars(){
starSize = 5;
}
Stars(int sX, int sY, int sW, int sH, int size){
starX = sX;
starY = sY;
starWidth = sW;
starHeight = sH;
starSize = size;
}
void drawStars(){
fill(255);
ellipse(starX, starY, starWidth, starHeight);
}
}//end of the class
Answers
Thanks for your answer, I am unclear as to what I need to do to fix my problem, maybe you could explain a bit more?
(that was a spam link. deleted)
Oh thanks koogs, thankfully I hadn't actually clicked on the link
don't call setup() from within your code (line 106). it does a lot of things that should only be done once.
instead, move all the initialisation code into a separate method and call that from setup() and from where you want to re-init your structures.
Okay so I've made the changes you have suggested and it is still not helping me get from the GameOver part back to the original screen so that the game restarts. I think it will be something I have done in lines 102-106 or 130-133 but I just don't know what to do to fix it
Here's a working example. You can put your code into this.
thank you for your help TfGuy44. I have inserted my code into your example and it now goes back to the 'game paused' (i.e. the original screen) but when I am moving around my Alien character with the arrow keys and I finish the game the gameover screen only flashes up for a moment before going back to the 'game paused' screen. As well as this when I then click the screen to restart the ending of the game does not work? (basically when trying to play the game a second time it does not work). I also have the problem that my 'Stars' no longer display?
I have inserted my code for the first screen (I have not included the Classes again as they have not been changed since the original question was asked.)
@PF201 -- in general, when you are having trouble restarting that means you have some state that isn't being reset.
Often that state is in a global variable or object that you forgot to reinitialize.
For example, all of these things seem like they should happen at the beginning of a game:
Unless they are CONSTANTS, declare them (without defining them) in the header, then define them in reset. If they are constants, name them in all caps and prefix them with
final
.For example: whenever reset happens, do you always set boolean
paused
to false? Should you?There's no need to cram everything into one place. I took some time to put logical sections of your code into functions, and now it runs much smoother:
Classes ommitted as they are unchanged.
There were a couple of problems. You had the check for gameover inside the loop for enemy collisions, and since it was doing a toggle (
gameover = !gameover;
), this might have been causing trouble. It's much clearer to just set it directly (gameover = true;
).You were drawing your stars no matter what state the game was in, so it makes more sense to have the
draw_stars()
function called once, before messing about with the game states. Also your stars were not displaying because you copied the loop that created the positions for the stars, not the one that calledStar::drawStars()
to draw your stars (which might be better namedStar::drawStar()
, since it only draws one star.)I didn't have your font so I removed it. General code cleanups here and there too.
EnemiesRemaining
needed to be reset to the starting value insidereset()
.Notice how much easier it is to understand what your
draw()
function is actually doing now!Wow thank you TfGuy44, that's really helpful! much appreciated, its working now :