2
\$\begingroup\$

I am making a game for my computer science class. My professor's requirements are:

  1. Write a Processing program that draws a triangle in the middle of the window.

  2. Rotate the triangle when the left and right arrow keys are pressed using the translate and rotate methods.

  3. When the spacebar is hit, create a torpedo that appears to shoot out one of the vertices of the triangle.

    Note: if you do not want a continuous stream of torpedoes generate when the space bar is held down, you can use the PApplet's keyReleased method instead of the keyPressed method.

  4. Create some number of large ellipses to represent asteroids. Have the asteroids move in random directions around the window, wrapping around when they cross one of the window's boundaries.

  5. Have the torpedoes destroy the asteroids when they collide. (Using an ellipse for the torpedo will probably make the collision detection easier.) When the asteroids are destroyed, create a Particle System centered at the center of the asteroid to make it look like there was an explosion.

  6. Keep track of points based on the number of asteroids destroyed and display the total points in the window.

  7. When an asteroid collides with the spaceship, destroy the spaceship and create a Particle System at the center of the colliding ship.

  8. Include a button to restart the game when the spaceship is destroyed.

I have finished most of it but I still have one problem: every time the Asteroid hits my spaceship, it takes a really long time to explode. What improvements can I make?

import java.util.ArrayList;
import java.util.Iterator;


import processing.core.PApplet;

public class spaceMain extends PApplet {

    float width = 1000;
    float height = 600;
    float angle = 0;

    int score = 0;

    boolean tNotAlive = false;
    boolean sAlive = true;
    boolean gameIsOver = false;


    spaceShip theSpaceShip;
    ArrayList<Torpedoes> TorpedoesList = new ArrayList<Torpedoes>();
    ArrayList<Asteroids> AsteroidsList = new ArrayList<Asteroids>();
    ArrayList<ParticleSystems> theList = new ArrayList<ParticleSystems>();


    public void setup(){
        theSpaceShip = new spaceShip(0, 0,angle);
        while(AsteroidsList.size() < 10){
            Asteroids theAsteroid = new Asteroids(random(0,1000), random(0,600),random(50,80));
            while(theAsteroid.getXPos() > width/2 - 200 && theAsteroid.getXPos() < width/2 + 200){
            theAsteroid = new Asteroids(random(0,1000), random(0,600),random(50,80));
            } //end while
         AsteroidsList.add(theAsteroid);
        }//end while 
        textSize(26);
    }//end set up  


    public void draw(){
       background(19,19,70);


        if(gameIsOver){
            text("You Lose", 450, 100);
        }else {
            text("score :" +score, 200,200);

        }//end else if

        destroySpaceShip();

        fill(127,127,127);
        pushMatrix();
           translate(width/2, height/2);
           rotate(angle);
           if(sAlive){
               theSpaceShip.display(this);
           }//end if 
        popMatrix();


        for(Torpedoes theTorpedo: TorpedoesList){

                theTorpedo.display(this);

                theTorpedo.shootOut();
        }//end for

        for(Asteroids theAsteroid: AsteroidsList){

            theAsteroid.display(this);

            theAsteroid.aMove();


        }//end for 

        destroyAsteroid();

        Iterator<Torpedoes> Titerator = TorpedoesList.iterator();

        int index = TorpedoesList.size()-1;
        while(index >= 0){
            Torpedoes theTorpedo2 = TorpedoesList.get(index);
            theTorpedo2.shootOut();
            if(tNotAlive){
               TorpedoesList.remove(index);
               tNotAlive = false;
            }//end if
            index--;
        }//end while 

         Iterator<Asteroids> Aiterator = AsteroidsList.iterator();

         while(Aiterator.hasNext()){
             Asteroids theAsteroid = Aiterator.next();
             if(! theAsteroid.isAlive()){
                Aiterator.remove();    
                theList.add(new       ParticleSystems(theAsteroid.getXPos(),theAsteroid.getYPos() ,1));     
             }//end if  
         }//end while


         for(ParticleSystems theParticleSystem: theList){

             theParticleSystem.display(this);
             theParticleSystem.update();
             theParticleSystem.addParticle();
         }//end for 



    }//end draw 








    public void keyPressed(){
        if(key == ' '){
            TorpedoesList.add(new Torpedoes(width/2, height/2, angle));
        }//end if

        if(key == CODED){
            if(keyCode == LEFT){
                angle = angle - (float)0.2;
            }//end if 
            if(keyCode == RIGHT){
                angle = angle + (float)0.2;
            }//end if


        }//end if
    }//end keyPressed 

