Loading...
Logo
Processing Forum

Shoot multiple bullets.

in General Discussion  •  Other  •  9 months ago  
Hello and Happy new year to all of those who read my post,
I'm here once again whit a problem in my Code,
I'v been working on this game in whitch for now i have a red dot you can move whit awsd keys and a green dot witch trys to catch up whit the red dot, and also a life bar for the red dot witch lowers down when the greed dot touches the red dot.
I would like it if when the player clicks whit the mouse on a location of the screen, a ellipse witch represents a bullet will come from the red dot and go to the pointed location, if it touches the borders of the screen i want it to do nothing and when it touches the green dot i can give it some effects.
The problem is i have no idea how to make an ellipse that stays after the mouse press and how to make it possible to get multiple bullets over the screen at one time...
coul you have a tought about how i could make this work, i would be vey gratefull.
i won't put my code on here right now but if needed i will.
The only thing is that the code has to be pretty basic because i'm doing this as a school project and i don't want to just copy and paste, the main goal is to discover new ways of coding but also to be able to understand them and be able to reuse them.

Replies(9)

You could use a Bullet class with a location and direction. And an arrayList to hold the bullets.

Code Example
Copy code
  1. ArrayList <Bullet> bullets = new ArrayList <Bullet> ();
  2. PVector player, playerSpeed;
  3. float maxSpeed = 3;
  4.  
  5. void setup() {
  6.   size(600, 600);
  7.   player = new PVector(width/2, height/2);
  8.   playerSpeed = new PVector();
  9.   noCursor();
  10.   noStroke();
  11.   smooth();
  12. }
  13.  
  14. void draw() {
  15.   background(255);
  16.  
  17.   player.add(playerSpeed);
  18.   fill(255, 0, 0);
  19.   ellipse(player.x, player.y, 20, 20);
  20.   fill(255);
  21.   ellipse(player.x, player.y, 10, 10);
  22.  
  23.   PVector mouse = new PVector(mouseX, mouseY);
  24.   fill(0);
  25.   ellipse(mouse.x, mouse.y, 5, 5);
  26.  
  27.   if (frameCount%5==0 && mousePressed) {
  28.     PVector dir = PVector.sub(mouse, player);
  29.     dir.normalize();
  30.     dir.mult(maxSpeed*3);
  31.     Bullet b = new Bullet(player, dir);
  32.     bullets.add(b);
  33.   }
  34.  
  35.   for (Bullet b : bullets) {
  36.     b.update();
  37.     b.display();
  38.   }
  39. }
  40.  
  41. class Bullet extends PVector {
  42.   PVector vel;
  43.  
  44.   Bullet(PVector loc, PVector vel) {
  45.     super(loc.x, loc.y);
  46.     this.vel = vel.get();
  47.   }
  48.  
  49.   void update() {
  50.     add(vel);
  51.   }
  52.  
  53.   void display() {
  54.     fill(0, 0, 255);
  55.     ellipse(x, y, 3, 3);
  56.   }
  57. }
  58.  
  59. void keyPressed() {
  60.   if (keyCode == UP)    { playerSpeed.y = -maxSpeed; }
  61.   if (keyCode == DOWN)  { playerSpeed.y = maxSpeed;  }
  62.   if (keyCode == LEFT)  { playerSpeed.x = -maxSpeed; }
  63.   if (keyCode == RIGHT) { playerSpeed.x = maxSpeed;  }
  64. }
  65.  
  66. void keyReleased() {
  67.   if (keyCode == UP || keyCode == DOWN)    { playerSpeed.y = 0; }
  68.   if (keyCode == LEFT || keyCode == RIGHT) { playerSpeed.x = 0; }
  69. }
