gpt4 book ai didi

java - 在绘画中使用thread.sleep方法

转载 作者:行者123 更新时间:2023-11-30 08:19:16 25 4
gpt4 key购买 nike

我有一个工作代码,它基本上在屏幕上绘制 15 个可以拖动的矩形。我这样做是为了让矩形随着时间的推移落在屏幕的底部。虽然我有更大的数字(例如 500)的 thread.sleep 方法,但我仍然可以在屏幕上拖动矩形,因为它们掉落时没有任何问题。但当我开始将 thread.sleep 方法减少到更小的数字(例如 50)时,突然出现问题。诸如我只能拖动最多 2 个矩形之类的问题,然后矩形就会开始故障回到我没有拖动它们的位置。有时我最多只能拖动一个矩形,一旦选择了该矩形,就无法选择任何其他矩形进行拖动。我知道我的代码绝对是正确的,因为它在 thread.sleep 方法处于较大数字时工作,所以我的问题是:为什么当我将 thread.sleep 设为较小数字时它会开始出现故障?这是我的代码的一部分。

while (true) {

for (int i = 0; i < 15; i++) {

P.fY[i]++;
}
Thread.sleep(500);
frame.repaint();

} //the 15 stands for 15 rectangles, and the P.fY stands for the position of y.

最佳答案

因此,根据您的评论,您似乎确实需要有人来弄清楚如何计算作为时间函数的距离。

通过在每个帧循环中添加 1,您实际上是在说每个方 block 的速度为 1 像素/1 帧

相反,您应该利用时间并通过时间函数更新距离,使其成为1 像素/时间单位。这意味着方 block 的速度将与每秒的帧数无关。

<小时/>

我编写了一个代码示例。重要的方法是 Square#doUpdate() 方法。这正是您正在寻找的内容。

其遵循的过程是:

  1. Calculate time from last update, store it in delta.
  2. Update the time of the last update to the current time
  3. Calculate deltaX, which is deltaX = delta * velocityX
  4. Calculate deltaY, which is deltaY = delta * velocityY
  5. Add deltaX to x - this updates the x coordinate
  6. Add deltaY to y - this updates the y coordinate

代码如下:

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
import javax.swing.WindowConstants;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.LinkedList;

/**
* @author Obicere
*/
public class MovingSquare {

private volatile int viewportWidth;
private volatile int viewportHeight;

private final LinkedList<Square> squares = new LinkedList<>();

public MovingSquare() {
final JFrame frame = new JFrame("Moving Square");
final JPanel displayPanel = new JPanel() {
@Override
protected void paintComponent(final Graphics g) {
synchronized (squares) {
for (final Square square : squares) {

// Update the square's locations, ideally this will
// be separate of the painting thread
square.doUpdate();
final int x = (int) square.getX();
final int y = (int) square.getY();

g.setColor(square.getColor());
g.drawRect(x, y, square.squareSize, square.squareSize);

}
}
}
};

displayPanel.addMouseListener(new MouseAdapter() {
@Override
public void mouseReleased(final MouseEvent e) {
final Color nextColor = Color.getHSBColor((float) Math.random(), 1, 0.5f);
final float speedX = (float) Math.random();
final float speedY = (float) Math.random();

synchronized (squares) {
final Square newSquare = new Square(nextColor, speedX, speedY);
squares.add(newSquare);
newSquare.x = e.getX();
newSquare.y = e.getY();
}
}
});

displayPanel.addComponentListener(new ComponentAdapter() {
@Override
public void componentResized(ComponentEvent e) {
viewportWidth = displayPanel.getWidth();
viewportHeight = displayPanel.getHeight();
}
});

final Timer repaintTimer = new Timer(20, null);

repaintTimer.addActionListener(e -> {
if (!frame.isVisible()) {
repaintTimer.stop();
return;
}
frame.repaint();
});
repaintTimer.start();

displayPanel.setPreferredSize(new Dimension(200, 200)); // Sorry MadProgrammer
frame.add(displayPanel);
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}

public static void main(final String[] args) {
SwingUtilities.invokeLater(MovingSquare::new);
}


private class Square {

private final int squareSize = 25;

private volatile float x;
private volatile float y;

private volatile long lastUpdateTime;

private volatile boolean negateX;
private volatile boolean negateY;

private final float speedX;
private final float speedY;

private final Color color;

public Square(final Color color, final float speedX, final float speedY) {
this.color = color;
this.speedX = speedX;
this.speedY = speedY;

lastUpdateTime = System.currentTimeMillis();
}

/**
* Important method here!!
* <p>
* This updates the location of the squares based off of a set
* velocity and the difference in times between updates.
*/

public void doUpdate() {

// Gets the change in time from last update
final long currentTime = System.currentTimeMillis();
final long delta = currentTime - lastUpdateTime;
if (delta == 0) {
return;
}
// be sure to update the last time it was updated
lastUpdateTime = currentTime;

// Calculate the speed based off of the change in time
final float deltaX = getSpeedX(delta);
final float deltaY = getSpeedY(delta);

// Move each square by the change of distance, calculated from
// the change in time and the velocity.
final float nextX = x + deltaX;
final float nextY = y + deltaY;

handleBouncing(nextX, nextY);
}

private void handleBouncing(final float nextX, final float nextY) {

if (nextX < 0) {
x = 0;
flipX();
} else if (nextX + squareSize >= viewportWidth) {
x = viewportWidth - squareSize;
flipX();
} else {
x = nextX;
}

if (nextY < 0) {
y = 0;
flipY();
} else if (nextY + squareSize >= viewportHeight) {
y = viewportHeight - squareSize;
flipY();
} else {
y = nextY;
}
}

private float getSpeedX(final long delta) {
return (negateX ? -1 : 1) * delta * speedX;
}

private float getSpeedY(final long delta) {
return (negateY ? -1 : 1) * delta * speedY;
}

protected void flipX() {
negateX = !negateX;
}

protected void flipY() {
negateY = !negateY;
}

public float getX() {
return x;
}

public float getY() {
return y;
}

public Color getColor() {
return color;
}

}
}

实际操作:

Sorry MadProgrammer, needed to do preferred size initially

这可能看起来有点难以承受。逐步完成它,改变一些事情。疯狂一下,看看结果是什么。

还有一些websites that can help with velocity以及如何计算这样的事情。如果您需要进一步的帮助,请在下面发表评论,我会看看我能做些什么。

关于java - 在绘画中使用thread.sleep方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29186208/

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