java - 在 JApplet 上使用 KeyAdapter 和 Thread 重置/重新启动我的迷你游戏

标签 java multithreading swing awt keylistener

我似乎无法重置我的游戏。 我想要发生的是一旦 numLives 达到 0 消息应该显示:

press R to Restart

我添加了我认为是“r”的 KeyListener 的内容,它符合要求,但不起作用。

其他一切似乎都按计划进行。

    class CharlieBrownGamePanel extends JPanel implements Runnable
{
    /** data variables */
    private int xCord=135, yCord=0;
    private int randXCord, randYCord;
    //private String movingMsg = "Moving Forward ";
    private int numHits=0, numLives=5;

    private boolean xNeedsToTurn=false, yNeedsToTurn=false;

    private String message = "CLICK ON THE BALL TO WIN!";
    private String hitsMsg = "Number of Hits"+numHits;
    private String livesMsg = "Number of Lives: "+numLives;
    private boolean hitTarget = false;

    private static final int EDGE =  30;
    private static final int ADJUST = 5;

    private Dimension dim = null;
    private Thread animate = null;

    public CharlieBrownGamePanel(Dimension dim)  // as a JPanel, need a constructor
    {
        this.dim = dim;
        setBackground(Color.black);
        setForeground(Color.blue);
        addMouseListener(new MouseHandler());
        addKeyListener(new KeyAdapter(){
            public void keyPressed(KeyEvent e) {
                if(e.getKeyCode()== 'r') {

                    xCord=getRandXCord(); 
                    yCord=getRandYCord();
                    animate.start();
                    numHits=0;
                    numLives=5;
                    hitTarget = false;
                    hitsMsg = "Number of Hits:" +numHits;
                    livesMsg= "Number of Lives: "+numLives;
                    message = "MISSED AGAIN";
                    repaint();      
                }


            } 



        });
    }
    public void run()   // as a Runnable class, need to override run() method
    {
        try
        {

            while(true)
            {
                repaint();
                Thread.sleep(100);

            //  char temp = movingMsg.charAt(0);
            //  movingMsg = movingMsg.substring(1,movingMsg.length());
            //  movingMsg += temp ;

                /** determine if ball is close to edge of screen,
                    if so, reverse ball's direction 
                */
                if(!xNeedsToTurn && xCord<(dim.width-EDGE))     //if still more room to go right
                {
                    xCord+=ADJUST;
                }
                else                                            //      otherwise
                {
                    xNeedsToTurn = (xCord>=EDGE);
                    xCord-=ADJUST;
                }

                if(!yNeedsToTurn && yCord<(dim.height-EDGE))    //if still more room to go down
                {
                    yCord+=ADJUST;
                }
                else                                            //      otherwise
                {
                    numLives-=1;
                    xCord=getRandXCord();
                    yCord=getRandYCord();
                    hitsMsg = "Number of Hits:" +numHits;
                    livesMsg= "Number of Lives: "+numLives;
                    message = "MISSED AGAIN";

                }
                if(numLives==0)
                {
                    animate.stop();
                    hitsMsg = "Number of Hits:" +numHits;
                    livesMsg= "Number of Lives: "+numLives;
                    message = "GAME OVER!  Press R to restart.";


                }
            }//end of while loop
        }
        catch(InterruptedException e) {
        }
    } //end of run method

    public void paintComponent(Graphics g)
    {
        super.paintComponent(g);

        //g.setColor(Color.red);
        g.fillOval(xCord,yCord,15,15);
        g.setFont(new Font("SanSerif",Font.BOLD,25));
        g.drawString(message,30,30);
        g.drawString(hitsMsg,30,70);
        g.drawString(livesMsg,30,110);

    }

    public void checkForHit(int newx, int newy)
    {
        if((newx >=xCord) && (newx <=(xCord+15)) &&
           (newy >=yCord) && (newy <=(yCord+15)))
        {
            hitTarget = true;
            numHits+=1;
            hitsMsg = "Number of Hits:" +numHits;
            livesMsg= "Number of Lives: "+numLives;
            message = "That's a Hit!";
            xCord=getRandXCord();
            yCord=getRandYCord();

        }
        else
        {
            hitTarget = false;
            hitsMsg = "Number of Hits:" +numHits;
            livesMsg= "Number of Lives: "+numLives;
            message = "MISSED AGAIN";
        }
    }

    /** USING THE ADAPTER CLASS FOR Mouse Listener */
    private class MouseHandler extends MouseAdapter
    {
        public void mousePressed(MouseEvent e)
        {
            checkForHit(e.getX(),e.getY());
            repaint();
        }
    } //end of MouseHandler class



    private int getRandXCord(){
        randXCord= (int)(Math.random() * (dim.width +1));
        return randXCord;
    }
    private int getRandYCord(){
        randYCord= (int)(Math.random() * (100 +1));
        return randYCord;
    }

    } //end of  class task and panel

最佳答案

首先,KeyEvent#getKeyCode 返回虚拟键代码,而不是字符。看一下 KeyEvent.VK_R

其次,KeyListerners 仅当它们注册的组件可聚焦并且具有键盘焦点时才会响应。 JPanel,默认情况下无法接收键盘焦点

第三,您应该使用 Key Bindings因为他们会克服这些缺点

关于java - 在 JApplet 上使用 KeyAdapter 和 Thread 重置/重新启动我的迷你游戏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16559354/

相关文章:

关于时钟的javascript和java

java - P5 : Remove TableRows containing Null/NaN

C# 套接字 : Do I really need so many separate threads

Java:在图像上创建阴影效果

java - Swing 应用程序阻止写入文件

java - 重载枚举抽象方法

java - 如何删除java中的所有对象指针

c# - 队列的并行处理

java - 潜在并发问题的单元测试

java - 如何以编程方式控制 JScrollPane 的位置?