PyGame Joystick

Hier werden alle anderen GUI-Toolkits sowie Spezial-Toolkits wie Spiele-Engines behandelt.
Sephiroth
User
Beiträge: 28
Registriert: Freitag 3. November 2006, 00:12

Sonntag 9. März 2008, 04:11

Hallo,
ich habe auf dem Rechner ein kleines Script geschrieben, dass jetzt auch auf meinem gp2x laufen soll.
Allerdings bekomme ich die Buttonansprache nicht richtig hin.

Ich habe ein zusätzliches Modul gp2x.py erstellt mit dem Inhalt:

Code: Alles auswählen

# GP2X joystick button mappings
BUTTON_UP            = 0
BUTTON_DOWN          = 4
BUTTON_LEFT          = 2
BUTTON_RIGHT         = 6
BUTTON_UPLEFT        = 1
BUTTON_UPRIGHT       = 7
BUTTON_DOWNLEFT      = 3
BUTTON_DOWNRIGHT     = 5
BUTTON_CLICK         = 18
BUTTON_A             = 12
BUTTON_B             = 13
BUTTON_X             = 14
BUTTON_Y             = 15
BUTTON_L             = 10
BUTTON_R             = 11
BUTTON_START         = 8 
BUTTON_SELECT        = 9
BUTTON_VOLUP         = 16
BUTTON_VOLDOWN       = 17
(Aus dem gp2x wiki kopiert..;) )

Bisher hab ich in meinem Programm Tastaturabfragen so engegengenommen:
zb:

Code: Alles auswählen

        pygame.event.pump()
        if pygame.key.get_pressed()[pygame.K_LEFT]:
            self.spieler1.move(-1,0)
Und das ganze in einer while-Schleife.

Wie kann ich diesen Aufruf umschrieben, dass er eben die Joystick oder Buttoneingabe vom Handheld annimmt?


Im wiki steht zwar folgendes:

Code: Alles auswählen

    event = pygame.event.poll()
    if event.type == pygame.JOYBUTTONDOWN:
        if event.button == gp2x.BUTTON_X:
            print "X pressed"
http://wiki.gp2x.org/wiki/SDL_Joystick_mapping#Python

Allerdings kann ich damit nicht den Button gedrückt halten, sondern muss immerwieder neu draufdrücken das zb self.spieler1.move(-1,0) ausgeführt wird.
Bei dem von mir als erstes geposteten war dies nicht so.

Also zusammenfassend:
Gibt es eine Anweisung, mit der ich den Input vom Joystick genauso regeln kann wie mit pygame.key.get_pressed()[pygame.K_LEFT] auf dem PC?

Gruss
BlackJack

Sonntag 9. März 2008, 09:10

Du solltest auf ereignisbasierte Verarbeitung umstellen wie's im Wiki steht und auch allen Tutorials für pygame/SDL allgmein, die ich bis jetzt gelesen habe.
Imperator
User
Beiträge: 275
Registriert: Montag 20. August 2007, 14:43
Kontaktdaten:

Sonntag 9. März 2008, 09:58

Sephiroth
User
Beiträge: 28
Registriert: Freitag 3. November 2006, 00:12

Sonntag 9. März 2008, 18:16

Mit pygame.event.get() und auch mit pygame.event.poll() (Wie im wiki) habe ich es schon versucht:

Code: Alles auswählen

        eingabe = pygame.event.poll()
        if eingabe.type == pygame.KEYDOWN:
            if eingabe.key == pygame.K_RIGHT:
                self.spieler1.move(1,0)
und

Code: Alles auswählen

        for eingabe in pygame.event.get():
            if eingabe.type == pygame.KEYDOWN:
                if eingabe.key == pygame.K_RIGHT:
                    self.spieler1.move(1,0)
Beides klappt wunderbar, bis auf:
Ich möchte, wenn ich zum Beispiel Taste K_RIGHT gedrückt halte, das er die ganze Zeit nach rechts geht. Und das ich nicht immer neu drücken muss um einen "Schritt" zu machen. Mit pygame.key.get_pressed()[pygame.K_RIGHT]
hat das ja funktioniert. Aber ist anscheinend nicht auf den Joystick übertragbar.

