Last active
August 8, 2025 09:40
-
-
Save horstjens/b2f376b8c75aac17c04711f671805206 to your computer and use it in GitHub Desktop.
turtle star wars
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import turtle | |
import random | |
import time | |
rebels = [] | |
imperials = [] | |
laser = [] | |
tasten = [] | |
treffer = {"fighter": 0, "bomber":0, "hitpoints": 100} | |
startzeit = time.time() | |
# imperials: spawnen an zufallspunkt in oberem Bildschirm-drittel | |
# fliegen langsam zu 1. Waypoint in unterm Bildschirm-drittel und | |
# werden dabei immer größer | |
# fliegen anschließend zum Rand und verschwinden | |
def hud_update(): | |
hudmaler.clear() | |
hudmaler.write(f"{treffer}", | |
align="center", | |
font=("System",22,"normal")) | |
def gameover(): | |
tasten.append("q") | |
def mouseclick(x,y): | |
turtle.hideturtle() | |
turtle.clear() # löscht alles alte | |
turtle.penup() | |
turtle.pencolor("blue") | |
turtle.goto(x,y) | |
turtle.pendown() | |
turtle.pensize(5) | |
turtle.circle(20) | |
turtle.penup() | |
# treffer ? | |
for i in imperials: | |
distanz = i.distance(x,y) | |
if distanz < (5 + i.shapesize()[0] * 2): | |
# treffer | |
i.color("red", "white") | |
i.burning = True | |
if i.shape() == "tie_bomber": | |
treffer["bomber"] += 1 | |
elif i.shape() == "tie_fighter": | |
treffer["fighter"] += 1 | |
hud_update() | |
break | |
#i.schritt = i.schritte - 100 | |
#turtle.write(f"mouseclick at {x}, {y}") | |
#print(f"mouseclick at {x}, {y}") | |
def create_laser(): | |
"""ein zufälliger imperial erzeugt | |
2 grüne laserstrahlen | |
""" | |
shooter = random.choice(imperials) | |
if shooter.burning: | |
return | |
# wie groß ist der imperial gerade ? | |
faktor = shooter.shapesize()[0] # 0.01 | |
exitpoint = (random.randint(0, pixel_x), | |
random.choice((0, pixel_y))) | |
abweichung = random.randint(10,50) | |
for delta_x in (-abweichung,abweichung): | |
x = turtle.Turtle() | |
x.shape("laser") | |
x.penup() | |
x.goto(shooter.pos()) | |
x.color("green", "green") | |
x.schritt = 1 #1 | |
x.schritte = 4000 # 4000 | |
x.zoomfaktor = faktor | |
x.spawnpoint = (shooter.xcor(), shooter.ycor()) | |
x.exitpoint = (exitpoint[0] + delta_x, exitpoint[1]) | |
x.setheading(x.towards(x.exitpoint)-180) | |
x.killme = False | |
laser.append(x) | |
def laser_bewegen(): | |
for strahl in laser: | |
gesamtstrecke_x = strahl.exitpoint[0] - strahl.spawnpoint[0] | |
gesamtstrecke_y = strahl.exitpoint[1] - strahl.spawnpoint[1] | |
teilstrecke_x = gesamtstrecke_x / strahl.schritte | |
teilstrecke_y = gesamtstrecke_y / strahl.schritte | |
strahl.goto(strahl.spawnpoint[0] + strahl.schritt * teilstrecke_x, | |
strahl.spawnpoint[1] + strahl.schritt * teilstrecke_y) | |
faktor = strahl.schritt / strahl.schritte * strahl.zoomfaktor # * 1.5 | |
strahl.shapesize(faktor, faktor, faktor) | |
strahl.schritt += 1 | |
strahl.schritt = int(strahl.schritt * 1.005) | |
strahl.schritt = min(strahl.schritt, strahl.schritte) | |
def points_machen(t): | |
"""gibt einer (imperal) turtle folgende zufallspunkte: | |
spawnpoint | |
waypoint | |
exitpoint | |
""" | |
# spawnpoint | |
x = random.randint(0, pixel_x) | |
y = random.randint(int(pixel_y * 0.66), pixel_y) | |
t.spawnpoint = (x,y) | |
# waypoint (1) | |
x = random.randint(0, pixel_x) | |
y = random.randint(int(pixel_y * 0.2), | |
int(pixel_y * 0.8)) | |
t.waypoint = (x,y) | |
# exitpoint | |
x = random.randint(0, pixel_x) | |
y = -50 | |
t.exitpoint = (x,y) | |
# goto spawnpoint | |
t.goto(t.spawnpoint) | |
t.ziel = "waypoint" | |
t.schritte = random.randint(1000,4000) | |
t.schritt = 1 | |
def move_imperials(): | |
""" | |
bewegt alle imperials von: | |
spawnpoint zu waypoint | |
von waypoint zu exitpoint | |
danach wiederholen mit neuen points | |
während der Bewegung werden die imperials größer. | |
beim spawn sind sie ganz klein | |
""" | |
for t in imperials: | |
if t.burning: | |
t.left(random.randint(1,5)) | |
#t.forward(random.randint(1,11)) | |
t.fillcolor(random.uniform(0.8,1.0),0,0) | |
if t.schritt % 25 == 0: | |
t.stamp() | |
#t.schritt+=1 | |
#if t.schritt == t.schritte: | |
## t.color("black", "#111111") | |
# t.clear() | |
# points_machen(t) | |
# t.burning = False | |
# #t.ziel = "waypoint" | |
# faktor = 0.01 | |
# t.shapesize(faktor, faktor, faktor) | |
# t.setheading(0) # TODO: fighter | |
if t.ziel == "waypoint": | |
gesamtstrecke_x = t.waypoint[0] - t.spawnpoint[0] | |
gesamtstrecke_y = t.waypoint[1] - t.spawnpoint[1] | |
teilstrecke_x = gesamtstrecke_x / t.schritte | |
teilstrecke_y = gesamtstrecke_y / t.schritte | |
t.goto(t.spawnpoint[0] + t.schritt * teilstrecke_x, | |
t.spawnpoint[1] + t.schritt * teilstrecke_y) | |
faktor = t.schritt / t.schritte * 4.0 | |
t.shapesize(faktor, faktor, faktor) | |
t.schritt += 1 | |
if t.schritt == t.schritte: | |
t.ziel = "exitpoint" | |
t.schritt = 1 | |
t.schritte = random.randint(500,1000) | |
elif t.ziel == "exitpoint": | |
gesamtstrecke_x = t.exitpoint[0] - t.waypoint[0] | |
gesamtstrecke_y = t.exitpoint[1] - t.waypoint[1] | |
teilstrecke_x = gesamtstrecke_x / t.schritte | |
teilstrecke_y = gesamtstrecke_y / t.schritte | |
t.goto(t.waypoint[0] + t.schritt * teilstrecke_x, | |
t.waypoint[1] + t.schritt * teilstrecke_y) | |
faktor = 4.0 + t.schritt / t.schritte * 4.0 | |
t.shapesize(faktor, faktor, faktor) | |
t.schritt += 1 | |
if t.schritt == t.schritte: | |
# exitpoint wurde erreicht | |
if not t.burning: | |
treffer["hitpoints"] -= 1 | |
hud_update() | |
points_machen(t) # respawn | |
t.burning = False | |
t.clear() | |
t.color("black", "#111111") | |
#t.ziel = "waypoint" | |
faktor = 0.01 | |
t.shapesize(faktor, faktor, faktor) | |
t.setheading(0) # TODO: fighter | |
# wackeln | |
t.left(random.choice(t.flight_data)) # in die Kurve legen | |
def move_rebels(margin=0): | |
"""move all rebel spaceships. wrap-around screen""" | |
for r in rebels: | |
r.forward(random.choice(r.speed_data)) | |
# out of border ? | |
# right border, heading east (0) | |
if (0 <= r.heading() < 90) or (270 < r.heading()): | |
if r.xcor() > pixel_x - margin: | |
r.setx(0 - margin) | |
#r.clear() | |
# left border, heading west (180) | |
if (90 < r.heading() < 270): | |
if r.xcor() < margin: | |
r.setx(pixel_x + margin) | |
#r.clear() | |
# top border, heading north (90) | |
if (0 < r.heading() < 180): | |
if r.ycor() > pixel_y - margin: | |
r.sety(0 - margin) | |
#r.clear() | |
# bottom border, heading south (270) | |
if (180 < r.heading() < 360): | |
if r.ycor() < margin: | |
r.sety(pixel_y + margin) | |
#r.clear() | |
# fly a curve? | |
r.left(random.choice(r.flight_data)) | |
# ---------------------------- SETUP ------------------------- | |
window = turtle.Screen() # screen definieren | |
# use maximum screensize | |
window.setup(1.0,1.0) | |
# finde bildschirmauflösung heraus | |
pixel_x = window.window_width() | |
pixel_y = window.window_height() | |
# Ursprung in die linke untere Ecke setzten (anstatt Mitte vom Bildschirm) | |
window.setworldcoordinates(0,0,pixel_x,pixel_y) | |
# hintergrund schwarz | |
window.bgcolor("#333333") | |
# schnell zeichnen | |
window.tracer(0) | |
# ------------ sterne malen ------------ | |
sternmaler = turtle.Turtle() | |
for _ in range(100): | |
sternmaler.penup() | |
sternmaler.goto(random.randint(0, pixel_x), | |
random.randint(0, pixel_y)) | |
sternmaler.pendown() | |
sternmaler.dot(random.randint(1,3),"yellow") | |
sternmaler.penup() | |
sternmaler.hideturtle() | |
# ---------- HUD ---------- | |
hudmaler = turtle.Turtle() | |
hudmaler.penup() | |
hudmaler.goto(pixel_x//2,pixel_y - 50) # oben mitte | |
hudmaler.pencolor("blue") | |
hudmaler.hideturtle() | |
hudmaler.write(f"{treffer}", | |
align="center", | |
font=("System",22,"normal")) | |
# laser | |
window.register_shape("laser", ((5,50), (-5,50),(-10,-50),(10,-50))) | |
# A-Wing | |
window.register_shape("x_wing", ( | |
(3,-10), | |
(-3,-10), | |
(-3,-5), | |
(-7,-5), | |
(-7,-7), | |
(-7,9), | |
(-7,-2), | |
(-3,-2), | |
(-3,0), | |
(-1,12), | |
(1,12), | |
(3,0), | |
(3,-2), | |
(7,-2), | |
(7,9), | |
(7,-7), | |
(7,-5), | |
(3,-5))) | |
# Tie-Fighter | |
window.register_shape("tie_fighter", ( | |
(0,-3), | |
(-3,0), | |
(-6,0), | |
(-6,-6), | |
(-6,6), | |
(-6,0), | |
(-3,0), | |
(0,3), | |
(3,0), | |
(6,0), | |
(6,-6), | |
(6,6), | |
(6,0), | |
(3,0))) | |
window.register_shape("tie_bomber", ( | |
(0,0), | |
(-2,1), | |
(-3,3), | |
(-2,5), | |
(0,6), | |
(0,8), | |
(-1,8), | |
(-4,7), | |
(-5,6), | |
(-4,7), | |
(-1,8), | |
(1,8), | |
(4,7), | |
(5,6), | |
(4,7), | |
(1,8), | |
(0,8), | |
(0,6), | |
(2,5), | |
(3,3), | |
(2,1), | |
(0,0), | |
(-2,-1), | |
(-3,-3), | |
(-2,-5), | |
(0,-6), | |
(0,-8), | |
(-1,-8), | |
(-4,-7), | |
(-5,-6), | |
(-4,-7), | |
(-1,-8), | |
(1,-8), | |
(4,-7), | |
(5,-6), | |
(4,-7), | |
(1,-8), | |
(0,-8), | |
(0,-6), | |
(2,-5), | |
(3,-3), | |
(2,-1))) | |
for _ in range(0): | |
a = turtle.Turtle() | |
a.penup() | |
a.shape("x_wing") | |
a.color("red", "white") | |
faktor = random.uniform(0.5,4.0) | |
a.setheading(random.randint(0,360)) | |
a.goto(random.randint(0, pixel_x), | |
random.randint(0, pixel_y)) | |
# kleine flieger sind schneller und wendiger als große | |
if faktor < 1.5: | |
a.flight_data = (-3,-2,-1,-1,0,0,0,1,1,2,3) # Kurvenflug | |
a.speed_data = (1,2,2,3,3,3,4,4,4,4) # | |
elif faktor < 2.5: | |
a.flight_data = (-3,-2,-1,-1,0,0,0,0,0,1,1,2,3) # Kurvenflug | |
a.speed_data = (1,1,2,2,3,3,3,4,4) # | |
elif faktor < 3.5: | |
a.flight_data = (-2,-1,-1,0,0,0,0,0,0,1,1,2) # Kurvenflug | |
a.speed_data = (1,1,2,2,3,3,3) # | |
else: | |
# raumschiff extragroß machen | |
faktor *= 2 # faktor = faktor * 2 | |
a.flight_data = (-1,0,0,0,0,0,0,1) # Kurvenflug | |
a.speed_data = (1,1,1,1,1,2,2) | |
a.shapesize(faktor, faktor, faktor) | |
rebels.append(a) | |
for _ in range(4): | |
# imperials | |
a = turtle.Turtle() | |
a.penup() | |
if random.random() < 0.33: | |
a.shape("tie_bomber") | |
a.flight_data = (-1,0,0,0,0,0,0,1) # Kurvenflug | |
a.speed_data = (1,1,1,1,1,2,2) | |
a.setheading(0) | |
else: | |
a.shape("tie_fighter") | |
a.setheading(90) | |
a.flight_data = (-3,-2,-1,0,0,1,2,3) # Kurvenflug | |
a.speed_data = (1,1,2,2,2,3,3,3,3,4) | |
a.color("black", "#111111") | |
a.burning = False | |
faktor = 0.01 | |
a.shapesize(faktor, faktor, faktor) | |
a.goto(random.randint(0, pixel_x), | |
random.randint(0, pixel_y)) | |
# spawnpoint festlegen | |
# waypoint festlegen | |
# exitpoint festlegen | |
points_machen(a) | |
imperials.append(a) | |
window.onscreenclick(mouseclick) | |
window.onkey(gameover,"q") | |
window.listen() # setzt den focus auf den turtlescreen | |
#turtle.tracer(1) | |
#while True: | |
while (not "q" in tasten) and (treffer["hitpoints"] >0): | |
#move_rebels() | |
move_imperials() | |
if random.random() < 0.001: | |
create_laser() | |
laser_bewegen() | |
window.update() | |
# laser löschen | |
for l in laser: | |
if l.schritt >= l.schritte: | |
l.hideturtle() | |
l.killme = True | |
if l.shapesize()[0] > 5.0: | |
l.hideturtle() | |
l.killme = True | |
laser = [l for l in laser if not l.killme] | |
#window.exitonclick() | |
print("Game Over") | |
print(treffer) | |
sekunden = time.time() - startzeit | |
print(f"Du hast {sekunden:.2f} Sekunden lang gespielt") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment