使用鼠标单击生成球

时间:2018-10-07 01:51:31

标签: java swing awt mouselistener

我有下面的代码,我需要对其进行更改,以使鼠标单击即可生成球,而不是一次生成所有球。我知道我需要使用鼠标侦听器,但是我不知道如何在不“破坏”应用程序的情况下将其集成到我的鼠标中。

无需更改

import javax.swing.JFrame;
import java.awt.Canvas;
import java.awt.Dimension;
import java.awt.Graphics2D;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.image.BufferStrategy;



public class Display {
    public final int width;
    public final int height;

    private JFrame frame;

    private boolean closeRequested;

    private long lastFrameTime;

    private BufferStrategy bufferStrategy;
    private Graphics2D graphics;

    public Display(int width, int height){
        this.width = width;
        this.height = height;
        initialize();
    }

    private void initialize() {
        frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
        frame.setAutoRequestFocus(true);
        frame.setResizable(false);

        frame.addWindowListener(new WindowAdapter(){
            @Override
            public void windowClosing(WindowEvent e){
                    closeRequested = true;
    }
        });

        Canvas canvas = new Canvas();
        canvas.setIgnoreRepaint(true);
        canvas.setPreferredSize(new Dimension(width, height));

        frame.getContentPane().add(canvas);
        frame.setVisible(true);
        frame.pack();
        frame.setLocationRelativeTo(null);

        canvas.createBufferStrategy(2);
        bufferStrategy = canvas.getBufferStrategy();
        graphics = (Graphics2D) bufferStrategy.getDrawGraphics();

        lastFrameTime = System.currentTimeMillis();

    }
    public boolean isCloseRequested(){
        return closeRequested;
    }
    public void destroy() {
        frame.dispose();
    }

    public void update(){
        if (bufferStrategy.contentsLost()){
            graphics.dispose();
            graphics = (Graphics2D) bufferStrategy.getDrawGraphics();
        }
        bufferStrategy.show();
    }

    public Graphics2D getGraphics() {
        return graphics;
    }

    public void sync(int fps) {
        if (fps < 1){
            return;
        }
        long currentFrameTime = System.currentTimeMillis();
        long deltaTime = currentFrameTime - lastFrameTime;
        long timeToSleep = (1000/fps) - deltaTime;

        while (System.currentTimeMillis() - currentFrameTime < timeToSleep){
            try{
                Thread.sleep(1L);
            } catch (InterruptedException e) {
            }
        }
        lastFrameTime = System.currentTimeMillis();
    }

}

无需更改

    import java.awt.Color;

public class Ball {

    public float x;
    public float y;

    public float sX;
    public float sY;

    public int radius;

    public Color color;

    public Ball(float x, float y, float sX, float sY, int radius, Color color){
        this.x = x;
        this.y = y;
        this.sX = sX;
        this.sY = sY;
        this.radius = radius;
        this.color = color;
    }

}

我认为这是添加鼠标侦听器以生成新球的地方。

如何更改addBalls()逻辑以通过鼠标单击来生成球?

import java.awt.Color;
import java.awt.Graphics2D;
import java.util.ArrayList;
import java.util.Random;


public class BouncingBallsApp {

    private Display display;

    private ArrayList<Ball> balls = new ArrayList<>();

    public BouncingBallsApp() {
        display = new Display(800,600);
        addBalls();
        mainLoop();
        display.destroy();
    }

    private void mainLoop() {
        while (!display.isCloseRequested()){
            updatePhysics();
            draw(display.getGraphics());
            display.update();
            display.sync(60);
        }
    }
    //Question????How to change this logic to generate ball with mouse click
    private void addBalls() {
        int numberOfBalls = 20;
        Random random = new Random();

        for (int i = 0; i < numberOfBalls; i++){
            int radius = random.nextInt(40) + 10;

            int x = random.nextInt(display.width - radius * 2) + radius;
            int y = random.nextInt(display.height - radius * 2) + radius;

            float sX = random.nextFloat() * 10f + 3f;
            float sY = random.nextFloat() * 10f + 3f;

            Color color;
            switch (random.nextInt(4)){
                case 0:
                    color = Color.red;
                    break;
                case 1:
                    color = Color.green;
                    break;
                case 2:
                    color = Color.yellow;
                    break;
                default:
                    color = Color.blue;
                    break;                   
            }
            Ball ball = new Ball(x, y, sX, sY, radius, color);
            balls.add(ball);
        }
    }

    private void updatePhysics() {
        for (Ball ball : balls){

            ball.x += ball.sX;
            ball.y += ball.sY;

            if (ball.x - ball.radius < 0){
                ball.sX = Math.abs(ball.sX);
            } else if (ball.x + ball.radius > display.width){
                ball.sX = -Math.abs(ball.sX);
            }
            if (ball.y - ball.radius < 0){
                ball.sY = Math.abs(ball.sY);
            } else if (ball.y + ball.radius > display.height){
                ball.sY = -Math.abs(ball.sY);
            }
        }
    }

    private void draw(Graphics2D g) {
        g.setBackground(Color.black);
        g.clearRect(0,0, display.width, display.height);

        for (Ball ball : balls){
        g.setColor(ball.color);

        int x = (int) (ball.x - ball.radius);
        int y = (int) (ball.y - ball.radius);
        int size = ball.radius * 2;

        g.fillOval(x, y, size, size);
        }
    }

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

}

1 个答案:

答案 0 :(得分:1)

BouncingBallsApp构造函数中进行以下更改:

public BouncingBallsApp() {
    display = new Display(800,600);

    //instead of calling add balls directly, use a mouse listener 
    //addBalls();  
    display.addMouseListener(getListener());

    mainLoop();
    display.destroy();
}

getListener()方法添加到BouncingBallsApp

private MouseListener getListener() {

    return new MouseAdapter() {
        @Override
        public void mousePressed(MouseEvent e) {
            addBalls(1); //call add balls when mouse pressed 
        }
    };
}

然后稍微更改addBalls(),以使numberOfBalls成为参数:

private void addBalls(int numberOfBalls) {
   //int numberOfBalls = 20;
   .....

将鼠标侦听器支持添加到Display

//add mouse listener to canvas 
void addMouseListener(MouseListener listener) {

    canvas.addMouseListener(listener);  //requiers to make canvas a field  
}

全部完成。
要生成球,只需单击画布。
(修改后的代码的link