Ths does exactly what i wanted , now there are some tinghs on this code i never used , i'm going to study it a bit and i'll ask my question on the way , thank you a lot amnon:
i got a hard time whit this...
Copy code
  1.   if (frameCount%5==0 && mousePressed) {
  2.     PVector dir = PVector.sub(mouse, player);
  3.     dir.normalize();
  4.     dir.mult(maxSpeed*3);
  5.     Bullet b = new Bullet(player, dir);
  6.     bullets.add(b);
  7.   }
  8.  
  9.   for (Bullet b : bullets) {
  10.     b.update();
  11.     b.display();
  12.   }
  13. }
  14.  
  15. class Bullet extends PVector {
  16.   PVector vel;
  17.  
  18.   Bullet(PVector loc, PVector vel) {
  19.     super(loc.x, loc.y);
  20.     this.vel = vel.get();
  21.   }
Commented...

Copy code
  1. // every 5th frame AND when the mouse is pressed
  2.   if (frameCount%5==0 && mousePressed) {
  3. // get the direction from the player to the mouse
  4.     PVector dir = PVector.sub(mouse, player);
  5. // normalize it to length 1 (make it as unit vector)
  6.     dir.normalize();
  7. // multiply it by maxSpeed times three (giving the direction a fixed velocity)
  8.     dir.mult(maxSpeed*3);
  9. // create a new bullet at the position of the player in the direction of the mouse
  10.     Bullet b = new Bullet(player, dir);
  11. // add the new bullet to the list
  12.     bullets.add(b);
  13.   }

  14. // for each bullet b in the the list of bullets
  15.   for (Bullet b : bullets) {
  16. // run the bullet's update() method
  17.     b.update();
  18. // run the bullet's display() method
  19.     b.display();
  20.   }
  21. }

  22. // class Bullet which extends PVector (note PVector differences between 1.5.1 and 2.0xx)
  23. class Bullet extends PVector {
  24. // have a velocity variable for the bullet's velocity
  25.   PVector vel;
  26. // constructor for Bullet with location and direction/velocity
  27.   Bullet(PVector loc, PVector vel) {
  28. // send the location to the PVector constructor (where it is stored in x, y variables)
  29.     super(loc.x, loc.y);
  30. // send the velocity to the instance variable PVector vel
  31.     this.vel = vel.get(); // make a copy just to avoid any reference problems
  32.   }


For me, PVector itself is a little hard to picture the whole thing in my head! 
It is however an interesting concept: 3 field float variables plus methods for vector math. 

So I've decided to fool around Ammon's example code to see whether I could finally grasp it in my mind.

Moreover, added in some checks for canvas border limits both for player & bullets.
PVector playerPos is transported to the opposite border if it is so.
And a Bullet class instance from the ArrayList is removed to save memory.

So, check it out:
Copy code
    /**
     * Multiple Bullets (v2.1)
     * by Ammon.Owed (2013/Jan)
     *
     * http://forum.processing.org/topic/shoot-multiple-bullets
     */
    
    final static List<Bullet> bullets = new ArrayList(50);
    
    final static PVector playerPos = new PVector(); 
    final static PVector playerSpd = new PVector();
    final static PVector bulletSpd = new PVector();
    
    final static byte  playerVel  = 3, bulletVel = 5, fps = 60;
    final static byte  playerSize = 20, holeSize = playerSize>>1;
    final static byte  aimSize = 5, bulletSize = 4, bulletGap = 3;
    
    final static color aimColor = 0, bg = 255;
    final static color playerColor = #FF0000, bulletColor = #0000FF;
    
    void setup() {
        size(600, 600);
        smooth();
        noStroke();
        noCursor();
        ellipseMode(CENTER);
        frameRate(fps);
    
        playerPos.set(width>>1, height>>1, 0);
    }
    
    void draw() {
        background(bg);
    
        updatePlayer();
        displayPlayer();
        displayAim();
    
        if (mousePressed && frameCount % bulletGap == 0)
            addBullet();
    
        //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");
    }
    
    void updatePlayer() {
        playerPos.add(playerSpd);
    
        if (playerPos.x > width)    playerPos.x = 0;
        else if (playerPos.x < 0)   playerPos.x = width;
    
        if (playerPos.y > height)   playerPos.y = 0;
        else if (playerPos.y < 0)   playerPos.y = height;
    }
    
    void displayPlayer() {
        fill(playerColor);
        ellipse(playerPos.x, playerPos.y, playerSize, playerSize);
    
        fill(bg);
        ellipse(playerPos.x, playerPos.y, holeSize, holeSize);
    }
    
    void displayAim() {
        fill(aimColor);
        ellipse(mouseX, mouseY, aimSize, aimSize);
    }
    
    void addBullet() {
        bulletSpd.set(mouseX, mouseY, 0);
    
        bulletSpd.sub(playerPos);
        bulletSpd.normalize();
        bulletSpd.mult(bulletVel);
    
        bullets.add( new Bullet(playerPos, bulletSpd) );
    }
    
    void keyPressed() {
        final int k = keyCode;
    
        if (k == LEFT || k == 'A')
            playerSpd.x = -playerVel;
        else if (k == RIGHT || k == 'D')
            playerSpd.x = playerVel;
        else if (k == UP || k == 'W') 
            playerSpd.y = -playerVel;
        else if (k == DOWN || k == 'S')
            playerSpd.y = playerVel;
    }
    
    void keyReleased() {
        final int k = keyCode;
    
        if ( (k == LEFT || k == 'A') && playerSpd.x < 0 
            || (k == RIGHT || k == 'D') && playerSpd.x > 0 )
            playerSpd.x = 0;
    
        else if ( (k == UP || k == 'W') && playerSpd.y < 0 
            || (k == DOWN  || k == 'S') && playerSpd.y > 0 )
            playerSpd.y = 0;
    }
    
    class Bullet extends PVector {
        PVector vel;
    
        Bullet(PVector loc, PVector vel) {
            super(loc.x, loc.y);
            this.vel = vel.get();
        }
    
        void display() {
            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();
        }
    }
    
Hello Amnon.owed, it took me some time to understand your code but i have to say after quite some learning and studying on it it finaly got it and was able to reproduce it.
But i got stuck on this next thing, when i want to set the borders of my screen as a limmit for the ellipse and not make it go around , it works when i move wile pressing and releasing asdz but when i use a continued press it ignores the limmits i imposed.
Tweaked my derived version so the player not be able to cross the borders now. 
It's located at function updatePlayer().
Old code is commented out for comparison.

Also, take a look at this post:
http://forum.processing.org/topic/array-usage-objects-in-general
Copy code
    /**
     * Multiple Bullets (v2.5)
     * by Ammon.Owed (2013/Jan)
     *
     * http://forum.processing.org/topic/shoot-multiple-bullets
     */
    
    final static List<Bullet> bullets = new ArrayList(50);
    
    final static PVector playerPos = new PVector(); 
    final static PVector playerSpd = new PVector();
    final static PVector bulletSpd = new PVector();
    
    final static byte  playerVel  = 3, bulletVel = 5, fps = 60;
    final static byte  playerSize = 20, holeSize = playerSize>>1;
    final static byte  aimSize = 5, bulletSize = 4, bulletGap = 3;
    
    final static color aimColor = 0, bg = 255;
    final static color playerColor = #FF0000, bulletColor = #0000FF;
    
    void setup() {
      size(600, 600);
      smooth();
      noStroke();
      noCursor();
      ellipseMode(CENTER);
      frameRate(fps);
    
      playerPos.set(width>>1, height>>1, 0);
    }
    
    void draw() {
      background(bg);
    
      updatePlayer();
      displayPlayer();
      displayAim();
    
      if (mousePressed && frameCount % bulletGap == 0)
        addBullet();
    
      //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");
    }
    
    void updatePlayer() {
      playerPos.add(playerSpd);
    
      if (playerPos.x > width - holeSize)  playerPos.x = width-holeSize;
      else if (playerPos.x < holeSize)     playerPos.x = holeSize;
    
      if (playerPos.y > height-holeSize)   playerPos.y = height-holeSize;
      else if (playerPos.y < holeSize)     playerPos.y = holeSize;
    
      /*
       if (playerPos.x > width)    playerPos.x = 0;
       else if (playerPos.x < 0)   playerPos.x = width;
       
       if (playerPos.y > height)   playerPos.y = 0;
       else if (playerPos.y < 0)   playerPos.y = height;
       */
    }
    
    void displayPlayer() {
      fill(playerColor);
      ellipse(playerPos.x, playerPos.y, playerSize, playerSize);
    
      fill(bg);
      ellipse(playerPos.x, playerPos.y, holeSize, holeSize);
    }
    
    void displayAim() {
      fill(aimColor);
      ellipse(mouseX, mouseY, aimSize, aimSize);
    }
    
    void addBullet() {
      bulletSpd.set(mouseX, mouseY, 0);
    
      bulletSpd.sub(playerPos);
      bulletSpd.normalize();
      bulletSpd.mult(bulletVel);
    
      bullets.add( new Bullet(playerPos, bulletSpd) );
    }
    
    void keyPressed() {
      final int k = keyCode;
    
      if (k == LEFT || k == 'A')
        playerSpd.x = -playerVel;
      else if (k == RIGHT || k == 'D')
        playerSpd.x = playerVel;
      else if (k == UP || k == 'W') 
        playerSpd.y = -playerVel;
      else if (k == DOWN || k == 'S')
        playerSpd.y = playerVel;
    }
    
    void keyReleased() {
      final int k = keyCode;
    
      if ( (k == LEFT  || k == 'A') && playerSpd.x < 0 
        || (k == RIGHT || k == 'D') && playerSpd.x > 0 )
        playerSpd.x = 0;
    
      else if ( (k == UP || k == 'W') && playerSpd.y < 0 
        || (k == DOWN    || k == 'S') && playerSpd.y > 0 )
        playerSpd.y = 0;
    }
    
    class Bullet extends PVector {
      PVector vel;
    
      Bullet(PVector loc, PVector vel) {
        super(loc.x, loc.y);
        this.vel = vel.get();
      }
    
      void display() {
        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();
      }
    }
    

I got what you did, i tried a similar thing ,i will try this one tought, maybe it is because i did not put it in the player update but in the player display that it mignt not have worked?


I made the player into a class..



Copy code
  1. /**
  2.  * Multiple Bullets (v2.5)
  3.  * by Ammon.Owed (2013/Jan)
  4.  *
  5.  * http://forum.processing.org/topic/shoot-multiple-bullets
  6.  */
  7. final static ArrayList<Bullet> bullets = new ArrayList();  // class Bullet
  8. Player player = new Player();                              // class Player
  9. final static color bg  = 255;
  10. final static byte  fps = 60;
  11. void setup() {
  12.   size(600, 600);
  13.   smooth();
  14.   noStroke();
  15.   noCursor();
  16.   cursor (CROSS);
  17.   ellipseMode(CENTER);
  18.   frameRate(fps);
  19.   player.playerPos.set(width>>1, height>>1, 0);
  20. }
  21. void draw() {
  22.   background(bg);
  23.   player.updatePlayer();
  24.   player.displayPlayer();
  25.   player.shoot();
  26.   // displayAim();
  27.   handleBullets();
  28. }
  29. void keyPressed() {
  30.   final int k = keyCode;
  31.   if (k == LEFT || k == 'A')
  32.     player.playerSpd.x = -player.playerVel;
  33.   else if (k == RIGHT || k == 'D')
  34.     player.playerSpd.x = player.playerVel;
  35.   else if (k == UP || k == 'W')
  36.     player.playerSpd.y = -player.playerVel;
  37.   else if (k == DOWN || k == 'S')
  38.     player.playerSpd.y = player.playerVel;
  39. }
  40. void keyReleased() {
  41.   final int k = keyCode;
  42.   if ( (k == LEFT  || k == 'A') && player.playerSpd.x < 0
  43.     || (k == RIGHT || k == 'D') && player.playerSpd.x > 0 )
  44.     player.playerSpd.x = 0;
  45.   else if ( (k == UP || k == 'W') && player.playerSpd.y < 0
  46.     || (k == DOWN    || k == 'S') && player.playerSpd.y > 0 )
  47.     player.playerSpd.y = 0;
  48. }
  49. // other functions -----------------------------------------
  50. void handleBullets() {
  51.   //for (Bullet b: bullets)  b.run(); //unremovable bullets!
  52.   for ( int b = bullets.size(); b != 0; )
  53.     if ( bullets.get(--b).run() )  
  54.       bullets.remove(b);
  55.   print(bullets.size() + "\t");
  56. }
  57. //  void displayAim() {
  58. //    final static byte  aimSize = 5;
  59. //    final static color aimColor = 0;
  60. //    fill(aimColor);
  61. //    ellipse(mouseX, mouseY, aimSize, aimSize);
  62. //  }
  63. // classes =====================================================
  64. class Player {
  65.   final PVector playerPos = new PVector();
  66.   final PVector playerSpd = new PVector();
  67.   final static byte playerVel = 3;
  68.   final static byte bulletVel = 5;
  69.   final static byte  playerSize = 20;
  70.   final static byte  holeSize   = playerSize>>1;
  71.   final static color playerColor = #FF0000 ;
  72.   void updatePlayer() {
  73.     playerPos.add(playerSpd);
  74.     if (playerPos.x > width - holeSize) 
  75.       playerPos.x = width-holeSize;
  76.     else if (playerPos.x < holeSize)    
  77.       playerPos.x = holeSize;
  78.     if (playerPos.y > height-holeSize)  
  79.       playerPos.y = height-holeSize;
  80.     else if (playerPos.y < holeSize)    
  81.       playerPos.y = holeSize;
  82.     /*
  83.    if (playerPos.x > width)    playerPos.x = 0;
  84.      else if (playerPos.x < 0)   playerPos.x = width;
  85.     
  86.      if (playerPos.y > height)   playerPos.y = 0;
  87.      else if (playerPos.y < 0)   playerPos.y = height;
  88.      */
  89.   }
  90.   void displayPlayer() {
  91.     fill(playerColor);
  92.     ellipse(playerPos.x, playerPos.y, playerSize, playerSize);
  93.     fill(bg);
  94.     ellipse(playerPos.x, playerPos.y, holeSize, holeSize);
  95.   }
  96.   void shoot() {
  97.     final byte bulletGap = 3;
  98.     if (mousePressed && frameCount % bulletGap == 0)
  99.       player.addBullet();
  100.   }
  101.   void addBullet() {
  102.     final PVector bulletSpd = new PVector();
  103.     bulletSpd.set(mouseX, mouseY, 0);
  104.     bulletSpd.sub(playerPos);
  105.     bulletSpd.normalize();
  106.     bulletSpd.mult(bulletVel);
  107.     bullets.add( new Bullet(playerPos, bulletSpd) );
  108.   }
  109. } // class Player
  110. // ==========================================================
  111. class Bullet extends PVector {
  112.   PVector vel;
  113.   final static color bulletColor = #0000FF;
  114.   Bullet(PVector loc, PVector vel) {
  115.     super(loc.x, loc.y);
  116.     this.vel = vel.get();
  117.   }
  118.   void display() {
  119.     final byte bulletSize = 4;
  120.     fill(bulletColor);
  121.     ellipse(x, y, bulletSize, bulletSize);
  122.   }
  123.   boolean update() {
  124.     add(vel);
  125.     return x > width || x < 0 || y > height || y < 0;
  126.   }
  127.   boolean run() {
  128.     display();
  129.     return update();
  130.   }
  131. } // class Bullet
  132. //