Moving jLabel to a different place in the jPanel (Pacman like game)

强颜欢笑 提交于 2021-02-10 09:34:07

问题


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...

enter image description here

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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!