Steuerung bleibt hängen

Hier werden alle anderen GUI-Toolkits sowie Spezial-Toolkits wie Spiele-Engines behandelt.
Imperator
User
Beiträge: 275
Registriert: Montag 20. August 2007, 14:43
Kontaktdaten:

Hallo,

mit meinem spiel gehts voran, aber jetzt hab ich ein problem. Die Steuerung funktioniert folgendermaßen:

Code: Alles auswählen

while True:
    for event in pygame.event.get():
        move_up = False
        move_down = False
        move_left = False
        move_right = False
        if event.type == KEYDOWN:
            if event.key == K_ESCAPE:
                pygame.quit()
            if event.key == K_UP:
                move_up = True
            if event.key == K_DOWN:
                move_down = True
            if event.key == K_LEFT:
                move_left = True
            if event.key == K_RIGHT:
                move_right = True
        if event.type == MOUSEBUTTONDOWN:
            pygame.mixer.music.load('Shot1.wav')
            pygame.mixer.music.play()
    if move_up:
        player = player.move(0, -2)
    if move_down:
        player = player.move(0, 2)
    if move_right:
        player = player.move(2, 0)
    if move_left:
        player = player.move(-2, 0)
Wenn man jetzt den charakter z.B. nach oben hatschen lässt und dabei ohne K_UP loszulassen auf K_RIGHT drückt, bleibt er hängen. eine fließende Steuerung ist also nicht möglich. habt ihr eine Idee wie man dasumgehen kann?
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Bleibt er hängen? Wer? Dein Ärmel? Woran? An der Türklinke?

Es ist schwer zu helfen, wenn du nur so wage Sachen erzählst. Ein Funktionsfähiges Mini-Programm würde sicherlich auch helfen, da sich hier niemand die Mühe machen wird, deinen Code in ein Programm zu bauen um deinen Fehler an einem funktionierenden Beispiel zu testen.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Imperator
User
Beiträge: 275
Registriert: Montag 20. August 2007, 14:43
Kontaktdaten:

Code: Alles auswählen

import pygame, os, sys
from pygame.locals import*
pygame.init()
landschaft = pygame.image.load('Soil01.bmp')
hintergrund = pygame.transform.scale(landschaft, (800, 400))
karte = hintergrund.get_rect()
spieler = pygame.image.load('Hopsy.bmp')
player = spieler.get_rect()
black = 0, 0, 0
size = width, height = 800, 400
screen = pygame.display.set_mode(size)
screen.fill(black)
while True:
    for event in pygame.event.get():
        move_up = False
        move_down = False
        move_left = False
        move_right = False
        if event.type == KEYDOWN:
            if event.key == K_ESCAPE:
                pygame.quit()
            if event.key == K_UP:
                move_up = True
            if event.key == K_DOWN:
                move_down = True
            if event.key == K_LEFT:
                move_left = True
            if event.key == K_RIGHT:
                move_right = True
        if event.type == MOUSEBUTTONDOWN:
            pygame.mixer.music.load('Shot1.wav')
            pygame.mixer.music.play()
    if move_up:
        player = player.move(0, -2)
    if move_down:
        player = player.move(0, 2)
    if move_right:
        player = player.move(2, 0)
    if move_left:
        player = player.move(-2, 0)
            
                
    screen.blit(hintergrund, karte)
    screen.blit(spieler, player)
    pygame.display.flip()
Ihr müsst dann halt andere Graphiken nehmen.
@Leonidas: die Figur bleibt bewegt sich nicht mehr bis man alle Tasten losgelassen hat, un dann halt wieder eine drückt.
Und um es gleich vornwegzunehmen: Ich war bisher zu faul den Code mit OOP aufzubereiten, mach ich aber noch.
fred.reichbier
User
Beiträge: 155
Registriert: Freitag 29. Dezember 2006, 18:27

Hallo

Code: Alles auswählen

    for event in pygame.event.get():
        move_up = False
        move_down = False
        move_left = False
        move_right = False
(...) 
Ich glaube, da liegt der Fehler. So, wie du das geschrieben hast, werden bei jedem Event die move_*-Variablen zurückgesetzt. Die False-Zuweisungen müssten vor der Schleife stehen.

Gruß Fred
Imperator
User
Beiträge: 275
Registriert: Montag 20. August 2007, 14:43
Kontaktdaten:

So funktioniert es tatsächlich, aber das Programm hängt sich nach einer weile auf.
BlackJack

Was heisst es hängt sich auf? Du meinst nicht zufällig, dass nachdem man alle Richtungen mal ausprobiert hat sich der Spieler nicht mehr bewegt!? Das hat auch mit Deiner Programmlogik zu tun.

