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!
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();
}