2010-10-16 8 views
6

Napisałem bota do kontrolowania gry wyścigowej za pomocą Java Robot. Bot działa dobrze dla Need For Speed ​​Underground z wyjątkiem klawisza "Down" (klawisze góra, lewo, prawo działają bardzo dobrze). Jednak mój bot nie może kontrolować Need For Speed ​​Most Wanted.Gra "Need for Speed ​​Most Wanted" nie może być kontrolowana przez klasę Java Robot

Bot działa dobrze, ale gra nie akceptuje symulowanych kluczowych zdarzeń. Zrobiłem trochę wyszukiwania i okazało się, że gra jest oparta na DirectX. W DirectX zdarzenia klawiatura/mysz są wyjątkowe. Wygląda na to, że gra "zadaje" bezpośrednio klawiaturę, a nie przez Windows. I próbuję swojego programu w CS i stwierdziłem, że działa całkiem nieźle.

Programuję w Windows 7, używając Eclipse i Java 1.6. Tak więc chcę zapytać, dlaczego nie potrzebuje akceptowalnych, kluczowych zdarzeń i jak rozwiązać ten program? Dziękuję Ci.

Odpowiedz

2

Napisałem bota do kontrolowania wyścigów gry za pomocą Java Robot.

Jakie Klucze do wygenerowania?

Do najważniejszych wydarzeń symulowanych Java robota jak "VK_Up, VK_Down, Vk_Left, VK_Right", to "Need for Speed ​​ Most Wanted" ignorowane. Ale, dla kluczy "A-Z", gra została zaakceptowana!

Być może próbujesz wygenerować zdarzenia keyTyped, gdy powinieneś używać klawiszy keyPressed i keyReleased?

Oto prosty przykład, który działa z przyciskami prawo/lewo/góra. Spróbuj wprowadzić (1, 2, 3), a następnie cofnij do początku i wprowadź (0). Następnie naciśnij przycisk odtwarzania.

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

Zarejestrowałem konto właśnie w tej rano i tylko 11 reputacji. Nie wystarcza upvoting

Nawet z 11 punktów powinien być w stanie „przyjąć” odpowiedź, jeśli odpowiedzi na swoje pytanie.

+0

Napisałem program testujący, aby zaakceptować kluczowe zdarzenia z bota. Wyniki pokazują, że keyPressed, keyReleased i keyTyped są wyzwalane. Nie rozumiem twojego punktu widzenia. I dziękuję za twoją radę. Pamiętam to.^_^ – suiyemin

+1

Chodzi mi o to, że powiedziałeś, że zadziałał klucz A-Z. Cóż, te naciśnięcia klawiszy wygenerują zdarzenie keyTyped, ponieważ są one znakami możliwymi do wyświetlenia. Z drugiej strony klawisze strzałek nie generują wyświetlanych znaków, więc nawet jeśli zostanie wygenerowane zdarzenie keyTyped, będzie zawierało niezdefiniowaną wartość dla wpisanego klucza. Może to powoduje problem w kodzie. Jeśli zauważysz, że mój robot śledzi tylko zdarzenia keyPressed i keyReleased, nie martwi się o zdarzenia keyTyped. Nie wiem, czy to robi różnicę, czy nie, ale może zignorować zdarzenia keyTyped. – camickr

+0

To dobra uwaga. Dzięki. – suiyemin

2

O ile rozumiem, DirectX nie polega na zdarzeniach generowanych przez system Windows w celu odbierania danych wejściowych z klawiatury. Dlatego symulowane zdarzenia strzelania nie będą działać dla ciebie. Nie sądzę, że możesz zrobić to, co chcesz.

+0

NIE! Jak mam oszukiwać w moich grach? – JoshD

+0

Debugowałem mój program do ostatniej chwili. Wielkie zaskoczenie znalezione! W przypadku symulowanych kluczowych zdarzeń Java Robot, takich jak "VK_Up, VK_Down, Vk_Left, VK_Right", "Need for Speed ​​Most Wanted" zostało zignorowane. Ale w przypadku kluczy "A-Z" gra została zaakceptowana! Teraz mój program działa całkiem dobrze po zresetowaniu klawiszy Speed. Może dla klawiszy strzałek wychodzą różne metody obsługi. – suiyemin

+0

Dziękuję za odpowiedź. – suiyemin

0

Choć jest to stara sprawa, wyślę moją odpowiedź w przypadku, gdy ktoś pomaga później.

Niedawno stanąłem w obliczu tego samego problemu. Dzwoniłem keyPress i keyRelease zaraz po drugim dla każdego z klawiszy: lewy, prawy, górny i dolny, w oparciu o zewnętrzne dane wejściowe. Próbowałem wielu gier, ale naciśnięcia klawiszy robota nie działały w żadnym z nich. Kiedy wypróbowałem ten sam kod z kursorem w pliku tekstowym, kursor przesunął się poprawnie.

Problem polegał na tym, że gry wymagały ciągłych naciśnięć klawiszy, dlatego kombinacja keyPress + keyRelease nie spowodowała żadnego efektu. Naprawiłem problem przez wywołanie keyRelease w przeciwnym kierunku dla każdego naciśnięcia klawisza ze strzałką.

Na przykład, jeśli lewy klawisz strzałki musiała zostać wciśnięty, wzywam

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

Utrzymuje lewy klawisz wciśnięty aż prawy klawisz strzałki w końcu musi być prasowany. Istnieją bardziej optymalne sposoby, aby to zrobić, śledząc ostatnie naciśnięcie klawisza, i tak dalej, ale ta metoda wydaje się działać dobrze.

+0

Możesz również wyświetlić [Pobierz za darmo z programu Underground 3 Free Download] (https://androidapksget.blogspot.com/2017/10/download-need-for-speed-underground-3.html) . – NomanJaved

0

Wiem, że to bardzo stary post, ale moja odpowiedź może być pomocne dla kogoś, kto szuka odpowiedzi

odpowiedź: -

Jego ponieważ niektóre gry używa DirectInput API dla czytanie klawiatury kodów skanowania zamiast kodów kluczy wirtualnych. Jako java.awt.Robot wykonuje naciśnięcia klawiszy za pomocą kodów kluczy wirtualnych, nie skanując kodów, dlatego zdarzenia klawiatury symulowane za pomocą java.awt.Robot mogą nie mieć wpływu na grę. Musisz wykonać natywne wywołanie Windows z aplikacji Java za pomocą JNI/JNA.

kod jest dostępny tutaj https://github.com/umer0586/winKeyboad

Keyboard keyboard = new Keyboard(); 
keyboard.winKeyPress(ScanCode.DIK_UP); 
//Thread.sleep(1000); 
keyboard.winKeyRelease(ScanCode.DIK_UP); 
Powiązane problemy