当前位置: 首页 > 知识库问答 >
问题:

按键后获得反应时间

苏骏
2023-03-14

所以我正在制作一个游戏,记录你看到屏幕上弹出的东西后的反应时间,但我在获取反应时间方面有困难。我希望用户看到一个蓝色的球后按向上箭头键,我希望记录他们按下该按钮后的反应时间。

这是我的代码:

public class Game extends JPanel 
{

private JLabel start, main, time;
private ImageIcon constant, react;

final int width = 600;
final int height = 600;

private Timer replace;


private Random random;
private int randTime;

private long startTime;
private long stopTime;
private long reactionTime;
private Action upAction;


public Game()
{

  setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));

  setPreferredSize(new Dimension(width, height));
  setBackground(Color.black);

  start = new JLabel("Click Up Arrow when you see a blue ball");
  start.setForeground(Color.white);
  start.setAlignmentX(Component.CENTER_ALIGNMENT);
  add(start);
 
  constant = new ImageIcon("constantCircle.png");
  main = new JLabel(constant);
  main.setAlignmentX(Component.CENTER_ALIGNMENT);


  randomTime();
  replace = new Timer(randTime, timeListener);
  startTime = System.currentTimeMillis();
  replace.setRepeats(false);
  replace.start();    
  add(main);

  time = new JLabel("0");

  time.getInputMap().put(KeyStroke.getKeyStroke("UP"), "upAction");
  time.getActionMap().put("upAction", upAction);


  add(time);

}


public void randomTime()
{
  random = new Random();
  int max = 8000;
  randTime = random.nextInt(max);

}


ActionListener timeListener = new ActionListener()
{
  public void actionPerformed (ActionEvent e)
  {
    react = new ImageIcon("reactCircle.png");
    main.setIcon(react);     
  }
};

public class UpAction extends AbstractAction
{
  public void actionPerformed(ActionEvent e)
  {
    stopTime = System.currentTimeMillis();
    reactionTime = stopTime - startTime;
    time.setText("" + reactionTime);
  
  }
}  
}

我用System.currentTimeMillis设置了一个“开始时间”来获取球变蓝后的时间,但我不确定这是否是正确的方法。

我还在“UpAction”类中设置了一个“stopTime”,我想在用户按下向上箭头时获取时间,但它不起作用。

如果有什么没有意义或不够清楚的,我会尽力详细说明

共有1个答案

咸玄天
2023-03-14

我提出了以下GUI。

我想解释两个重要原则。首先,创建GUI与更新GUI是一个独立的过程。第二,博弈过程是一个状态机。游戏分为六个不同的州。以下是我写的内容,让大家牢记美国。

事件的顺序

  1. 左键点击按钮
  2. 等待2-4秒以显示圆圈
  3. 捕获开始时间
  4. 左键点击按钮
  5. 捕获结束时间
  6. 计算并显示反应时间
  7. 重复1-6

因此,对于GUI,我创建了一个JFrame和三个jpanel;上部JPanel、绘图JPanel和按钮JPanel。

我通过调用SwingU实用程序发票稍后方法启动了Swing应用程序。此方法确保在事件调度线程上创建和执行Swing组件。

JFrame有一个默认的边界布局,我用它来放置三个jpanel。JFrame方法调用必须按特定顺序执行。这是我所有Swing应用程序的顺序。

上面板包含指令和反应时间显示。JTextArea非常适合显示指令。我使用流布局将JTextArea放置在内部JPanel中,我使用边界布局将其放置在上部JPanel中。这样的嵌套布局是以逻辑方式组织Swing组件的好方法。

我把反应时间摆动组件放在另一个内部的JPanel中,我把它放在上面的JPanel中。

我创建了一个图形JPanel,这样我就不必为图像费心了。

按钮JPanel保存提交JButton

我创建了两个控制器类。一个控制器类ButtonListener响应左键单击。另一个控制器类TimerListener创建绘制圆的延迟。

ButtonListener状态变量允许我使用相同的ActionListener提供不同的功能。如果您愿意,您可以编写单独的ActionListener类,每个函数一个。

通过将代码分为视图类和控制器类,我可以将关注点分开,一次只关注应用程序的一部分。

这是完整的可运行代码。我将所有的类都设置为内部类,这样我就可以将这些代码作为一个块发布。

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Random;

import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import javax.swing.Timer;

