2

I'm a newbie in Java and I'm trying to make a ship fire a bullet. What I want is actually make the ship fire bullets as long as the Spacebar button is being held down. I've successfully made the ship move here and there and also fire the bullet. However the bullet just won't go up. Here's my code -

package learningPackage;
import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;

public class Draw extends JFrame implements Runnable {

    //Variables for the x and y coordinates, xDirection for modifying the values of x only.
    int x, y, xDirection;
    int bx, by;

    Image dbImage;
    Graphics dbGraphics;

    boolean shot;

    Rectangle bullet;
    
    
    //Thread run
    public void run() {
        try {
            while (true) {
                move();
                shoot();
                //Setting sleep to 0 will make it light-speed!
                Thread.sleep(5);

            }
        }
        catch (Exception e) {
            System.out.println("Error!");
            }
    }
    
    

    //Ship move
    //Ship moves only in one direction, x - axis
    public void move() {
        x += xDirection;

        //Collision detection
        if (x <= 10) {
            x = 10;
        }
        if (x >= 415) {
            x = 415;
        }
    }

    //KeyListeners
    public class AL extends KeyAdapter {
        public void keyPressed(KeyEvent e) {
            int keyCode = e.getKeyCode();
            if (keyCode == e.VK_LEFT) {
                xDirection = -2;
            }
            if (keyCode == e.VK_RIGHT) {
                xDirection = 2;
            }
            if (keyCode == e.VK_SPACE) {
                shot = true;
                
            }
        }

            public void keyReleased(KeyEvent e) {
                int keyCode = e.getKeyCode();
                if (keyCode == e.VK_LEFT) {
                    xDirection = 0;
                }
                if (keyCode == e.VK_RIGHT) {
                    xDirection = 0;
                }
                if (keyCode == e.VK_SPACE) {
                    shot = false;
                }
            }
        }


        //Constructor for the game frame
        public Draw() {
            super("Game");
            setSize(500, 500);
            setLocationRelativeTo(null);
            setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            setResizable(false);
            addKeyListener(new AL());

            x = 200;
            y = 465;


            setVisible(true);
        }
        
        //Double - buffering
        public void paint(Graphics g) {
            dbImage = createImage(getWidth(), getHeight());
            dbGraphics = dbImage.getGraphics();
            paintComponent(dbGraphics);
            g.drawImage(dbImage, 0, 0, this);

        }

        //All the graphics
        public void paintComponent(Graphics g) {
            
            bullet = new Rectangle(bx, by, 10, 10);
            g.setColor(Color.RED);
            //Ship rectangle
            g.fillRect(x, y, 75, 25);
            //Gun rectangle
            g.fillRect(x + 32, y - 15, 10, 15);
            
            //Setting the same values for bx and by as x and y so that the bullet will start from the Gun rectangle
            bx = x + 32;
            by = y - 15;
            
            if (shot == true) {
                
                g.setColor(Color.BLACK);
                g.fillRect(bx, by, bullet.width, bullet.height);

            }

            repaint();

        }

        
        public void shoot() {
            if (shot == true) {
                by = by - 2;
            }
            if (by <= -5) {
                //Resetting values
                bx = x + 32;
                by = y - 15;
                bullet = new Rectangle(bx, by, 10, 10);
                shot = false;
            }
        }

        //Main method
        public static void main(String[] args) {
            Draw gameTry = new Draw();
            Thread t1 = new Thread(gameTry);
            t1.start();

        }
    }

[Here's what happens when I just move the ship, working perfectly fine -][1]

[Here's what happens when I hold down space -][2]

I was actually coping this code from a tutorial but since the tutorial-code wasn't working out, I decided to do this on my own, but I can't do it on my own as well!

TA_800
  • 69
  • 1
  • 9
  • 1
    You never change anything about the `Rectangle` you are using as a bullet. if you are not *telling* it to move, it won't. – Timothy Groote Sep 28 '17 at 07:56
  • I'm having a hard time figuring out how any of this code is supposed to do anything. there a variables for the position of the ship, which are updated on keypresses, but also set to predefined values for every `Draw` call. does this work at all, currently? – Timothy Groote Sep 28 '17 at 08:00
  • @TimothyGroote I'm sorry but I didn't get you. Could you explain it to me further in detail? Am I not telling it to move by updating the values of the y-axis in the shoot() method? – TA_800 Sep 28 '17 at 08:01
  • Yep the ship movement works fine, even the collision. Only the bullet doesn't move up when the spacebar is pressed. It just appears on the ship (image in the post) but it just won't go up! – TA_800 Sep 28 '17 at 08:01
  • no, unfortunately not ;) gathering from what you describe, the `shoot()` method is only called once per "shot". you need to keep track of your bullets in a separate variable, then update their Y position in ( i think) `paintComponent`. something along the lines of `by -= 15;` – Timothy Groote Sep 28 '17 at 08:04
  • I just noticed i got confused because `Draw()` is a constructor. – Timothy Groote Sep 28 '17 at 08:04
  • oooh hang on, i think i know what you meant now. took me a while to shake the idea that this was an attempt at object oriented code. – Timothy Groote Sep 28 '17 at 08:06
  • 1
    the code in `shoot()` looks OK, but in your `paintcomponent` method, you are setting `by = y - 15;`, effectively undoing the changes made by `shoot()`. try setting `by` only at the *start* of the game, and when you need to reset the position of the bullet. – Timothy Groote Sep 28 '17 at 08:08
  • also, try not setting `bx` while the bullet has been fired, or it will move along sideways with the ship ;) – Timothy Groote Sep 28 '17 at 08:09
  • Okay, your suggestion did make my bullet go up but there arises another problem as well. Lemme try and fix it. Thank you so much for your help! – TA_800 Sep 28 '17 at 08:12

1 Answers1

2

The reason for the bullet not moving becomes appearant when you compare your shoot() method, and the paintComponent method.

Shoot checks if you have the shot boolean set, and if so, moves the bullet y position up by 2.

When the bullet leaves the top of the screen, it resets the "bullet". This is all fine, it does what it's supposed to.

 public void shoot() {
        if (shot == true) {
            by = by - 2; //this is fine, it moves the bullet up
        }
        if (by <= -5) {
            //Resetting values
            bx = x + 32;
            by = y - 15;
            bullet = new Rectangle(bx, by, 10, 10);
            shot = false;
        }
    }

Then comes paintComponent, which is executed time your game is "painted" to the screen.

It defines a rectangle for the bullet at its current position, draws the ship,

Then overwrites the bullet's x and y position so it sits on top of the ship. That is where your problem is

    public void paintComponent(Graphics g) {
        bullet = new Rectangle(bx, by, 10, 10);
        g.setColor(Color.RED);
        g.fillRect(x, y, 75, 25);
        g.fillRect(x + 32, y - 15, 10, 15);

        //you are messing with bx and by here.
        //probably because you wanted the bullet to be in the
        //same position as the ship.

        //this means they will be put back into the same position
        //for every time your game is painted to the screen.
        //my advice is, do *not* do this here.
        bx = x + 32;
        by = y - 15;

        if (shot == true) {
            g.setColor(Color.BLACK);
            g.fillRect(bx, by, bullet.width, bullet.height);
        }
        repaint();
    }
Timothy Groote
  • 8,614
  • 26
  • 52