Kann mir jemand kurz erläutern, was konkret an meinen beiden Code-Schnipseln falsch ist, bzw was ich verändern muss, dass "der Held" bei gedrückthalten der Taste "ununterbrochen" die Aktion durchführt.
(Egal ob für die Tastatur oder einen Joystick. Wenn ich das eine hab wird die Erschließung vom andern nicht so schwer sein..:D )


Gruss

und schonmal danke im vorraus für eure Hilfe!
BlackJack

Sonntag 9. März 2008, 18:38

Wenn Du das jeweilige *_DOWN-Ereignis bekommst läufst Du solange bis das *_UP dazu kommt.
Imperator
User
Beiträge: 275
Registriert: Montag 20. August 2007, 14:43
Kontaktdaten:

Sonntag 9. März 2008, 19:15

das kannst du per Syntax machen
Sephiroth
User
Beiträge: 28
Registriert: Freitag 3. November 2006, 00:12

Sonntag 9. März 2008, 20:20

Wenn Du das jeweilige *_DOWN-Ereignis bekommst läufst Du solange bis das *_UP dazu kommt.
Dachte ich auch, aber er macht immer nur einen Schritt, obwohl ich garkein *_UP drin habe.(Also sollte das *_DOWN ja durchgehend ausgeführt werden oder?)
das kannst du per Syntax machen
Syntax ist doch sowas wie "wie-ein-Befehl-strukturiert-sein-muss" oder?
Verstehe die Aussage nicht ganz..

Ich habe hier mal den kompletten Code hochgeladen, vielleichts hilfts ja bei der Problemerkennung..
http://paste.pocoo.org/show/32638/
die "def handleEventPC" ist die, die atm funktioniert, aber eben nur mit der Tastatur.
In der "def handleEventPC2" hab ich schon einiges durchprobiert. Funktioniert aber nichts so wirklich..^^
Die "def handleEventgp2x" könnter einfach ignorieren..

Gruss
BlackJack

Sonntag 9. März 2008, 21:17

Es gibt nur einmal ein *_DOWN, bis zum *_UP musst *Du* selbst dafür sorgen, dass die Figur bewegt wird.
Sephiroth
User
Beiträge: 28
Registriert: Freitag 3. November 2006, 00:12

Sonntag 9. März 2008, 23:55

Es gibt nur einmal ein *_DOWN, bis zum *_UP musst *Du* selbst dafür sorgen, dass die Figur bewegt wird.
Ok, ich glaube ich weiß jetzt was falsch bei mir war.
Aber kann ich denn sowas umsetzten?

Code: Alles auswählen

IF button_rechts gedrückt:
   while not button_rechts gelöst:
     laufen
So funktionierts mal nicht(bei mir)..

Gruss
Benutzeravatar
Hyperion
Moderator
Beiträge: 7472
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Montag 10. März 2008, 00:29

Merk Dir doch in der Klasse der Figur einfach die Bewegungsrichtung. In Deinem Event-Management änderst Du dann einfach die Bewegungsrichtung. Solange sich nichts ändert, rennt die Figur einfach stumpf weiter in eine Richtung!

Code: Alles auswählen

class Player():
    def __init__(self):
       self.xmove, self.ymove = (0, 0)

...
player = Player()
...
// Eventmanagement
if eingabe.type == KEYDOWN and event.key == pygame.K_UP:
    self.xmove, self.ymove = (0, -1)
elif ...
// usw.
Sephiroth
User
Beiträge: 28
Registriert: Freitag 3. November 2006, 00:12

Montag 10. März 2008, 02:05

Merk Dir doch in der Klasse der Figur einfach die Bewegungsrichtung. In Deinem Event-Management änderst Du dann einfach die Bewegungsrichtung. Solange sich nichts ändert, rennt die Figur einfach stumpf weiter in eine Richtung!
Danke!! Es funktioniert:) :



Eventmanagement sieht jetzt bei mir so aus:

