带键绑定的线程
多线程不是必需的,除非您希望游戏是多线程的。
问题是,两个玩家可以按不同的键吗?如果是这样,您可以使用布尔值来指示按键是否按下,并在释放按键时重置标志。
在您的游戏逻辑中,检查布尔值的状态并采取适当的行动。请参阅以下示例,其中两个桨都可以独立移动:
[桨独立移动的图像]
以下是示例代码:
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中文网其他相关文章!