首页  >  文章  >  Java  >  如何使用按键绑定在 Java 游戏中同时处理多个按键?

如何使用按键绑定在 Java 游戏中同时处理多个按键?

Susan Sarandon
Susan Sarandon原创
2024-11-21 02:44:14425浏览

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