키 바인딩이 있는 스레드
게임을 멀티 스레드로 구현하려는 경우가 아니면 멀티 스레드는 필요하지 않습니다.
문제는 두 플레이어가 서로 다른 키를 누를 수 있다는 것입니다. 그렇다면 부울을 사용하여 키가 눌려졌는지 여부를 나타내고 키를 놓을 때 플래그를 재설정할 수 있습니다.
게임 로직에서 부울의 상태를 확인하고 적절하게 행동하십시오. 두 패들이 독립적으로 움직일 수 있는 다음 예를 참조하세요.
[독립적으로 움직이는 패들의 이미지]
다음은 예시 코드입니다.
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 중국어 웹사이트의 기타 관련 기사를 참조하세요!