Help me make bullets for a game I'm trying to make

Hi! I’m trying to build a retro top down arena shooter game and I’m struggling to get shooting to work. What I want is to have an ArrayList of bullets that can be shot using a keypressed fucntion and that are shot in the direction of the player is moving or the direction that the player last moved. I sort of have it working now, but I can’t shoot the bullets diagonally and I would really like to be able to do that. If anyone can maybe help me change my code up a bit to solve this problem or if anyone has ant tips to make my code better in general please help :slight_smile:

+//classes
player myPlayer;
Bullet myBullets;

void setup() {
size(1600, 1000);
myPlayer = new player(width/2, height/2, 4, 40);
myBullets = new Bullet(0, 0, 0, 0, 10);
}
void draw() {
background(0);
myPlayer.update();
myBullets.update(myBullets.x, myBullets.y, myBullets.speedX,
myBullets.speedY, myBullets.diameter);

myPlayer.draw();
myBullets.draw();
}

void keyPressed() {
myPlayer.keyp();
myBullets.keyp();
}

void keyReleased() {
myPlayer.keyr();
myBullets.keyr();
}

+class player {

float x, y, speed, size;
float xVelocity, yVelocity;
boolean keys = new boolean[4];

//constructor
player(int x1, int y1, int speed1, int size1) {
x = x1;
y = y1;
speed = speed1;
size = size1;
}

void update() {
xVelocity = 0;

// gives the bullet a speed and direction when keys are pressed
if (keys[0] == true) {
yVelocity = -speed;

}
if (keys[1] == true) {
  xVelocity = -speed;

}
if (keys[2] == true) {
  yVelocity = speed;
  
}
if (keys[3] == true) {
  xVelocity = speed;
  
}

x = x + xVelocity;
y = y + yVelocity;

collisionDetec();

}

void draw() {
circle(x, y, size);
}

void keyp() {
//allows for character movement when keys are pressed
if (key == ‘w’ || key == ‘W’) {
keys[0] = true;
}
if (key == ‘a’ || key == ‘A’) {
keys[1] = true;
}
if (key == ‘s’ || key == ‘S’) {
keys[2] = true;
}
if (key == ‘d’ || key == ‘D’) {
keys[3] = true;
}
}

void keyr() {
//ensures character doesn’t move when keys are released
if (key == ‘w’ || key == ‘W’) {
keys[0] = false;
}
if (key == ‘a’ || key == ‘A’) {
keys[1] = false;
}
if (key == ‘s’ || key == ‘S’) {
keys[2] = false;
}
if (key == ‘d’ || key == ‘D’) {
keys[3] = false;
}
}

void collisionDetec() {
//speed and direction in which x moves
//collision detection x axis
if (x > width - size/2) {
x = width - size/2;
}
if ( x < size/2 ) {
x = size/2;
}
//speed and direction in which y moves
//collision detection y axis
if ( y >= height - size/2) {
y = height - size/2;
}
if ( y <= size/2) {
y = size/2;
}
}
}

ArrayList bullets = new ArrayList();

class Bullet {
float x, y, speedX, speedY, diameter, startX, startY;
boolean keys = new boolean[4];

//constructor
Bullet(float x1, float y1, float speedX1, float speedY1, float
diameter1) {
x = x1;
y = y1;
speedX = speedX1;
speedY = speedY1;
diameter = diameter1;
}

void draw() {
// – because bullets are removed when it leaves screen
for (int i = bullets.size() - 1; i >= 0; i–) {
Bullet b = bullets.get(i);
b.update(b.x, b.y, b.speedX, b.speedY, diameter);
noStroke();
circle(b.x, b.y, diameter);
//when bullets are beyond screen they are removed
if ( ( b.x >= width || b.x < 0 ) || ( b.y >= height || b.y < 0 ) ) {
bullets.remove(i);
}
}
}

void update( float x2, float y2, float speedX2, float speedY2, float
diameter2 ) {
x = x2 + speedX2;
y = y2 + speedY2;
diameter = diameter2;
}

void keyp() {
if (key == ’ ') {
x = myPlayer.x;
y = myPlayer.y;
if ( startY == 0 ) {
speedX = startX;
speedY = 0;
} else {
speedY = startY;
speedX = 0;
}
//adds new bullet to ArrayList when spacebar is pressed
bullets.add(new Bullet(x, y, speedX, speedY, diameter));
}

if (key == 'w' || key == 'W') {
  keys[0] = true;
  startY = myPlayer.speed * - 1.5;
  startX = 0;
}
//gives bullets direction based on last direction of player
if (key == 'a' || key == 'A') {
  keys[1] = true;
  startX = myPlayer.speed * - 1.5;
  startY = 0;
}
if (key == 's' || key == 'S') {
  keys[2] = true;
  startY = myPlayer.speed * 1.5;
  startX = 0;
}
if (key == 'd' || key == 'D') {
  keys[3] = true;
  startX = myPlayer.speed * 1.5;
  startY = 0;
}

}

void keyr() {
//gives bullet its own speed and direction after it is fired
if (key == ‘w’ || key == ‘W’) {
keys[0] = false;
startY = myPlayer.speed * - 1.5;
}
if (key == ‘a’ || key == ‘A’) {
keys[1] = false;
startX = myPlayer.speed * - 1.5;
}
if (key == ‘s’ || key == ‘S’) {
keys[2] = false;
startY = myPlayer.speed * 1.5;
}
if (key == ‘d’ || key == ‘D’) {
keys[3] = false;
startX = myPlayer.speed * 1.5;
}
}
}

