我正在为Java中的弹跳球制作一个JApplet。
这是我到目前为止所拥有的。我可以让球向右移动,但是我不能再让它向左移动。我仍然对为什么使用计时器而不是像无限循环这样的东西感到困惑。
import java.applet.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class animation extends Applet implements ActionListener {
Timer clock;
boolean sleepy;
int x = 100;
int y = 100;
// Initializes this applet
public void init()
{
clock = new Timer(100,this);
// fires every second
clock.start();
}
// Called automatically after a repaint request
public void paint(Graphics g) {
// super.paint(g);
g.setColor(Color.blue);
g.fillOval(x, y, 100, 100);
//Redraws the circles
if(x < 240){
x = x+10;
System.out.println(x);
}
if(x > 240){
x = x - 10;
System.out.println(x);
}
}
// Called automatically when the timer fires
public void actionPerformed (ActionEvent e) {
repaint();
}
}
这个逻辑现在逃脱了,我真的想不出如何让球回来,并继续回到x = 0再次。
有没有办法实现计时器,这样球可以正确行进5秒钟然后离开5秒钟?
答案 0 :(得分:1)
好吧,我建议你应用矢量数学来更新球的位置和速度。这使代码更清晰,更容易理解。
您还应该进行适当的边界检查。您可以调整它以调整更新之间的速度和时间。
这是一个相当的样板示例,它允许轻松扩展。
在可绘制的面板上显示一个弹跳球。
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
public class App implements Runnable, ActionListener {
private final static String APP_TITLE = "Bouncing Ball";
private JFrame frame;
private DrawablePanel drawPanel;
private Timer clock;
private int fps = 60;
private int timeout = 1000 / fps;
public App() {
frame = new JFrame();
drawPanel = new DrawablePanel(240, 240);
frame.setTitle(APP_TITLE);
frame.setContentPane(drawPanel);
Ball ball = new Ball(50, Color.BLUE, 1.0, Math.PI);
drawPanel.addDrawable(ball);
}
@Override
public void run() {
frame.pack();
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
clock = new Timer(timeout, this);
clock.start();
}
public void actionPerformed(ActionEvent e) {
drawPanel.updateAll();
drawPanel.repaint();
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new App());
}
}
绘制一个数字列表并在需要时更新它们。
import java.awt.Dimension;
import java.awt.Graphics;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JPanel;
public class DrawablePanel extends JPanel {
private static final long serialVersionUID = 3746382634873472355L;
private List<Drawable> objects;
public DrawablePanel(int width, int height) {
this.setPreferredSize(new Dimension(width, height));
objects = new ArrayList<Drawable>();
}
public boolean addDrawable(Drawable drawable) {
drawable.setParent(this);
return objects.add(drawable);
}
public boolean removeDrawable(Drawable drawable) {
drawable.setParent(null);
return objects.remove(drawable);
}
public void updateAll() {
for (Drawable object : objects) {
object.update();
}
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
for (Drawable object : objects) {
object.draw(g);
}
}
}
代表一个可绘制的球,当它被告知要更新时会移动。它也知道如何画自己。
import java.awt.Color;
import java.awt.Graphics;
public class Ball extends DrawableShape {
private Color color;
public Ball(int size, Color color, double speedX, double speedY) {
this(size, color, 0, 0, speedX, speedY);
}
public Ball(int size, Color color, int x, int y, double dX, double dY) {
super(new Vector2D(size, size), new Vector2D(x, y), new Vector2D(dX, dY));
this.color = color;
}
@Override
public void draw(Graphics g) {
if (g.getColor() != color) {
g.setColor(color);
}
g.fillOval(position.getX(), position.getY(), size.getX(), size.getY());
}
}
一个抽象类,用于描述和处理可绘制形状的更新和定位。
import java.awt.Container;
public abstract class DrawableShape implements Drawable {
private Container parent;
protected Vector2D size;
protected Vector2D position;
protected Vector2D speed;
@Override
public Container getParent() {
return parent;
}
@Override
public void setParent(Container parent) {
this.parent = parent;
}
public DrawableShape(Vector2D size, Vector2D position, Vector2D speed) {
this.size = size;
this.position = position;
this.speed = speed;
this.parent = null;
}
public void update() {
position = position.add(speed);
double directionX = inBoundsX() ? 1 : -1;
double directionY = inBoundsY() ? 1 : -1;
speed = speed.scale(directionX, directionY);
}
private boolean inBoundsX() {
return (position.getX() > 0)
&& (position.getX() + size.getX() < parent.getWidth());
}
private boolean inBoundsY() {
return (position.getY() > 0)
&& (position.getY() + size.getY() < parent.getHeight());
}
}
表示放置在绘图面板上的可绘制图形。
import java.awt.Container;
import java.awt.Graphics;
public interface Drawable {
Container getParent();
void setParent(Container parent);
void update();
void draw(Graphics g);
}
这是我从Google搜索中检索到的一个简单的二维矢量类。
/**
* ========================================================
* Vector2D.java: Source code for two-dimensional vectors
*
* Written by: Mark Austin November, 2005
* ========================================================
*/
import java.lang.Math;
public class Vector2D {
protected double dX;
protected double dY;
public int getX() {
return (int) dX;
}
public int getY() {
return (int) dY;
}
// Constructor methods ....
public Vector2D() {
dX = dY = 0.0;
}
public Vector2D(double dX, double dY) {
this.dX = dX;
this.dY = dY;
}
// Convert vector to a string ...
public String toString() {
return "Vector2D(" + dX + ", " + dY + ")";
}
// Compute magnitude of vector ....
public double length() {
return Math.sqrt(dX * dX + dY * dY);
}
// Sum of two vectors ....
public Vector2D add(Vector2D v1) {
Vector2D v2 = new Vector2D(this.dX + v1.dX, this.dY + v1.dY);
return v2;
}
// Subtract vector v1 from v .....
public Vector2D sub(Vector2D v1) {
Vector2D v2 = new Vector2D(this.dX - v1.dX, this.dY - v1.dY);
return v2;
}
// Scale vector by a constant ...
public Vector2D scale(double scaleFactorX, double scaleFactorY) {
Vector2D v2 = new Vector2D(this.dX * scaleFactorX, this.dY * scaleFactorY);
return v2;
}
public Vector2D scale(double scaleFactor) {
return scale(scaleFactor, scaleFactor);
}
// Normalize a vectors length....
public Vector2D normalize() {
Vector2D v2 = new Vector2D();
double length = Math.sqrt(this.dX * this.dX + this.dY * this.dY);
if (length != 0) {
v2.dX = this.dX / length;
v2.dY = this.dY / length;
}
return v2;
}
// Dot product of two vectors .....
public double dotProduct(Vector2D v1) {
return this.dX * v1.dX + this.dY * v1.dY;
}
// Exercise methods in Vector2D class
public static void main(String args[]) {
Vector2D vA = new Vector2D(1.0, 2.0);
Vector2D vB = new Vector2D(2.0, 2.0);
System.out.println("Vector vA =" + vA.toString());
System.out.println("Vector vB =" + vB.toString());
System.out.println("Vector vA-vB =" + vA.sub(vB).toString());
System.out.println("Vector vB-vA =" + vB.sub(vA).toString());
System.out.println("vA.normalize() =" + vA.normalize().toString());
System.out.println("vB.normalize() =" + vB.normalize().toString());
System.out.println("Dot product vA.vB =" + vA.dotProduct(vB));
System.out.println("Dot product vB.vA =" + vB.dotProduct(vA));
}
}