statek ol

This commit is contained in:
tymek 2026-06-13 13:48:15 +02:00
parent f0a7f7cbca
commit b69f77b912
2 changed files with 317 additions and 28 deletions

0
2os._tenks.py Normal file
View file

335
statki.py
View file

@ -1,6 +1,7 @@
from tkinter import *
from random import randrange as rand
from math import radians, cos, sin
from random import uniform as uni
from math import radians, cos, sin, atan2, sqrt
def obroc(x, y, sx, sy, a_stopnie):
@ -23,13 +24,206 @@ def klawisz_puszczony(event):
def gluwna():
global czekaj_scala, przeladowanie
rusz()
strzal()
aktu_pociski()
skala()
asteroidy_ruch()
sprawdz_kolizje_statku()
sprawdz_kolizje_asteroid_i_pociskow()
odlamki_ruch()
czekaj_scala -= 1
przeladowanie -= 1
root.after(16, gluwna)
def asteroidy_ruch():
for a in range(len(asteroidy)):
ast = asteroidy[a]
xp = uni(-0.01, 0.01)
ast["dx"] += xp
yp = uni(-0.01, 0.01)
ast["dy"] += yp
canvas.move(ast["id"], ast["dx"], ast["dy"])
if ast["dziury"]:
for dz in ast["dziury"]:
canvas.move(dz["id1"], ast["dx"], ast["dy"])
canvas.move(dz["id2"], ast["dx"], ast["dy"])
dz["x"] += ast["dx"]
dz["y"] += ast["dy"]
def sprawdz_kolizje_statku():
global v, mapa_x, mapa_y
if v == 0:
return
cx = srodek_ekranu_x
cy = srodek_ekranu_y
promien_statku = 25
for k in asteroidy:
kordy_ast = canvas.coords(k["id"])
if len(kordy_ast) < 4:
continue
kx_srodek = (kordy_ast[0] + kordy_ast[2]) / 2
ky_srodek = (kordy_ast[1] + kordy_ast[3]) / 2
r_asteroidy = k["r"]
odleglosc = sqrt((cx - kx_srodek) ** 2 + (cy - ky_srodek) ** 2)
min_odleglosc = promien_statku + r_asteroidy
if odleglosc < min_odleglosc:
nakladanie = min_odleglosc - odleglosc
kat = atan2(cy - ky_srodek, cx - kx_srodek)
dx = nakladanie * cos(kat)
dy = nakladanie * sin(kat)
canvas.move("gwiazdy", dx, dy)
canvas.move(koniec_mapy, dx, dy)
mapa_x -= dx
mapa_y -= dy
v = 0
wcisniete_klawisze["w"] = False
break
def odlamki_ruch():
if odlamki:
for odlamek in odlamki:
canvas.move(odlamek["id"], odlamek["dx"], odlamek["dy"])
def sprawdz_kolizje_asteroid_i_pociskow():
for ast in asteroidy:
kordy_ast = canvas.coords(ast["id"])
if not kordy_ast:
continue
srx = (kordy_ast[0] + kordy_ast[2]) / 2
sry = (kordy_ast[1] + kordy_ast[3]) / 2
r_ast = ast["r"]
for zast in asteroidy:
if ast["id"] == zast["id"]:
continue
kordy_zast = canvas.coords(zast["id"])
if not kordy_zast: continue
srxz = (kordy_zast[0] + kordy_zast[2]) / 2
sryz = (kordy_zast[1] + kordy_zast[3]) / 2
r_zast = zast["r"]
odleglosc = sqrt((srx - srxz) ** 2 + (sry - sryz) ** 2)
min_odleglosc = r_ast + r_zast
# print(f"Sprawdzam asteroidę {ast["id"]}. Liczba dziur: {len(ast["dziury"])}")
if odleglosc < min_odleglosc:
ast["dx"] = -ast["dx"]
ast["dy"] = -ast["dy"]
zast["dx"] = -zast["dx"]
zast["dy"] = -zast["dy"]
canvas.move(ast["id"], ast["dx"], ast["dy"])
if ast["dziury"]:
for dz in ast["dziury"]:
canvas.move(dz["id1"], ast["dx"], ast["dy"])
canvas.move(dz["id2"], ast["dx"], ast["dy"])
dz["x"] += ast["dx"]
dz["y"] += ast["dy"]
# print("xx")
if len(kordy_ast) >= 4:
kx_srodek = (kordy_ast[0] + kordy_ast[2]) / 2
ky_srodek = (kordy_ast[1] + kordy_ast[3]) / 2
r_ast = ast["r"]
for p in range(len(pociski) - 1, -1, -1):
po = pociski[p]
pos1 = canvas.coords(po["id1"])
pos2 = canvas.coords(po["id2"])
if not pos1 or not pos2:
continue
pos_x = (pos1[0] + pos1[2] + pos2[0] + pos2[2]) / 4
pos_y = (pos1[1] + pos1[3] + pos2[1] + pos2[3]) / 4
rpos = po["r"]
odleglosc = sqrt((pos_x - kx_srodek) ** 2 + (pos_y - ky_srodek) ** 2)
if odleglosc < r_ast + rpos:
prze = 2 * po["rr"] + uni(0.0, 1.0)
canvas.move(po["id1"], po["dx"] * prze, po["dy"] * prze)
canvas.move(po["id2"], po["dx"] * prze, po["dy"] * prze)
pos1 = canvas.coords(po["id1"])
pos2 = canvas.coords(po["id2"])
if pos1 and pos2:
p1_srodek_x = (pos1[0] + pos1[2]) / 2
p1_srodek_y = (pos1[1] + pos1[3]) / 2
p2_srodek_x = (pos2[0] + pos2[2]) / 2
p2_srodek_y = (pos2[1] + pos2[3]) / 2
pos_x = (p1_srodek_x + p2_srodek_x) / 2
pos_y = (p1_srodek_y + p2_srodek_y) / 2
dz1 = canvas.create_oval(p1_srodek_x - po["rr"], p1_srodek_y - po["rr"], p1_srodek_x + po["rr"], p1_srodek_y + po["rr"], fill=kolory[po["zestaw"]][po["kolor"] - 1], outline=kolory[po["zestaw"]][po["kolor"]], tags="gwiazdy")
dz2 = canvas.create_oval(p2_srodek_x - po["rr"], p2_srodek_y - po["rr"], p2_srodek_x + po["rr"], p2_srodek_y + po["rr"], fill=kolory[po["zestaw"]][po["kolor"] - 1], outline=kolory[po["zestaw"]][po["kolor"]], tags="gwiazdy")
ast["dziury"].append({"id1": dz1, "id2": dz2, "x": pos_x, "y": pos_y})
for odla in range(10):
odlamek1 = canvas.create_oval(p1_srodek_x - po["rr"], p1_srodek_y - po["rr"], p1_srodek_x + po["rr"], p1_srodek_y + po["rr"], fill=f"grey{rand(20, 30)}", outline="", tags="gwiazdy")
odlamki.append({"id": odlamek1, "dx": uni(-1.0, 1.0), "dy": uni(-1.0, 1.0)})
root.after(1000, lambda od=odlamek1: canvas.delete(od))
odlamek2 = canvas.create_oval(p2_srodek_x - po["rr"], p2_srodek_y - po["rr"], p2_srodek_x + po["rr"], p2_srodek_y + po["rr"], fill=f"grey{rand(20, 30)}", outline="", tags="gwiazdy")
odlamki.append({"id": odlamek2, "dx": uni(-1.0, 1.0), "dy": uni(-1.0, 1.0)})
root.after(1000, lambda od=odlamek2: canvas.delete(od))
root.after(600, lambda d1=dz1: canvas.itemconfig(d1, fill=f"grey{rand(10, 30)}", outline=""))
root.after(600, lambda d2=dz2: canvas.itemconfig(d2, fill=f"grey{rand(10, 30)}", outline=""))
# print("Dziura dodana pomyślnie!")
canvas.delete(po["id1"])
canvas.delete(po["id2"])
pociski.pop(p)
# print("x")
def bok(lewo):
global srodek_ekranu_x, srodek_ekranu_y, obroc_o, statek_bazowy
if lewo:
r = 3
x, y = obroc(statek_bazowy[2], statek_bazowy[3], srodek_ekranu_x, srodek_ekranu_y, obroc_o)
s2 = canvas.create_oval(x - r, y - r, x + r, y + r, fill="#000000", outline="", tags="gwiazdy")
for i in range(50):
wartosc_rgb = int((49 - i) * (255 / 49))
he = f"{wartosc_rgb:02X}"
kolor = f"#0000{he}"
root.after(i * 6, lambda k=kolor: canvas.itemconfig(s2, fill=k))
root.after(300, lambda: canvas.delete(s2))
canvas.tag_lower(s2)
else:
r = 3
x, y = obroc(statek_bazowy[6], statek_bazowy[7], srodek_ekranu_x, srodek_ekranu_y, obroc_o)
s2 = canvas.create_oval(x - r, y - r, x + r, y + r, fill="#000000", outline="", tags="gwiazdy")
for i in range(50):
wartosc_rgb = int((49 - i) * (255 / 49))
he = f"{wartosc_rgb:02X}"
kolor = f"#0000{he}"
root.after(i * 6, lambda k=kolor: canvas.itemconfig(s2, fill=k))
root.after(300, lambda: canvas.delete(s2))
canvas.tag_lower(s2)
def skala():
global czekaj_scala
if wcisniete_klawisze["q"] and wiel_pocis.get() >= 1 and czekaj_scala <= 0:
wiel_pocis.set(wiel_pocis.get() - 1)
czekaj_scala = 20
if wcisniete_klawisze["e"] and wiel_pocis.get() < 6 and czekaj_scala <= 0:
wiel_pocis.set(wiel_pocis.get() + 1)
czekaj_scala = 20
def rusz():
global wcisniete_klawisze, mapa_y, mapa_x, obroc_o
v = 4
global wcisniete_klawisze, mapa_y, mapa_x, obroc_o, probrotowa, v
a_rad = radians(obroc_o)
@ -37,25 +231,29 @@ def rusz():
dy = v * cos(a_rad)
if wcisniete_klawisze["a"]:
obroc_o -= 2
probrotowa -= 0.1
bok(True)
if wcisniete_klawisze["d"]:
obroc_o += 2
probrotowa += 0.1
bok(False)
if wcisniete_klawisze["w"]:
if probrotowa < 0:
probrotowa += 0.03
if probrotowa > 0:
probrotowa -= 0.03
obroc_o += probrotowa
if -1500 < mapa_x + dx < 3600 and -800 < mapa_y - dy < 1800:
canvas.move("gwiazdy", -dx, dy)
canvas.move("pociski", -dx, dy)
canvas.move(koniec_mapy, -dx, dy)
mapa_x += dx
mapa_y -= dy
if wcisniete_klawisze["s"]:
if -1500 < mapa_x - dx < 3600 and -800 < mapa_y + dy < 1800:
canvas.move("gwiazdy", dx, -dy)
canvas.move(koniec_mapy, dx, -dy)
mapa_x -= dx
mapa_y += dy
if wcisniete_klawisze["w"] and v < 5:
v += 0.05
if wcisniete_klawisze["s"] and v > -2:
v -= 0.05
nowe_punkty = []
for i in range(0, len(statek_bazowy), 2):
@ -66,20 +264,87 @@ def rusz():
canvas.coords(statek, *nowe_punkty)
nowe_punkty = []
for i in range(0, len(lewe_bazowe), 2):
bx = lewe_bazowe[i]
by = lewe_bazowe[i + 1]
nx, ny = obroc(bx, by, srodek_ekranu_x, srodek_ekranu_y, obroc_o)
nowe_punkty.extend([nx, ny])
canvas.coords(lewe_dzialo, *nowe_punkty)
nowe_punkty = []
for i in range(0, len(prawe_bazowe), 2):
bx = prawe_bazowe[i]
by = prawe_bazowe[i + 1]
nx, ny = obroc(bx, by, srodek_ekranu_x, srodek_ekranu_y, obroc_o)
nowe_punkty.extend([nx, ny])
canvas.coords(prawe_dzialo, *nowe_punkty)
if wcisniete_klawisze["w"] or wcisniete_klawisze["s"]:
r = 6
s1 = canvas.create_oval(srodek_ekranu_x - r, srodek_ekranu_y - r, srodek_ekranu_x + r, srodek_ekranu_y + r, fill="#000000", outline="", tags="gwiazdy")
for i in range(100):
wartosc_rgb = int((99 - i) * (255 / 99))
for i in range(50):
wartosc_rgb = int((49 - i) * (255 / 49))
he = f"{wartosc_rgb:02X}"
kolor = f"#{he}0000"
root.after(i * 12, lambda k=kolor: canvas.itemconfig(s1, fill=k))
root.after(i * 24, lambda k=kolor: canvas.itemconfig(s1, fill=k))
root.after(1200, lambda: canvas.delete(s1))
canvas.tag_lower(s1)
def strzal():
global srodek_ekranu_x, srodek_ekranu_y, obroc_o, v, przeladowanie
if wcisniete_klawisze["space"] and przeladowanie <= 0:
r = wiel_pocis.get()
kolor = kolory[int(kol_pocis.get() - 1)][rand(0, len(kolory[int(kol_pocis.get() - 1)]))]
xl, yl = obroc(lewe_bazowe[2], lewe_bazowe[3], srodek_ekranu_x, srodek_ekranu_y, obroc_o)
xp, yp = obroc(prawe_bazowe[2], prawe_bazowe[3], srodek_ekranu_x, srodek_ekranu_y, obroc_o)
s3 = canvas.create_oval(xl - r, yl - r, xl + r, yl + r, fill=kolor, outline="", tags="pociski")
s4 = canvas.create_oval(xp - r, yp - r, xp + r, yp + r, fill=kolor, outline="", tags="pociski")
kat_rad = radians(obroc_o)
predkosc_pocisku = v + 8 - wiel_pocis.get()
przeladowanie = wiel_pocis.get() ** 2.5
vx = predkosc_pocisku * sin(kat_rad) + uni(-0.1, 0.1)
vy = -predkosc_pocisku * cos(kat_rad) + uni(-0.1, 0.1)
# print(kolory[int(kol_pocis.get())])
pociski.append({"id1": s3, "id2": s4, "dx": vx, "dy": vy, "r": 2 * r + 14, "rr": r, "zestaw": kol_pocis.get() - 1, "kolor": kolory[int(kol_pocis.get()) - 1].index(kolor)})
r_blysk = wiel_pocis.get() * 2
s5 = canvas.create_oval(xl - r_blysk, yl - r_blysk, xl + r_blysk, yl + r_blysk, fill="yellow", outline="red", tags="pociski")
s6 = canvas.create_oval(xp - r_blysk, yp - r_blysk, xp + r_blysk, yp + r_blysk, fill="yellow", outline="red", tags="pociski")
root.after(rand(30, 60), lambda w6=s6: canvas.delete(w6))
root.after(rand(30, 60), lambda w5=s5: canvas.delete(w5))
def aktu_pociski():
global pociski
aktywne_pociski = []
for p in pociski:
wspolrzedne = canvas.coords(p["id1"])
if not wspolrzedne:
continue
if wspolrzedne[0] < -2000 or wspolrzedne[0] > 4000 or wspolrzedne[1] < -1500 or wspolrzedne[1] > 2500:
canvas.delete(p["id1"])
canvas.delete(p["id2"])
continue
canvas.move(p["id1"], p["dx"], p["dy"])
canvas.move(p["id2"], p["dx"], p["dy"])
aktywne_pociski.append(p)
pociski = aktywne_pociski
root = Tk()
root.geometry("1000x700")
root.attributes("-fullscreen", True)
@ -89,33 +354,57 @@ canvas.pack(fill="both", expand=True)
koniec_mapy = canvas.create_rectangle(-1900, -1000, 3800, 2000, fill="", outline="red", width=5)
for i in range(5000):
for i in range(1000):
x = rand(-1900, 3800)
y = rand(-1000, 2000)
r = 2
g = canvas.create_oval(x, y, x + r, y + r, fill="white", outline="", tags="gwiazdy")
wcisniete_klawisze = {"w": False, "s": False, "a": False, "d": False, "space": False}
wcisniete_klawisze = {"w": False, "s": False, "a": False, "d": False, "space": False, "q": False, "e": False}
root.update()
x_w = canvas.winfo_width()
y_w = canvas.winfo_height()
srodek_ekranu_x = x_w / 2
srodek_ekranu_y = y_w / 2
mapa_x = srodek_ekranu_x
mapa_y = srodek_ekranu_y
x = 20
y = 30
statek_bazowy = [srodek_ekranu_x, srodek_ekranu_y - y, srodek_ekranu_x + x, srodek_ekranu_y + y, srodek_ekranu_x, srodek_ekranu_y, srodek_ekranu_x - x, srodek_ekranu_y + y]
statek = canvas.create_polygon(*statek_bazowy, fill="lightblue", outline="")
lewe_bazowe = [srodek_ekranu_x - 7, srodek_ekranu_y + 5, srodek_ekranu_x - 7, srodek_ekranu_y - y + 10]
lewe_dzialo = canvas.create_line(*lewe_bazowe, fill="lightblue", width=3)
prawe_bazowe = [srodek_ekranu_x + 7, srodek_ekranu_y + 5, srodek_ekranu_x + 7, srodek_ekranu_y - y + 10]
prawe_dzialo = canvas.create_line(*prawe_bazowe, fill="lightblue", width=3)
przeladowanie = 10
pociski = []
wiel_pocis = Scale(root, from_=1, to=6, orient=HORIZONTAL, length=200, width=20, bg="grey30", fg="#ffffff", troughcolor="#4a90e2", activebackground="#ff9900", label="Wielkość pocisków: < q | e >", highlightthickness=0, bd=2)
wiel_pocis.place(x=0, y=0)
wiel_pocis.set(1)
czekaj_scala = 10
kolory = [["red", "yellow", "gold", "orange", "red3"], ["green", "limegreen", "forestgreen", "darkgreen", "lawngreen"], ["blue", "blue2", "DeepSkyBlue3", "RoyalBlue3", "mediumblue"], ["grey20", "grey18", "grey16", "grey14", "grey12", "grey10"]]
kol_pocis = Scale(root, from_=1, to=len(kolory), showvalue=False, tickinterval=1, orient=HORIZONTAL, length=200, width=20, bg="grey30", fg="#ffffff", troughcolor="#4a90e2", activebackground="#ff9900", label="Kolor pocisków: zestaw: ", highlightthickness=0, bd=2)
kol_pocis.place(x=0, y=68)
kol_pocis.set(1)
obroc_o = 0
probrotowa = 0
v = 0
odlamki = []
asteroidy = []
for i in range(rand(40, 80)):
x = rand(-1900, 3800)
y = rand(-1000, 2000)
r = rand(10, 50)
g = canvas.create_oval(x - r, y - r, x + r, y + r, fill=f"grey{rand(20, 31)}", outline="", tags=("gwiazdy", "asteroidy"))
asteroidy.append({"id": g, "r": r, "dx": 0, "dy": 0, "dziury": []})
root.bind("<KeyPress>", klawisz_wcisniety)
root.bind("<KeyRelease>", klawisz_puszczony)
root.bind("<Escape>", lambda event: root.destroy())