    public void destroySpaceShip(){
        for(Asteroids theAsteroid: AsteroidsList){
            if(distance(theAsteroid.getXPos(), theAsteroid.getYPos(), theSpaceShip.getXPos(), theSpaceShip.getYPos()) <= 80 ){
                theList.add(new ParticleSystems(width/2,height/2,1));
                sAlive = false;
                gameIsOver = true;

            }//end if 
        }//end for 
    }//end destroySpaceShip 






     public void destroyAsteroid(){
             for(Torpedoes theTorpedo: TorpedoesList){
                 for(Asteroids theAsteroid: AsteroidsList){
                     if(distance(theAsteroid.getXPos(), theAsteroid.getYPos(), theTorpedo.getXPos(), theTorpedo.getYPos()) <= 50){
                         score = score + 1;
                         tNotAlive = true;
                         theAsteroid.die();



                     }//end if

                 }//end for 


              }//end for 
          }//end destroyA

        float distance(float Ax, float Ay, float Tx, float Ty){
             return sqrt(sq(Ax-Tx) + sq(Ay-Ty));
        }//end distance









        public void settings(){
            size(1000,600);
        }// end settings

        public static void  main(String[] args){
            PApplet.main("spaceMain");
        }//end run processing 
}//end class 

Spaceship class:

import processing.core.PApplet;

public class spaceShip {


    float xPos;
    float yPos;
    float angle;


    spaceShip(float xInit, float yInit, float aInit){
        xPos = xInit;
        yPos = yInit;
        angle = aInit;
    }//end constructor


    void display(PApplet proc){
        proc.triangle(xPos+50, yPos, xPos-50, yPos-50, xPos-50, yPos+50);
    }//end of display

    void up(){
        xPos = xPos + (float)Math.cos(angle)*10;
        yPos = yPos + (float)Math.sin(angle)*10;
    }//end up

    void down(){
        xPos = xPos - (float)Math.cos(angle)*10;
        yPos = yPos - (float)Math.sin(angle)*10;
    }//end down 

    float getXPos(){
        return xPos;
    }//end getxPos

    float getYPos(){
        return yPos;
    }//end getyPos
}//end spaceship class

Asteroid class:

import processing.core.PApplet;

public class Asteroids {

    float xPos;
    float yPos;
    float length;


    float xDir = (float)Math.random()*2 -1;
    float yDir = (float)Math.random()*2 -1;

    int red;
    int green;
    int blue;

    boolean alive = true;




    Asteroids(float xInit, float yInit, float lInit){
        xPos = xInit;
        yPos = yInit;
        length = lInit;
    }//end constructor

    void display(PApplet proc){
        proc.fill(230,230,20);
        proc.ellipse(xPos, yPos, length,length);
    }//end display

    void aMove(){
        xPos = xPos + (float)2*xDir;
        yPos = yPos + (float)2*yDir;

        if(xPos < 0 || xPos > 1000){
            xDir = - xDir;
        }//end if

        if(yPos < 0 || yPos > 600){
            yDir = - yDir;
        }//end if 
    }//end aMove

    float getXPos(){
        return xPos;
    }//end getxPos

    float getYPos(){
        return yPos;
    }//end getyPos

    float getLength(){
        return length;
    }//end getLength

    void setColor(int R, int G, int B){
        red = R;
        green = G;
        blue = B;
    }


    void die(){
        alive  = false;
    }

    boolean isAlive(){
        return alive;
    }
}//end class

Torpedoes class:

import processing.core.PApplet;

public class Torpedoes {
      float xPos;
      float yPos;
      float angle;

      float xDir;
      float yDir;

      Torpedoes(float xInit, float yInit, float aInit){
          xPos = xInit;
          yPos = yInit;
          angle = aInit;
          xDir = (float)Math.cos(angle);
          yDir = (float)Math.sin(angle);
      }//end constructor;

      void display(PApplet proc){
          proc.fill(255,0,0);
          proc.pushMatrix();
              proc.translate(xPos, yPos);   
              proc.rotate(angle);
              proc.ellipse(0, 0, 40,20);
          proc.popMatrix();       



      }//end display 

      void shootOut(){
          xPos = xPos + 4*xDir;
          yPos = yPos + 4*yDir;


      }//end shoot out

      float getXPos(){
         return xPos;
      }//end getxPos

      float getYPos(){
        return yPos;
      }//end getyPos



}//end classTorpedoes

Particle class:

import processing.core.PApplet;

public class Particles {



    float xPos;
    float yPos;

