[Python/Pygame]Mysteriöser Fehler

Hier werden alle anderen GUI-Toolkits sowie Spezial-Toolkits wie Spiele-Engines behandelt.
Antworten
paulkoch95
User
Beiträge: 15
Registriert: Samstag 21. Januar 2012, 16:31

Hallo Community,
ich programmiere seit einiger Zeit mit Python bzw. pygame, seit kurzen habe ich ein seltsames Problem, wenn ich mein Spiel aus der Idle das 1.te mal starte
dann funktioniet alles, wenn ich es aber im gleichen durchlauf ein 2.tes mal starten will kommt nach kurzer zeit "Python funktioniert nicht mehr..."
Meine Frage, warum? bzw wie kann man das beheben
Hier der bisherige recht überschaubare Code:

Code: Alles auswählen

print("Load")
bif="bg_earth.jpg"
#Wichtige Kerndeklarationen!
print("load 40%")
mif="greenrunner_default.png"
bif="bg_stone.jpg"
leben = 100
intro_img="intro_lamp_improved.png"
light="light_default.png"
run2="kreuz.png"
auswahl_img="inventar_selection.png"
lebensleiste_img="lives_bar.png"
leben_full="live_full.png"
strength_image="strength.png"
while_register=0
jump_moved=0
inventar="inventar.png"
block1_image="block_1.png"
bullet_image="bullet.png"
maske_image="maske.png"
jh=60
lebenspunkte = 100
#array für x-koordinaten
arrayx = 200 , 220, 240, 260, 280, 300
#array für y-koordinaten
arrayy = 200 , 200, 200, 200, 200, 200


jh_caption=str(jh)
print("load 80%")
#imports setzen
import time
import math
import pygame, sys
import Tilemap
#import inventar_render
from pygame.locals import *
#/imports:D
pygame.init()

#BILDER KONVERTIEREN
screen=pygame.display.set_mode((640,480),0,32)
background=pygame.image.load(bif).convert()
player_char=pygame.image.load(mif).convert_alpha()
light_convert=pygame.image.load(light).convert_alpha()
run_rechts=pygame.image.load(run2).convert_alpha()
inventar_inv=pygame.image.load(inventar).convert_alpha()
inv_auswahl=pygame.image.load(auswahl_img).convert_alpha()
lebensleiste=pygame.image.load(lebensleiste_img).convert_alpha()
lebenvoll=pygame.image.load(leben_full).convert_alpha()
strength=pygame.image.load(strength_image).convert_alpha()
intro=pygame.image.load(intro_img).convert_alpha()
block1=pygame.image.load(block1_image).convert_alpha()
bullet=pygame.image.load(bullet_image).convert_alpha()
maske=pygame.image.load(maske_image).convert_alpha()
#FPS kontrollieren
clock = pygame.time.Clock()
print("loaded 100% completed")

#DEBUG MDOE kontrollieren

                
pygame.display.set_caption("Find it yourself!")            
#POSIOTIONS bariablen setzen
x,y=60,120
movex, movey=0,0
#INVENTAR auswahl
auswahlx,auswahly=4,482
#INTRO
screen.blit(intro,(0,0))
font = pygame.font.Font(None, 33)
text = font.render('Find it yourself!', True, (255,
255, 255))
textRect = text.get_rect()
textRect.centerx = screen.get_rect().centerx
textRect.centery = screen.get_rect().centery
screen.blit(text, textRect)
pygame.display.update()
time.sleep(2)
#Menue anfang
xb = 2
xc = 2
while xb == 2:
    screen.blit(intro,(0,0))
    font2 = pygame.font.Font(None, 36)
    text2 = font2.render('Hauptmenü:', True, (255,255, 255))
    screen.blit(text2, (10,10))
    font3 = pygame.font.Font(None, 36)
    text3 = font3.render('[1]Spiel starten', True, (255,255, 255))
    screen.blit(text3, (150,150))
    font4 = pygame.font.Font(None, 36)
    text4 = font4.render('[2]Spieleinstellungen', True, (255,255, 255))
    screen.blit(text4, (150,200))
    if xc == 3:
        print("EINSTELLUNGEN AUFGERUFEN")
    for event in pygame.event.get():
        if event.type==KEYDOWN:
            if event.key==K_1:
                xb = 3
                screen=pygame.display.set_mode((640,544),0,32)
            if event.key==K_2:
                xc = 3
                
    time.sleep(0.05)
    pygame.display.update()
