Hello,

I havr created a program in which there are two classes. One ship, and shooter. However it is not working.

Any idea?

package shooter;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Rectangle;
import java.awt.event.KeyEvent;

public class Ship implements Runnable {
    
    int x, y, xDirection;

    boolean shoot = false;
    
    boolean ready = false;
    int bullX;
    int bullY;
    Rectangle bullet;
    
    
    public Ship(){
        x = 175;
        y = 275;
    }
    
    public void draw(Graphics g){
        g.setColor(Color.BLUE);
        g.fillRect(x, y, 40, 10);
        g.fillRect(x+18, y-7, 4, 7);
        if (shoot)
        {
            g.setColor(Color.BLACK);
            g.fillRect(bullet.x, bullet.height, bullet.width, bullet.height);
        }
    }
    
    public void move(){
        x += xDirection;
        if(x <= 0)
            x = 0;
        if(x >= 360)
            x = 360;
    }
    
    public void setXDirection(int xdir){
        xDirection = xdir;
    }
    
    public void keyPressed(KeyEvent e){
        int keyCode = e.getKeyCode();
        if(keyCode == e.VK_LEFT){
            setXDirection(-1);
        }
        if(keyCode == e.VK_RIGHT){
            setXDirection(1);
        }
        
         if(keyCode == e.VK_SPACE){
          if(bullet == null)
              ready = true;
          if (ready)
            
                bullY = y-7;
                bullX = x + 18;
                bullet = new Rectangle(bullX, bullY, 3 , 5); // 3 and 5 width and height
                shoot = true;
            
        }
    }
    
    
    public void keyReleased(KeyEvent e){
        int keyCode = e.getKeyCode();
        if(keyCode == e.VK_LEFT){
            setXDirection(0);
        }
        if(keyCode == e.VK_RIGHT){
            setXDirection(0);
        }
        if(keyCode == e.VK_SPACE){
           
            ready = false;
            if(bullet.y <=-5)
                bullet = new Rectangle(0,0,0,0);
            shoot = false;
      
            
            
        }
    }
    
    public void shoot(){
        if(shoot)
        {
            bullet.y--;
            
        }   
    }
            
    
    @Override
    public void run(){
        try{
            while(true){
                move();
                Thread.sleep(5);
            }
        }catch(Exception e){System.err.println(e.getMessage());}
    }
    
}

My second class

package shooter;


import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import javax.swing.JFrame;

public class Shooter extends JFrame {
    
    private Image dbImage;
    private Graphics dbg;
    
    static Ship s1 = new Ship();
        
    public Shooter(){
        setSize(400,300);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setResizable(false);
        setVisible(true);
        addKeyListener(new AL());
    }
    
    @Override
    public void paint(Graphics g){
         
        dbImage = createImage(getWidth(), getHeight());
        dbg = dbImage.getGraphics();
        paintComponent(dbg);
        g.drawImage(dbImage, 0, 0, this);
    }
    public void paintComponent(Graphics g){
        //Draw the ship
        s1.draw(g);
        s1.shoot();
        repaint();
    }
    
    public class AL extends KeyAdapter {
        @Override
        public void keyPressed(KeyEvent e){
            s1.keyPressed(e);
        }
        @Override
        public void keyReleased(KeyEvent e){
            s1.keyReleased(e);
        }
    }
    
    public static void main(String[] args) {
        Shooter shoot = new Shooter();
        //Threads
        Thread ship = new Thread(s1);
        ship.start();
    }
}


Program is running but shooting is not working

Your loop calls move() to update positions etc, but Swing has no reason to update the screen. Call repaint() on your main window to request a screen refresh (which will use your latest values).
Your paint method seems to be doing its own double buffering? If so, no need, because Swing does its own double buffering anyway.
http://java.sun.com/products/jfc/tsc/articles/painting/

You use a thread and a loop to control animation - this certainly can be done, but you will avoid all kind of thread-related problems if you use a javax.swing.Timer to call your move() method at regular intervals. ps 5 mSec (200 moves/sec) is probably too fast. The eye isn't going to see anything faster than 50/60 mSec intervals, even if your program can refresh that fast.

Comments
Very decent approach!

Thank you for the reply, I don't understand, I already have repaint() in my main window. Should I call it somewhere else?

That's in paintComponent - that's the wrong place - it will only be called when Swing has called your paint anyway. You need to call it each time you have updated your positions etc.

Ok so what I did is I created a shooter object in my Ship class, and call the method repaint in the move() method.

It is still not working?

Put a load of print statements into your code, printing the values of the key variables at each stage so you can see where it's going wrong. Especially in move() and paintComponent(...)

This article has been dead for over six months. Start a new discussion instead.