gpt4 book ai didi

java - 重绘方法在短暂延迟后停止工作

转载 作者:行者123 更新时间:2023-11-30 03:04:43 24 4
gpt4 key购买 nike

我正在尝试创建一个简单的面板,其中二维球上下弹跳。我无法让它工作,因为由于某种原因我不能每秒调用重绘方法超过一次。该设计基本上是有一个对象可以通过 move() 方法给予“脉冲”。每次调用evaluatePosition方法时,都会通过耗时、速度和加速度计算当前位置。面板的代码是:

public class Display extends JPanel {
private MovableObject object = new MovableObject(new Ellipse2D.Double(5,5,50,50));
private static final int DELAY = 1000;

public Display(){
object.move(50,50);
Timer timer = new Timer(DELAY, new ActionListener(){
@Override
public void actionPerformed(ActionEvent e){
object.evaluatePosition();
repaint();
}
});
timer.start();
}
}

@Override
public void paintComponent(Graphics g){
super.paintComponent(g);
Graphics2D g2 = (Graphics2D)g;
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g.drawOval((int)object.getPosition().getX(), (int)object.getPosition.getY()
(int)object.getShape().getWidth(), object.getShape().getHeight());
}

此代码适用于 DELAY=1000,但不适用于 DELAY=100 或 DELAY=10 等。我在这里阅读了一些示例代码,但在我看来,它们都像我已经做过的那样。那么为什么我的代码不起作用?

编辑(2016-01-30):由于这似乎确实是一个性能问题,因此这是 MovableObject 的代码(我只是认为它是无关紧要的,您可能会明白原因):

public class MovableObject {
// I would really like to use Shape instead of Ellipse2D so that
// objects of any shape can be created
private Ellipse2D.Double shape;
private Point position;
// Vector is my own class. I want to have some easy vector addition and
// multiplication and magnitude methods
private Vector velocity = new Vector(0, 0);
private Vector acceleration = new Vector(0, 0);
private Date lastEvaluation = new Date();

public MovableObject(Ellipse2D.Double objectShape){
shape = objectShape;
}

public void evaluatePosition(){
Date currentTime = new Date();
long deltaTInS = (currentTime.getTime()-lastEvaluation.getTime())/1000;
// s = s_0 + v*t + 0.5*a*t^2
position = new Point((int)position.getX()+ (int)(velocity.getX()*deltaTInS) + (int)(0.5*acceleration.getX()*deltaTInS*deltaTInS),
(int)position.getY()+ (int)(velocity.getY()*deltaTInS) + (int)(0.5*acceleration.getY()*deltaTInS*deltaTInS));
lastEvaluation = currentTime;
}
}

public void move(Vector vector){
velocity = velocity.add(vector);
evaluatePosition();
}

public Point getPosition(){
return position;
}

public Ellipse2D.Double getShape(){
return shape;
}

我的移动方法不会改变位置,而是改变速度。 请注意,我刚刚将形状对象从 Shape 更改为 Ellipse2D,以测试我的代码是否因附加代码而存在性能问题。因此,如果您认为这比需要的更复杂:我实际上想添加一些复杂性,以便 MovableObject 可以具有任何形状子类的形状。我见过很多对我来说似乎更复杂并且渲染速度更快的代码。所以我想知道这有什么问题(除了渲染椭圆有点太复杂之外)。

最佳答案

好的,这是一个简单的示例,基于您留下的脱离上下文的代码片段,它似乎没有任何问题。它具有由简单 slider 控制的可变速度...

Bounce

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.RenderingHints;
import java.awt.Shape;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.AffineTransform;
import java.awt.geom.Ellipse2D;
import java.awt.geom.GeneralPath;
import java.awt.geom.PathIterator;
import java.util.Random;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JSlider;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

public class Display extends JPanel {

public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}

JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new Display());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}

private MovableObject object = new MovableObject(new Ellipse2D.Double(5, 5, 50, 50));
private int delay = 40;

private Timer timer = new Timer(40, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
object.evaluatePosition(getSize());
repaint();
}
});

private JSlider slider = new JSlider(5, 1000);

public Display() {
object.move(50, 50);

slider = new JSlider(5, 1000);
slider.setSnapToTicks(true);
slider.setMajorTickSpacing(10);
slider.setMinorTickSpacing(5);
setLayout(new BorderLayout());
add(slider, BorderLayout.SOUTH);

// This is simply designed to put an artificate delay between the
// change listener and the time the update takes place, the intention
// is to stop it from pausing the "main" timer...
Timer delay = new Timer(250, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if (timer != null) {
timer.stop();
}
timer.setDelay(slider.getValue());
timer.start();
}
});

slider.addChangeListener(new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
delay.restart();
repaint();
}
});

slider.setValue(40);
}

@Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}

@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g.create();
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2.draw(object.getTranslatedShape());
FontMetrics fm = g2.getFontMetrics();
String text = Integer.toString(slider.getValue());
g2.drawString(text, 0, fm.getAscent());
g2.dispose();
}

public class MovableObject {

private Shape shape;
private Point location;

private int xDelta, yDelta;

public MovableObject(Shape shape) {
this.shape = shape;
location = shape.getBounds().getLocation();
Random rnd = new Random();
xDelta = rnd.nextInt(8);
yDelta = rnd.nextInt(8);

if (rnd.nextBoolean()) {
xDelta *= -1;
}
if (rnd.nextBoolean()) {
yDelta *= -1;
}
}

public void move(int x, int y) {
location.setLocation(x, y);
}

public void evaluatePosition(Dimension bounds) {
int x = location.x + xDelta;
int y = location.y + yDelta;

if (x < 0) {
x = 0;
xDelta *= -1;
} else if (x + shape.getBounds().width > bounds.width) {
x = bounds.width - shape.getBounds().width;
xDelta *= -1;
}
if (y < 0) {
y = 0;
yDelta *= -1;
} else if (y + shape.getBounds().height > bounds.height) {
y = bounds.height - shape.getBounds().height;
yDelta *= -1;
}

location.setLocation(x, y);
}

public Shape getTranslatedShape() {
PathIterator pi = shape.getPathIterator(AffineTransform.getTranslateInstance(location.x, location.y));
GeneralPath path = new GeneralPath();
path.append(pi, true);
return path;
}

}
}

你也可以看看

更多示例...

关于java - 重绘方法在短暂延迟后停止工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35078074/

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