Make a shoot function

Trying to make a copy of space invaders, it’s purely for fun but now i’ve used quite a while trying to make the shoot function work proberly. The problem is that my “bullet” disapears after i move my player, due to the fact that i called it’s x to be the players x, but i can’t figure out how to make it not update all the time, cause i’m calling the shoot function in draw() everytime i press UP. Hope you guys can help me out here, thx in advance.

Rune

class Shoot{
  
  int scl = 15;
  
  int bulletSpeed = -10;
  int bulletX;
  int bulletY;
  
  Shoot(){
    bulletY = 900;
  }
  
  void shoot(){
    edge();
    bulletX = p.x;
    fill(255);
    bulletY = bulletY + bulletSpeed;
    ellipse(bulletX, bulletY, scl, scl);
  }  

  void edge(){
    if (bulletY < 0+(scl*1.25)){
      bulletY = 900;
    }
  }
}
1 Like

Make Bullet it’s own class

Because sometimes you will have multiple bullets visible at the same time, put them in an Arraylist.

Upon shooting add a new bullet to the list and copy the player pos in it.

For loop over the list in draw and display them

There is more to it, but we come to that later.

Ah, sorry I misread your code

You already have the class

Sorry!

Thx this should be helpful

So i cant quite figure out how to make sure that when i shoot it’s only the current x value of my player. It still seems like it’s only running the function as long as it is getting the input “UP”

This line would belong into the constructor Shoot (if you use Shoot upon firing, like ....new Shoot(...);)

The function shoot is your display method of the class (you display the bullet with it). Therefore this is called throughout and should not receive the player position anymore.

The function / method shoot be called throughout from draw(). Not only when you shoot but throughout, because you want to see the bullet after firing it.

To get more help, post your entire code or show how you fire and call shoot.

<if(key == CODED){
if(keyCode == UP){

Shoot sh = s.get(0);
sh.shoot();>
that’s the way i call the shoot function, dont mind the fact that’s it’s only possible for me to call 1 object currently i’ll fix that afterwards. But declaring the x value in the constructor brings me to the problem of x just being the center of the screen where the player spawns

before setup() : Shoot sh ;

in keyPressed :

if(key == CODED){
    if(keyCode == UP){
       s.get(0).fire() ; // fire a new bullet
       sh=s.get(0);

in the class add

void fire() {  // to fire a new bullet (as opposed to displaying it throughout (shoot)
    bulletX = p.x;
    bulletY = 900;
}

**This - as I said - in draw() please sh.shoot(); // displaying it throughout **

Or when you have an ArrayLis already, say in draw():

// display multiple bullets that have been fired 
for ( Shoot currentBullet : s) {
     currentBullet.shoot();   
}

(or rename the method shoot() in the class as display() to not to confuse it with fire())

Chrisir

This is about as far as I got before I got bored.

class Bullet {
  float x, y;
  Bullet() {
    x = player.x;
    y = player.y;
  }
  boolean draw() {
    y--;
    fill(255);
    noStroke();
    ellipse(x, y, 3, 3);
    return y > -50;
  }
}

class Invader {
  float x, y;
  Invader() {
    x = random(600);
    y = random(300);
  }
  boolean draw() {
    fill(200, 0, 0);
    rect(x-10, y-10, 20, 20);
    if ( random(1) < 0.01 ) {
      beams.add( new Beam(x, y) );
    }
    return true;
  }
}

class Beam {
  float x, y;
  Beam(float ix, float iy) {
    x = ix;
    y = iy;
  }
  boolean draw() {
    y++;
    fill(255, 255, 0);
    rect(x-2, y-10, 4, 10);
    return y < height + 50;
  }
}

class Player {
  float x, y;
  Player() {
    x = 300;
    y = 400;
  }
  boolean draw() {
    fill(0, 255, 0);
    rect(x-20, y-20, 40, 20);
    return true;
  }
  void key() {
    if ( keyCode == ' ') bullets.add( new Bullet() );
  }
}

Player player = new Player();
ArrayList<Invader> invaders = new ArrayList();
ArrayList<Bullet> bullets = new ArrayList();
ArrayList<Beam> beams = new ArrayList();

void setup() {
  size(600, 400);
  noStroke();
  invaders.add( new Invader() );
}

void draw() {
  background(0);
  for ( int i = beams.size()-1; i >= 0; i--) if (!beams.get(i).draw()) beams.remove(i);
  for ( int i = bullets.size()-1; i >= 0; i--) if (!bullets.get(i).draw()) bullets.remove(i);
  for ( int i = invaders.size()-1; i >= 0; i--) if (!invaders.get(i).draw()) invaders.remove(i);
  player.draw();
}

void keyPressed() {
  player.key();
}