Problem mit Einrücken

Hier werden alle anderen GUI-Toolkits sowie Spezial-Toolkits wie Spiele-Engines behandelt.
Antworten
Benutzeravatar
Weltbesiedler
User
Beiträge: 103
Registriert: Dienstag 2. Februar 2010, 18:44
Wohnort: Bayern

Code: Alles auswählen

import pygame, sys, random

screen = pygame.display.set_mode ([1000, 800])
screen.fill ([255, 255, 255])


x = random.randint(0, 255)
y = random.randint(0, 255)
z = random.randint(0, 255)

x2 = random.randint(0, 255)
y2 = random.randint(0, 255)
z2 = random.randint(0, 255)

x3 = random.randint(0, 255)
y3 = random.randint(0, 255)
z3 = random.randint(0, 255)

x4 = random.randint(0, 255)
y4 = random.randint(0, 255)
z4 = random.randint(0, 255)

pygame.display.flip()

while True:
    for event in pygame.event.get(): 
       if event.type == pygame.QUIT:
            sys.exit()
       elif event.type == pygame.KEYDOWN:
            if event.key == pygame.K_m:
                screen.fill ((x, y, z))
       elif event.type == pygame.KEYDOWN:
            if event.key == pygame.K_a:
                screen.fill ((x2, y2, z2))
       elif event.type == pygame.KEYDOWN:
            if event.key == pygame.K_l:
                screen.fill ((x3, y3, z3))
       elif event.type == pygame.KEYDOWN:
            if event.key == pygame.K_i:
                screen.fill ((x4, y4, z4))
       pygame.display.update()
Das der Bildschirm die Farbe wechselt funktioniert nur, wenn ich m drücke, nicht aber bei a bzw. l bzw. i.

Was ist da das Problem?
Barabbas
User
Beiträge: 349
Registriert: Dienstag 4. März 2008, 14:47

Du hast da vier Mal stehen
elif event.type == pygame.KEYDOWN
. Das ist nicht nur unnötig, sondern funktioniert auch nicht: In "elif" steckt ja "else if" - also "andernfalls wenn....".

Wenn ich jetzt schreibe:

Code: Alles auswählen

Wenn X:
    irgendwas
andernfalls wenn Y:
    irgendwas anderes
andernfalls wenn Y:
    nochwas anderes
Nun wird die dritte Bedingung niemals abgearbeitet, selbst, wenn sie erfüllt ist, weil die zweite Bedingung ja bereits zutrifft. Es wird also *immer nur eine* Bedingung des If-Blockes ausgewertet. Ist eine Bedingung erfüllt, werden die anderen Bedingungen gar nicht mehr angeschaut - selbst wenn sie *immer* wahr sind. Dabei geht es strickt nach Reihenfolge - also von oben nach unten.

Mach nur eine "elif event.type == pygame.KEYDOWN" Abfrage und checke dann mit einem if..elif..elif Block, welche Taste gedrückt wurde.

Gruß,

brb
Zuletzt geändert von Barabbas am Mittwoch 16. Juni 2010, 14:10, insgesamt 1-mal geändert.
Benutzeravatar
pillmuncher
User
Beiträge: 1484
Registriert: Samstag 21. März 2009, 22:59
Wohnort: Pfaffenwinkel

Das Problem ist, dass du sagst:

Code: Alles auswählen

Wenn eine Taste gedrückt wurde:
    ...
andernfalls wenn eine Taste gedrückt wurde:
    ...
Das "andernfalls" wird nie erreicht, da du ja schon weiter oben getestet hast, ob eine Taste gedrückt wurde, und "andernfalls" würde ja bedeuten, dass gerade KEINE Taste gerückt wurde (dass also ein ganz andere event eingetreten ist, als event.KEYDOWN).

Die Lösung ist, zu testen, ob eine Taste gedrückt wurde, und wenn ja, nachzusehen welche:

Code: Alles auswählen

Wenn eine Taste gedrückt wurde:
    wenn m gedrückt wurde: ...
    anderfalls wenn a gedrückt wurde: ...
   usw.
andernfalls wenn ein anderes Ereignis eintrat::
    ...
In specifications, Murphy's Law supersedes Ohm's.
Benutzeravatar
Weltbesiedler
User
Beiträge: 103
Registriert: Dienstag 2. Februar 2010, 18:44
Wohnort: Bayern

Ok jetzt funktioniert es:

Code: Alles auswählen

import pygame, sys, random

screen = pygame.display.set_mode ([1000, 800])
screen.fill ([255, 255, 255])


x = random.randint(0, 255)
y = random.randint(0, 255)
z = random.randint(0, 255)

x2 = random.randint(0, 255)
y2 = random.randint(0, 255)
z2 = random.randint(0, 255)

x3 = random.randint(0, 255)
y3 = random.randint(0, 255)
z3 = random.randint(0, 255)

x4 = random.randint(0, 255)
y4 = random.randint(0, 255)
z4 = random.randint(0, 255)

pygame.display.flip()

while True:
    for event in pygame.event.get(): 
       if event.type == pygame.QUIT:
            sys.exit()
       if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_m:
                screen.fill ((x, y, z))
       if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_a:
                screen.fill ((x2, y2, z2))
       if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_l:
                screen.fill ((x3, y3, z3))
       if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_i:
                screen.fill ((x4, y4, z4))
       pygame.display.update()
Danke!
Jack Daniels
User
Beiträge: 30
Registriert: Freitag 1. Januar 2010, 11:38

Das funktioniert zwar so, aber die Vorschläge, die gemacht wurden waren eher so gedacht:

Code: Alles auswählen

if event.type == pygame.QUIT:
    sys.exit()
elif event.type == pygame.KEYDOWN:
    if event.key == pygame.K_m:
        screen.fill ((x, y, z))
    elif event.key == pygame.K_a:
        screen.fill ((x2, y2, z2))
    elif event.key == pygame.K_l:
        screen.fill ((x3, y3, z3))
    elif event.key == pygame.K_i:
        screen.fill ((x4, y4, z4))
, was zumindest ich schöner finde und nebenbei auch kürzer ist, weil die Vergleiche nicht unnötig doppelt gemacht werden.
BlackJack

@Weltbesiedler: Und dann könnte man die Tupel mit den Farben noch an Namen binden statt die drei Einzelbestandteile. Und statt diese Namen dann zu nummerieren, könnte man sie in eine Liste stecken. Oder vielleicht sogar in ein Dictionary mit der zugehörigen Tastenkonstante als Schlüssel und der Farbe als Wert. Würde das Programm noch einmal etwas kürzer und flexibler machen.

Edit:

Code: Alles auswählen

import random
import sys
import pygame


def random_color():
    return (random.randint(0, 255),
            random.randint(0, 255),
            random.randint(0, 255))


def main():
    screen = pygame.display.set_mode ([1000, 800])
    screen.fill((255, 255, 255))
    pygame.display.flip()
    
    key_codes = [pygame.K_m, pygame.K_a, pygame.K_l, pygame.K_i]
    key2color = dict((k, random_color()) for k in key_codes)
    
    while True:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                sys.exit()
            elif event.type == pygame.KEYDOWN:
                color = key2color.get(event.key)
                if color:
                    screen.fill(color)
            pygame.display.update()


if __name__ == '__main__':
    main()
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

So langsam könnte der OP auch mal wissen, dass es Python-Syntax-Highlighting hier im Board gibt...
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
Antworten