Was passiert in dem Programm mit `move_up` wenn ich die Cursor-Hoch-Taste drücke und dann wieder loslasse? Überprüfe Deine Antwort am besten mal mit einem ``print`` in der Schleife bevor Du sie postest. Ist vielleicht nicht das was Du denkst.
Imperator
User
Beiträge: 275
Registriert: Montag 20. August 2007, 14:43
Kontaktdaten:

Hallo,

Tipp befolgt, aber irgendwie werd ich daraus nicht schlau. Auch wenn man die Taste längst losgelasen und eine Andere gedrückt hat, werden weiterhin strings in der shell ausgegeben. Ich hatte jetzt die idee das ganze so umzuändern:

Code: Alles auswählen

    if move_up:
        player = player.move(0, -2)
        if event.type == KEYUP:
            if event.key == K_UP:
                move_up = False
Dann bewegt der Spieler sich aber gar nicht mehr nach oben. Damit lässt sich nur die Bewegung in eine andere Richtung unterbrechen. Lässt man dann K_UP wieder los, bewegt sich der Spieler munter weiter.
BlackJack

Ausserhalb der Event-Schleife das Event zu untersuchen ist bestimmt keine so gute Idee.
Imperator
User
Beiträge: 275
Registriert: Montag 20. August 2007, 14:43
Kontaktdaten:

Ich hab das print jetzt nach

Code: Alles auswählen

move_up = True
eingefügt und kapier die welt nicht mehr. Wenn K_UP gedrückt wird bewegt er sich nur beim ersten mal aber auch danach werden bei Druck strings ausgegeben. Lässt die IDLE eine Zeile aus?
Imperator
User
Beiträge: 275
Registriert: Montag 20. August 2007, 14:43
Kontaktdaten:

Ich kapiers einfach nicht. Könnt ihr mir nicht noch einen Denkanstoß geben?
Imperator
User
Beiträge: 275
Registriert: Montag 20. August 2007, 14:43
Kontaktdaten:

halleluja, im Fitnessstudio kam mir die Erlechrung. Das Problem ist gelöst.
Imperator
User
Beiträge: 275
Registriert: Montag 20. August 2007, 14:43
Kontaktdaten:

Hallo,

wie angekündigt habe ich den Code nun OOP-gerecht aufbereitet. Die Steuerung habe ich logischerweise genauso programmiert wie im Kauderwelschcode, aber jetzt funktioniert sie schon wieder nicht mehr. Aber es ist genau das Selbe.
Erst der Kauderwelschcoe:

Code: Alles auswählen

import pygame, os, sys
from pygame.locals import*
pygame.init()
landschaft = pygame.image.load('Soil01.bmp')
hintergrund = pygame.transform.scale(landschaft, (900, 700))
karte = hintergrund.get_rect()
spieler = pygame.image.load('Hopsy.bmp')
player = spieler.get_rect()
black = 0, 0, 0
size = width, height = 900,700
screen = pygame.display.set_mode(size)
screen.fill(black)
move_up = False
move_down = False
move_right = False
move_left = False
while True:
    for event in pygame.event.get():
        if event.type == KEYDOWN:
            if event.key == K_ESCAPE:
                pygame.quit()
            if event.key == K_UP:
                move_down = False
                move_right = False
                move_left = False
                move_up = True
            if event.key == K_DOWN:
                move_up = False
                move_right = False
                move_left = False
                move_down = True
            if event.key == K_LEFT:
                move_down = False
                move_up = False
                move_right = False
                move_left = True
            if event.key == K_RIGHT:
                move_down = False
                move_up = False
                move_left =False
                move_right = True

    if move_up:
        player = player.move(0, -2)
    if move_down:
        player = player.move(0, 2)
    if move_right:
        player = player.move(2, 0)
    if move_left:
        player = player.move(-2, 0)
    if event.type == MOUSEBUTTONDOWN:
        isplaying = pygame.mixer.music.get_busy()
        if isplaying == False:
            pygame.mixer.music.load('Shot1.wav')
            pygame.mixer.music.play()
        
    screen.blit(hintergrund, karte)
    screen.blit(spieler, player)
    pygame.display.flip()
   
und nun der OOP-Code:

Code: Alles auswählen

import pygame, os, sys
from pygame.locals import*
pygame.init()