#Menue ende

while True:

    if x == 0:
        x = 1
    if y == 0:
        y =1

    if x==640:
        x=120
        lebenspunkte=-int(10)
        if lebenspunkte<=70:
            print("TOD")
            
                       
    if y>=480:
        y=120
    for event in pygame.event.get():
        if event.type == QUIT:
            font = pygame.font.Font(None, 33)
            text = font.render('Vielen Dank fürs Spielen!', True, (255,
            255, 255))
            textRect = text.get_rect()
            textRect.centerx = screen.get_rect().centerx
            textRect.centery = screen.get_rect().centery
            screen.blit(text, textRect)
            pygame.display.update()
            time.sleep(2)
            pygame.quit()
            sys.exit()
        
        if event.type==KEYDOWN:
            if event.key==K_SPACE:
                movey*2
                movex*2
                player_char = pygame.transform.rotate(player_char, 90)
            if event.key==K_LEFT:
                movex=-0.5
                while_register=0
            elif event.key==K_RIGHT:
                movex=+0.5
                while_register=0
            elif event.key==K_UP:
                movey=-0.5
            elif event.key==K_DOWN:
                movey=+0.5
            elif event.key==K_1:
                auswahlx,auswahly=4,482
            elif event.key==K_2:
                auswahlx,auswahly=68,482
            elif event.key==K_3:
                auswahlx,auswahly=136,482
            elif event.key==K_4:
                auswahlx,auswahly=200,482
            elif event.key==K_5:
                auswahlx,auswahly=264,482
         
                  
            

                
        if event.type==KEYUP:
            if event.key==K_LEFT:
                movex=0
            elif event.key==K_RIGHT:
                movex=0
            elif event.key==K_UP:
                movey=0
            elif event.key==K_DOWN:
                movey=0
        map = Tilemap.Tilemap
   

    clock.tick(600)        
    x+=movex
    y+=movey

    
    screen.blit(background, (0,0))
    screen.blit(player_char,(x,y))
    #screen.blit(maske,(x,y))
    #screen.blit(maske,(-x,-y))
    screen.blit(light_convert, (0,0))
    pygame.transform.rotate(player_char, 90)
    screen.blit(inventar_inv, (0,480))
    screen.blit(inv_auswahl, (auswahlx,auswahly))
    screen.blit(lebensleiste,(6,448))
    #==lebensanzeigerenderinhalt==
    screen.blit(lebenvoll,(12,454))
    screen.blit(lebenvoll,(34,454))
    screen.blit(lebenvoll,(56,454))
    screen.blit(lebenvoll,(78,454))
    screen.blit(lebenvoll,(100,454))
    screen.blit(lebenvoll,(122,454))
    screen.blit(block1,(200,200))
    #stärke
    screen.blit(strength,(150,454))
    screen.blit(strength,(172,454))
    screen.blit(strength,(194,454))
    screen.blit(strength,(216,454))
    screen.blit(strength,(238,454))
    #==ENDE render lebensanzeige inhalt==
    'NOTHING TO RENDER AT THIS MOMENT'
    #==Render blöcke bzw, versch. Blocktypen==
    #Ende Render Blocktypen
    #ITEM test vorbehalten: screen.blit(item_lamp,(6,484))
    pygame.display.update()

Ich freu mich über alle Antworten
Mit freundlichen Grüssen
paulkoch95
BlackJack

