2010-10-16 25 views
6

Escribí un bot para controlar el juego de carreras usando Java Robot. El bot funciona bien para Need For Speed ​​Underground a excepción de la tecla "Abajo" (las teclas Arriba, Izquierda, Derecha funcionan muy bien). Sin embargo, mi bot no puede controlar Need For Speed ​​Most Wanted.El juego "Need for Speed ​​Most Wanted" no puede ser controlado por la clase Java Robot

El bot funciona bien, pero el juego no acepta los eventos clave simulados. Realicé algunas búsquedas y descubrí que el juego está basado en DirectX. En DirectX, los eventos de teclado/mouse son especiales. Parece que el juego "pregunta" directamente al teclado, no a través de Windows. Y pruebo mi programa en CS, y encontré que funciona bastante bien.

Programa en Windows 7, usando Eclipse y Java 1.6. Entonces quiero preguntar ¿por qué no acepta Need for Speed ​​Most Wanted los eventos clave simulados y cómo resolver este programa? Gracias.

Respuesta

2

Escribí un bot para controlar carreras juego usando Java Robot.

¿Qué KeyEvents genera?

Para eventos simulada de teclas de Java Robot como "VK_UP, VK_DOWN, Vk_Left, VK_Right", la "necesidad for Speed ​​Most Wanted" ignorado. Pero, para las teclas "A-Z", el juego aceptado!

Quizás esté intentando generar eventos KeyType cuando debería usar keyPressed y keyReleased?

Aquí hay un ejemplo simple que funciona con las teclas derecha/izquierda/arriba abajo. Intente ingresar (1, 2, 3), luego retroceda hasta el comienzo e ingrese (0). Luego presione el botón de reproducción.

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); 
    } 
} 

que registró la cuenta sólo en este mañana y sólo 11 reputaciones. No suficiente para la votación ascendente

Incluso con 11 puntos, debería ser capaz de "aceptar" una respuesta si responde a su pregunta.

+0

Escribí un programa de prueba para aceptar los eventos clave del bot. Los resultados muestran que keyPressed, keyReleased y keyTyped se activan. No entiendo tu punto. Y gracias por tu consejo. Yo recuerdo eso.^_^ – suiyemin

+1

Mi punto fue que dijiste que la tecla A-Z funcionaba. Bueno, estas pulsaciones de tecla generarán un evento KeyType ya que son caracteres que se pueden visualizar. Por otro lado, las teclas de flecha no generan caracteres visualizables, por lo que incluso si se genera el evento keyTyped, contendrá un valor indefinido para el carácter escrito clave. Tal vez esto esté causando un problema en tu código. Si observa que mi Robot solo rastrea los eventos keyPressed y keyReleased, no se preocupe por los eventos KeyTyped. No sé si hace la diferencia o no, pero tal vez puedas ignorar los eventos Key key. – camickr

+0

Ese es un buen punto. Gracias. – suiyemin

2

Por lo que tengo entendido, DirectX no se basa en los eventos generados por Windows para recibir datos del teclado. Por lo tanto, disparar eventos simulados no funcionará para usted. No creo que puedas hacer lo que quieras.

+0

NO! ¿Cómo se supone que debo hacer trampa en mis juegos? – JoshD

+0

Estaba depurando mi programa hasta el último minuto. ¡Gran sorpresa encontrada! Para los eventos clave simulados de Java Robot como "VK_Up, VK_Down, Vk_Left, VK_Right", se ignoró el "Need for Speed ​​Most Wanted". Pero, para las teclas "A-Z", ¡el juego es aceptado! Ahora mi programa funciona bastante bien ya que reinicié las teclas para Speed. Tal vez para las teclas de flecha, existen diferentes métodos de manejo. – suiyemin

+0

Gracias por su respuesta de todos modos. – suiyemin

0

Aunque esta es una vieja pregunta, voy a publicar mi respuesta en caso de que ayude a alguien más tarde.

Hace poco tuve el mismo problema. Estaba llamando a keyPress y KeyRelease uno tras otro para cada una de las teclas izquierda, derecha, arriba y abajo, en función de alguna entrada externa. Probé un montón de juegos, pero las pulsaciones de teclas de Robot no funcionaron en ninguno de ellos. Cuando probé el mismo código con el cursor en un archivo de texto, el cursor se movió correctamente.

El problema es que los juegos suelen requerir pulsaciones de teclas continuas, por lo que la combinación de pulsación de teclas + tecla no causa ningún efecto. Así que solucioné el problema llamando a KeyRelease en la dirección opuesta para cada pulsación de tecla de flecha.

Por ejemplo, si la tecla de flecha izquierda necesaria para ser presionado, me llaman

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

Esto mantiene el botón izquierdo pulsado hasta que la tecla de flecha derecha, finalmente, tiene que ser presionado. Hay formas más óptimas de hacerlo haciendo un seguimiento de la última pulsación de tecla, y así sucesivamente, pero este método parece funcionar bien.

+0

También puede ver [Descargar Need For Speed ​​Underground 3] (https://androidapksget.blogspot.com/2017/10/download-need-for-speed-underground-3.html) . – NomanJaved

0

Sé que esto es un post muy viejo, pero mi respuesta podría ser útil para alguien que está buscando respuesta

respuesta: -

Su porque algunos juegos utilizan DirectInput API de teclado de lectura códigos de escaneo en lugar de códigos de tecla virtual. Como java.awt.Robot realiza pulsaciones de teclas a través de códigos de tecla virtuales no escanea códigos, por lo tanto, los eventos de teclado simulados usando java.awt.Robot pueden no afectar el juego. Tienes que hacer una llamada nativa de Windows desde tu aplicación java usando JNI/JNA.

código está disponible aquí https://github.com/umer0586/winKeyboad

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