public class ReactionTimeGame implements Runnable {

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new ReactionTimeGame());
    }
    
    private long reactionTime;
    
    private DrawingPanel drawingPanel;
    
    private JTextField reactionTimeField;
    
    public ReactionTimeGame() {
        this.reactionTime = 0L;
    }

    @Override
    public void run() {
        JFrame frame = new JFrame("Reaction Time Game");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        
        frame.add(createUpperPanel(), BorderLayout.BEFORE_FIRST_LINE);
        this.drawingPanel = new DrawingPanel();
        frame.add(drawingPanel, BorderLayout.CENTER);
        frame.add(createButtonPanel(), BorderLayout.AFTER_LAST_LINE);
        
        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
    }
    
    private JPanel createUpperPanel() {
        JPanel panel = new JPanel(new BorderLayout());
        panel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
        
        JPanel innerPanel = new JPanel(new FlowLayout());
        
        String instructions = "This game will test your reaction time. To play "
                + "the game, left-click on the Submit button.  After a random time "
                + "from 2 - 4 seconds, a circle will appear.  Left-click the "
                + "Submit button again.  Your reaction time will be displayed "
                + "above where the circle was.\n\n"
                + "Left-click the Submit button to start each round of the game.";
        JTextArea textArea = new JTextArea(7, 40);
        textArea.setEditable(false);
        textArea.setText(instructions);
        textArea.setLineWrap(true);
        textArea.setWrapStyleWord(true);
        innerPanel.add(textArea);
        
        panel.add(innerPanel, BorderLayout.BEFORE_FIRST_LINE);
        
        innerPanel = new JPanel(new FlowLayout());
        
        JLabel label = new JLabel("Reaction Time:");
        innerPanel.add(label);
        
        reactionTimeField = new JTextField(5);
        reactionTimeField.setEditable(false);
        updateReactionTime();
        innerPanel.add(reactionTimeField);
        
        label = new JLabel("seconds");
        innerPanel.add(label);
        
        panel.add(innerPanel, BorderLayout.AFTER_LAST_LINE);
        
        return panel;
    }
    
    private JPanel createButtonPanel() {
        JPanel panel = new JPanel(new FlowLayout());
        panel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
        
        JButton button = new JButton("Submit");
        button.addActionListener(new ButtonListener());
        panel.add(button);
        
        return panel;
    }
    
    public void setReactionTime(long reactionTime) {
        this.reactionTime = reactionTime;
    }

    public void drawCircle() {
        drawingPanel.setDrawCircle(true);
        drawingPanel.repaint();
    }
    
    public void eraseCircle() {
        drawingPanel.setDrawCircle(false);
        drawingPanel.repaint();
    }
    
    public void updateReactionTime() {
        double time = 0.001 * reactionTime;
        reactionTimeField.setText(String.format("%.3f", time));
    }
    
    public class DrawingPanel extends JPanel {

        private static final long serialVersionUID = 1L;
        
        private boolean drawCircle;
        
        public DrawingPanel() {
            this.drawCircle = false;
            this.setPreferredSize(new Dimension(300, 300));
        }

        public void setDrawCircle(boolean drawCircle) {
            this.drawCircle = drawCircle;
        }
        
        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            
            if (drawCircle) {
                int centerX = getWidth() / 2;
                int centerY = getHeight() / 2;
                int radius = Math.min(getWidth(), getHeight()) * 9 / 20;
                int diameter = radius + radius;
                g.setColor(Color.MAGENTA);
                g.fillOval(centerX - radius, centerY - radius, diameter, diameter);
            }
        }
        
    }
    
    public class ButtonListener implements ActionListener {
        
        private int state;
        
        private long startTime;
        
        private final Random random;
        
        private Timer timer;
        
        public ButtonListener() {
            this.state = 1;
            this.random = new Random();
        }

        @Override
        public void actionPerformed(ActionEvent event) {
            switch (state) {
            case 1:
                int delay = random.nextInt(2000) + 2000;
                timer = new Timer(delay, new TimerListener(this));
                timer.start();
                state = 2;
                break;
            case 2:
                setEndTime(System.currentTimeMillis());
                eraseCircle();
                state = 1;
                break;
            }
        }

        public int getState() {
            return state;
        }

        public void setStartTime(long startTime) {
            this.startTime = startTime;
        }

        public void setEndTime(long endTime) {
            long elapsedTime = endTime - startTime;
            setReactionTime(elapsedTime);
            updateReactionTime();
        }
        
    }
    
    public class TimerListener implements ActionListener {
        
        private final ButtonListener listener;

        public TimerListener(ButtonListener listener) {
            this.listener = listener;
        }

        @Override
        public void actionPerformed(ActionEvent event) {
            Timer timer = (Timer) event.getSource();
            timer.stop();
            
            if (listener.getState() == 2) {
                listener.setStartTime(System.currentTimeMillis());
                drawCircle();
            }
        }
        
    }

}
 类似资料:
  • 我遇到了一个奇怪的错误,我的搜索输入组件,它失去了对每个按键的关注,不知道为什么。 我还得到了一个

  • 我做了一个蛇游戏(通过尝试遵循youtuber的代码),方向由WASD控制。然而,当我按下其中一个键时,什么都没有发生。如果我按住它,它会改变方向,但会有很大的延迟,可能会超过一秒钟。如何修复此问题?我已经查看了我的代码,并将其与我关注过几次的youtube代码进行了比较,但似乎仍然看不出问题出在哪里。这是我第一次做游戏,所以我对这个很陌生。 如果有帮助的话,这是我试图跟踪的视频。 https:/

  • 问题内容: 我有一个用Java编写的控制台程序,该程序可以响应单键按下,但是用户不按Enter。 我正在打乒乓球,所以需要上下键来移动蝙蝠的东西。 欢迎使用其他方法!(除了制作GUI外) -编辑: 我将只在UNIX系统(OSX和Linux)上运行程序,因此我可以通过以下方式将终端置于“原始”模式: 当我在运行程序之前在控制台中键入该命令时,它将起作用!但是我需要Java自动执行此操作,因此我尝试了

  • 我正在安装我的应用程序,然后使用主活动保存数据,并转到另一个片段活动。下一次我启动我的应用程序时,总是预览第二个片段,然后按“返回”键返回主活动,但我不想返回主活动。我想按后退按钮关闭我的应用程序。我试试这个

  • 我将spring MVC用于服务。通过添加依赖项,我的rest控制器自动。 依赖关系 对象 问题 问题出现在中。例如,我想向添加。以下用户-JSON良好, 但是如果我添加一个带有子活动的activity,它就会崩溃! 的确,jackson这个json,我不明白为什么。我得到以下错误..知道吗? 这里的对象与所有字段,也许与我的错误有关?

  • 问题内容: 我正在使用react native导航(react- navigation)StackNavigator。它从应用程序整个生命周期的“登录”页面开始。我不想使用返回选项,返回“登录”屏幕。有谁知道登录屏幕后如何将其隐藏在屏幕上?顺便说一句,我也使用以下命令将其隐藏在登录屏幕中: 问题答案: 1)要使后退按钮在react-navigation v2或更高版本中消失: 2)如果您要清理导航