@paulkoch95: Starte es einfach nicht aus IDLE heraus.
paulkoch95
User
Beiträge: 15
Registriert: Samstag 21. Januar 2012, 16:31

aber ich bearbeite es doch mit der idle, dann möcht ichs von dort aus starten, is ja sonst immens aufwendig.....-.-
mfg
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

paulkoch95 hat geschrieben:aber ich bearbeite es doch mit der idle, dann möcht ichs von dort aus starten, is ja sonst immens aufwendig.....-.-
Wieso? Du hast eben parallel noch eine Shell auf, in der Du den Aufruf einfach per "up"-Taste erneut aufrufst. Ist das so aufwendig?
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
BlackJack

@paulkoch95: Dann musst Du halt IDLE immer neu starten, nachdem Du das Spiel einmal gestartet hast. Einfacher wird es dadurch nicht gerade. ;-)
paulkoch95
User
Beiträge: 15
Registriert: Samstag 21. Januar 2012, 16:31

so danke erstmal für alle antworten (man bekommt in diesem forum schön schnell hilfe, find ich gut..:))
ich habe mir jetzt pydev für ecplipse installiert, is komfortabler und schöner und bereitet keine probleme..
mfg paulkoch95
BlackJack

@paulkoch95: Du meinst Du bist nur noch nicht auf die Probleme gestossen, die man mit Eclipse+PyDev hat. ;-)
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

paulkoch95 hat geschrieben: Hier der bisherige recht überschaubare Code:
...
Von allen Problemen mal abgesehen: Brrrr! Der sieht alles andere als "überschaubar" aus!

Du hast da so viele "magic numbers" drin und zudem dermaßen viel "copy & paste"-Code, dass Du da sicherlich nicht mehr lange durchsteigen wirst.

Für jemanden, der sich angeblich schon länger mit Python befasst, vermisse ich hier Funktionen, Listen, Dictionaries usw. Ich sehe hier einen langen Spaghetti-Code, dem es an allen Enden und Ecken an Struktur mangelt.

Die ersten zig Zeilen Code bestehen aus ziemlich unsinnigen Dingen. Hier mal an einem Beispiel:

Code: Alles auswählen

mif="greenrunner_default.png"
...
player_char=pygame.image.load(mif).convert_alpha(
`mif` wird nie wieder verwendet - klar, ist ja auch nur der Dateiname. Aber wozu wird der an einen Namen gebunden? Und was bedeutet "mif"?
Zudem werden gefühlte 30 einzelne Bilder auf dieselbe Art und Weise behandelt - wieso gibt es dafür keine Liste / Dict? Dann könnte man das Laden sauber in einer Schleife erledigen.

Dieses Beispiel zeigt mir irgend wie, dass Dir noch viele Grundlagen fehlen. Aber ok, vielleicht ist `pygame` ja eben doch als Motivation so wichtig, dass es ohne nicht geht. Dennoch solltest Du Dir noch mal grundlegende Tutorials angucken, bevor Du hier weitermachst.
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
webspider
User
Beiträge: 485
Registriert: Sonntag 19. Juni 2011, 13:41

Bisher dachte ich, es wäre zwangsläufig notwendig für das Nutzen von Pygame den Umgang mit Klassen zu beherrschen. Anscheinend stimmt das nicht ganz.

Dass Zuweisungen wie "arrayx = 200 , 220, 240, 260, 280, 300" gehen, wusste ich auch noch nicht. Normalerweise setzt man um Listen eckige Klammern, damit klar wird, dass eine erstellt wird. Und überhaupt, mit einer einfachen Schleife und der geeigneten Datenstruktur wären die Koordinatenpaare sehr viel übersichtlicher erstellt.
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

webspider hat geschrieben: Dass Zuweisungen wie "arrayx = 200 , 220, 240, 260, 280, 300" gehen, wusste ich auch noch nicht. Normalerweise setzt man um Listen eckige Klammern, damit klar wird, dass eine erstellt wird.

Code: Alles auswählen

In [1]: arrayx = 200 , 220, 240, 260, 280, 300

In [2]: type(arrayx)
Out[2]: <type 'tuple'>
So erzeugt¹ man Tupel.

¹genauer "kann" man erzeugen ;-)

