Input vom Controller?

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
Xalooz
User
Beiträge: 19
Registriert: Samstag 17. April 2021, 07:28

Hallo,

habe hier einen Joystick (Marke unbekannt, Anschluss über USB).

Ich möchte folgendes machen:
-Ich habe ein bereits ein Programm, das über die Eingabe einer bestimmten Taste irgendwas ausführt. Nun möchte ich diese Taste auf der Tastatur ersetzen durch einen Tastendruck auf dem Controller. Aber wie genau kann man das realisieren? Muss ja irgendwie herausfinden, die ich die Taste auf dem Controller ansprechen kann
__deets__
User
Beiträge: 14494
Registriert: Mittwoch 14. Oktober 2015, 14:29

Zb mit pygame, das erlaubt das ansprechen von Gaming Hardware.
Xalooz
User
Beiträge: 19
Registriert: Samstag 17. April 2021, 07:28

Hab jetzt folgendes

Code: Alles auswählen

import sys

import pygame

from pygame.locals import *
pygame.init()

pygame.joystick.init()
joysticks = [pygame.joystick.Joystick(i) for i in range(pygame.joystick.get_count())]
for joystick in joysticks:
    print(joystick.get_name())


while True:


    for event in pygame.event.get():
        if event.type == JOYBUTTONDOWN:
            print(event)

            if event.button == 5:
                print("test")
                
            elif event.button == 7:
                print("test1")

Die Eingabe funktioniert so.

So war mein Code vorher:

....

Code: Alles auswählen

for x in y:
        ...
        ...

        eingabe = input("EINGABE)
        if eingabe == a:
             .......
Der Code wurde also bei der eingabe gestoppt und es musste eine Eingabe über die Tastatur erfolgen, damit es weitergeht.
Es klappt nicht so wirklich die Controllereingabe hier einzubauen, da der Code nicht gestoppt wird, sondern mir werden alle x in y angezeigt, ohne irgendeine Eingabe über den Controller

Wie kann ich es also realisieren, dass mein zweiter Wert in Liste y erst dann genommen wird, wenn ich eine Eingabe am Controller tätige. Also erst wenn ich auf den Button am Controller drücke, soll meine Schleife weitergehen
__deets__
User
Beiträge: 14494
Registriert: Mittwoch 14. Oktober 2015, 14:29

Der Nutzcode muss in Teilschritte zerlegt werden, d.h. in der pygame-Hauptschleife stellt man fest, dass es weitergehen soll, und erledigt einen Schritt. In Python kann man das gut mit Generatoren erledigen, weil die einen natuerlichen Weg aufzeigen, wie man an bestimmten Stellen Code unterbrechen kann.

Code: Alles auswählen

def arbeite():
    for x in dinge:
        yield
        tuwas()

generator = arbeite()
next(generator) # in's yield stellen.

while True:
   if joystick_sagt_ja():
       next(generato)
Xalooz
User
Beiträge: 19
Registriert: Samstag 17. April 2021, 07:28

Danke erst mal, aber ich kann das so nicht machen, da ich zwei for-Schleifen habe und ich möchte in der zweiten bleiben. Wenn ich aber die Funktion nach jeden Tastendruck starte, geht er doch erst in die erste for Schleife

Code: Alles auswählen

def keine ahnung

             for....

                     for x in y
Xalooz
User
Beiträge: 19
Registriert: Samstag 17. April 2021, 07:28

Wenn ich das so mache:

Code: Alles auswählen

def keine ahnung
     for...:
         for x in y:
              ....
              while True:
                     for event in pygame.event.get():
                        if event.type == JOYBUTTONDOWN:
                              print(event)

                               if event.button == 5:
                                   print("test")
                
                               elif event.button == 7:
                                   print("test1")

Jetzt ist es so, wenn ich meine Taste bestätige kommt test oder test1 raus. So wie es sein soll. Aber wie kann ich nach dem Tastendruck aus der Schleife raus und meine Schleife das zweite x von y übergeben? Ich komme nämlich im Moment nicht aus der letzten Schleife raus
Sirius3
User
Beiträge: 17711
Registriert: Sonntag 21. Oktober 2012, 17:20

Ich würde dir ja raten, dein Programm so umzuschreiben, dass es Eventgesteuert läuft, __deets__ hat dir aber schon gezeigt, dass man das auch mit Generatoren lösen kann, indem Du jedes Input durch ein yield ersetzt.
Was Du jetzt machst, ist nur Raten ohne Ahnung zu haben. Generatoren sind kompliziert, vor allem wenn man sie so einsetzt,wie du es brauchst. Lerne also erst einmal den Umgang damit, an einfachen Beispielen,mit viel Debugausgaben, bevor Du hier versuchst das einzubauen.
Xalooz
User
Beiträge: 19
Registriert: Samstag 17. April 2021, 07:28

Im Prinzip muss ich doch nur die while Schleife verlassen wenn ein Button gedrück wurde. Das wäre doch viel einfacher. Mehr brauche ich ja gar nicht, aber mit break funktioniert das nicht weil sich das break auf die for-Schleife bezieht. Kann man nicht dem Programm sagen, z.B. solange keine Eingabe erfolgt ist bleibe in der while-Schleife, ansonsten raus aus der while Schleife
__deets__
User
Beiträge: 14494
Registriert: Mittwoch 14. Oktober 2015, 14:29

Wir haben dein Problem schon verstanden. Glaubst du wir verraten dir absichtlich einen einfachen Weg nicht?

Man kann ein Programm nicht beliebig von außen stoppen. Wenn es stückweise laufen soll, muss es entsprechend programmiert werden.
Xalooz
User
Beiträge: 19
Registriert: Samstag 17. April 2021, 07:28

Hab nochmal 2 Fragen zu dem Code.

Code: Alles auswählen

def arbeite():
    for x in dinge:
        yield
        tuwas()

generator = arbeite()
next(generator) # in's yield stellen.

while True:
   if joystick_sagt_ja():
       next(generator)
Mein arbeite() wird direkt nach run ausgeführt. Wie könnte man es programmieren, damit es nicht direkt ausgeführt wird? Normalerweise startet meine Funktion erst dann wenn ich einen Button in der GUI betätige. Und wie ist es, wenn man zwei yield hat?
__deets__
User
Beiträge: 14494
Registriert: Mittwoch 14. Oktober 2015, 14:29

Du kannst beliebig viele yields in deinen Code stecken. Das next laeuft dann bis zum ersten yield. Eigentlich ist das bei mir unnoetig gewesen, das macht man nur, wenn man send benutzen will. Damit kann man Eingaben an den Generator machen. Es reicht also im Zweifel fuer dich, einfach das erste next() wegzulassen.

Es gibt auch die Moeglichkeit, mit asyncio zu experimentieren, das ist syntaktischer Zucker um diese Generatorei. Da gibt es Leute, die mit der Integration in pygame experimentieren, siehe https://blubberquark.tumblr.com/post/17 ... mer-part-i - wie gut das geht, habe ich aber keine Erfahrung mit.
Antworten