首頁 >Java >java教程 >如何使用按鍵綁定在 Java 遊戲中同時處理多個按鍵?

如何使用按鍵綁定在 Java 遊戲中同時處理多個按鍵?

Susan Sarandon
Susan Sarandon原創
2024-11-21 02:44:14463瀏覽

How Can I Handle Multiple Key Presses Simultaneously in a Java Game Using Key Bindings?

帶鍵綁定的執行緒

多執行緒不是必需的,除非您希望遊戲是多執行緒的。

問題是,兩個玩家可以按不同的鍵嗎?如果是這樣,您可以使用布林值來指示按鍵是否按下,並在釋放按鍵時重設標誌。

在您的遊戲邏輯中,檢查布林值的狀態並採取適當的行動。請參閱以下範例,其中兩個槳都可以獨立移動:

[槳獨立移動的圖像]

以下是範例程式碼:

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class GameLogic extends JFrame 
{

    public GameLogic() 
    {
        initComponents();
    }

    private void initComponents() 
    {
        JFrame frame = new JFrame("Game Test");
       //create the gamepanel
        final GamePanel gp = new GamePanel(600, 500);
        //create panel to hold buttons to start, pause
        JPanel buttonPanel = new JPanel();
        final JButton startButton = new JButton("Start");
        final JButton pauseButton = new JButton("Pause");
        final JButton resetButton = new JButton("Reset");

        pauseButton.setEnabled(false);
        resetButton.setEnabled(false);
        //add listeners to buttons
        startButton.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent ae) {
                gp.clearEntities();
                addEntityToPanel(gp);
                
                startButton.setEnabled(false);
                pauseButton.setEnabled(true);
                resetButton.setEnabled(true);

               //start the game loop which will repaint the screen
                runGameLoop(gp);

            }
        });
        //create and add keybindings for game panel 
        GameKeyBindings gameKeyBindings = new GameKeyBindings(gp, player1Entity, player2Entity);

        pauseButton.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent ae) {
                boolean b = GamePanel.paused.get();

                GamePanel.paused.set(!b);//set it to the opposite of what it was i.e paused to unpaused and vice versa

                if (pauseButton.getText().equals("Pause")) {
                    pauseButton.setText("Un-pause");
                } else {
                    pauseButton.setText("Pause");
                }
            }
        });

        resetButton.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent ae) {
                resetGame(gp);

            }
        });

        buttonPanel.add(startButton);
        buttonPanel.add(pauseButton);
        buttonPanel.add(resetButton);

        frame.add(gp);
        frame.add(buttonPanel, BorderLayout.SOUTH);

       
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);

    }
    

    //Simply used for testing (to simulate sprites) can create different colored images 
    public static BufferedImage createColouredImage(String color, int w, int h, boolean circular) {
        BufferedImage img = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
        Graphics2D g2 = img.createGraphics();
        switch (color.toLowerCase()) {
            case "green":
                g2.setColor(Color.GREEN);
                break;
            case "magenta":
                g2.setColor(Color.MAGENTA);
                break;
            case "red":
                g2.setColor(Color.RED);
                break;
            case "yellow":
                g2.setColor(Color.YELLOW);
                break;
            case "blue":
                g2.setColor(Color.BLUE);
                break;
            case "orange":
                g2.setColor(Color.ORANGE);
                break;
            case "cyan":
                g2.setColor(Color.CYAN);
                break;
            case "gray":
                g2.setColor(Color.GRAY);
                break;
            default:
                g2.setColor(Color.WHITE);
                break;
        }
        if (!circular) {
            g2.fillRect(0, 0, img.getWidth(), img.getHeight());
        } else {
            g2.fillOval(0, 0, img.getWidth(), img.getHeight());
        }
        g2.dispose();
        return img;
    }

    private void runGameLoop(final GamePanel gp) {
        Thread loop = new Thread(new Runnable() {

            @Override
            public void run() {
                gp.gameLoop();
            }
        });
        loop.start();
    }

    private void resetGame(GamePanel gp) {
        gp.reset();
        gp.clearEntities();
        addEntityToPanel(gp);
        gp.repaint();
    }
    void addEntityToPanel(GamePanel gp){
    
                ArrayList<BufferedImage> ballEntityImages = new ArrayList<>();
                ArrayList<Long> ballEntityTimings = new ArrayList<>();
                ballEntityImages.add(createColouredImage("white", 50, 50, true));
                ballEntityTimings.add(500l);

                Entity ballEntity = new Entity(gp.getWidth() / 2, gp.getHeight() / 2, ballEntityImages, ballEntityTimings);
                ballEntity.RIGHT = true;

                //create images  for entities 
                ArrayList<BufferedImage> advEntityImages = new ArrayList<>();
                ArrayList<Long> advEntityTimings = new ArrayList<>();
                advEntityImages.add(createColouredImage("orange", 10, 100, false));
                advEntityTimings.add(500l);
                advEntityImages.add(createColouredImage("blue", 10, 100, false));
                advEntityTimings.add(500l);

                //create entities 
                AdvancedSpritesEntity player1Entity = new AdvancedSpritesEntity(0, 100, advEntityImages, advEntityTimings);


                ArrayList<BufferedImage> entityImages = new ArrayList<>();
                ArrayList<Long> entityTimings = new ArrayList<>();
                entityImages.add(createColouredImage("red", 10, 100, false));
                entityTimings.add(500l);//as its the only image it doesnt really matter what time we put we could use 0l
                //entityImages.add(createColouredImage("magenta", 100, 100));
                //entityTimings.add(500l); 

                Entity player2Entity = new Entity(gp.getWidth() - 10, 200, entityImages, entityTimings);

                gp.addEntity(player1Entity);
                gp.addEntity(player2Entity);//just a standing still Entity for testing
                gp.addEntity(ballEntity);//just a standing still Entity for testing

           
    }
    //Code starts here
    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {

                try {//attempt to set look and feel to nimbus Java 7 and up
                    for (UIManager.LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) {
                        if ("Nimbus".equals(info.getName())) {
                            UIManager.setLookAndFeel(info.getClassName());
                            break;
                        }
                    }
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                }
                GameLogic gameLogic = new GameLogic();
            }
        });
    }
}

class GameKeyBindings {

    public GameKeyBindings(JComponent gp, final Entity entity, final Entity entity2) {

        gp.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_W, 0, false), "W pressed");
        gp.getActionMap().put("W pressed", new AbstractAction() {

            @Override
            public void actionPerformed(ActionEvent ae) {
               entity.UP=true;
            }
        });
        gp.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_S, 0, false), "S pressed");
        gp.getActionMap().put("S pressed", new AbstractAction() {

            @Override
            public void actionPerformed(ActionEvent ae) {
               entity.DOWN=true;
            }
        });

        gp.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0, false), "up pressed");
        gp.getActionMap().put("up pressed", new AbstractAction() {

            @Override

以上是如何使用按鍵綁定在 Java 遊戲中同時處理多個按鍵?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn