我如何制作一个固定墙壁的阵列

时间:2018-06-08 22:28:57

标签: java graphics collision-detection

我的游戏需要一个简单的do循环,但不知道如何创建一个。 我有一个简单的迷宫游戏。 我还需要添加更多墙壁 我正在考虑创建一个数组并在do循环中调用数组的索引来调用墙,但我现在不知道怎么做 我以为我可以创建一个do循环而不是复制并将碰撞代码复制30次。 我的播放器需要在触及墙壁时重置为开头

玩家是简单的JLabel。我的墙也是JLabel。我在游戏中使用摇摆组件。

import java.awt.CardLayout;
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.HashSet;
import java.util.Set;

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.Timer;

/**
 * This class Holds the game pane that has the moving player. It also contains
 * the GamePane
 * 
 * @author 602052004
 *
 */

public class GamePane extends JPanel implements ActionListener, KeyListener {// *change GamePane to GamePane
    // This is where the game screen is made and the player is created.

    private static final long serialVersionUID = 1L;
    JLabel player = new JLabel();
    //This is were the Jlabels for the walls are created
    JLabel wall1 = new JLabel();
    JLabel wall2 = new JLabel();
    JLabel wall3 = new JLabel();
    JLabel wall4 = new JLabel();
    JLabel wall5 = new JLabel();

    int playerSpeed = 5;
    int FPS = 40;
    private final Set<Integer> keys = new HashSet<>();

    // The keys set holds the keys being pressed

    public static void main(String[] args) {
        // Open the GUI window
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                // Create a new object and
                // run its go() method
                new GamePane().go();
            }
        });
    }

    GamePane() {
        // Run the parent class constructor
        super();
        // Allow the panel to get focus
        setFocusable(true);
        // Don't let keys change the focus

    }

    /**
     * The frame that shows my game. It contains the game frame which holds my
     * JPanel GameStage and ButtonPane.
     */
    protected void go() {
        setLayout(new CardLayout());
        // Setup the window
        JFrame GameFrame = new JFrame();
        // Add this panel to the window
        GameFrame.setLayout(new CardLayout());
        GameFrame.add(this, "main");
        GameFrame.setContentPane(this);

        // Set's the window properties
        GameFrame.setTitle("main");
        GameFrame.setSize(800, 600);
        GameFrame.setLocationRelativeTo(null);
        GameFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        GameFrame.setVisible(true);
        GameFrame.add(new ButtonPane(GameFrame), "buttons");
        // Creates the new JPanel that will hold the game.
        JPanel gamestage = new JPanel();
        gamestage.setBackground(Color.darkGray);
        GameFrame.add(gamestage, "game");
        gamestage.setLayout(null);
        // *Move the setup of the player and the timer under the walls
        // Get a sample of collisions going so that i can do it over the weekend
        // Setup the movable box
        player.setBounds(25, 25, 20, 20);
        player.setVisible(true);
        player.setBackground(Color.cyan);
        // Opaque makes the background visible
        player.setOpaque(true);

        // Setup the key listener
        addKeyListener(this);
        // Null layout allows moving objects!!!
        gamestage.add(player);
        // Set the timer
        Timer tm = new Timer(1000 / FPS, this);
        tm.start();

        wall1.setBounds(10, 15, 10, 480);
        wall1.setVisible(true);
        wall1.setBackground(Color.white);
        wall1.setOpaque(true);
        gamestage.add(wall1);

        wall2.setBounds(10, 10, 755, 10);
        wall2.setVisible(true);
        wall2.setBackground(Color.white);
        wall2.setOpaque(true);
        gamestage.add(wall2);
        // wall3.setBounds(x, y, width, height);
        wall3.setBounds(10, 100, 100, 10);
        wall3.setVisible(true);
        wall3.setBackground(Color.white);
        wall3.setOpaque(true);
        gamestage.add(wall3);

        wall4.setBounds(100, 60, 10, 40);
        wall4.setVisible(true);
        wall4.setBackground(Color.white);
        wall4.setOpaque(true);
        gamestage.add(wall4);

        wall5.setBounds(70, 60, 35, 10);
        wall5.setVisible(true);
        wall5.setBackground(Color.white);
        wall5.setOpaque(true);
        gamestage.add(wall5);


    }

    public boolean areColliding(JLabel a, JLabel b) {
         return a.getBounds().intersects(b.getBounds());
         }



    /**
     * this method makes the player move. It takes the players speed and subtracts
     * or adds the player speed to the current position of the player. It also
     * figures out were the player is at currently aswell.
     * 
     * @param arg0
     */
    @Override
    public void actionPerformed(ActionEvent arg0) {
        // Move up if W is pressed
        if (keys.contains(KeyEvent.VK_W)) {
            player.setLocation(player.getX(), player.getY() - playerSpeed);
        }
        // Move right if D is pressed
        if (keys.contains(KeyEvent.VK_D)) {
            player.setLocation(player.getX() + playerSpeed, player.getY());
        }
        // Move down if S is pressed
        if (keys.contains(KeyEvent.VK_S)) {
            player.setLocation(player.getX(), player.getY() + playerSpeed);
        }
        // Move left if A is pressed
        if (keys.contains(KeyEvent.VK_A)) {
            player.setLocation(player.getX() - playerSpeed, player.getY());
        }

         // Check for collisions
         if (areColliding(wall1, player)) {
         // Reposition the target
         int newX = (int) (25);
         int newY = (int) (25);
         player.setLocation(newX, newY);}
    }

    @Override
    public void keyPressed(KeyEvent e) {
        // Add the key to the list
        // of pressed keys
        if (!keys.contains(e.getKeyCode())) {
            keys.add(e.getKeyCode());
        }
    }

    @Override
    public void keyReleased(KeyEvent e) {
        // Remove the key from the
        // list of pressed keys
        keys.remove((Integer) e.getKeyCode());
    }

    @Override
    public void keyTyped(KeyEvent e) {
    }

}

