Hi, I am making a simple game,this is my first time to develop java game,but i think i am lost in my code,i could not display or show my bullet when i pressed arrow up,can you help me please how can i achieve on this.

here is my simple code.

import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.io.IOException;
import java.util.*;
import java.util.List;


public class Mygame{
    private Image ship;
    private boolean up;
    private boolean down;
    private boolean right;
    private boolean left;
    private int posX = 300;
    private int posY = 560;
    Graphics2D g2d;
    Thread gameloop;
    Bullet bb = new Bullet();
    Mypanel p = new Mypanel();



    public Mygame(){

        JFrame frame = new JFrame("Title");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        Mypanel panel = new Mypanel();

        panel.setPreferredSize(new Dimension(600,600));
        frame.add(panel);
        frame.pack();
        frame.setVisible(true);
        panel.startGame();



    }

     class Mypanel extends JPanel{

        private List <Bullet> bullets = new ArrayList <Bullet>();

        public Mypanel() {

            try {
                ship = ImageIO.read(getClass().getResource("images/spaceship.png"));
            } catch (IOException exc) {
                exc.printStackTrace();
            }

            bullets = new ArrayList <Bullet>();

            bullets.add(new Bullet(posX,posY));

            getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0, false),
                    "arrowUP");
            getActionMap().put("arrowUP",
                    arrowUP);


            Action arrowUP = new AbstractAction() {
            public void actionPerformed(ActionEvent e) {
                up = true;
                posY-=5;
                repaint();

            }
        };

          public void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2d = (Graphics2D) g;
            g2d.fillRect(0,0,600,600);
            g2d.setColor(Color.BLACK);
            g2d.drawImage(ship, posX, posY, null);

        }

    }



    class Bullet{
        final int speed = 2;
        int x,y;
        public Bullet(){}
         Bullet(int x, int y){
           this.x = x;
           this.y = y;

         }

        public void setX(int x){
            this.x = x;
        }


        public void setY(int y){
            this.y=y;
        }

        public int getX(){
            return x;
        }

       public int getY(){
           return y;
       }

       public void moveForward(){
           y-=speed;

       }

    }





       public static void main(String []args) {
          new Mygame();
    }   
}   

I see no code to paint bullets! In your paintComponent, around line 79, you need to loop through your arraylist of bullets, painting each bullet at its current x,y position.

Hi JamesCherrill,

you mean like this

 public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
g2d.fillRect(0,0,600,600);
g2d.setColor(Color.BLACK);
g2d.drawImage(ship, posX, posY, null);

  for(Bullet b : bullets){
     new Bullet(getX(),getY());
 }  

}

I am confuse...please help me on this.

No, that just creates a new Bullet.
For each existing bullet in the list you need to get its x and y coordinates, then draw something (eg a small circle) at that position.

Hi James, do i need to put method in my class bullet to draw a circle?

Hi James, is this what you mean ?

 public void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2d = (Graphics2D) g;
            g2d.fillRect(0,0,600,600);
            g2d.setColor(Color.BLACK);
            g2d.drawImage(ship, posX, posY, null);

            for(Bullet b: bullets){
                b.setX(posX);
                b.setY(posY);
            }

        }

A method in your bullet class is a good way to do it. Then call that method for every bullet from your main paintComponent. You last post is completely wrong - you set x,y when you should get them, and don't paint anything.

Hi james,

A method in your bullet class is a good way to do it.

you mean to use the setters and getters in my bullet class ?

Hi james, do i need to add another method for my bullet class to draw the circle ?and then call this method in paintComponent() ?

Here are some fragments from a little demo program I wrote. Hopefully these will illustrate how to do it. - the SimpleSprite class corresponds to your Bullets, and "sprites" is an arraylist of sprites....
First the main paintComponent method...

   @Override
   public void paintComponent(Graphics g) {
      Graphics2D g2d = (Graphics2D) g;
      paintBackground(g2d);  
      for (SimpleSprite s : sprites) {
         s.draw(g2d);// ask the sprite to draw itself at latest position
      }
   }

... then in the SimpleSprite class...

   public void draw(Graphics2D g2d) {
      g2d.setColor(color);
      g2d.fillOval((int) x, (int) y, 100, 100); // draw this at latest position.
   }

In summary, the main paintComponent method asks each Sprite to draw itself, passing the Graphics, and each Sprite draws itself as a circle at its current x,y position.

You should be able to adapt these concepts easily to your program.

Hi james, it draws now but why is it only one? i draw here small rect,i expected that when i pressed arrow up the bullet will go forward.

        public void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2d = (Graphics2D) g;
            g2d.fillRect(0,0,600,600);
            g2d.setColor(Color.BLACK);
            g2d.drawImage(ship, posX, posY, null);

            for(Bullet b: bullets){
                b.setX(posX);
                b.setY(posY);
                 b.draw(g2d);
            }


        }

I add another method same as your example inside in my Bullet class

       public void draw(Graphics2D g){
           Graphics2D gg = (Graphics2D)g;
           gg.setColor(Color.orange);
           gg.fillRect(getX(),getY(),5,5);

       }

No more time today - will try to enswer tomorrow. You need a Timer to update the position at regular intervals..,

for(Bullet b: bullets){
   b.setX(posX); // wrong!
   b.setY(posY); // why?
b.draw(g2d);

You keep resetting the position of every Bullet back to its original position every time you paint it. You don't need to / must not do that.

Hi James, I already change it to this way,..how do i move forward my bullet?

        public void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2d = (Graphics2D) g;
            g2d.fillRect(0,0,600,600);
            g2d.setColor(Color.BLACK);
            g2d.drawImage(ship, posX, posY, null);

            for(Bullet b: bullets){
                b.draw(g2d);
            }

        }

Hi James,This is how i understand how to update the position of my bullet,but it's not moving

        public void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2d = (Graphics2D) g;
            g2d.fillRect(0,0,600,600);
            g2d.setColor(Color.BLACK);
            g2d.drawImage(ship, posX, posY, null);

            for(Bullet b: bullets){
                b.draw(g2d);
            }

        }

        public void update(){
            for(Bullet b: bullets){
                b.update();
            }
        }

I implements runnable in my Main class

    public void start(){
        gameloop = new Thread(this);
        gameloop.start();
    }



    public void run(){

        Thread t = Thread.currentThread();

        while(t==gameloop){
            try {
                Thread.sleep(20);
            }
            catch(InterruptedException e) {
                e.printStackTrace();
            }

             p.update();
             bb.draw(g2d);

        }
    }

in the main method

  public static void main(String []args) {

        (new Mygame()).start();


    }

I add update method in my Bullet Class

 public void update(){
            x += speed;
            y += speed;

        }

Loops with a sleep are always a problem - too many ways for then to go wrong. The best way is to use a java.util.Timer to call your main update() method at regular intervals. Lots of examples on the web, eg
http://www.easywayserver.com/blog/java-scheduling-task-with-timer-class/

And don;t forget to call repaint() for your JPanel after running update, otherwize the screen won't be updated with the new positions.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.