1

这是我的简单箭头排序应用程序的代码。

它生成一个大小为 4 的随机序列,包括向上、向下、向左和/或向右箭头键,并一次显示一个。如果他们用户正确地重复该序列,它会显示另一个 5 个键的序列。只要用户输入正确的序列,序列的大小就会不断增加,但如果输入了无效的序列,则序列的大小就会减小。

我遇到的问题是,第一次执行完美无缺,它甚至第二次显示序列,但在第二次迭代期间它不接受我的键盘输入。

为了更好地理解问题,我将其分解为主要动作执行块和完整的代码以及最后。

序列生成

for(int flag=1;flag<size;flag++)
    {
    random = randomGenerator.nextInt(4);
    generated[flag]=random;
    setVisible(true);
    switch(random)
        {
            case 0:
            left();
            break;
            case 1:
            up();
            break;
            case 2:
            right();
            break;
            case 3:
            down();
            break;
        }
        delaybig();     
    }

用户输入序列

public void keyPressed(KeyEvent e)
{
    if(cflag<=size) 
    {
        if(e.getKeyCode()==37)
            {
                entered[cflag]=0;
                cflag++;
                Keys.setText("LEFT");
                left();
            }
        else if(e.getKeyCode()==38)
            {
                entered[cflag]=1;
                cflag++;
                Keys.setText("UP");
                up();
            }
        else if(e.getKeyCode()==39)
            {
                entered[cflag]=2;
                cflag++;
                Keys.setText("RIGHT");
                right();
            }
        else if(e.getKeyCode()==40)
            {
                entered[cflag]=3;
                cflag++;
                Keys.setText("DOWN");
                down();
            }
    else
        {
            Keys.setText("INVALID");
        }
    }

使用 Arrays.equals 进行序列比较

if(cflag==size)
    {
        boolean check = Arrays.equals(generated, entered);
        if(check)
            {
                delaysmall();
                Keys.setText("PERFECT");
                size++;
                cflag=1;
                delaysmall();
                Keys.setText("GO AGAIN");
                delaybig();
                restart();  
            }
        else
            {
                delaysmall();
                Keys.setText("FAILED");
                if(size>5)
                    {
                        delaybig();
                        restart();
                        size--;
                        cflag=1;
                    }
            }
    }

循环线程

public void restart() 
{ 
    Thread goagain =  new Thread() 
    {
        @Override
        public void run()
             {
                launchframe();
             }
        };
        goagain.start();
}

我在这上面花了很长时间都无济于事,所以这里是完整的代码,以防你怀疑错误喜欢其他地方。

import java.io.*;
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
import java.util.Random;
import java.util.Arrays;

class ArrowSorrow extends Frame implements KeyListener{

int flag;
Image img;
int random;
int cflag=1,size=5;
boolean ShowImage=true;
int entered[]=new int[50];
int generated[]=new int[50];
TextField Keys=new TextField(8);
Random randomGenerator = new Random();
MediaTracker mt = new MediaTracker(this);

public ArrowSorrow(String title)
    {
        super(title);
    }

public void restart() 
    { 
        // Create a new thread
    Thread goagain =  new Thread() 
    {
        // Override run() to provide the running behavior of this thread.
        @Override
        public void run()
             {
                launchframe();
             }
        };
        goagain.start();
}
public void launchframe()
{
    for(int flag=1;flag<1;flag++)
        generated[flag]=0;
    for(int flag=1;flag<1;flag++)
        entered[flag]=0;
            splash();
    add(Keys);
            delaybig();
    setSize(400,400);
    Keys.setEditable(false);
    Keys.setText("MEMORIZE");
    Keys.addKeyListener(this);      
    setBackground(Color.black);
    setLayout(new FlowLayout());
for(int flag=1;flag<size;flag++)
        {
        random = randomGenerator.nextInt(4);
        generated[flag]=random;
        setVisible(true);
        switch(random)
            {
                case 0:
                left();
                break;
                case 1:
                up();
                break;
                case 2:
                right();
                break;
                case 3:
                down();
                break;
            }
            delaybig();     
        }
        String sequence=new String("");
        for(flag=1;flag<size;flag++)
            {
                sequence=sequence+(Integer.toString(generated[flag]));
            }
            Keys.setText(sequence);
            delaysmall();
            Keys.setText("REPEAT");
            delaysmall();
            setVisible(true);

            addWindowListener(new WindowAdapter()
                {
                    public void windowClosing(WindowEvent we)
                        {
                            dispose();
                        }
                });
    }
public void splash()
    {
    img = ToolKit.getDefaultToolkit().getImage("image address for splashscreen.jpg");
    mt.addImage(img,0);
    repaint();
    setVisible(true);
}

public void left()
{
    img = Toolkit.getDefaultToolkit().getImage("image address for left.jpg");
    mt.addImage(img,0);
    repaint();
    setVisible(true);
}

public void right()
{
    img = Toolkit.getDefaultToolkit().getImage("image address for right.jpg");
    mt.addImage(img,0);
    repaint();
    setVisible(true);
}

public void up()
{
    img = Toolkit.getDefaultToolkit().getImage("image address for up.jpg");
    mt.addImage(img,0);
    repaint();
    setVisible(true);
}

public void down()
{
    img = Toolkit.getDefaultToolkit().getImage("image address down.jpg");
    mt.addImage(img,0);
    repaint();
    setVisible(true);
}
//minor delay
public void delaysmall()
{
    try 
        {
            Thread.sleep(600);
        } 
    catch(InterruptedException ex) 
        {
            Thread.currentThread().interrupt();
        }   
}
//major delay
public void delaybig()
{
    try 
        {
            Thread.sleep(1200);
        } 
    catch(InterruptedException ex) 
        {
            Thread.currentThread().interrupt();
        }   
}

public void paint(Graphics g)
{
super.paint(g); 
if(img != null)
    g.drawImage(img,70,70, this);
else
    g.clearRect(0, 0, getSize().width, getSize().height);
}

public void keyPressed(KeyEvent e)
{
    if(cflag<size)  
    {
        if(e.getKeyCode()==37)
            {
                entered[cflag]=0;
                cflag++;
                Keys.setText("LEFT");
                left();
            }
        else if(e.getKeyCode()==38)
            {
                entered[cflag]=1;
                cflag++;
                Keys.setText("UP");
                up();
            }
        else if(e.getKeyCode()==39)
            {
                entered[cflag]=2;
                cflag++;
                Keys.setText("RIGHT");
                right();
            }
        else if(e.getKeyCode()==40)
            {
                entered[cflag]=3;
                cflag++;
                Keys.setText("DOWN");
                down();
            }
    else
        {
            Keys.setText("INVALID");
        }
    }
//comparing generated sequence and user input sequence      
if(cflag==size)
    {
        boolean check = Arrays.equals(generated, entered);
        if(check)
            {
                delaysmall();
                Keys.setText("PERFECT");
                size++;
                cflag=1;
                delaysmall();
                Keys.setText("GO AGAIN");
                delaybig();
                restart();  
            }
        else
            {
                delaysmall();
                Keys.setText("FAILED");
                if(size>5)
                    {
                        delaybig();
                        restart();
                        size--;
                        cflag=1;
                    }
            }
    }
}
public void keyTyped(KeyEvent e){}
public void keyReleased(KeyEvent e){}
}

class ArrowSorrowLaunch{
public static void main(String args[])
    {
        ArrowSorrow instance=new ArrowSorrow("Arrow Sorrow");
        instance.launchframe();
    }
}
4

3 回答 3

1
  1. 更改Thread.sleep(int)Swing Timer,否则您会为Swing 中的 Concurency烦恼

  2. Thread.sleep(int)冻结Swing GUI直到结束,在此睡眠期间,任何MouseKey事件都不会被调度或消耗

  3. 不要paint直接到JFrame,放在那里JPanelJComponent

  4. 用于 JPanelJComponent必须使用paintComponent而不是paint()

  5. 不要使用KeyListener,使用Keybindings 代替,否则必须setFocusable()

于 2012-10-31T18:17:42.690 回答
1

您调用launchFrame开始游戏的每次迭代。但是,您正在做很多工作launchFrame,应该只做一次。您应该将该初始化代码移出launchFrame并只执行一次。特别是您不应重复调用Keys.addKeyListener(this);或添加多个窗口侦听器。

于 2012-10-31T18:23:53.273 回答
0

OP的解决方案。

修复,感谢 Ted Hopp。

通过将它们移出 launchframe() 创建了这个新方法

void oneTime()
{
    add(Keys);
    setSize(400,400);
    Keys.requestFocus();
    Keys.setEditable(false);
    Keys.setText("MEMORIZE");
    Keys.addKeyListener(this);      
    setBackground(Color.black);
    setLayout(new FlowLayout());
    launchframe();
}

更换

    instance.launchframe();//this
    instance.oneTime();//with this in main
于 2018-05-12T15:35:06.160 回答