这只是为了让你在玩游戏时有一个正在运行的主屏幕

/**
 * This pane contains the button and sets up the button pane
 */
import java.awt.CardLayout;
import java.awt.Color;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class ButtonPane extends JPanel {

    private JButton startBTN;// Calls the JButton
    JFrame game;

    public ButtonPane(JFrame g) {
        game = g;
        setLayout(new GridBagLayout());
        setBackground(Color.gray);// Sets the menu stages color blue
        startBTN = new JButton("Start");// Creates a new button
        add(startBTN);// Adds the button on the startStage

        startBTN.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                if (game.getContentPane().getLayout() instanceof CardLayout) {
                    CardLayout layout = (CardLayout) getParent().getLayout();
                    layout.show(game.getContentPane(), "game");

                }
            }
        });
    }

}

1 个答案:

答案 0 :(得分:0)

基本思想是将玩家可以碰撞的所有物体放在List中。

在播放器的每次移动中,循环显示此列表并使用组件的getBounds方法提供的Rectangle#containsRectangle#intersects

这可能看起来像这样......

public class GamePane extends JPanel implements ActionListener, KeyListener {// *change GamePane to GamePane

    private List<JComponent> collidableStuff;

    public GamePane() {
        collidableStuff = new ArrayList<>(25);
        //...
        wall1 = ...;
        wall2 = ...;
        wall3 = ...;
        wall4 = ...;
        wall5 = ...;
        // In fact, you could get rid of wall1-5 and just
        // use the list instead
        collidableStuff.add(wall1);
        collidableStuff.add(wall2);
        collidableStuff.add(wall3);
        collidableStuff.add(wall4);
        collidableStuff.add(wall5);
        //...
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        //...
        player.setLocation(newX, newY);

        performCollisionDetection();
    }

    protected void performCollisionDetection() {
        Rectangle playerBounds = player.getBounds();
        for (JComponent nonPassable : collidableStuff) {
            // Because I didn't test the code, I'm covering all bases
            Rectangle nonPassableBounds = nonPassable.getBounds();
            if (nonPassableBounds.contains(playerBounds) || playerBounds.contains(nonPassableBounds) 
                            || playerBounds.intersects(nonPassableBounds) || nonPassableBounds.intersects(playerBounds)) {
                // Smack, we have a collision
            }
        }
    }

}

这个例子将创建对象的责任转移到构造函数,而不是go方法,坦率地说不应该存在 - GamePane不应该关心“如何“它已被证明,这不是它的责任