    float xDir;
    float yDir;

    float lifeSpan = 255; 

    Particles(float xPosInit, float yPosInit, float xDirInit, float yDirInit){
        xPos = xPosInit;
        yPos = yPosInit;
        xDir = xDirInit;
        yDir = yDirInit;
    }//end constructor

    void update(){
        xPos = xPos + xDir;
        yPos = yPos + yDir;
        lifeSpan = lifeSpan - 3;
    }// end update

    void display(PApplet proc){
        proc.fill(255,0,0, lifeSpan);
        proc.stroke(255,0,0, lifeSpan);
        proc.ellipse(xPos, yPos, 5, 5);
    }//end display

    boolean isAlive(){
        return (lifeSpan > 0);
    }
}//end class

ParticleSystem class:

  import java.util.ArrayList;
import java.util.Iterator;

import processing.core.PApplet;

public class ParticleSystems {

 ArrayList<Particles> particlesList = new ArrayList<Particles>(); 


    float xOrigin;
    float yOrigin;
    int numParticles;


    ParticleSystems(float xInit, float yInit, int numInit){
        xOrigin = xInit;
        yOrigin = yInit;
        numParticles = numInit;

        while(particlesList.size() < numParticles){
            addParticle();
        }//end while
    }//end construction 

    void addParticle(){
        particlesList.add(new Particles(xOrigin, yOrigin, 
                (float) Math.random()*2 -1,(float) Math.random()*2 -1));
    }// end addParticle

    void display(PApplet proc){
        for(Particles theParticle: particlesList){
            theParticle.display(proc);
        }//end for 
    }//end display()

    void update(){
        Iterator <Particles> piterator = particlesList.iterator();

        int index = particlesList.size()-1;
        while(index >= 0){
            Particles theParticle = particlesList.get(index);
            theParticle.update();
            if(! theParticle.isAlive()){
                particlesList.remove(index);
            }//end if
            index--;
        }//end while
    }//end update

}//end class

I am not sure if it's my computer's problem or some parts of my code are wrong.

\$\endgroup\$
  • 1
    \$\begingroup\$ I'm really tempted to vote to close this question as off-topic. The way I understand the question is that your spaceship is exploding but it takes too long ? Or the ship is not exploding at all? Do know that question regarding broken code is off-topic for Code Review. \$\endgroup\$ – Marc-Andre Mar 3 '16 at 19:46
2
\$\begingroup\$

Break out of loops sooner

This applies specifically to your spaceship and to a lesser extent to asteroids and torpedoes. Once the spaceship is destroyed, return. Any other collision checks are wasted processing time. For torpedoes and asteroids, once a torpedo has destroyed an asteroid, break out and move on to the next torpedo. This leaves a small edge case where a torpedo might perfectly hit two asteroids at once, so this decision is up to you.

public void destroySpaceShip(){
    for(Asteroids theAsteroid: AsteroidsList){
        if(distance(theAsteroid.getXPos(), theAsteroid.getYPos(), theSpaceShip.getXPos(), theSpaceShip.getYPos()) <= 80 ){
            theList.add(new ParticleSystems(width/2,height/2,1));
            sAlive = false;
            gameIsOver = true;
            return;  // <-------- No need to process anymore
        }//end if 
    }//end for 
}//end destroySpaceShip 

public void destroyAsteroid(){
    for(Torpedoes theTorpedo: TorpedoesList){
        for(Asteroids theAsteroid: AsteroidsList){
            if(distance(theAsteroid.getXPos(), theAsteroid.getYPos(), theTorpedo.getXPos(), theTorpedo.getYPos()) <= 50){
                score = score + 1;
                tNotAlive = true;
                theAsteroid.die();
                break;  // <--- Presumably a torpedo will only destroy one asteroid 
            }//end if
        }//end for 
    }//end for 
}//end destroyA

Finally, if the spaceship is destroyed, skip directly to the particle application logic. Don't waste time checking torpedoes and asteroids.

destroySpaceShip();
if(sAlive)
{
    //asteroids
    //torpedoes
    //etc
}
for(ParticleSystems theParticleSystem: theList){
    //...
}//end for 
\$\endgroup\$
0
\$\begingroup\$

I didn't run your code, but it seems like you're doing everything in a single thread. You're moving things and looping through all kinds of stuff while it's in the draw method. I'd recommend you position and do collision detection in a separate thread and just store the state. In your draw function, you just use all your calculated values.

Also, it's best practice to name your classes in upper-camel-case. So instead of spaceShip, use SpaceShip.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.