How to Create a Bullet Array for Asteroids Game

Hello,

I not to recently posted some quite problematic and disorganized code for my Asteroids game that I am working on for my Computer Programming class. I cleaned it up, and organized it a bit better. But I can't for the life of me figure out how to create and array of bullets for my ship, and in turn get them to fire when holding down say the, SHIFT or SPACE key. I am quite new to Processing and computer programming, any help would be enormously appreciated. Below I am posting the code for just my ship. I think my main confusion is that I used PVectors and I don't know how to incorporate the bullets properly with this technique. Thanks so much!

float shipX;//initial location
float shipY;//initial location
float shipAngle;
float direction;//ships's direction
PVector location;//ships's location
PVector velocity;//ship's speeds
PVector accel;//ship acceleration



void setup() {
  size(500, 500);


  location = new PVector(width/2, height/2, 0);
  velocity = new PVector();
  accel = new PVector();

  shipX = width/2;
  shipY = height/2;

  shipAngle = 0.0;

}



void draw() {

  checkKeys();

  background(0);
  stroke(0);

  velocity.add(accel);
  location.add(velocity);
  drawShip();

  accel.set(0, 0, 0);
  if (velocity.mag() != 0) velocity.mult(0.99);

  //wrap function
  if (location.x<0) {
    location.x = location.x+width;
  }
   if (location.x>width) {
      location.x = 0;
    }
    if (location.y<0) {
      location.y = location.y+height;
    }
    if (location.y>height) {
      location.y = 0;
    }
}

  void drawShip() {


  pushMatrix();
    // Translate ship origin
    translate(location.x, location.y);

    // Rotate ship
    rotate(direction);

    // Display the ship
    fill(105,95,95);
    stroke(255,0,0);
    triangle(-10, 20, 10, 20, 0, -20);

    // if the ship is accelerating draw a thruster
    if (accel.mag() != 0) {

    float thrusterCol = random(0,255);//thuster feature that appears behind the ship when accelerating
    fill(thrusterCol, thrusterCol/2, 0);
    triangle(-5, 22, 5, 22, 0, 40);
  }
  popMatrix();

  }

//moving the ship
void checkKeys() {
   if (keyPressed && key == CODED) {
    if (keyCode == LEFT) {
      direction-=0.1;
    }
    else if (keyCode == RIGHT) {
      direction+=0.1;
    }
    else if (keyCode == UP) {
      float totalAccel = 0.2;                 // how much ship accelerates
      accel.x = totalAccel * sin(direction);  // total accel
      accel.y = -totalAccel * cos(direction); // total accel
    }
   }
}
Tagged:

