Flappy Bird Punkteanzeige

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
idkidk9idk
User
Beiträge: 1
Registriert: Samstag 20. Januar 2024, 19:48

Moin,
Ich bin gerade am verzweifeln.
Ich wollte Fragen ob es hier vllt ein paar Cracks gibt, die mein Problem lösen könnten.
Ich möchte einem Flappy Bird Spiel eine Punkteanzeige geben, jedoch geht die Punkteanzeige nur von 0-2 und zählt danach nicht weiter...
Eine Anzeige für die Münzen / Herzen wäre auch cool aber das schaffe ich bis morgen leider nicht mehr.

Klasse-Punkteanzeige:

"""
Erstellt eine Punkteanzeige.
Sorgt dafür, dass der Benutzer die Punkte im Spiel angezeigt bekommt,
sobald er durch
"""

from algoviz.svg import Text

class PunkteAnzeige:
def __init__(self, view):
self._punkte = 0
self._text = Text(250, 50, "Punkte: 0", view)

def erhoehe_punkte(self):
self._punkte += 1
self._text.set_text(f"Punkte: {self._punkte}")

def get_punkte(self):
return self._punkte

///////////////////////////////////////////////////////////////////////////

Klasse-Hindernisse:

from algoviz.svg import SVGView, Image, Rect
from random import seed, randrange
seed()

class Hindernisse:
"""
Es werden zwei Hindernisse ertsellt. Jedes Hinderniss besteht aus zwei Röhren durch die hindurchgeflogen werden muss. Die Länge der Gap ist fix, ihre Position wird aber für jedes Hinderniss zufällig generiert. Sobald ein Hinderniss aus dem Viewer ist, wird es auf den Startpunkt zurückgesetzt und die Gap wird neu generiert.
"""

def __init__(self,view):
"""
Start- und Endkoordinaten. Beide liegen auußerhalb des Viewers. Sobald die Hindernisse nicht mehr zu sehen sind, wird ihre Gap neu generiert und ihre Position auf den Start zurückgesetzt. Ähnliches Prinzip wie bei der Klasse Item.
"""
self._laenge = 50
self._hoehe = 300
#Gameplay relevante Paramter
self._start = 550
self._ende = -80
self._abstand_zwischen_hindernissen = 300
self._gap_laenge = 80 # Länge der Gap
self._abstand_gap = 50 #Mindest Abstand zur oberen (Viewport-Ende) und unteren (Boden) Begrenzung

#Hinderniss 1
self._oben_hinderniss_one = Image("assets/pipe_green_oben.png",0,0,self._laenge,self._hoehe,view)
self._unten_hinderniss_one = Image("assets/pipe_green_unten.png",0,0,self._laenge,self._hoehe,view)
self._y_oben_hinderniss_one = 0
self._y_unten_hinderniss_one = 0
self._x_one = self._start
#Hinderniss 2
self._oben_hinderniss_two = Image("assets/pipe_green_oben.png",0,0,self._laenge,self._hoehe,view)
self._unten_hinderniss_two = Image("assets/pipe_green_unten.png",0,0,self._laenge,self._hoehe,view)
self._y_oben_hinderniss_two = 0
self._y_unten_hinderniss_two = 0
self._x_two = self._x_one + self._abstand_zwischen_hindernissen

self._durchflogen_one = False
self._durchflogen_two = False



def gap(self):
"""
Erstellt einen Gap für ein Hinderniss.
Der Gap ist immer 80 Pixel lang. Er wird zufälig im Bereich zwischen dem oberern Rand (+50 Pixel) und dem unterer Rand (+100 Höhe des Bodens)(+50 Pixel) positioniert.
"""
y_oben = 0
y_unten = 0
mitte_der_gap = randrange(self._abstand_gap,300 - self._abstand_gap)
y_oben = mitte_der_gap - (self._gap_laenge/2) - self._hoehe
y_unten = mitte_der_gap + (self._gap_laenge/2)
return(y_oben,y_unten)

def außerhalb_des_viewers(self,x):
return (x < self._ende)


def neu(self, muenze):
if self.außerhalb_des_viewers(self._x_one):
self._x_one = self._start
self._y_oben_hinderniss_one, self._y_unten_hinderniss_one = self.gap()
x_one = self._x_one + (self._laenge/2) - 20
y_one = self._y_unten_hinderniss_one - ((self._gap_laenge/2)+20)
muenze.neu_erscheinen_one(x_one,y_one)
elif self.außerhalb_des_viewers(self._x_two):
self._x_two = self._start
self._y_oben_hinderniss_two, self._y_unten_hinderniss_two = self.gap()
x_two = self._x_two + (self._laenge/2) - 20
y_two = self._y_unten_hinderniss_two - ((self._gap_laenge/2)+20)
muenze.neu_erscheinen_two(x_two,y_two)

def bewegung(self, geschwindigkeit,muenze):
self._x_one = self._x_one - geschwindigkeit
self._x_two = self._x_two - geschwindigkeit
#Hinderniss One bewegen
self._oben_hinderniss_one.move_to(self._x_one, self._y_oben_hinderniss_one)
self._unten_hinderniss_one.move_to(self._x_one,self._y_unten_hinderniss_one)
#Hindernis Two bewegen
self._oben_hinderniss_two.move_to(self._x_two, self._y_oben_hinderniss_two)
self._unten_hinderniss_two.move_to(self._x_two,self._y_unten_hinderniss_two)
self.neu(muenze)

def initialisieren(self):
"""
Erstellt initial die Hindernisse. Danach eiegnständige Erzeugung durch die Bewegen-Operation
"""
a,b = self.gap()
self.set_y_hinderniss_one(a,b)
c,d = self.gap()
self.set_y_hinderniss_two(c,d)

#Getter
def get_laenge(self):
return(self._laenge)

def get_abstand_zwischen_hindernissen(self):
return(self._abstand_zwischen_hindernissen)

#Hinderniss One
def get_x_one(self):
return(self._x_one)

def get_y_hinderniss_one_oben(self):
return(-1000)#Entspricht nicht den eigentlichen Koordinaten, ist aber nötig, damit die Spielfigur nicht einfach außerhlab des Viewers an den Hindenrissen vorbei fliegen kann

def get_y_hinderniss_one_unten(self):
return(self._y_unten_hinderniss_one)#Entspricht nicht den eigentlichen Koordinaten, ist aber nötig, damit die Spielfigur nicht einfach außerhlab des Viewers an den Hindenrissen vorbei fliegen kann

def get_hoehe_oben_hinderniss_one(self):
return(self._y_oben_hinderniss_one + self._hoehe + 1000)

def get_hoehe_unten_hinderniss_one(self):
return(self._hoehe)


#Hinderniss Two
def get_x_two(self):
return(self._x_two)

def get_y_hinderniss_two_oben(self):
return(-1000)#Entspricht nicht den eigentlichen Koordinaten, ist aber nötig, damit die Spielfigur nicht einfach außerhlab des Viewers an den Hindenrissen vorbei fliegen kann

def get_y_hinderniss_two_unten(self):
return(self._y_unten_hinderniss_two)#Entspricht nicht den eigentlichen Koordinaten, ist aber nötig, damit die Spielfigur nicht einfach außerhlab des Viewers an den Hindenrissen vorbei fliegen kann

def get_hoehe_oben_hinderniss_two(self):
return(self._y_oben_hinderniss_two + self._hoehe + 1000)

def get_hoehe_unten_hinderniss_two(self):
return(self._hoehe)


def is_durchflogen_one(self):
return self._durchflogen_one

def is_durchflogen_two(self):
return self._durchflogen_two



#Setter
def set_y_hinderniss_one(self,a,b):
self._y_oben_hinderniss_one = a
self._y_unten_hinderniss_one = b

def set_y_hinderniss_two(self,a,b):
self._y_oben_hinderniss_two = a
self._y_unten_hinderniss_two = b

def test(self,view):
a = self.get_y_hinderniss_one_oben()
b = self.get_hoehe_oben_hinderniss_one()
self.test = Rect(100,100,50,100,view)


def set_durchflogen_one(self, value):
self._durchflogen_one = value

def set_durchflogen_two(self, value):
self._durchflogen_two = value


/////////////////////////////////////////////////////////////////////////////////////////////////////

from algoviz.svg import SVGView, Image
from algoviz.system.devices import MouseState





Figur Klasse:

class Figur:
"""
Komplexeste Klasse. Erstellt die Spielfigur. Diese fällt mit einer konstanten Geschwindigkeit. Bei drücken der Leertaste kommt es zu einem Sprung. Ein Großteil des Backends und des Controllings verläuft in dieser Klasse. Jede Form von Kollisionserkennung verläuft in dieser Klasse. Spielerwerte wie Leben, Punkte und Muenzen werden hier verwaltet. Durch die Kollisison mit Münzen erhöht sich die entsprechende Anzahl. Durch Kollision mit einem Herz erhöht sich die Anzahl an Leben. Due Kollision mit einer Flamme verändert für eine bestimmbare Zeit die Steuerung. Die Punkte werden erhöht, sobald eine Hinderniss durchflogen wurde.
"""

def __init__(self,view):
self._y = 120
self._x = 100
self._laenge= 30
self._hoehe = 30
self._rotation = 30
self._kollision_mit_flamme = False #Nötig, um den Effekt der Flamme nach einer gewissen Zeit zurückzusetzen
self._zaehler = 0 #Zähler zum Stoppen des Effekts der Flamme nach 2 durchlaufenden Hinderissen
self._figur = Image("assets/bird.png",self._x,self._y,self._laenge,self._hoehe,view)
#Spielerwerte
self._punkte = 0
self._leben = 3
self._muenzen = 0
# Gameplay relevante Paramter
self._fallgeschwindigkeit_standard = 2
self._fallgeschwindigkeit = self._fallgeschwindigkeit_standard
self._sprungdistanz = -30
self._dauer_effekt_flamme = 2 # Anzahl der Hindernisse die durchflogen werden, bevor Effekt der Flamme wieder aufhört
self._durchflogene_hindernisse = 0


def steuerung(self,view):
"""
Bei aktiver Flamme kann mit der Mouse gesteuert werden.
"""
key = view.last_key()
mouse = view.get_mouse_state()
if key == " " and self._kollision_mit_flamme == False:
self._y = self._y + self._sprungdistanz
#self._figur.rotate_to(self._rotation)
self._figur.move_to(self._x, self._y)
elif self._kollision_mit_flamme == True:
if mouse.is_legal():
self._y = mouse.y()

def fallen(self):
self._y = self._y + self._fallgeschwindigkeit
self._figur.rotate_to(0)
self._figur.move_to(self._x, self._y)

def bewegung(self,view):
self.fallen()
self.sprung(view)
self.steuerung_bei_aktiver_flamme(view)
self.effekt_flamme()

#Getter
def get_y(self):
return(self._y)

def get_x(self):
return(self._x)

def get_leben(self):
return(self._leben)

def get_muenzen(self):
return(self._muenzen)

def get_punkte(self):
return(self._punkte)

def get_durchflogene_hindernisse(self):
return self._durchflogene_hindernisse


########Kollisionserkennungen
def kollisionserkennung_item(self,x,y,hoehe,laenge):
"""
Prüft auf eine Kollision mit einem Item
"""
if (self._x + self._laenge >= x and self._x <= x + laenge) and ((self._y + hoehe >= y and self._y <= y + hoehe) or (self._y <= y + hoehe and self._y >= y)):
return (True)
else: return(False)

def kollision_mit_item(self,item,x,y,hoehe,laenge):
"""
Wenn eine Kollision mit einem Item stattfindet, wird gespeichert, um welches Item es sich gehandelt hat. Zudem wird der Effekt des Items initialisiert.
"""
if self.kollisionserkennung_item(x,y,hoehe,laenge):
item.verschwinden()
if item.get_aktives_item() == "flamme":
self._fallgeschwindigkeit = 0
self._kollision_mit_flamme = True
self._zaehler = self._punkte
elif item.get_aktives_item() == "rote_muenze":
self._muenzen += 5
elif item.get_aktives_item() == "herz":
self._leben += 1