from a technical perspective, your code is not good.

Especially, the class Bullet should know only ONE bullet - hence the name. Everything like adding to the bullets ArrayList or for-loop over the ArrayList should take outside the class.

For example in a class BulletsManagement.

for diagonal shooting make sure speedX and speedY have a value that is for example both -1 OR 1,1 OR -1,1 and so on

do you think you could show me how to do that? I’m really new to using processing and programming in general so I wouldn’t even know where to begin

Hello,

Please format your code as a courtesy to this community:
https://discourse.processing.org/faq#format-your-code

:)
This is what happens if you do not format properly:

Not really, maybe i can make a mock-up

if you don’t mind doing that

I advice you to read the objects tutorial : https://www.processing.org/tutorials/objects/

here you can see a clean Bullet class - everything done to the ArrayList happens OUTSIDE of the class (mostly in the player class)


// ********************************************************************************
//         joined pde-file of folder  ShootTest3
// ********************************************************************************


/* OpenProcessing Tweak of *@*http://www.openprocessing.org/sketch/77863*@* */
/* !do not delete the line above, required for linking your tweak if you upload again */

// overall structure: The tab ShootTest1 is the main program.
// A player (only a white rectangle) 
// shoots bullets (in class Bullet).
// The player can only shoot upwards, follows mouse, click mouse. 
//
// idea from 
// http://forum.processing.org/topic/need-help-adding-shooting
// with help from 
// http://forum.processing.org/topic/have-eyes-follow-mouse
//
// Player
Player thePlayer = new Player();

// ------------------------------------------------------------------

void setup() {
  size(600, 480);
  cursor(CROSS);
}

void draw() {
  background(111);

  thePlayer.draw();
}

void mousePressed() {
  thePlayer.fire();
}

void keyPressed() {
  thePlayer.fire();
}

// ================================================================
// Bullet - Simple class for bullets
// http://www.processing.org/learning/topics/arraylistclass.html

class Bullet {

  float x;
  float y;
  float speedX;  
  float speedY;
  float widthBullet;
  float life = 255;

  Bullet(float tempX, float tempY, 
    float tempSpeedX, float tempSpeedY, 
    float tempWidthBullet) {
    x = tempX;
    y = tempY;
    widthBullet = tempWidthBullet;
    speedX = tempSpeedX; 
    speedY = tempSpeedY;
  }

  void move() {
    // Add speed to location
    x = x + speedX; 
    y = y + speedY;
    //
    // kill bullet when outside screen
    if (x<4) 
      life=-1;
    if (y<4) 
      life=-1;
    if (x>width-4) 
      life=-1;
    if (y>width-4) 
      life=-1;
    //
  } // method 

  boolean finished() {
    // bullet dead?
    if (life < 0) {
      return true;
    } else {
      return false;
    }
  }

  void display() {
    // Display the circle
    fill(244, 2, 2);
    noStroke();
    ellipse(x, y, 
      widthBullet, widthBullet);
  }
} // class 

// =====================================================================
// the Player class

class Player {

  ArrayList<Bullet> bullets;   
  PVector position, velocity; // contains x and y...

  // bullets
  int lastFired=millis();  // timer to determine when next bullet starts 
  final float bulletFlySpeed = 4.2;  // how fast bullet flies
  final int fireSpeed=200; // how often you fire / distance between bullets

  Player() {
    bullets  = new ArrayList();   
    position = new PVector(333, 333);
    velocity = new PVector();
    velocity.x = 0;
    velocity.y = 0;
  }

  void fire() {     // new2
    if (fireSpeed<=millis()-lastFired) {

      // ammoCount--;
      lastFired=millis();

      float xSpeed ;
      float ySpeed ; 
      float angle = update(mouseX, mouseY);
      xSpeed = cos(angle);
      ySpeed = sin(angle);
      xSpeed*= bulletFlySpeed;
      ySpeed*= bulletFlySpeed;
      if (ySpeed>0)
        ySpeed=0;
      bullets.add ( new Bullet( 
        position.x+12, position.y-14, 
        xSpeed, ySpeed, 
        5 ));
    } // if
  } // method 

  float update(int mx, int my) {
    //determines angle to mouse
    float angle = atan2(float(my)-(position.y-14), float(mx)-(position.x+12));
    return angle;
  }

  void draw() {
    // draw player & bullets
    //
    // draw player 
    pushMatrix();
    translate(position.x, position.y);
    noStroke();
    fill(255);
    rect (0, 0, 20, 40);
    popMatrix(); // undoes all

    // draw bullets
    for (Bullet currentBullet : bullets ) {    
      currentBullet.move();
      currentBullet.display();
    }

    // With an array, we say length, with an ArrayList, we say size()
    // The length of an ArrayList is dynamic
    // Notice how we are looping through the ArrayList backwards
    // This is because we are deleting elements from the list  
    for (int i = bullets.size()-1; i >= 0; i--) { 
      // An ArrayList 
      Bullet currentBullet = bullets.get(i);
      if (currentBullet.finished()) {
        // Items can be deleted with remove()
        bullets.remove(i);
      }//if
    }//for
  }//method
}//class
// End of joined file. ****************************************************************************
1 Like