class spieler:
    def __init__(self):
        self.graphic = pygame.image.load('Hopsy.bmp')
        self.image = self.graphic.get_rect()
        life = 100
        self.move_up = False
        self.move_down = False
        self.move_right = False
        self.move_left = False
    def steuern(self):
        for event in pygame.event.get():
            if event.type == KEYDOWN:
                 if event.key == K_ESCAPE:
                     pygmae.quit()
                 if event.key == K_w:
                     self.move_down = False
                     self.move_right= False
                     self.move_left = False
                     self.move_up = True
                 if event.key == K_s:
                     self.move_up = False
                     self.move_right = False
                     self.move_left = False
                     self.move_down = True
                 if event.key == K_d:
                     self.move_up = False
                     self.move_down = False
                     self.move_left = False
                     self.move_right = True
                 if event.key == K_a:
                     self.move_up = False
                     self.move_down = False
                     self.move_right = False
                     self.move_left = True
        
        if self.move_up:
            self.image = self.image.move(0, -2)
        if self.move_down:
            self.image = self.image.move(0, 2)
        if self.move_right:
            self.image = self.image.move(2, 0)
        if self.move_left:
            self.image = self.image.move(-2, 0)
    def erscheinen(self):
        screen.blit(self.graphic, self.image)
           

landschaft = pygame.image.load('Soil01.bmp')
hintergrund = pygame.transform.scale(landschaft, (900, 700))
karte = hintergrund.get_rect()
fighter = spieler()
black = 0, 0, 0
size = width, height = 900, 700
screen = pygame.display.set_mode(size)
screen.fill(black)
while True:
    fighter.steuern()
    screen.blit(hintergrund, karte)
    fighter.erscheinen()
    pygame.display.flip()
Die Steuerung ist doch beide male genau gleich umgesetzt. Warum funktioniert sie nur im Kauderwelschcode?
fred.reichbier
User
Beiträge: 155
Registriert: Freitag 29. Dezember 2006, 18:27

Hallo,

ich bezweifle, dass spieler.erscheinen so funktioniert (wenn ich jetzt nicht völlig eingerostet bin :p). Die Variable 'screen' ist ja nicht definiert. Ich würde da am besten entweder screen als Argument übergeben, oder der Klasse spieler einfach eine Eigenschaft screen zu spendieren.

Gruß Fred
BlackJack

Doch das `screen` ist auf Modulebene definiert. Was natürlich unschön ist, weil es zu solchen Annahmen führen kann. :?
Imperator
User
Beiträge: 275
Registriert: Montag 20. August 2007, 14:43
Kontaktdaten:

Hallo,

an erscheinen kann es nicht liegen, denn die Spielfigur wird ja angezeigt, nr sie bewegt sich nicht. Also muss es mit der Steuerung zusammenhängen.
Imperator
User
Beiträge: 275
Registriert: Montag 20. August 2007, 14:43
Kontaktdaten:

Hallo,

ich habe mir gedacht, vielleicht liegt der Fehler auch in der endlosschleife. Bloß wo?
Imperator
User
Beiträge: 275
Registriert: Montag 20. August 2007, 14:43
Kontaktdaten:

Hallo,

Code: Alles auswählen

import pygame, os, sys
from pygame.locals import*
pygame.init()

class spieler:
    def __init__(self):
        self.graphic = pygame.image.load('Hopsy.bmp')
        self.image = self.graphic.get_rect()
        life = 100
        self.move_up = False
        self.move_down = False
        self.move_right = False
        self.move_left = False
    def steuern(self):
        for event in pygame.event.get():
            if event.type == KEYDOWN:
                 if event.key == K_ESCAPE:
                     pygame.quit()
                 if event.key == K_w:
                     self.move_down = False
                     self.move_right= False
                     self.move_left = False
                     self.move_up = True
                 if event.key == K_s:
                     self.move_up = False
                     self.move_right = False
                     self.move_left = False
                     self.move_down = True
                 if event.key == K_d:
                     self.move_up = False
                     self.move_down = False
                     self.move_left = False
                     self.move_right = True
                 if event.key == K_a:
                     self.move_up = False
                     self.move_down = False
                     self.move_right = False
                     self.move_left = True

landschaft = pygame.image.load('Soil01.bmp')
hintergrund = pygame.transform.scale(landschaft, (900, 700))
karte = hintergrund.get_rect()
fighter = spieler()
black = 0, 0, 0
size = width, height = 900, 700
screen = pygame.display.set_mode(size)
screen.fill(black)
while True:
    fighter.steuern()
    if fighter.move_up:
        fighter.image = fighter.image.move(0, -2)
    if fighter.move_down:
        fighter.image = fighter.image.move(0, 2)
    if fighter.move_right:
        fighter.image = fighter.image.move(2, 0)
    if fighter.move_left:
        fighter.image = fighter.image.move(-2, 0)
    screen.blit(hintergrund, karte)
    screen.blit(fighter.graphic, fighter.image)
    pygame.display.flip()
Das bringt auch nichts. Gibt es den niemand der so eine Situation auch schon mal hatte und helfen könnte?
BlackJack

Also bei mir funktioniert der letzte Quelltext.
Imperator
User
Beiträge: 275
Registriert: Montag 20. August 2007, 14:43
Kontaktdaten:

Hallo BlackJack,

hast du irgendwas dran verändert?
BlackJack

Die Dateinamen für die Bilder. ;-)
Antworten