首页  >  文章  >  Java  >  线程如何改进两人游戏中的按键绑定处理?

线程如何改进两人游戏中的按键绑定处理?

Mary-Kate Olsen
Mary-Kate Olsen原创
2024-11-25 05:49:10572浏览

How Can Threads Improve Key Binding Handling in a Two-Player Game?

具有键绑定的线程

在给定的上下文中,您可以使用单独的线程来处理键绑定并更新游戏状态。这允许玩家使用不同的按键独立控制他们的球拍,并确保两个玩家可以同时移动他们的球拍。

以下示例演示了如何使用线程的键绑定:

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.util.HashSet;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicBoolean;

import javax.swing.JFrame;
import javax.swing.SwingUtilities;

public class Main {
    private static final int WIDTH = 600;
    private static final int HEIGHT = 500;

    public static void main(String[] args) {
        // Create a new game instance
        Game game = new Game(WIDTH, HEIGHT);

        // Create a thread pool to handle key bindings
        ExecutorService keyBindingPool = Executors.newCachedThreadPool();

        // Create key bindings for the two players
        KeyBindings player1Bindings = new KeyBindings(game, "W", "S");
        KeyBindings player2Bindings = new KeyBindings(game, "UP", "DOWN");

        // Install the key bindings using SwingUtilities to ensure they work on the EDT
        SwingUtilities.invokeLater(() -> {
            game.getComponent().getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_W, 0, false), "player1Up");
            game.getComponent().getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_S, 0, false), "player1Down");
            game.getComponent().getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0, false), "player2Up");
            game.getComponent().getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0, false), "player2Down");
            game.getComponent().getActionMap().put("player1Up", new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) { player1Bindings.up = true; }
            });
            game.getComponent().getActionMap().put("player1Down", new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) { player1Bindings.down = true; }
            });
            game.getComponent().getActionMap().put("player2Up", new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) { player2Bindings.up = true; }
            });
            game.getComponent().getActionMap().put("player2Down", new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) { player2Bindings.down = true; }
            });
        });

        // Add the key bindings to the thread pool
        keyBindingPool.submit(player1Bindings);
        keyBindingPool.submit(player2Bindings);

        // Start the game loop
        game.start();
    }

    private static class Game {
        private final int width;
        private final int height;
        private final Paddle paddle1;
        private final Paddle paddle2;
        private final Thread gameLoopThread;
        private final AtomicBoolean running;

        public Game(int width, int height) {
            this.width = width;
            this.height = height;
            this.paddle1 = new Paddle(0, 100, 10, 100);
            this.paddle2 = new Paddle(width - 10, 200, 10, 100);
            this.running = new AtomicBoolean(false);
            this.gameLoopThread = new Thread(this::gameLoop);
        }

        public void start() {
            running.set(true);
            gameLoopThread.start();
        }

        private void gameLoop() {
            while (running.get()) {
                // Update the game state based on the key bindings
                if (player1Bindings.up) { paddle1.moveUp(); } else if (player1Bindings.down) { paddle1.moveDown(); }
                if (player2Bindings.up) { paddle2.moveUp(); } else if (player2Bindings.down) { paddle2.moveDown(); }

                // Render the game on the screen
                paint();
            }
        }

        public void paint() {
            // Clear the screen
            // Draw the paddles
            // Draw the ball
            // Update the display
        }

        public JComponent getComponent() { return null; }
    }

    private static class KeyBindings implements Runnable {
        private final Game game;
        private final String upKey;
        private final String downKey;
        private final HashSet<String> keysPressed;
        public boolean up;
        public boolean down;
        private AtomicBoolean running;

        public KeyBindings(Game game, String upKey, String downKey) {
            this.game = game;
            this.upKey = upKey;
            this.downKey = downKey;
            this.keysPressed = new HashSet<>();
            this.running = new AtomicBoolean(false);
        }

        public void start() {
            running.set(true);
        }

        @Override
        public void run() {
            while (running.get()) {
                // Check for key presses
                if (keysPressed.contains(upKey)) { up = true; } else { up = false; }
                if (keysPressed.contains(downKey)) { down = true; } else { down = false; }

                // Sleep for a bit
                try {
                    Thread.sleep(10);
                } catch (InterruptedException e) {}
            }
        }
    }

    private static class Paddle {
        private int x;
        private int y;
        private int width;
        private int height;

        public Paddle(int x, int y, int width, int height) { this.x = x; this.y = y; this.width = width; this.height = height; }

        public void moveUp() { if (y > 0) { y -= 5; } }
        public void moveDown() { if (y < game.getHeight() - height) { y += 5; } }
    }
}

在此示例中:

  • Game 类管理游戏状态并初始化球拍。它还启动游戏循环线程。
  • KeyBindings 类用于处理键绑定。它监听按键并相应地更新游戏状态。
  • Paddle 类代表由玩家控制的桨。
  • main 方法创建一个新的游戏实例并安装按键绑定使用 SwingUtilities。它还会启动游戏循环。

此示例可确保两个玩家都可以使用不同的键独立移动球拍,并且游戏状态会平滑且响应迅速地更新。

以上是线程如何改进两人游戏中的按键绑定处理?的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn