简体   繁体   English

如何同时收听多个按键输入

[英]How do I have multiple key inputs Listened to at the same time

I'm attempting to create a simple pong game in Java, but I don't know how to have both players using the keyboard at the same time. 我正在尝试用Java创建一个简单的Pong游戏,但我不知道如何让两个玩家同时使用键盘。 The game is incomplete and I'm working on the paddle movement for both players currently. 游戏尚不完整,我目前正在为两位玩家进行划桨动作。 The problem is, when a player pushes their up key and moves their paddle up, but if the other players hits any of their keys it cancels the previous players action and causes the paddle to stop. 问题是,当一个玩家按下自己的向上键并向上移动其拨片时,但是如果其他玩家按下其任意键,它将取消先前的玩家动作并导致拨片停止。 I think I need a way to handle multiple key inputs at once. 我想我需要一种可以一次处理多个关键输入的方法。 Here's my code the KeyListeners at the bottom is where I need help. 这是我的代码,底部的KeyListeners是我需要帮助的地方。 I'm only a 1 year Java programmer so go easy on the rest of my code. 我只有1年的Java程序员,所以其余的代码都变得简单。

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;

import javax.swing.*;

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.HashSet;
import java.util.Set;

public class DrawGame extends JPanel implements ActionListener{
    public static final int XPOS = 0;
    public static final int YPOS = 0;
    public boolean xFlag = true; // true means ballx is going right
    public boolean yFlag = true; // true means bally is going down
    public int ballX = 300; // Ball starting point
    public int ballY = 400; // Ball starting point
    Timer ballTimer; // Starts balls animation

    public int leftScore;
    public int rightScore;

    public int rightPadY; // Right players paddle position
    public int leftPadY; // left players paddle position

    // Constructor
    public DrawGame(){
        addKeyListener(new RightListener());
        addKeyListener(new LeftListener());

        leftScore = 0;
        rightScore = 0;

        rightPadY = YPOS + 230;
        leftPadY = YPOS + 230;

        setBackground(Color.BLACK);
        setPreferredSize(new Dimension(800, 600));
        setFocusable(true);

        ballTimer = new Timer(10, this);
        ballTimer.start();
    }

    // Draws game
    public void paintComponent(Graphics g){
        super.paintComponent(g);
        Graphics2D g2d = (Graphics2D)g;

        //Drawing Side Boards
        g2d.setColor(Color.WHITE);
        g2d.fillRect(XPOS + 5, YPOS + 20, 775, 25); // Top Board
        g2d.fillRect(XPOS + 5, YPOS + 517, 775, 25); // Bottom board

        //Drawing the center line
        g2d.fillRect(XPOS + 377, YPOS + 45 * 1, 25, 25);
        g2d.fillRect(XPOS + 377, YPOS + 45 * 2, 25, 25);
        g2d.fillRect(XPOS + 377, YPOS + 45 * 3, 25, 25);
        g2d.fillRect(XPOS + 377, YPOS + 45 * 4, 25, 25);
        g2d.fillRect(XPOS + 377, YPOS + 45 * 5, 25, 25);
        g2d.fillRect(XPOS + 377, YPOS + 45 * 6, 25, 25);
        g2d.fillRect(XPOS + 377, YPOS + 45 * 7, 25, 25);
        g2d.fillRect(XPOS + 377, YPOS + 45 * 8, 25, 25);
        g2d.fillRect(XPOS + 377, YPOS + 45 * 9, 25, 25);
        g2d.fillRect(XPOS + 377, YPOS + 45 * 10, 25, 25);
        g2d.fillRect(XPOS + 377, YPOS + 45 * 11, 25, 25);

        //Drawing the paddles
        g2d.fillRect(XPOS + 10, leftPadY, 20, 100);// Left
        g2d.fillRect(XPOS + 755, rightPadY, 20, 100); // Right

        //Drawing the ball
        g2d.fillRect(ballX, ballY, 23, 23); 

        //Drawing the score
        switch(leftScore){
            case 0:
                g2d.fillRect(XPOS + 305, YPOS + 50, 7, 30);
                g2d.fillRect(XPOS + 325, YPOS + 50, 7, 30);
                g2d.fillRect(XPOS + 305, YPOS + 50, 25, 7);
                g2d.fillRect(XPOS + 305, YPOS + 80, 27, 7);
                break;
            case 1:
                g2d.fillRect(XPOS + 325, YPOS + 50, 7, 30);
        }

        switch(rightScore){
            case 0:
                g2d.fillRect(XPOS + 450, YPOS + 50, 7, 30);
                g2d.fillRect(XPOS + 470, YPOS + 50, 7, 30);
                g2d.fillRect(XPOS + 450, YPOS + 50, 25, 7);
                g2d.fillRect(XPOS + 450, YPOS + 80, 27, 7);
                break;
            case 1:
                g2d.fillRect(XPOS + 450, YPOS + 50, 7, 30);
        }
    }

