游戏“极品飞车的极品飞车”无法通过Java类机器人控制

时间:2010-10-16 04:21:30

标签: java

我用Java Robot编写了一个用于控制赛车游戏的机器人。该机器人适用于极品飞车地下除了键“向下”(向上,向左,向右键非常好)。但是我的机器人无法控制极品飞车最需要的速度

机器人工作正常,但游戏不接受模拟的关键事件。我做了一些搜索,发现游戏是基于DirectX的。在DirectX中,键盘/鼠标事件是特殊的。似乎游戏直接“询问”键盘,而不是通过Windows。我在CS中尝试我的程序,发现它运行得很好。

我使用Eclipse和Java 1.6在Windows 7中编程。所以我想问为什么极品飞车需要接受模拟的关键事件以及如何解决这个程序?谢谢。

5 个答案:

答案 0 :(得分:2)

据我了解,DirectX不依赖Windows生成的事件来接收键盘输入。因此,触发模拟事件对您不起作用。我认为你不能做你想做的事。

答案 1 :(得分:2)

  

我写了一个控制赛车的机器人   使用Java Robot的游戏。

您要生成哪些KeyEvents?

  

对于Java Robot的模拟键事件   像“VK_Up,   VK_Down,Vk_Left,VK_Right“,”需要   为速度最想要的“被忽视。但是,   对于“A-Z”键,游戏接受了!

当你应该使用keyPressed和keyReleased时,也许你正在尝试生成keyTyped事件?

这是一个使用右/左/上向下键的简单示例。尝试输入(1,2,3)然后退格到开头并输入(0)。然后按播放按钮。

import java.awt.*;
import java.awt.event.*;
import java.util.ArrayList;
import java.util.List;
import javax.swing.*;

public class RobotPlayback extends JFrame implements KeyListener, ActionListener
{
    JTextField textField1;
    JTextField textField2;
    List playback = new ArrayList();

    public RobotPlayback()
    {
        textField1 = new JTextField(30);
        textField1.addKeyListener( this );
        getContentPane().add(textField1, BorderLayout.NORTH);
//
        JButton button = new JButton("Playback");
        button.addActionListener( this );
        button.setFocusable(false);
        getContentPane().add(button);
//
        textField2 = new JTextField(30);
        getContentPane().add(textField2, BorderLayout.SOUTH);
    }

    public void keyPressed(KeyEvent e)
    {
        playback.add(e);
    }

    public void keyReleased(KeyEvent e)
    {
        playback.add(e);
    }

    public void keyTyped(KeyEvent e) {}

    public void actionPerformed(ActionEvent e)
    {
        Thread playback = new Thread()
        {
            public void run()
            {
                 playback();
            }
        };
        playback.start();
    }

    private void playback()
    {
        textField2.requestFocus();

        try
        {
            Robot robot = new Robot();
            robot.setAutoDelay( 200 );

            for (int i = 0; i < playback.size();i++)
            {
                KeyEvent event = (KeyEvent)playback.get(i);

                if (event.getID() == KeyEvent.KEY_PRESSED)
                    robot.keyPress( event.getKeyCode() );
                else
                    robot.keyRelease( event.getKeyCode() );
            }
        }
        catch(Exception exc)
        {
            System.out.println(exc);
        }

        setVisible(true);
        playback = new ArrayList();
        textField1.requestFocus();
    }

    public static void main(String[] args)
        throws Exception
    {
        JFrame frame = new RobotPlayback();
        frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
        frame.pack();
        frame.setLocationRelativeTo( null );
        frame.setVisible( true );
     }
}
  

我在此注册了帐户   早上只有11个声誉。不   足以支持

即使有11分,如果它能回答你的问题,你也应该能够“接受”答案。

答案 2 :(得分:2)

Java Robot在箭头键方面存在错误。它将按下数字键盘箭头。目前,无法按非数字键盘箭头。

参考:http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4838497

答案 3 :(得分:0)

虽然这是一个老问题,但我会发布我的答案,以防以后帮助某人。

我最近遇到了同样的问题。我根据一些外部输入为左,右,上和下键分别调用了keyPress和keyRelease。我尝试了很多游戏,但机器人按键操作并没有在任何游戏中起作用。当我在文本文件中使用光标尝试相同的代码时,光标移动正确。

问题在于游戏通常需要连续按键,因此keyPress + keyRelease组合不会产生任何影响。所以我通过在每个箭头键按下的相反方向调用keyRelease来解决问题。

例如,如果需要按下左箭头键,我会调用

  

keyRelease(KeyEvent.VK_RIGHT);
  keyPress(KeyEVent.VK_LEFT);

这样可以按住左键,直到最后需要按下右箭头键。有更多的最佳方法可以通过跟踪最后一次按键来完成此操作,依此类推,但这种方法似乎运行得很好。

答案 4 :(得分:0)

我知道这是一篇非常古老的帖子,但我的回答可能对寻找答案的人有帮助

<强>答案: -

这是因为有些游戏使用 DirectInput API 来读取键盘扫描码而不是虚拟键码。由于 java.awt.Robot 通过虚拟键码执行击键而不是扫描码,因此使用 java.awt.Robot 模拟的键盘事件可能对游戏没有影响。您必须使用JNI / JNA从Java应用程序进行Windows本机调用。

代码可在 https://github.com/umer0586/winKeyboad

获取
Keyboard keyboard = new Keyboard();
keyboard.winKeyPress(ScanCode.DIK_UP);
//Thread.sleep(1000);
keyboard.winKeyRelease(ScanCode.DIK_UP);