gpt4 book ai didi

Java JPanel 闪烁

转载 作者:行者123 更新时间:2023-11-30 04:06:59 29 4
gpt4 key购买 nike

我遇到了与 JPanel 中闪烁相关的问题。不知道为什么, window 里的球时不时地闪烁。我尝试了几种方法,比如双缓冲、BufferStrategy、Canvas,但都不起作用。主要思想是使用线程池,当一个球已经绑定(bind)了几次时,将其删除并创建另一个线程。必须同时有很多球。

这是我的代码:

public class BallWindow extends JFrame {

private static final long serialVersionUID = 1L;
private BallPanel panel;
private final int WINDOW_WIDTH = 700;
private final int WINDOW_HEIGHT = 700;

public BallWindow() {
super("Balls");
this.panel = new BallPanel();
this.panel.setPreferredSize(new Dimension(WINDOW_WIDTH, WINDOW_HEIGHT));
this.add(panel);
this.pack();
}

public int getPanelWidth() {
return panel.getWidth();
}

public int getPanelHeight() {
return panel.getHeight();
}

public void initGUI() {
this.setSize(WINDOW_WIDTH, WINDOW_HEIGHT);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setVisible(true);
}
//Balls have to tell to the window to paint them, just once
public void drawMe(BallThread ball) {
this.panel.drawMe(ball);
}
}


class BallPanel extends JPanel {

private static final long serialVersionUID = 1L;
private Queue<BallThread> queue;

public BallPanel() {
this.queue = new LinkedList<>();
}

public void drawMe(BallThread ball) {
this.queue.add(ball);
}

@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
while(queue.peek() != null) {
queue.poll().drawBall(g2);
}
}
}

这是球(它们是线程):

public class BallThread implements Runnable {

private int x;
private int y;
private int dx;
private int dy;
private int diameter;
private int bounces;
private BallWindow window;

public BallThread(int x, int y, int dx, int dy, int diameter, int lBounces, BallWindow window) {
this.x = x;
this.y = y;
this.dx = dx;
this.dy = dy;
this.diameter = diameter;
this.bounces = lBounces;
this.window = window;
}

public int getX() {
return x;
}

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

public int getY() {
return y;
}

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

public void setWindow(BallWindow window) {
this.window = window;
}

public void drawBall(Graphics2D g) {
g.setColor(Color.BLUE);
g.fillOval(this.x, this.y, this.diameter, this.diameter);
}

private void move() {
this.x += this.dx;
this.y += this.dy;
bounce();
this.window.drawMe(this);
}

private void bounce() {
if(this.x < 0) {
this.x = 0;
this.dx = -dx;
this.bounces--;
} else if(this.x+diameter > this.window.getPanelWidth()) {
this.x = this.window.getPanelWidth()-diameter;
this.dx = -dx;
this.bounces--;
}

if(this.y < 0) {
this.y = 0;
this.dy = -dy;
this.bounces--;
} else if(this.y+diameter > this.window.getPanelHeight()) {
this.y = this.window.getPanelHeight()-diameter;
this.dy = -dy;
this.bounces--;
}
}

@Override
public void run() {
while(this.bounces > 0) {
this.move();
try {
Thread.sleep(20);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
GameLoop.decreaseThreadsWorking();
}

}

游戏循环:

public class GameLoop {

private final int N_BALLS = 20;
private static int nThreadsNow = 0;
private BallWindow window;
private ExecutorService poolThreads;

public GameLoop() {
this.poolThreads = Executors.newFixedThreadPool(N_BALLS);
gameLoop();
}

private void gameLoop() {
window = new BallWindow();
window.initGUI();

while(true) {
while(GameLoop.nThreadsNow < this.N_BALLS) {
BallThread ball = BallFactory.getInstance().getBall(window);
this.poolThreads.execute(ball);
GameLoop.nThreadsNow++;
}
window.repaint();

try {
Thread.sleep(20);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

public static void decreaseThreadsWorking() {
GameLoop.nThreadsNow--;
}

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

最佳答案

这里有很多强耦合,看起来很奇怪的是球不断地将自己添加到要绘制的队列中。

把那 block 拿出来,让框架按计划重新粉刷。这包括重新绘制所有球,而不是试图跟上不断增加的队列。

关于Java JPanel 闪烁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20519006/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com