JPanel中的多个动画(线程)

我正在尝试用Java编写棋盘游戏。

我有11个class,包括Main。 Board类扩展了JPanel并绘制了板图像以及骰子图像。 类Player,它扩展了JCoponent并实现了Runnable(Thread)。 每个玩家实例都是一个典当动画,它正在全面移动。 玩家类在棋盘上绘制棋子。

图案
代码如何:

Board b=new Board(); Player p=new Player(); b.add(p); JPanel panel=new JPanel(); panel.add(b); add(panel); //adding the panel to the frame. 

问题是我不能在棋盘上同时拥有多个棋子。 我已经尝试在另一个类中重新绘制所有玩家(作为非动画),但它不起作用。 我也试过JLayeredPane,但也许我做错了。 不幸的是,我无法改变上述模式,所以不要提出这个建议。

预先感谢您的帮助。

PS:我不能发布任何代码,因为它的巨大。
PPS:如果你问我,会给出更多的澄清。

编辑:我改革了我的问题。 是否可以在同一个面板上同时拥有两个动画? 如果答案是肯定的..我可以这样做吗?

最有可能让许多组件同时移动。 要么使用javax.swing.Timer,要么使用SwingWorker。

这是一个向您展示的快速示例。 它将16个棋子放在棋盘上并随机地从一个地方移动到另一个地方。

董事会动画

 import java.awt.BorderLayout; import java.awt.Color; import java.awt.Component; import java.awt.Dimension; import java.awt.Graphics; import java.awt.GridLayout; import java.awt.Image; import java.awt.Point; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.net.MalformedURLException; import java.net.URL; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Random; import javax.swing.ImageIcon; import javax.swing.JComponent; import javax.swing.JFrame; import javax.swing.JLayeredPane; import javax.swing.JPanel; import javax.swing.SwingUtilities; import javax.swing.Timer; import javax.swing.UIManager; import javax.swing.UnsupportedLookAndFeelException; public class TestAnimation { private static final String PAWN_URL = "http://files.chesskidfiles.com/images_users/tiny_mce/BoundingOwl/bishop_happywhite.png"; private Image pawn; private Map pawnLocations = new HashMap<>(); private Board board; private Timer timer; private JLayeredPane glassPane; public TestAnimation() { try { pawn = new ImageIcon(new URL(PAWN_URL)).getImage(); } catch (MalformedURLException e) { e.printStackTrace(); } } private static class Location { public final int row; public final int col; public Location(int row, int col) { super(); this.row = row; this.col = col; } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + col; result = prime * result + row; return result; } @Override public boolean equals(Object obj) { if (this == obj) { return true; } if (obj == null) { return false; } if (getClass() != obj.getClass()) { return false; } Location other = (Location) obj; return (col == other.col && row == other.row); } } private static class Cell extends JPanel { private final Location location; public Cell(Location location) { super(new BorderLayout()); this.location = location; setOpaque(true); setBackground(((location.row + location.col) % 2) == 0 ? Color.WHITE : Color.BLACK); } @Override protected void addImpl(Component comp, Object constraints, int index) { while (getComponentCount() > 0) { remove(0); } super.addImpl(comp, constraints, index); } } private static class Board extends JPanel { private Map cells = new HashMap<>(); public Board() { super(new GridLayout(8, 8)); for (int i = 0; i < 8; i++) { for (int j = 0; j < 8; j++) { Cell cell = new Cell(new Location(i, j)); add(cell); cells.put(new Location(i, j), cell); } } } public void add(Pawn pawn, Location location) { cells.get(location).add(pawn); } @Override public Dimension getPreferredSize() { return new Dimension(400, 400); } public Cell getCell(Location location) { return cells.get(location); } } private class Pawn extends JComponent { public Pawn() { } @Override protected void paintComponent(Graphics g) { super.paintComponent(g); g.drawImage(pawn, 0, 0, getWidth(), getHeight(), this); } } protected void initUI() { JFrame frame = new JFrame(TestAnimation.class.getSimpleName()); board = new Board(); for (int i = 0; i < 8; i++) { for (int j = 0; j < 2; j++) { Location location = new Location(i, j); Pawn aPawn = new Pawn(); board.add(aPawn, location); pawnLocations.put(location, aPawn); } } for (int i = 0; i < 8; i++) { for (int j = 6; j < 8; j++) { Location location = new Location(i, j); Pawn aPawn = new Pawn(); board.add(aPawn, location); pawnLocations.put(location, aPawn); } } timer = new Timer(7000, new Animation()); timer.setInitialDelay(0); timer.setRepeats(true); timer.setCoalesce(false); glassPane = new JLayeredPane(); glassPane.setOpaque(false); frame.add(board); frame.setGlassPane(glassPane); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.pack(); frame.setVisible(true); timer.start(); glassPane.setVisible(true); } public class Animation implements ActionListener { private Map futureLocations; private Random random = new Random(); private Timer subTimer; private List movingPawns; private Map originalCoordinates = new HashMap<>(); private Map futureCoordinates = new HashMap<>(); @Override public void actionPerformed(ActionEvent e) { futureLocations = new HashMap<>(); movingPawns = new ArrayList<>(); for (Pawn p : pawnLocations.values()) { int row = random.nextInt(8); int col = random.nextInt(8); Location location; while (futureLocations.containsKey((location = new Location(row, col)))) { row = random.nextInt(8); col = random.nextInt(8); } futureLocations.put(location, p); Cell futureCell = board.getCell(location); futureCoordinates.put(p, SwingUtilities.convertPoint(futureCell, 0, 0, glassPane)); movingPawns.add(p); } for (Pawn p : movingPawns) { Point locationInGlassPane = SwingUtilities.convertPoint(p.getParent(), 0, 0, glassPane); glassPane.add(p); p.setLocation(locationInGlassPane); originalCoordinates.put(p, locationInGlassPane); } subTimer = new Timer(50, new AnimationSteps()); subTimer.setInitialDelay(0); subTimer.setCoalesce(true); subTimer.setRepeats(true); subTimer.start(); } public class AnimationSteps implements ActionListener { private int step = 0; @Override public void actionPerformed(ActionEvent e1) { if (step < 50 + 1) { for (Pawn p : movingPawns) { Point p1 = originalCoordinates.get(p); Point p2 = futureCoordinates.get(p); int x = (int) (p1.x + ((p2.x - p1.x) * (double) step / 50)); int y = (int) (p1.y + ((p2.y - p1.y) * (double) step / 50)); p.setLocation(x, y); } } else { for (Entry e : futureLocations.entrySet()) { board.add(e.getValue(), e.getKey()); } board.revalidate(); subTimer.stop(); pawnLocations = futureLocations; } step++; } } } public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, UnsupportedLookAndFeelException { UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); SwingUtilities.invokeLater(new Runnable() { @Override public void run() { new TestAnimation().initUI(); } }); } } 

也许你的问题是尝试用每个对象的线程开发一个程序,大多数流行的游戏用一个线程运行,最多两个。 原因是:将线程彼此同步会非常复杂,更不用说你的性能会很差。 甚至Java中的图形引擎也是单线程的,这意味着你不会同时绘制两个线程。