Code: Alles auswählen

        eingabe = pygame.event.poll() 
        if eingabe.type == pygame.QUIT or (eingabe.type == pygame.KEYDOWN and eingabe.key == pygame.K_ESCAPE):
            self.running = False
        #---Spieler2---
        #S2 hoch
        if eingabe.type == pygame.KEYDOWN and eingabe.key == pygame.K_UP:
                self.spieler2.xmove = 0
                self.spieler2.ymove = -1  
Allerdings ist die Steuerung jetzt viel hakeliger..:(
Kann das vielleicht daran liegen, dass zwei Tasten gleichzeitig nichtmehr berücksichtigt werden(wie rechts und hoch zb)?

Gruss
Benutzeravatar
Hyperion
Moderator
Beiträge: 7472
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Montag 10. März 2008, 09:36

Nein, daran kann es eigentlich nicht liegen!

Ohne Deinen Code zu sehen, kann man da schlecht Aussagen machen. Wenn Du bisher nur immer genau einen Schritt gemacht hast, dann ist ja klar, dass man viel mehr Zeit hatte zu reagieren als Spieler, die Richtung zu wechseln!
Benutzeravatar
mkesper
User
Beiträge: 919
Registriert: Montag 20. November 2006, 15:48
Wohnort: formerly known as mkallas
Kontaktdaten:

Montag 10. März 2008, 10:56

Du darfst beim entsprechenden Event nur die Richtung beeinflussen, die auch gewünscht ist. Wenn du den Joytick nach rechts unten drückst, müßte er zwei Events erzeugen: rechts und unten gedrückt. Gehst du jetzt nur noch nach rechts, erhältst du einen "unten losgelassen" Event. Dieser darf aber nur die eine Richtung beeinflussen, nicht die andere.
Sephiroth
User
Beiträge: 28
Registriert: Freitag 3. November 2006, 00:12

Montag 10. März 2008, 17:42

Ohne Deinen Code zu sehen, kann man da schlecht Aussagen machen.
Hab hier mal den kompletten Code hochgeladen.(Das Main Menu ist noch im Aufbau;) )
http://paste.pocoo.org/show/32808/
(Zur Erläuterung: Das Programm ist ein Spiel(solls jedenfalls mal werden) in dem 2Spieler(die jeweils ein Quadrat steuern) einem dritten, das zufällig auf der Oberfläche gesetzt wird hinterherjagen. Wenn es berührt wurde, bekommt der Spieler einen Punkt und ein neues ziel wird gesetzt.)


Also ich habe mal etwas getestet, und ich glaube, dass wenn ein Spieler gerade eine Eingabe macht(wie nach rechts laufen), werden die Eingaben vom Anderen ignoriert.
Und:
Vorher hatte meine Eventmanagement Funktion etwas so ausgesehen:

Code: Alles auswählen

        pygame.event.pump()
        if pygame.key.get_pressed()[pygame.K_d]:
            self.spieler2.move(1,0)
        if pygame.key.get_pressed()[pygame.K_LEFT]:
            self.spieler1.move(-1,0)
.....usw
Damit hat auch sowas wie rechtshoch etc. funktioniert, und beide konnten gleichzeitig was eingeben.
Hat jemand ne Idee wie ich das realisieren könnte?

Gruss
BlackJack

Montag 10. März 2008, 18:42

@mkallas: Die Frage hat mkallas doch schon beantwortet und das sollte doch klar sein, wenn Du mal kurz drüber nachdenkst. Es gibt kein "rechts-oben", sondern nur "rechts" und "oben" und wenn beide jeweils die x- und die y-Richtung beeinflussen, kann nur eines davon "gewinnen". Und das beim Loslassen *irgendeiner* Taste alle Bewegungsrichtungen auf 0 gesetzt werden, ist auch ein wenig bescheuert und erklärt vielleicht warum Du die Steuerung als hakelig empfindest. :roll:

Wenn Du "oben" drückst, wird x=0 und y=-1 gesetzt, wenn dann noch "rechts" dazu kommt, wird x=1 und y=0 gesetzt, wobei Du den Effekt von "oben" zunichte gemacht hast. Wenn Du jetzt "oben" loslässt bleibt der Spieler stehen (x=0, y=0) obwohl ja immer noch "rechts" gedrückt ist.
Antworten