Mein Bildschirm macht meinen Spiel kaputt, da es die ganze Zeit flackert! wie kann ich das beheben. mein 1 Uni- Projekt

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
Achim04
User
Beiträge: 1
Registriert: Samstag 11. Januar 2025, 21:53

Ähnlich snack-game mit Änderungen von mir !

Code: Alles auswählen

import os
import time
import random
import msvcrt


# play ground
WIDTH = 50
HEIGHT = 20


PLAYER = "U"
BOMB= "*"
EMPTY= "."
FOOD="$"
FREEZ="§"
follow_person="V"
live=2
bombs=[]
player_pos = [HEIGHT - 2, WIDTH // 2]
freeZ=[]
nfood=[]
# Directions (dy, dx)
UP = (-1, 0)
DOWN = (1, 0)
LEFT = (0, -1)
RIGHT = (0, 1)

running =True

def getkey(screen):
    
    key = screen.getch()
    if key != -1:
        return chr(key)
    return None


def game():

    global running
    global live
    global player_pos
    global follow_pers_pos2
    direction=None
    score=0
    max_score=5
    food=gift()
    bombs=bom()
    freeZ=frez()
    follow_pers_pos2=sec_player()
    score_player2=0
    max_score_player2=10

    screen = Screen()
    
    #curses.curs_set(0)
    
    Screen.keypad(True)
    screen.timeout(50)
    
    try:
         
        while True and live>0:
         
         clear_screen()
         border(screen)
         time.sleep(0.2)
         field(screen)
         
         screen.addch(player_pos[0], player_pos[1], PLAYER)
         screen.addch(follow_pers_pos2[0], follow_pers_pos2[1], follow_person)
         screen.addch(food[0], food[1],FOOD)
# ChatGPt hat geholfen um das food zu generiern bzw. platzieren 
         screen.addstr(0,25,f"Dein Score: {score}")
         screen.addstr(0,10,f"Leben: {live}")
         screen.addstr(HEIGHT,0,"Seien Sie schneller als 'Golosino'und sammeln mind. 3$")
         for bomb in bombs:
          screen.addch(bomb[0],bomb[1],"*")
         for fres in freeZ:
          screen.addch(fres[0],fres[1],FREEZ)
         
         screen.refresh()

         key = getkey(screen)
         if key:
            if key == "w":
                direction = UP
            elif key == "s":
                direction = DOWN
            elif key == "a":
                direction = LEFT
            elif key == "d":
                direction = RIGHT
# Z.87 bis 96 Quelle Herr Prof.Dok.Nierhoff und so geaendert dass es fuers game passt

         new_pos = player_pos.copy()
         if direction:
             new_pos = [player_pos[0] + direction[0],player_pos[1] + direction[1]]
# Z. 99 bis Z. 101 Loesung dieses Problems von ChatGPT 

         if 0 < new_pos[0] < HEIGHT - 1 and 0 < new_pos[1] < WIDTH - 1:
                    player_pos = new_pos
         for food in nfood:
             if food==player_pos:  
                 nfood.remove(food)
                 score=score+1
                 food=[random.randint(2, HEIGHT - 2), random.randint(2, WIDTH - 2)]  
                 nfood.append(food)
             
         for food in nfood:
             dis=[abs(follow_pers_pos2[0]-food[0]),abs(follow_pers_pos2[1]-food[1])]
           
         if dis[0] != 0 or dis[1] != 0:
             if follow_pers_pos2[0] < food[0]:
                 follow_pers_pos2[0] += 1
             elif follow_pers_pos2[0] > food[0]:
                 follow_pers_pos2[0] -= 1
             if follow_pers_pos2[1] < food[1]:
                 follow_pers_pos2[1] +=1
             elif follow_pers_pos2[1] > food[1]:
                 follow_pers_pos2[1] -= 1
        
             dis=[abs(follow_pers_pos2[0]-food[0]),abs(follow_pers_pos2[1]-food[1])]
             if dis[0]==0 and dis[1]==0:
                nfood.remove(food)
                score_player2=score_player2+1
                food=[random.randint(2, HEIGHT - 2), random.randint(2, WIDTH - 2)]  
                nfood.append(food)
                if score_player2==max_score_player2:
                   clear_screen()
                   print(" BOOOOOH Golosino won , you are Bot! ")
                   break
                 
         if score>=3:
               screen.timeout(25)  
         if score == max_score:
            break
            
         for nbombs in bombs:
             if nbombs ==player_pos:
               bombs.remove(nbombs)
               live-=1
               score-=1
               nbombs=[random.randint(2, HEIGHT - 2), random.randint(2, WIDTH - 2)]
               bombs.append(nbombs)
               if score <0:
                 break
               if live==0:
                  break

         for fres in freeZ:
          if fres!=(HEIGHT - 2, WIDTH // 2):
              if fres ==player_pos:
                freeZ.remove(fres)
                fres = [random.randint(2, HEIGHT - 2), random.randint(2, WIDTH - 2)]
                freeZ.append(fres)
                time.sleep(5)

         new_pos2 = [follow_pers_pos2[0],follow_pers_pos2[1]]
         if 0 < new_pos2[0] < HEIGHT - 2 and 0 < new_pos2[1] < WIDTH - 2:
                    follow_pers_pos2 = new_pos2

                
    finally:
     clear_screen()
     if  score<3 and live==0:
      print("Game Over!")
     elif 3<=score<5 and live==0:
        print(f"You won level_1 ! your Score: {score}")
     elif score==5:
        print(f"You won last-level ! your Score: {score}")
   

def clear_screen():
    os.system('cls')
def get_key():
    if msvcrt.kbhit():
        return msvcrt.getch().decode("utf-8").lower()
    return None

def border(screen):
 
    for x in range(1,WIDTH):
        screen.addch(1, x, "#") 
        screen.addch(HEIGHT - 1, x, "#")
    for y in range(1,HEIGHT):
       screen.addch(y,0,"#")
       screen.addch(y,WIDTH-1,"#")

def field(screen):
    for y in range(2,HEIGHT-1):
        for x in range(1,WIDTH-1):
         screen.addch(y, x, EMPTY) 
        
def gift():
    while True:  
     food=[random.randint(2, HEIGHT - 2), random.randint(2, WIDTH - 2)]
     nfood.append(food)
     if food !=(HEIGHT - 2, WIDTH // 2):
        return food
     

def bom(): 
   while True:
     for _ in range(20):
      nbombs=[random.randint(2, HEIGHT - 2), random.randint(2, WIDTH - 2)]
      bombs.append(nbombs)
     return bombs
# def bom funktion von ChatGPT

def sec_player():
    while True:
        follow_pers_pos2=[random.randint(2, HEIGHT - 2), random.randint(2, WIDTH - 2)]
        if follow_pers_pos2 !=(HEIGHT - 2, WIDTH // 2) and follow_pers_pos2!=bombs:
         return follow_pers_pos2
  
def frez(): 
   while True:
     for _ in range(5):
      freez=[random.randint(2, HEIGHT - 2), random.randint(2, WIDTH - 2)]
      freeZ.append(freez)
     return freeZ
      
class Screen: 
   def render(self):
        # Simuliert das Darstellen auf dem Bildschirm
        print("\033[H", end="")  # Cursor zurücksetzen (ANSI)
        for row in self.buffer:
            print("".join(row))
        print("\033[H", end="")
   
   

if __name__ == "__main__":
 
 game()
Sirius3
User
Beiträge: 18250
Registriert: Sonntag 21. Oktober 2012, 17:20

In Python sind Einrückungen wichtig. Eingerückt wird immer mit 4 Leerzeichen pro Ebene, nicht eine zufällig Anzahl zwischen 1 und 4.
Deine Klasse Screen ist unvollständig. Das Programm so nicht lauffähig.
Du scheinst ja die Curses-Bibliothek zu benutzen, die hat natürlich auch einen Befehl um den Bildschirm zu löschen. Ein externes Programm dafür aufzurufen (`os.system('cls')`) ist falsch.
Du benutzt gleichzeitig curses und msvcrt um Tastendrücke abzufragen. Du solltest dich auf ersteres beschränken.
Variablennamen und Funktionsnamen sind für das Verständnis wichtig. Es gibt ein getkey und ein get_key. Wie soll sich der Programmierer merken, was für was zuständig ist?
Es gibt frez und freez und freeZ. Die Namen sind zu ähnlich, als dass irgendjemand die Unterschiede erkennen könnte, was das Programmieren unnötig schwierig macht.
Ebenso nfood und food, oder bom, bombs, nbombs

Globale Variablen dürfen in einem sauberen Programm nicht vorkommen. Du kennst ja schon Klasse (Screen), warum setzt Du sie für Dein Game nicht auch ein?
Benutzeravatar
__blackjack__
User
Beiträge: 13997
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Achim04: Zur Namensvergabe vielleicht noch der Hinweis, dass Funktionen und Methoden üblicherweise nach der Tätigkeit benannt werden, die sie durchführen. Dann weiss der Leser was die Funktion macht und man kann Funktionen und Methoden leicht(er) von eher passiven Werten unterscheiden.

`screen` wäre beispielsweise ein guter Name für einen Wert der den Bildschirm repräsentiert, `field` für einen Wert der das Spielfeld repräsentiert, aber beides sind keine guten Namen für Funktionen, weil man nicht weis *was* die machen, sondern höchstens ahnen kann womit die etwas machen.

Ansonsten gibt es noch Namenskonventionen in Python: Namen werden in Python klein_mit_unterstrichen geschrieben. Ausnahmen sind Konstanten (KOMPLETT_GROSS) und Klassen (PascalCase). Siehe auch den Style Guide for Python Code.

In Kommentaren in Zeilennummern anzugeben worauf sich der Kommentar bezieht ist ganz schlecht. Wenn man schreibt ``# Zeile 80 bis 90…`` heisst das ja, das man davor keine Zeilen einfügen oder löschen kann, ohne das der Kommentar falsch wird und man nicht mehr so genau weiss worauf sich der bezieht. Noch schlimmer: Wenn der trotzdem noch sinnvoll erscheint für das was *dann* in den Zeilen steht, ist der sehr wahrscheinlich inhaltlich falsch. Das sollten Kommentare nie sein, denn genau dafür sind die ja da: inhaltliche Fragen klären die beim Leser aufkommen (könnten).

Das Programm ist viel zu lang für den/die Fehler die es enthält. Programme schreibt man nicht in einem Stück runter, sondern man entwickelt die Schritt für Schritt. Das heisst man schreibt ein Stück Programm das eine Funktionalität implementiert, die man testen kann, und das tut man dann auch, man testet ob das bis dahin überhaupt funktioniert. Und bis beispielsweise kein Rahmen gezeichnet wird, sollte da kein Code für Spieler, Nahrung, Tastatur und Bewegung, und alles andere sein. Bevor man nicht alles geklärt hat um den Rahmen zu zeichnen und das tatsächlich funktioniert, weiss man ja gar nicht ob Code um den Spieler zu zeichnen überhaupt funktionieren würde. Wenn man dann am Ende feststellt man hat etwas bei der API falsch verstanden, hat man lauter Code geschrieben der falsch ist und korrigiert oder neu geschrieben werden muss.

Ich würde deshalb dazu raten noch mal mit einer leeren Datei anzufangen, und das Schritt für Schritt zu machen und nicht Code zu haben mit einem Fehler an dem es nicht weitergeht, und wenn man den behebt, rennt es bis zum nächsten Fehler, und wenn man den behebt… Das ist auch psychologisch ungünstig. Man hat dann ”eigentlich fertigen” Code und rennt dann nur noch in einen Fehler nach dem anderen. Das kann sehr frustrierend sein. Insbesondere wenn man *dann* merkt, dass man grössere Teile noch mal neu schreiben muss. Wenn man Schritt für Schritt immer mal wieder testet was man bisher hat und Fehler gleich behebt, hat man zwischendurch immer wieder Erfolgserlebnisse, weil man immer sieht was schon funktioniert, und man verteilt die Fehler die passieren auf die gesamte Entwicklungszeit und staut die nicht alle am Ende auf.

Bei ChatGPT gilt übrigens das selbe wie beim abschreiben von anderen: Man sollte verstanden haben was man da übernimmt, sonst fällt einem das früher oder später auf die Füsse. Wenn man die Lösung erklären muss, oder wenn man etwas ähnliches lösen muss, aber gerade keine Fremdquelle zur Verfügung steht, man das Wissen aber eigentlich schon haben müsste.
“The best book on programming for the layman is »Alice in Wonderland«; but that's because it's the best book on anything for the layman.” — Alan J. Perlis
Antworten