问题
I'm making a game like pacman and so far I am just starting with the grid. I got the grid started but I need to figure out how to move something to a different place in the grid so that when the user clicks or my ghosts move, it will display on the screen. How do I make it move? I have tried a bunch of different ways but none worked for me.
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);
}
}
回答1:
Start by taking a look at Concurrency in Swing and How to Use Swing Timers
The next problem you're going to have is the fact that the container is under the control of a LayoutManager
. While it's possible to achieve movement using this, it will be blocky, as each component will jump cells.
If you want smooth movement, you're going to have to devise your own layout logic, this can be very complicated.
None the less, what you should be aiming for is maintaining the a "virtual" view of the game. This allows you to know the shape of the maze and the position of the characters without need to do a lot of comparisons with the UI. You should then simply render the state of this "virtual" view or model
Updated with VERY BASIC example
This is a basic example, which uses a GridLayout
and setComponentZOrder
to move to components about the panel...There is no collision detection and the "AI" is pathetic...
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();
}
}
}
回答2:
It might be simpler to put labels at each spot in the grid, and then just change the icons associated with each label as your creatures move. See Add and remove an icon on a JLabel
来源:https://stackoverflow.com/questions/21032140/moving-jlabel-to-a-different-place-in-the-jpanel-pacman-like-game