我想创建多个独立且同时移动的正方形,我认为最有效的方法是通过Graphics2D中的转换方法,但我不知道如何让它适用于每个方块。我想要方形对象是自包含的并创建自己的变换(实例变换)。这是我到目前为止所拥有的。
TransformPanel
import javax.swing.*;
import java.awt.*;
import java.awt.geom.AffineTransform;
import java.util.Random;
import java.util.concurrent.TimeUnit;
public class TranformPanel extends JPanel {
private int[] xcoords = {250,248,253,255,249};
private int[] ycoords = {250,253,249,245,250};
private double randomx = 0;
private double randomy = 0;
public void paintComponent(Graphics g)
{
super.paintComponent(g);
drawTransform(g,randomx,randomy);
}
private void drawTransform(Graphics g,double randomx,double randomy)
{
Random rn = new Random();
int xnum = rn.nextInt(10)-5;
randomx = xnum;
int ynum = rn.nextInt(10)-5;
randomy = ynum;
Rectangle rect = new Rectangle(250,250,10,10);
AffineTransform transform = new AffineTransform();
Graphics2D g2d = (Graphics2D)g;
transform.translate(randomx,randomy);
g2d.draw(transform.createTransformedShape(rect));
}
}
TransformDraw
import java.awt.*;
import javax.swing.*;
import java.awt.geom.AffineTransform;
import java.util.Scanner;
import java.util.concurrent.TimeUnit;
public class TransformDraw{
private static TranformPanel panel = new TranformPanel();
public static void main(String[] args) {
// Setup our JFrame details
JFrame frame = new JFrame();
frame.setTitle("Transform Polygon Example");
frame.setSize(500,500);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.setVisible(true);
frame.add(panel);
Scanner input = new Scanner(System.in);
for (int i=0;i<10;i++)
{
try {
TimeUnit.SECONDS.sleep(1);
frame.repaint();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
谢谢你的进步!
答案 0 :(得分:0)
首先创建一些可以管理它的位置(以及其他属性)并且可以被绘制的东西&#34;
public interface Box {
public void update(Dimension size);
public void paint(Graphics2D g2d);
}
所以,这是非常基本的,它可以做的就是更新(在给定区域内)并进行绘制。您可以根据您的特定需求公开其他属性(例如它的边界框)
接下来,我们需要一个简单的实现,比如......
public class DefaultBox implements Box {
private Color color;
private Rectangle bounds;
private int xDelta;
private int yDelta;
public DefaultBox(Color color, Dimension size) {
this.color = color;
bounds = new Rectangle(new Point(0, 0), size);
xDelta = 1 + (int) (Math.random() * 10);
yDelta = 1 + (int) (Math.random() * 10);
}
@Override
public void update(Dimension size) {
bounds.x += xDelta;
bounds.y += yDelta;
if (bounds.x < 0) {
bounds.x = 0;
xDelta *= -1;
} else if (bounds.x + bounds.width > size.width) {
bounds.x = size.width - bounds.width;
xDelta *= -1;
}
if (bounds.y < 0) {
bounds.y = 0;
yDelta *= -1;
} else if (bounds.y + bounds.height > size.height) {
bounds.y = size.height - bounds.height;
yDelta *= -1;
}
}
@Override
public void paint(Graphics2D g2d) {
g2d.setColor(color);
g2d.fill(bounds);
}
}
现在,它维护了一个简单的Rectangle
实例,它描述了对象的位置和大小,它还保留了有关颜色和速度的属性。
当调用update
时,它会更新它的位置并执行一些简单的边界检查以确保该框保留在指定区域内。
当调用paint
时,它只会自行绘制。
最后,我们需要一些方法来更新和绘制这些框....
public class TestPane extends JPanel {
private List<Box> boxes;
private Color[] colors = {Color.RED, Color.BLACK, Color.BLUE, Color.CYAN, Color.DARK_GRAY, Color.GREEN, Color.LIGHT_GRAY, Color.MAGENTA, Color.ORANGE, Color.PINK, Color.WHITE, Color.YELLOW};
public TestPane() {
boxes = new ArrayList<>(25);
for (int index = 0; index < 100; index++) {
Color color = colors[(int) (Math.random() * colors.length)];
int width = 10 + (int) (Math.random() * 9);
int height = 10 + (int) (Math.random() * 9);
boxes.add(new DefaultBox(color, new Dimension(width, height)));
}
Timer timer = new Timer(40, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
for (Box box : boxes) {
box.update(getSize());
}
repaint();
}
});
timer.start();
}
@Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
protected void paintComponent(Graphics g) {
super.paintComponent(g);
for (Box box : boxes) {
Graphics2D g2d = (Graphics2D) g.create();
box.paint(g2d);
g2d.dispose();
}
}
}
好的,再次,这很简单。它保留了List
Box
个{Swing Timer
来定期更新List
个Box
,并呼叫他们update
方法。 Timer
只需拨打repaint
即可(最后一轮)最终调用paintComponent
,然后在paint
的每个实例上调用Box
100盒......