    // Controls the animation of the ball
    public void actionPerformed(ActionEvent e){
        if(xFlag == true && ballX >= 735){
            ballX += 2;
            xFlag = false;
        } else if(xFlag == true){
            ballX += 2;
        }

        if(xFlag == false && ballX <= 25){
            ballX -= 2;
            xFlag = true;
        } else if(xFlag == false){
            ballX -= 2;
        }

        if(yFlag == true && ballY >= 500){
            ballY += 2;
            yFlag = false;
        } else if(yFlag == true){
            ballY += 2;
        }

        if(yFlag == false && ballY <= 45){
            ballY -= 2;
            yFlag = true;
        } else if(yFlag == false){
            ballY -= 2;
        }
        repaint();
        ballTimer.restart();
    }

    // Keylistener for right player
    private class RightListener implements KeyListener{

        @Override
        public synchronized void keyPressed(KeyEvent event) {
            if(event.getKeyCode() == KeyEvent.VK_UP){
                rightPadY -= 5;
            }else if(event.getKeyCode() == KeyEvent.VK_DOWN){
                rightPadY += 5;
            }
            repaint();
        }

        @Override
        public synchronized void keyReleased(KeyEvent e) {
            // TODO Auto-generated method stub

        }

        @Override
        public synchronized void keyTyped(KeyEvent e) {
            // TODO Auto-generated method stub

        }
    }

    // Keylistener for left player
    private class LeftListener implements KeyListener{
        @Override
        public synchronized void keyPressed(KeyEvent event) {
            if(event.getKeyCode() == KeyEvent.VK_W){
                leftPadY -= 5;
            } else if(event.getKeyCode() == KeyEvent.VK_S){
                leftPadY += 5;
            }
            repaint();
        }

        @Override
        public synchronized void keyReleased(KeyEvent e) {
            // TODO Auto-generated method stub

        }

        @Override
        public synchronized void keyTyped(KeyEvent e) {
            // TODO Auto-generated method stub

        }
    }




}

Don't use a KeyListener. 不要使用KeyListener。 You should be using Key Bindings . 您应该使用Key Bindings

See Motion Using the Keyboard for more information. 有关更多信息,请参见使用键盘运动

I added the following code to the KeyboardAnimation example from the above link, which will allow you to do what you want: 我从上面的链接向KeyboardAnimation示例添加了以下代码,该代码可让您执行所需的操作:

JLabel label2 = new JLabel( new ColorIcon(Color.GREEN, 40, 40) );
label2.setSize( label2.getPreferredSize() );
label2.setLocation(500, 500);
contentPane.add( label2 );

KeyboardAnimation animation2 = new KeyboardAnimation(label2, 24);
animation2.addAction("A", -3,  0);
animation2.addAction("D", 3,  0);
animation2.addAction("W",    0, -3);
animation2.addAction("S",  0,  3);

It's better to use a thread for animations. 最好将线程用于动画。 When you keyPressed we will tell the program that the key is down. 当您按下keyPressed我们将告诉程序该按键已按下。 On keyReleased we will tell the program that the key is up. keyReleased我们将告诉程序密钥已打开。 In the thread we will read this value and determine if we want to move or not. 在线程中,我们将读取该值并确定是否要移动。 This will also be much smoother. 这也将更加平滑。

First, you need to implement Runnable in some class. 首先,您需要在某些类中实现Runnable You could even do it in your main class there. 您甚至可以在那里在那里上主课。 Add the public void run method. 添加public void run方法。

In it will be something like: 其中将是这样的:

while(true)
{
    if(player1.upkeyIsDown() && player1.downKeyIsUp())
    {
         //move Player1 Up
    }
    else if(player1.downKeyIsDown() && player1.upKeyIsUp())
    {
         //move Player1 Down
    }
    //do similar for player 2
    try{
        Thread.sleep(50);
    }
    catch(InterruptedException ie)
    {
        ie.printStackTrace();
    }
}

This is semi-pseudo code, you'll have to implement how you save the key being down. 这是半伪代码,您必须实现如何保存关闭的密钥。 In your KeyListeners, you need to call something in the main class to change these values, and then this thread will deal with the rest. 在您的KeyListener中,您需要在主类中调用某些内容来更改这些值,然后该线程将处理其余的线程。

This thread also needs to be started. 此线程也需要启动。 In your main/constructor somewhere write new Thread(this).start(); 在您的主/构造器中的某个地方写一个new Thread(this).start();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM