我正在制作像pacman这样的游戏,到目前为止我只是从网格开始。我开始了网格,但我需要弄清楚如何将某些东西移动到网格中的不同位置,以便当用户点击或我的鬼移动时,它将显示在屏幕上。我该如何移动?我尝试了很多不同的方法,但没有一个适合我。
import java.awt.*;
import javax.swing.*;
import javax.swing.border.BevelBorder;
public class GUI {
public static void main(String[] args) {
final JFrame f = new JFrame("Frame Test");
GridLayout Layout = new GridLayout(50,50);
JPanel panel = new JPanel(new GridLayout(50, 50, 1, 1));
//Not sure if I need this or not?
//panel.setLayout(new GridBagLayout());
//first set of black
for (int i = 0; i < 1000; i++) {
JLabel a = new JLabel(new ImageIcon("black-square.jpg"), JLabel.CENTER);
panel.add(a);
}
//adds pacman
JLabel b = new JLabel(new ImageIcon("pacman.png"), JLabel.CENTER);
panel.add(b);
//next set of black
for (int i = 0; i < 1000; i++) {
JLabel c = new JLabel(new ImageIcon("black-square.jpg"), JLabel.CENTER);
panel.add(c);
}
//do the thing
f.setContentPane(panel);
f.setSize(1000, 1000);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setVisible(true);
}
}
答案 0 :(得分:1)
首先看看Concurrency in Swing和How to Use Swing Timers
您将遇到的下一个问题是容器受LayoutManager
的控制。虽然使用它可以实现移动,但它将是块状的,因为每个组件都会跳过单元格。
如果你想要平滑移动,你将不得不设计自己的布局逻辑,这可能非常复杂。
尽管如此,你应该瞄准的是保持游戏的“虚拟”视图。这使您可以了解迷宫的形状和角色的位置,而无需与UI进行大量比较。然后,您应该简单地呈现此“虚拟”视图或模型的状态
更新了非常基本的示例
这是一个基本的例子,它使用GridLayout
和setComponentZOrder
移动到关于面板的组件......没有碰撞检测,“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();
}
}
}
答案 1 :(得分:0)
将标签放在网格中的每个位置可能更简单,然后只需在生物移动时更改与每个标签关联的图标。见Add and remove an icon on a JLabel