java 绘图球的移动_在Java上绘制2个朝不同方向移动的球,但一个消失了

小编典典

问题…

while-loop 在事件调度线程中,该线程可调整图形对象的位置

Thread.sleep在paint方法上。

不打电话 super.paintComponent

在paintComponent方法中更新对象的状态。

Swing使用一个单线程模型,该模型负责将重绘请求分派给所有组件。

在EDT中执行任何停止处理这些事件的操作,将防止Swing重新绘制UI。这将使您的动画看起来像突然从一个步骤到整个步骤都消失了。

我要强调第4点

您无法控制重绘周期。重涂请求可能是出于多种原因而提出的,这些原因并非您所要求的,这将导致您的对象无法控制或在您不希望被更新时被更新。您绝对不能从任何paint方法中更改UI的任何部分的状态。

简单的例子

这是一个非常简单的示例,但它演示了在Swing中制作任何动画时需要了解的基本概念

public class SimpleBouncyBall {

public static void main(String[] args) {

new SimpleBouncyBall();

}

public SimpleBouncyBall() {

EventQueue.invokeLater(new Runnable() {

@Override

public void run() {

try {

UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());

} catch (Exception ex) {

}

JFrame frame = new JFrame("Test");

frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

frame.add(new CourtPane());

frame.pack();

frame.setLocationRelativeTo(null);

frame.setVisible(true);

}

});

}

public class CourtPane extends JPanel {

private Ball ball;

private int speed = 5;

public CourtPane() {

Timer timer = new Timer(40, new ActionListener() {

@Override

public void actionPerformed(ActionEvent e) {

Rectangle bounds = new Rectangle(new Point(0, 0), getSize());

if (ball == null) {

ball = new Ball(bounds);

}

speed = ball.move(speed, bounds);

repaint();

}

});

timer.setRepeats(true);

timer.setCoalesce(true);

timer.start();

}

@Override

public Dimension getPreferredSize() {

return new Dimension(100, 100);

}

@Override

protected void paintComponent(Graphics g) {

super.paintComponent(g);

if (ball != null) {

Graphics2D g2d = (Graphics2D) g.create();

g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

Point p = ball.getPoint();

g2d.translate(p.x, p.y);

ball.paint(g2d);

g2d.dispose();

}

}

}

public class Ball {

private Point p;

private int radius = 12;

public Ball(Rectangle bounds) {

p = new Point();

p.x = 0;

p.y = bounds.y + (bounds.height - radius) / 2;

}

public Point getPoint() {

return p;

}

public int move(int speed, Rectangle bounds) {

p.x += speed;

if (p.x + radius >= (bounds.x + bounds.width)) {

speed *= -1;

p.x = ((bounds.x + bounds.width) - radius) + speed;

} else if (p.x <= bounds.x) {

speed *= -1;

p.x = bounds.x + speed;

}

p.y = bounds.y + (bounds.height - radius) / 2;

return speed;

}

public void paint(Graphics2D g) {

g.setColor(Color.RED);

g.fillOval(0, 0, radius, radius);

}

}

}

2020-11-01

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值