def kollision_mit_muenze(self, muenze, hinderniss):
"""
Prüft auf eine Kollision mit einer Münze. Eine gleichzeitige Kollision mit beiden Münzen ist nicht möglich. Daher wird zunächst geprüft, welche Münze die nächste ist und nur mit dieser Münze wird auf eine Kollision geprüft. Wenn eine Kollision stattgefunden hat, wird die Anzahl eingesammelter Münzen erhöhrt und die Münze springt in einen nicht mehr sichtbaren Bereich.
"""
if hinderniss.get_x_one() < hinderniss.get_x_two() and (hinderniss.get_x_one() + hinderniss.get_laenge() > self._x):
if self.kollisionserkennung_item(muenze.get_x_one(), muenze.get_y_one(),muenze.get_hoehe(), muenze.get_laenge()):
muenze.one_verschwinden()
self._muenzen += 1
else:
if self.kollisionserkennung_item(muenze.get_x_two(), muenze.get_y_two(), muenze.get_hoehe(), muenze.get_laenge()):
muenze.two_verschwinden()
self._muenzen += 1


def kollision_mit_boden(self,y_boden):
if self._y + self._hoehe >= y_boden:
return(True)
else: return(False)

def kollisionserkennung_hinderniss_oben(self,x,y,hoehe,laenge):
"""
Prüft auf eine Kollision mit einer Röhre, welche von oben kommt.
"""
if self._y <= (y + hoehe) and self._x + self._laenge >= x and self._x <= x + laenge:
return(True)
else: return(False)

def kollisionserkennung_hinderniss_unten(self,x,y,hoehe,laenge):
"""
Prüft auf eine Kollision mit einer Röhre, welche von unten kommt.
"""
if self._y + self._hoehe >= y and self._x + self._laenge >= x and self._x <= x + laenge:
return(True)
else: return(False)


def kollision_mit_hinderniss(self, hinderniss):
"""
Prüft auf ein Kollision mit einem Hinderniss. Eine gleichzeitige Kollision mit beiden Hindernissen ist nicht möglich. Daher wird zunächst das nächste Hinderniss, welches es zu überwinden gilt, identifiziert und nur für dieses Hinderniss wird auf eine Kollision geprüft.
"""
if hinderniss.get_x_one() < hinderniss.get_x_two() and (hinderniss.get_x_one() + hinderniss.get_laenge() > self._x):
if self.kollisionserkennung_hinderniss_oben(hinderniss.get_x_one(), hinderniss.get_y_hinderniss_one_oben(), hinderniss.get_hoehe_oben_hinderniss_one(), hinderniss.get_laenge()) or self.kollisionserkennung_hinderniss_unten(hinderniss.get_x_one(), hinderniss.get_y_hinderniss_one_unten(), hinderniss.get_hoehe_unten_hinderniss_one(), hinderniss.get_laenge()):
return(True)
else: return (False)
else:
if self.kollisionserkennung_hinderniss_oben(hinderniss.get_x_two(), hinderniss.get_y_hinderniss_two_oben(), hinderniss.get_hoehe_oben_hinderniss_two(), hinderniss.get_laenge()) or self.kollisionserkennung_hinderniss_unten(hinderniss.get_x_two(), hinderniss.get_y_hinderniss_two_unten(), hinderniss.get_hoehe_unten_hinderniss_two(), hinderniss.get_laenge()):
return(True)
else: return(False)


###########Item Effekte
def effekt_flamme_beenden(self):
"""
Wenn ausgehend vom Zeitpunkt der Kollision eine festlegbare Anzahl an Hindernissen durchflogen wird, wird der Effekt der Flamm beendent
"""
if (self._zaehler + self._dauer_effekt_flamme <= self._punkte) and self._kollision_mit_flamme == True:
self.set_fallgeschwindigkeit_standard()
self._zaehler = 0
self._kollision_mit_flamme = False

def set_fallgeschwindigkeit_standard(self):
"""
Setzt die Fallgeschwindigkeit auf einen Standardwert zurück. Wird benötigt, um den Effekt des Flammen_Item zurückzusetzen
"""
self._fallgeschwindigkeit = self._fallgeschwindigkeit_standard


####### Anzahl der durchflogenden Hindernisse ermitteln


def anzahl_durchflogende_hindernisse(self, hinderniss):
if hinderniss.get_x_one() <= (self._x + self._laenge) <= (hinderniss.get_x_one() + hinderniss.get_laenge()) and not hinderniss.is_durchflogen_one():
hinderniss.set_durchflogen_one(True)
self._durchflogene_hindernisse += 1
elif hinderniss.get_x_two() <= (self._x + self._laenge) <= (hinderniss.get_x_two() + hinderniss.get_laenge()) and not hinderniss.is_durchflogen_two():
hinderniss.set_durchflogen_two(True)
self._durchflogene_hindernisse += 1