Leserlicher ist es aber natürlich so:

Code: Alles auswählen

In [3]: arrayx = (200 , 220, 240, 260, 280, 300)
Die vom OP gewählte Form kennt man eher bei Rückgabewerten, z.B. bei `return`:

Code: Alles auswählen

In [4]: def foo():
   ...:     return 1, 2
   ...: 

In [5]: res = foo()

In [6]: res
Out[6]: (1, 2)
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
paulkoch95
User
Beiträge: 15
Registriert: Samstag 21. Januar 2012, 16:31

hmm, ich weiss was ihr meint, der Code ist nicht wirklich sauber, allerdings ist eher auch schon älter und ich
habe ihn erst kürzlich gefunden und habe mir gedacht machste mal weiter damit, das das ganze weder in funktionionen aufgespalten ist nocht
in einzelen unter dateien zeugt von früherer unwissenheit, die unterstellung es wäre copy&paste code finde ich allerdings nicht gerechtfertigt, alles ist von mir geschrieben
wenn auch unsauber, aber nie von irgendwo kopiert...-.-
ich habe diesen code aber auch eher als beispiel genommen weil es nur mit diesem code passiert..^^
mfg paulkoch95
deets

Copy & Paste Code hat nix mit Klauen zu tun. Sondern damit, dass du gleichförmige Code-Stücke wiederholst statt eine saubere Abstraktion durch Funktionen, Klassen und die richtigen Datentypen zu wählen.
BlackJack

@paulkoch95: Das kopieren und einfügen bezog sich nicht auf fremden Quelltext sondern auf solche Aktionen *innerhalb* Deines eigenen Quelltextes. Wenn man mehrfach ein Quelltextfragment kopiert und geringfügig ändert, dann ist das ein „code smell”, der darauf hindeutet, dass man vielleicht an der Stelle entweder gemeinsamen Code in eine Funktion heraus ziehen könnte, oder Daten aus dem Code in eine Datenstruktur heraus ziehen kann und den Code *einmal* in eine Schleife schreiben kann, welche über die Daten iteriert.

Edit: Vielleicht mal ein Beispiel:

Code: Alles auswählen

    font2 = pygame.font.Font(None, 36)
    text2 = font2.render('Hauptmenü:', True, (255,255, 255))
    screen.blit(text2, (10,10))
    font3 = pygame.font.Font(None, 36)
    text3 = font3.render('[1]Spiel starten', True, (255,255, 255))
    screen.blit(text3, (150,150))
    font4 = pygame.font.Font(None, 36)
    text4 = font4.render('[2]Spieleinstellungen', True, (255,255, 255))
    screen.blit(text4, (150,200))
Da könnte man die Texte und Koordinaten heraus ziehen und ausserdem die unnötigen `Font`-Objekte einsparen:

Code: Alles auswählen

    font = pygame.font.Font(None, 36)
    for text, coordinates in [
        ('Hauptmenü:', (10, 10)),
        ('[1] Spiel starten', (150, 150)),
        ('[2] Spieleinstellungen', (150, 200)),
    ]:
        screen.blit(font.render(text, True, (255, 255, 255)), coordinates)
paulkoch95
User
Beiträge: 15
Registriert: Samstag 21. Januar 2012, 16:31

Okay, dann habe ich das falsch aufgenommen, sry..-.-
und btw. danke für die "Stilverbesserung" mit dem "Menü"..^^
mir war zwar schon bewusst das es prinzipiell doppel-gemoppelt ist, andereseite hatte ich erstmal keine
ideee wie verbessern..
mfg paulkoch95
stay tuned!
Antworten