Answers

  • To do this you would probably need a class named Bullet. In that class you would need values like x, y, etc. You would also need a few methods such as bullet.move, bullet.display, etc. Then you create a global Array of bullets OR an ArrayList cast to bullets. then on each frame you update, display and do all that good stuff with the bullets. Consider my example:

    ArrayList <Bullet> bullets;//where our bullets will be stored
    
    void setup()
    {
      size(800,800);
      bullets = new ArrayList();
    }
    void draw()
    {
      background(0);
      removeToLimit(100);//some other code that removes bullets if there are too many on screen
      moveAll();//move all the bullets
      displayAll();//display all the bullets
    }
    class Bullet//bullet class
    {
      float x;
      float y;
      float speed;
      Bullet(float tx, float ty)
      {
        x = tx;
        y = ty;
      }
      void display()
      {
        stroke(255);
        point(x,y);
      }
      void move()
      {
        y -= 0.5;
      }
    }
    
    void removeToLimit(int maxLength)
    {
      while(bullets.size() > maxLength)
      {
        bullets.remove(0);
      }
    }
    void moveAll()
    {
      for(Bullet temp : bullets)
      {
        temp.move();
      }
    }
    void displayAll()
    {
      for(Bullet temp : bullets)
      {
        temp.display();
      }
    }
    void mousePressed()//add a new bullet if mouse is clicked
    {
      Bullet temp = new Bullet(mouseX,mouseY);
      bullets.add(temp);
    }
    
  • void mousePressed()//add a new bullet if mouse is clicked { Bullet temp = new Bullet(mouseX,mouseY); bullets.add(temp); }

    // How can I make the bullets come from an ship image instead of using mouseX and mouseY

  • replace mouseX,mouseY with the ship's pos

     void mousePressed()
    //add a new bullet if mouse is clicked 
    { 
    Bullet temp = new Bullet(ship.x, ship.y); 
    bullets.add(temp); 
    }
    
  • edited March 2014

    when the ship has a cannon attached, with a cannon pos, use this of course

    • it may be interesting when the ship looks right, bullet flies to the right and vice versa
  • //When I do this i get an error message "myShip.ship cannot be resolved or is not a field"

      Bullet temp = new Bullet(myShip.ship.x, myShip.ship.y);
    
  • This is my ship class,I'm trying to get the bullets to fire from my ship Image by using KeyPressed function outside the class.

    class Ship {

    //Global Variables PVector position; PVector accel; PVector velocity; PVector rotation; float drag = .9; //Ship image PImage ship = loadImage("ship.png");

    //How much the ship accelerates float acc = 0;

    //rotation angle float a = 0;

    //CONSTRUCTOR public Ship() {

    position = new PVector(width/2, 445);
    accel = new PVector(0, 0);
    velocity = new PVector(0, 0);
    

    }

    //FUNCTIONS void update() {

    drawShip();
    drawFinished();
    velocity.add(accel);
    velocity.mult(drag);
    position.add(velocity);
    
    acc *= 0.95;
    
    //Stops the ship when it reaches the surface 
    if (position.y > height - 20 - ship.height/2 ) {
      position.y = height - 20 - ship.height/2;
    }
    

    }

    void drawShip() { pushMatrix(); //method to use the new pos variable translate(position.x, position.x); rotate(a); stroke(255, 50, 0); fill(255, 50, 20);

    for ( int i=4; i >= 0; i--) {
      stroke(255, i*50, 0);
      fill(255, i*50, 20);
      ellipse( 0, 40, min(1, acc*10) *i*4, min(1, acc*10)* i*10);
    }
    image(ship, -ship.width/2, -ship.height/2, ship.width, ship.height);
    popMatrix();
    

    }

    void drawFinished() {

    textAlign(CENTER);
    fill(0);
    if (position.y > height - 50 - ship.height/2 ) {
    
    
      text("you have crashed!", width/2, height/2);
    }
    

    } }

  • edited March 2014

    well, when your ship's name is myShip outside the class (we don't know, because you don't tell), use it.

    Since you use a PVector for position, you have to use that too:

    Bullet temp = new Bullet(myShip.position.x, myShip.position.y);

    Greetings, Chrisir ;-)

  • this is the idea

    hit space or mouse to fire

    /**
     * Multiple Bullets (v2.5)
     * by Ammon.Owed (2013/Jan)
     *
    
     from http://forum.processing.org/one/topic/shoot-multiple-bullets 
    
     **/
    
    
    final static ArrayList<Bullet> bullets = new ArrayList();  // class Bullet
    Ship player = new Ship();                              // class Player
    
    // main functions -----------------------------------------
    
    
    void setup () {
      size(600, 600);
    }
    
    void draw() {
      background(0);
      player.update();
      player.drawShip();
      player.shoot();
      // displayAim();
      handleBullets();
    }
    
    // other functions -----------------------------------------
    
    void handleBullets() {
      //for (Bullet b: bullets)  b.run(); //unremovable bullets!
      for ( int b = bullets.size(); b != 0; )
        if ( bullets.get(--b).run() )  
          bullets.remove(b);
      print(bullets.size() + "\t");
    }
    
    // ==============================
    
    class Ship {
    
      //Global Variables 
      PVector position; 
      PVector accel; 
      PVector velocity; 
      PVector rotation; 
      float drag = .9; 
    
      //Ship image 
      PImage ship = loadImage("ship.png");
    
      //How much the ship accelerates 
      float acc = 0;
    
      //rotation angle
      float a = 0;
    
      final byte bulletVel = 5;
    
      //CONSTRUCTOR  --------------------------------
      public Ship() {
        position = new PVector(330, 445);
        accel = new PVector(0, 0);
        velocity = new PVector(0, 0);
      }
    
      //FUNCTIONS -------------------------------------
      void update() {
        drawShip();
        drawFinished();
        // velocity.add(accel);
        // velocity.mult(drag);
        // position.add(velocity);
    
        acc *= 0.95;
    
        //Stops the ship when it reaches the surface
        if (position.y > height - 20 - 10 ) {
          position.y = height - 20 - 10;
        }
      }
    
      void drawShip() { 
        pushMatrix(); 
        //method to use the new pos variable 
        translate(position.x, position.y); 
        //rotate(a); 
        stroke(255, 50, 0); 
        fill(255, 50, 20);
        for ( int i=4; i >= 0; i--) {
          stroke(255, i*50, 0);
          fill(255, i*50, 20);
          ellipse( 0, 40, min(1, acc*10) *i*4, min(1, acc*10)* i*10);
        }
        //  image(ship, -ship.width/2, -ship.height/2, ship.width, ship.height);
        fill(222, 2, 2);
        //  rect ( width/2, height/2, 70, 20);
        rect ( 0, 0, 70, 20);
        popMatrix();
      }
    
      void drawFinished() {
        textAlign(CENTER);
        fill(0);
        if (position.y > height - 50 - 10 ) {
          text("you have crashed!", width/2, height/2);
        }
      }
    
      void shoot() {
        final byte bulletGap = 3;
        if ((mousePressed && frameCount % bulletGap == 0) || 
          (keyPressed && key ==' ' && frameCount % bulletGap == 0)) 
        {
          player.addBullet();
        }
      }
    
      void addBullet() {
        final PVector bulletSpd = new PVector();
        bulletSpd.set(3, 0);
        //bulletSpd.sub(position);
        bulletSpd.normalize();
        bulletSpd.mult(bulletVel);
        bullets.add( new Bullet(position, bulletSpd) );
      }
    
      //
    } // class 
    
    // ==========================================================
    
    class Bullet extends PVector {
    
      PVector vel;
      final static color bulletColor = #0000FF;
    
      Bullet(PVector loc, PVector vel) {
        super(loc.x, loc.y);
        this.vel = vel.get();
      }
    
      void display() {
        final byte bulletSize = 4;
        fill(bulletColor);
        ellipse(x, y, bulletSize, bulletSize);
      }
    
      boolean update() {
        add(vel);
        return x > width || x < 0 || y > height || y < 0;
      }
    
      boolean run() {
        display();
        return update();
      }
      //
    } // class Bullet
    
    // ==========================================================
    
  • Screen Shot 2014-03-13 at 13.52.42

    Thank you, I got it working with my image. The only problem now is that I want the bullets to come out from the end of the ship not in the middle. When I rotate my ship the bullets stays in the middle of the Ship. How could I go about doing this?

  • can your ship look in every direction?

    is this angle a?

  • Yes. a is the angle of the ship.

    class Bullet//bullet class { float x; float y; float speed; float ang;

      Bullet(float tx, float ty, float _ang)
      {  
        x = tx;
        y = ty;
    
      }
      void display() {
        //draw bullet
        pushMatrix();
        //move it first
        translate(x, y);
        rotate(ang);
        fill(255, 0, 0);
        rect(-2, -10, 4, 20);
        popMatrix();
      }
    
      void move()
      {
        y -= 5;
      }
    }
    

    I have tried adding a float angle inside the class but when I do I get an error message "(float, float) is underfined"

    Bullet temp = new Bullet(myShip.position.x, myShip.position.y);
    
  • edited March 2014

    can your ship look in every direction?

    so like ---> and <-----

    and | and / and \ etc. .................. ??

    can bullets fly in every direction?

  • The ship can look in every direction but the bullets only fly out in one direction (middle of the ship). Is this what you mean?

  • edited March 2014

    this would be it in my sketch above...

    you need to determine the position of the gun (where your bullet starts) by using sin and cos, since the bullet-position rotates on a circle with the ship or around the ship.

    As you can see in the formula

                positionbullet.x = 70 * cos (radians(a)) + position.x; 
                positionbullet.y = 70 * sin (radians(a)) + position.y; 
    

    the trick is that you know the radius of the circle (length of your ship / ship image / 70) and the position of the center of the ship (position.x,position.y) and the angle a

    now you can calculate the bullets starting position positionbullet

    sin and cos do all the hard work for you then

    It is really this easy!

    see https://forum.processing.org/tutorials/trig/

      void addBullet() {
        final PVector bulletSpd = new PVector();
        bulletSpd.set(3, 0);
        //bulletSpd.sub(position);
        bulletSpd.normalize();
        bulletSpd.mult(bulletVel);
    
        PVector positionbullet = new PVector();
    
        positionbullet.x = 70 * cos (radians(a)) + position.x; 
        positionbullet.y = 70 * sin (radians(a)) + position.y; 
    
        bullets.add( new Bullet(positionbullet, bulletSpd) );
      }
    
This discussion has been closed.