Main-File:

from algoviz import AlgoViz
from algoviz.svg import SVGView
#Eigene Klassen
from klassen.figur import Figur
from klassen.hindernisse import Hindernisse
from klassen.item import Item
from klassen.spielfeld import Spielfeld
from klassen.muenze import Muenze
from klassen.punkteanzeige import PunkteAnzeige

AlgoViz.clear()
view = SVGView(500,400)

geschwindigkeit = 5 # globale Geschwindigkeit für alle bewegenden Objekte

#Konstruktoren
spielfeld = Spielfeld(view)
figur = Figur(view)
hindernisse = Hindernisse(view)
item = Item(view)
muenze = Muenze(view)
punkteanzeige = PunkteAnzeige(view)

# Initialisierung der Hindernisse
hindernisse.initialisieren()
#Spielfeld-Boden erstellen
spielfeld.boden_erstellen(view)





while True:
#Bewegung und Steuerung der Spielfigur
figur.fallen()
figur.steuerung(view)

#Bewegung von Hindernissen, Items und Münzen
hindernisse.bewegung(geschwindigkeit, muenze)
item.bewegung(geschwindigkeit, hindernisse.get_x_one(), hindernisse.get_abstand_zwischen_hindernissen(), view)
muenze.bewegung(geschwindigkeit)

#Kollisionserkennungen
figur.kollision_mit_item(item, item.get_x(), item.get_y(), item.get_hoehe(), item.get_laenge())
figur.kollision_mit_muenze(muenze, hindernisse)

if figur.kollision_mit_boden(spielfeld.get_y()):
#print("Kollision mit Boden")

if figur.kollision_mit_hinderniss(hindernisse):
#print("Kollision mit einem Hinderniss.")

# Erhöhung der Punkte wenn ein Hinderniss durchflogen wurde
figur.anzahl_durchflogende_hindernisse(hindernisse)

# Zeitliche Effekte
figur.effekt_flamme_beenden() # Effekt Flamme nach 2 Hindernissen beenden
spielfeld.hintergrund_wechsel(geschwindigkeit, figur) # Hintergrund nach 10 Hindernissen wechseln

# Erhöhung der Punkte wenn ein Hinderniss durchflogen wurde
if figur.get_durchflogene_hindernisse() > punkteanzeige.get_punkte():
punkteanzeige._punkte = figur.get_durchflogene_hindernisse()
punkteanzeige._text.set_text(f"Punkte: {punkteanzeige.get_punkte()}")


AlgoViz.sleep(10)

# Für das restliche Frontend
print(figur.get_leben()) # so kommt man an die Anzahl der LebenS
print(figur.get_muenzen()) # so kommt man an die Anzahl der Muenzen
print(figur.get_punkte()) # so kommt man an die Anzahl der Punkte, also der durchflogenen Hindernisse



LG!
Benutzeravatar
sparrow
User
Beiträge: 4237
Registriert: Freitag 17. April 2009, 10:28

Code immer in Vode Blöcken posten. Die erscheinen, wenn man den </> Button im erweiterten Editor drückt. Dazwischen gehört dein Code.

Wer hat das Programm geschrieben?
Sirius3
User
Beiträge: 17826
Registriert: Sonntag 21. Oktober 2012, 17:20

Zuerst einmal solltest du nicht versuchen Java in Python-Syntax zu schreiben. Ein Modul enthält normalerweise mehr als eine Klasse. Die ganzen trivialen Getter und Setter gehören weg.
Return ist keine Funktion. Die unsinnigen Klammern gehören weg.
seed tut nicht das, was Du denkst und sollte gelöscht werden.
Wenn das Ergebnis einer if-Abfrage nur True oder False sein kann, dann kann man auch gleich die Bedingung direkt verwenden, denn die ist ja auch True oder False.
Du verwendest deine Punkteanzeige gar nicht richtig. Du greifst auf Internet Attribute zu und hast in der Hauptschleife die Textausgabe noch einmal kopiert.
Wenn ich das richtig sehe, hast du zwei Hindernisse, die jeweils einmal geflogen werden können. Das ergibt maximal zwei Punkte.
Antworten