使用动作监听器在边缘周围弹跳球

时间:2015-08-12 18:28:47

标签: java graphics actionlistener graphics2d actionevent

我对java比较陌生,我试图制作一个动画,当跑球时应该稳定地围绕封闭的矩形移动,从边缘反弹。单击STOP按钮时,动作应该冻结,最后当按下GO按钮时,它应该恢复。

这是我到目前为止制作的代码:

import javax.swing.*;

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.Ellipse2D;

// Does the drawing
class MyDrawing extends JPanel {

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

    g.setColor(Color.red);
    Ellipse2D.Double circle = new Ellipse2D.Double(300,120,50,50);
    g2.draw(circle);
    g2.fill(circle);
    Rectangle box1 = new Rectangle(10, 10, 380, 300);
    g.setColor(Color.BLACK);
    g2.draw(box1);
}
}

//Produces window plus everything inside it
public class ControlledBall extends JFrame {
JButton flash = new JButton("Go");
JButton steady = new JButton("Stop");

JPanel panel = new JPanel(new GridBagLayout());
MyDrawing drawing = new MyDrawing();
Timer timer;
public ControlledBall(){
    panel.add(flash);
    panel.add(steady);
    this.add(panel,BorderLayout.SOUTH);
    this.add(drawing,BorderLayout.CENTER);
    steady.addActionListener(new SteadyListener());
    flash.addActionListener(new MoveListener());
    timer = new Timer(500, new MoveListener());
    timer.start();

}


class MoveListener implements ActionListener{
    public void actionPerformed(ActionEvent event){
        timer.start();
        move();
    }
}

//Stuck what to implement here
class SteadyListener implements ActionListener{
    public void actionPerformed(ActionEvent event){    
    }
} 

public static void main(String[] args) {
    JFrame window = new ControlledBall();
    window.setSize(400,400);
    window.setTitle("Controlled Ball");
    window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    window.setVisible(true);

}
public void move() {

    long delay = 40;}
    private int x = 1;
    private int y = 1;
    private int dx = 3;
    private int dy = 2;{

    int dia = 30;
    Color color = Color.red;

    if(x + dx < 0 || x + dia + dx > getWidth()) {
        dx *= -1;
        color = Color.red;
    }
    if(y + dy < 0 || y + dia + dy > getHeight()) {
        dy *= -1;
        color = Color.red;
    }
    x += dx;
    y += dy;
}   
}

当我运行程序时,这是我的输出,但没有任何反应:

enter image description here

1 个答案:

答案 0 :(得分:0)

正如chiliNUT所说,保持方向和位置的x,y,dx,dy变量必须是类字段,而不是局部变量。

您可以将xPos,yPos字段添加到MyDrawing类以保持球的位置 和dx ControlledBall类保持方向,例如:

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagLayout;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.Ellipse2D;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;

//Does the drawing
class MyDrawing extends JPanel {

    private int xpos;
    private int ypos;

    public void setXPos(final int x) {
        this.xpos = x;
    }

    public void setYPos(final int y) {
        this.ypos = y;
    }

    public int getXpos() {
        return xpos;
    }

    public int getYpos() {
        return ypos;
    }

    @Override
    public void paintComponent(final Graphics g) {
        super.paintComponent(g);
        final Graphics2D g2 = (Graphics2D) g;
        g.setColor(Color.red);
        final Ellipse2D.Double circle = new Ellipse2D.Double(xpos, ypos, 50, 50);
        g2.draw(circle);
        g2.fill(circle);
        final Rectangle box1 = new Rectangle(10, 10, 380, 300);
        g.setColor(Color.BLACK);
        g2.draw(box1);
    }
}

// Produces window plus everything inside it
public class ControlledBall extends JFrame {
    private final JButton       flash       = new JButton("Go");
    private final JButton       steady  = new JButton("Stop");
    private final JPanel        panel       = new JPanel(new GridBagLayout());
    private final MyDrawing drawing = new MyDrawing();
    private final Timer         timer;

    //direction
    private int dx = 3;
    private int dy = 2;

    public ControlledBall() {
        panel.add(flash);
        panel.add(steady);
        this.add(panel, BorderLayout.SOUTH);
        this.add(drawing, BorderLayout.CENTER);
        drawing.setXPos(300);
        drawing.setYPos(150);
        steady.addActionListener(new SteadyListener());
        final MoveListener ml = new MoveListener();
        flash.addActionListener(ml);
        timer = new Timer(15, ml);
    }

    class MoveListener implements ActionListener {
        @Override
        public void actionPerformed(final ActionEvent event) {
            if (!timer.isRunning()){
                timer.start();
            }
            move();
        }
    }

    // Stuck what to implement here
    class SteadyListener implements ActionListener {
        @Override
        public void actionPerformed(final ActionEvent event) {
            if (timer.isRunning()){
                timer.stop();
            }
        }
    }

    private void move() {

        int x = drawing.getXpos();
        int y = drawing.getYpos();
        final int dia = 30;
        if (x + dx < 0 || x + dia + dx > getWidth()) {
            dx *= -1;
        }
        if (y + dy < 0 || y + dia + dy > getHeight()) {
            dy *= -1;
        }
        x += dx;
        y += dy;
        drawing.setXPos(x);
        drawing.setYPos(y);
        repaint();
    }

    public static void main(final String[] args) {
        final JFrame window = new ControlledBall();
        window.setSize(400, 400);
        window.setTitle("Controlled Ball");
        window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        window.setVisible(true);
    }
}