Skip to content

Instantly share code, notes, and snippets.

@horstjens
Last active August 8, 2025 09:40
Show Gist options
  • Save horstjens/b2f376b8c75aac17c04711f671805206 to your computer and use it in GitHub Desktop.
Save horstjens/b2f376b8c75aac17c04711f671805206 to your computer and use it in GitHub Desktop.
turtle star wars
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