diff --git a/2os._tenks.py b/2os._tenks.py new file mode 100644 index 0000000..e69de29 diff --git a/statki.py b/statki.py index 930c0a0..ba9bd69 100644 --- a/statki.py +++ b/statki.py @@ -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(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 -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["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("", klawisz_wcisniety) root.bind("", klawisz_puszczony) root.bind("", lambda event: root.destroy())