我有下面的代码,我需要对其进行更改,以使鼠标单击即可生成球,而不是一次生成所有球。我知道我需要使用鼠标侦听器,但是我不知道如何在不“破坏”应用程序的情况下将其集成到我的鼠标中。
无需更改
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();
}
}
答案 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)