erstes py"game"
Verfasst: Dienstag 6. Februar 2024, 21:50
Hallo zusammen,
ich bin noch sehr frisch in Python und möchte hier mein erstes "Game" vorstellen. Hab hier mit random, date, time, Datei speichern, Tastatur- und Mausabfrage rum gespielt. Es macht was es 'soll' aber vermutlich könnte man den Code noch etwas eleganter schreiben?!
Das wäre meine Bitte an euch - mir hierzu Tips geben.
Vielen Dank im Voraus
..................................................................................................................................................
# auf dem Screen werden an zufälligen Stellen Punkte in zufälliger Größe und zufälliger
# Farbe erzeugt. Diese müssen mit der Maus geklickt werden.
# Es wird die Reaktionszeit gemessen.
# Die durchschnittliche ReaktZeit wird in einer Datei "zeiten.txt" gespeichert.
import pygame
import random as rnd
import sys, datetime
from os import path
from datetime import timedelta
from pygame.locals import *
from bt_vars import *
# Initialisierung von pg - IMMER nötig
pygame.init()
# Erzeugung des Screens und Benamung in der Titelzeile
SCR = pygame.display.set_mode((SCR_W, SCR_H))
pygame.display.set_caption("BT-Punkte fangen")
#global aktiv
# diverse var werden definiert
clock = pygame.time.Clock()
FPS = FPS
font = pygame.font.SysFont("Arial",30)
f_p = path.realpath("res/zeiten.txt")
# hat das Spiel begonnen (True) oder noch nicht (False). Für die Anzeige der Regeln
aktiv = False
ANZ_RUNDEN = ANZ_RUNDEN_GES
# liste die alle Dauer Werte aufnimmt
l_Dauer = [0]
l_Dauer_avg = sum(l_Dauer)/len(l_Dauer)
start_time = datetime.datetime.now()
dt_avg = 0
class Ball():
def __init__(self,x,y):
self.new_ball(x,y)
def draw_ball(self):
pygame.draw.circle(SCR, self.col_ball_PK, (self.x + self.ball_rad, self.y + self.ball_rad), self.ball_rad)
def new_ball(self,x,y):
self.x = x
self.y = y
self.ball_rad = rnd.randint(5, 20)
self.col_ball_PK = (10,rnd.randint(1,255),rnd.randint(1,255))
self.rect = Rect(self.x, self.y, self.ball_rad, self.ball_rad)
start_time = get_Time()
def mouse_ball(self, pos):
# Prüfung, ob die Maus die gleichen Koordinaten wie der Punkt hat
#global ANZ_RUNDEN, aktiv
if pos[0] >= self.rect.x and pos[0] <= (self.rect.x + self.ball_rad*2) and pos[1] >= self.rect.y and pos[1] <= self.rect.y + self.ball_rad*2:
# Timestamp wird ausgelesen
end_time = get_Time()
# die Dauer der beiden Mouseklicks wird errechnet
dauer_time = round(timedelta.total_seconds(end_time - start_time),4)
# die Dauer jeder Runde wird an die List angehängt
l_Dauer.append(dauer_time)
# ein neuer Ball wird aufgerufen
ball.new_ball(rnd.randint(15, SCR_W - 40),rnd.randint(15, SCR_H - 40))
def get_Time():
# liest die aktuelle Uhrzeit aus
return datetime.datetime.now()
def anz_reaktion():
global dt_avg, dt, l_Dauer
# Berechnung der Reaktionszeit. Wenn erst ein Element in der Liste, dann wird dieses angezeigt
# wenn mehr als zwei in der Liste, werden die letzten beiden Elemente subtrahiert
if len(l_Dauer) <= 1:
dt = round(l_Dauer[0],4)
else:
dt = round(l_Dauer[-1] - l_Dauer[-2],4)
draw_text("Reaktionszeit: " + str(dt), font, col_text, 50, SCR_H // 7 -40)
dt_avg = round(sum(l_Dauer)/len(l_Dauer)-1, 4)
def rahmen():
#Zeichnet den Rahmen um das Spielfeld (nur für die Optik)
pygame.draw.rect(SCR, col_rahmen_PK, [0, 0, SCR_W, SCR_H], 15)
# stellt Text auf dem Bildschirm dar
def draw_text(text, font, col_text, x, y):
img = font.render(text, True, col_text)
SCR.blit(img, (x, y))
def spielbeschreibung():
# wird angezeigt bevor das Spiel los geht
draw_text("- - - P u n k t e f a n g e n - - -", font, col_text, 50, SCR_H // 7 -40)
draw_text("Klicken Sie mit der Maus auf den Punkt.", font, col_text, 50, SCR_H // 7)
draw_text("Gefragt ist Geschwindigkeit.", font, col_text, 50, SCR_H // 7 + 80)
draw_text("Größe,Farbe und Ort variieren.", font, col_text, 50, SCR_H // 7 + 40)
draw_text("Drücken Sie die Space-Taste zum Start", font, col_text, 50, SCR_H // 7 + 120)
def start_sequenz():
global aktiv, start_time, dt_avg, ANZ_RUNDEN
# Spiel wird gestartet, Startzeit wird abgefragt und ein erster Ball erzeugt
SCR.fill(col_bg_PK)
aktiv = True
start_time = get_Time()
ANZ_RUNDEN = ANZ_RUNDEN_GES
dt_avg = 0
ball.new_ball(rnd.randint(15, SCR_W - 40),rnd.randint(15, SCR_H - 40))
def neu_ende():
# Abfrage ob noch eine Runde gespielt werden soll oder nicht
global run
SCR.fill(col_bg_PK)
t = datetime.datetime.now()
t1 = t.strftime('%d-%m-%Y %H:%M:%S')
draw_text("Wollen Sie nochmal? j / n", font, col_text, 50, SCR_H // 7 + 260)
pygame.time.wait(1000)
for event in pygame.event.get():
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_j:
with open (f_p, "a") as dat:
dat.write("Zeiten von " + str(t1) + ": " + str(dt_avg))
dat.write("\n")
start_sequenz()
if event.key == pygame.K_n:
run = False
pygame.QUIT
# hier wird ein ball der Klasse Ball außerhalb des Spielfeldes erzeugt
ball = Ball(-100,-100,)
# die var fragt ab, ob das Spiel eigentlich noch läuft, wenn wahr, dann geht und bleibt es in der eigentlichen SpielSchleife
run = True
### hier beginnt die eigentliche Spielschleife ###
while run: #and ANZ_RUNDEN > 0:
clock.tick(FPS)
SCR.fill(col_bg_PK)
rahmen()
# Zeigt die Spielregeln
if aktiv == False:
spielbeschreibung()
if aktiv:
anz_reaktion()
# Abfrage ob eine Taste oder Maus gedrückt wurde
for event in pygame.event.get():
# wenn die Aktion das X rechts oben im Spielfenster war, dann wird das Spiel beendet
if event.type == pygame.QUIT:
run = False
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_SPACE:
start_sequenz()
#ball.new_ball(rnd.randint(15, SCR_W - 40),rnd.randint(15, SCR_H - 40))
if event.type == pygame.MOUSEBUTTONUP:
# ermittelt wo der Maouszeiger gerade steht (x,y)
pos = pygame.mouse.get_pos()
# vergleicht, ob die Mouse Position der des Balls gleich ist
ball.mouse_ball(pos)
ANZ_RUNDEN -= 1
ball.draw_ball()
if ANZ_RUNDEN == 0:
# ein Durchgang ist vorbei, Sprung in die fun mit j / n Abfrage
aktiv = False
neu_ende()
# für die immer wiederkehrende neue Anzeige des Screens
pygame.display.update()
# beendet das Spiel
pygame.quit
.............................................................................................................................................................
in dieser Datei (bt_vars.py) stehen einige Variablen:
.............................................................................................................................................................
import pygame
import random as rnd
# Constanten und Variablen
global ball_PK
# Größe der Spiel Screens
SCR_W = 1600
SCR_H = 700
# Anzahl der Runden, die das Spiel laufen soll
ANZ_RUNDEN_GES = 3
# FPS
FPS = 60
# Farben - bt_PunktKlick
col_bg_PK = (204, 204, 204)
col_rahmen_PK = (255, 153, 0)
col_text = (51, 51, 102)
dt = 0
ich bin noch sehr frisch in Python und möchte hier mein erstes "Game" vorstellen. Hab hier mit random, date, time, Datei speichern, Tastatur- und Mausabfrage rum gespielt. Es macht was es 'soll' aber vermutlich könnte man den Code noch etwas eleganter schreiben?!
Das wäre meine Bitte an euch - mir hierzu Tips geben.
Vielen Dank im Voraus
..................................................................................................................................................
# auf dem Screen werden an zufälligen Stellen Punkte in zufälliger Größe und zufälliger
# Farbe erzeugt. Diese müssen mit der Maus geklickt werden.
# Es wird die Reaktionszeit gemessen.
# Die durchschnittliche ReaktZeit wird in einer Datei "zeiten.txt" gespeichert.
import pygame
import random as rnd
import sys, datetime
from os import path
from datetime import timedelta
from pygame.locals import *
from bt_vars import *
# Initialisierung von pg - IMMER nötig
pygame.init()
# Erzeugung des Screens und Benamung in der Titelzeile
SCR = pygame.display.set_mode((SCR_W, SCR_H))
pygame.display.set_caption("BT-Punkte fangen")
#global aktiv
# diverse var werden definiert
clock = pygame.time.Clock()
FPS = FPS
font = pygame.font.SysFont("Arial",30)
f_p = path.realpath("res/zeiten.txt")
# hat das Spiel begonnen (True) oder noch nicht (False). Für die Anzeige der Regeln
aktiv = False
ANZ_RUNDEN = ANZ_RUNDEN_GES
# liste die alle Dauer Werte aufnimmt
l_Dauer = [0]
l_Dauer_avg = sum(l_Dauer)/len(l_Dauer)
start_time = datetime.datetime.now()
dt_avg = 0
class Ball():
def __init__(self,x,y):
self.new_ball(x,y)
def draw_ball(self):
pygame.draw.circle(SCR, self.col_ball_PK, (self.x + self.ball_rad, self.y + self.ball_rad), self.ball_rad)
def new_ball(self,x,y):
self.x = x
self.y = y
self.ball_rad = rnd.randint(5, 20)
self.col_ball_PK = (10,rnd.randint(1,255),rnd.randint(1,255))
self.rect = Rect(self.x, self.y, self.ball_rad, self.ball_rad)
start_time = get_Time()
def mouse_ball(self, pos):
# Prüfung, ob die Maus die gleichen Koordinaten wie der Punkt hat
#global ANZ_RUNDEN, aktiv
if pos[0] >= self.rect.x and pos[0] <= (self.rect.x + self.ball_rad*2) and pos[1] >= self.rect.y and pos[1] <= self.rect.y + self.ball_rad*2:
# Timestamp wird ausgelesen
end_time = get_Time()
# die Dauer der beiden Mouseklicks wird errechnet
dauer_time = round(timedelta.total_seconds(end_time - start_time),4)
# die Dauer jeder Runde wird an die List angehängt
l_Dauer.append(dauer_time)
# ein neuer Ball wird aufgerufen
ball.new_ball(rnd.randint(15, SCR_W - 40),rnd.randint(15, SCR_H - 40))
def get_Time():
# liest die aktuelle Uhrzeit aus
return datetime.datetime.now()
def anz_reaktion():
global dt_avg, dt, l_Dauer
# Berechnung der Reaktionszeit. Wenn erst ein Element in der Liste, dann wird dieses angezeigt
# wenn mehr als zwei in der Liste, werden die letzten beiden Elemente subtrahiert
if len(l_Dauer) <= 1:
dt = round(l_Dauer[0],4)
else:
dt = round(l_Dauer[-1] - l_Dauer[-2],4)
draw_text("Reaktionszeit: " + str(dt), font, col_text, 50, SCR_H // 7 -40)
dt_avg = round(sum(l_Dauer)/len(l_Dauer)-1, 4)
def rahmen():
#Zeichnet den Rahmen um das Spielfeld (nur für die Optik)
pygame.draw.rect(SCR, col_rahmen_PK, [0, 0, SCR_W, SCR_H], 15)
# stellt Text auf dem Bildschirm dar
def draw_text(text, font, col_text, x, y):
img = font.render(text, True, col_text)
SCR.blit(img, (x, y))
def spielbeschreibung():
# wird angezeigt bevor das Spiel los geht
draw_text("- - - P u n k t e f a n g e n - - -", font, col_text, 50, SCR_H // 7 -40)
draw_text("Klicken Sie mit der Maus auf den Punkt.", font, col_text, 50, SCR_H // 7)
draw_text("Gefragt ist Geschwindigkeit.", font, col_text, 50, SCR_H // 7 + 80)
draw_text("Größe,Farbe und Ort variieren.", font, col_text, 50, SCR_H // 7 + 40)
draw_text("Drücken Sie die Space-Taste zum Start", font, col_text, 50, SCR_H // 7 + 120)
def start_sequenz():
global aktiv, start_time, dt_avg, ANZ_RUNDEN
# Spiel wird gestartet, Startzeit wird abgefragt und ein erster Ball erzeugt
SCR.fill(col_bg_PK)
aktiv = True
start_time = get_Time()
ANZ_RUNDEN = ANZ_RUNDEN_GES
dt_avg = 0
ball.new_ball(rnd.randint(15, SCR_W - 40),rnd.randint(15, SCR_H - 40))
def neu_ende():
# Abfrage ob noch eine Runde gespielt werden soll oder nicht
global run
SCR.fill(col_bg_PK)
t = datetime.datetime.now()
t1 = t.strftime('%d-%m-%Y %H:%M:%S')
draw_text("Wollen Sie nochmal? j / n", font, col_text, 50, SCR_H // 7 + 260)
pygame.time.wait(1000)
for event in pygame.event.get():
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_j:
with open (f_p, "a") as dat:
dat.write("Zeiten von " + str(t1) + ": " + str(dt_avg))
dat.write("\n")
start_sequenz()
if event.key == pygame.K_n:
run = False
pygame.QUIT
# hier wird ein ball der Klasse Ball außerhalb des Spielfeldes erzeugt
ball = Ball(-100,-100,)
# die var fragt ab, ob das Spiel eigentlich noch läuft, wenn wahr, dann geht und bleibt es in der eigentlichen SpielSchleife
run = True
### hier beginnt die eigentliche Spielschleife ###
while run: #and ANZ_RUNDEN > 0:
clock.tick(FPS)
SCR.fill(col_bg_PK)
rahmen()
# Zeigt die Spielregeln
if aktiv == False:
spielbeschreibung()
if aktiv:
anz_reaktion()
# Abfrage ob eine Taste oder Maus gedrückt wurde
for event in pygame.event.get():
# wenn die Aktion das X rechts oben im Spielfenster war, dann wird das Spiel beendet
if event.type == pygame.QUIT:
run = False
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_SPACE:
start_sequenz()
#ball.new_ball(rnd.randint(15, SCR_W - 40),rnd.randint(15, SCR_H - 40))
if event.type == pygame.MOUSEBUTTONUP:
# ermittelt wo der Maouszeiger gerade steht (x,y)
pos = pygame.mouse.get_pos()
# vergleicht, ob die Mouse Position der des Balls gleich ist
ball.mouse_ball(pos)
ANZ_RUNDEN -= 1
ball.draw_ball()
if ANZ_RUNDEN == 0:
# ein Durchgang ist vorbei, Sprung in die fun mit j / n Abfrage
aktiv = False
neu_ende()
# für die immer wiederkehrende neue Anzeige des Screens
pygame.display.update()
# beendet das Spiel
pygame.quit
.............................................................................................................................................................
in dieser Datei (bt_vars.py) stehen einige Variablen:
.............................................................................................................................................................
import pygame
import random as rnd
# Constanten und Variablen
global ball_PK
# Größe der Spiel Screens
SCR_W = 1600
SCR_H = 700
# Anzahl der Runden, die das Spiel laufen soll
ANZ_RUNDEN_GES = 3
# FPS
FPS = 60
# Farben - bt_PunktKlick
col_bg_PK = (204, 204, 204)
col_rahmen_PK = (255, 153, 0)
col_text = (51, 51, 102)
dt = 0