首先看一下Swing 中的并发以及如何使用 Swing 计时器
您将遇到的下一个问题是容器受 LayoutManager
. 虽然可以使用它来实现移动,但它会是块状的,因为每个组件都会跳跃单元格。
如果你想要平滑的移动,你将不得不设计自己的布局逻辑,这可能非常复杂。
尽管如此,您的目标应该是保持游戏的“虚拟”视图。这可以让你知道迷宫的形状和角色的位置,而无需与 UI 做大量的比较。然后你应该简单地渲染这个“虚拟”视图或模型的状态
更新了非常基本的示例
这是一个基本示例,它使用GridLayout
andsetComponentZOrder
移动到面板周围的组件......没有碰撞检测,“AI”很可怜......
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class PacMan101 {
public static void main(String[] args) {
new PacMan101();
}
public PacMan101() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new MazePane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class MazePane extends JPanel {
private JLabel pacMan;
private JLabel ghost;
public MazePane() {
pacMan = new JLabel(new ImageIcon(getClass().getResource("/PacMan.png")));
ghost = new JLabel(new ImageIcon(getClass().getResource("/Ghost.png")));
setLayout(new GridLayout(8, 8));
add(pacMan);
for (int index = 1; index < (8 * 8) - 1; index++) {
add(new JPanel() {
@Override
public Dimension getPreferredSize() {
return new Dimension(32, 32);
}
});
}
add(ghost);
Timer timer = new Timer(500, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
move(pacMan);
move(ghost);
revalidate();
repaint();
}
protected void move(Component obj) {
int order = getComponentZOrder(obj);
int row = order / 8;
int col = order - (row * 8);
boolean moved = false;
while (!moved) {
int direction = (int) (Math.round(Math.random() * 3));
int nextRow = row;
int nextCol = col;
switch (direction) {
case 0:
nextRow--;
break;
case 1:
nextCol++;
break;
case 2:
nextRow++;
break;
case 3:
nextCol--;
break;
}
if (nextRow >= 0 && nextRow < 8 && nextCol >= 0 && nextCol < 8) {
row = nextRow;
col = nextCol;
moved = true;
}
}
order = (row * 8) + col;
setComponentZOrder(obj, order);
}
});
timer.start();
}
}
}