user2880113
user2880113

Reputation: 355

Add moving objects to JFrame

I'm creating a java game. In the game there are a hero and a bubble. The hero is supposed to move when I press the arrow keys and the bubble is supposed to have continuous diagonal movement. When I add the hero or the bubble directly into to the JFrame separately I get the desired behavior, but when I add them both I just get a very small square! I tried to add them to the same JPanel and after add that JPanel to the JFrame but it is not working. Probably I have to define some type of layout to the JPanels.

What am I doing wrong?

Code:

public class Pang {
public static void main(String[] args) {

    JFrame f=new JFrame();
    JPanel gamePanel=new JPanel();
    gamePanel.setPreferredSize(new Dimension(800, 600));


    DrawHero d=new DrawHero();
    DrawBubble bubble=new DrawBubble();

    gamePanel.add(d);
    gamePanel.add(bubble);

    f.add(gamePanel);

    f.setVisible(true);
    f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    f.setSize(800, 600);
}
}


public class DrawHero extends JPanel implements ActionListener, KeyListener {
    Timer myTimer = new Timer(5, this);
    int x = 0, y = 0, dx = 0, dy = 0, step = 10;
    private transient Image imageHero = null;

    public DrawHero() {
        myTimer.start();
        addKeyListener(this);
        setFocusable(true);
        setFocusTraversalKeysEnabled(false);

    }

    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2 = (Graphics2D) g;

        imageHero = getHeroImage();

        g2.drawImage(imageHero, x, y, 40, 40, null);

    }

    public Image getHeroImage() {
        Image image = null;

        image = getImage("hero.png");
        return image;
    }

    public Image getImage(String path) {
        Image tempImage = null;
        try {
            URL heroiURL = DrawHero.class.getResource(path);
            tempImage = Toolkit.getDefaultToolkit().getImage(heroiURL);
        } catch (Exception e) {
            System.out.println("Error loading hero image! - "
                    + e.getMessage());
        }
        return tempImage;
    }

    public void actionPerformed(ActionEvent e) {

        repaint();
    }

    public void moveUp() {

        y = y - step;

    }

    public void moveDown() {
        y = y + step;

    }

    public void moveLeft() {

        x = x - step;

    }

    public void moveRight() {
        x = x + step;

    }

    public void keyPressed(KeyEvent e) {
        int keyCode = e.getKeyCode();
        if (keyCode == KeyEvent.VK_UP) {
            moveUp();
        }
        if (keyCode == KeyEvent.VK_DOWN) {
            moveDown();
        }
        if (keyCode == KeyEvent.VK_LEFT) {
            moveLeft();
        }
        if (keyCode == KeyEvent.VK_RIGHT) {
            moveRight();
        }
    }

    public void keyTyped(KeyEvent e) {
    }

    public void keyReleased(KeyEvent e) {
    }
}


public class DrawBubble extends JPanel implements ActionListener, KeyListener {
    Timer myTimer = new Timer(5, this);
    int x = 100, y = 200, dx = 0, dy = 0, step = 10;
    private transient Image imageHero = null;

    public DrawBubble() {
        myTimer.start();
        addKeyListener(this);
        setFocusable(true);
        setFocusTraversalKeysEnabled(false);

    }

    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2 = (Graphics2D) g;
        g2.fill(new Ellipse2D.Double(x, y, 40, 40));


    }


    public void actionPerformed(ActionEvent e) {

         x=x+dx;
         y=y+dy;
        repaint();
    }

    public void moveBubble() {
         dy=2;
         dx=2;
    }



    public void keyPressed(KeyEvent e) {
        moveBubble();

    }

    public void keyTyped(KeyEvent e) {
    }

    public void keyReleased(KeyEvent e) {
    }
}

Upvotes: 2

Views: 1329

Answers (2)

Andrew Thompson
Andrew Thompson

Reputation: 168845

I recommend that neither the DrawHero nor DrawBubble (which should be called Hero nor Bubble respectively) should extend any JComponent. Instead each should simply know how to draw itself to a Graphics object passed to it, when requested to do so.

Then a single GameField or PlayingArea class should keep references to all the Bubble objects and the Hero and draw call the draw(Graphics) method of those objects.

Using this approach it is not necessary to worry about layouts within the GameField component (they become irrelevant).

That is the basic strategy I pursue for rendering the stationary objects in this answer to [Collision detection with complex shapes.

Upvotes: 3

camickr
camickr

Reputation: 324197

When I add the hero or the bubble directly into to the JFrame separately I get the desired behavior, but when I add them both i just get a very small square!

The default layout manager for a JFrame is a BorderLayout. When you use add(component) without a constraint the component goes to the CENTER. Only one component can be added to the CENTER, so only the last one added is displayed.

I tried to add them to the same JPanel and after add that JPanel to the JFrame but it is not working.

The default layout manager for a JPanel is the FlowLayout which respects the preferred size of component. The problem is you don't override the getPreferredSize() method so the size is (0, 0) and there is nothing to paint.

Probably I have to define some type of layout to the JPanels.

Actually since you want random motion you need to use a null layout on the panel and then use the setSize() and setLocation() method of your components to position the components.

Then when you do this the custom painting should always be done at (0, 0) instead of (x, y) since the location will control where the component is painted on the panel.

Upvotes: 3

Related Questions