diff --git a/.idea/zolwik.iml b/.idea/zolwik.iml index 6cb8b9a..e9b33ee 100644 --- a/.idea/zolwik.iml +++ b/.idea/zolwik.iml @@ -4,7 +4,7 @@ - + \ No newline at end of file diff --git a/2os._tenks.py b/2os._tenks.py index 8b878f9..e11c0a6 100644 --- a/2os._tenks.py +++ b/2os._tenks.py @@ -44,15 +44,17 @@ def animuj(krok): j["x"] = j["cel_x"] j["y"] = j["cel_y"] + j["linia"]["nazwa"] = None + j["linia"]["prze"] = 0 koniec_planowania = True + canvas.delete("linie") return for j in jednostki: dx = (j["cel_x"] - j["x"]) / (ANIMACJA_KROKI - krok) dy = (j["cel_y"] - j["y"]) / (ANIMACJA_KROKI - krok) - canvas.move(j["rect"], dx, dy) - canvas.move(j["text"], dx, dy) + canvas.move(j["sprite"], dx, dy) j["x"] += dx j["y"] += dy @@ -66,11 +68,23 @@ def animuj(krok): else: roznica += 360 - j["kat"] += roznica * 0.15 + j["kat"] += roznica * 0.01 + obrocony = j["img_org"].rotate( + -j["kat"], + expand=True, + resample=Image.Resampling.BICUBIC + ) + j["img_tk"] = ImageTk.PhotoImage(obrocony) + + canvas.itemconfig( + j["sprite"], + image=j["img_tk"] + ) root.after(15, lambda: animuj(krok + 1)) + def zmien_predkosc(*args): if not jednostki: return @@ -97,12 +111,6 @@ def zmien_predkosc(*args): j["cel_x"] = j["x"] j["cel_y"] = j["y"] - canvas.itemconfig( - j["rect"], - outline="black", - width=1 - ) - wybrana_jednostka = None aktualna_strona = "USA" @@ -227,18 +235,38 @@ def ustaw_pojazd(event): placed_units.append((x1, y1, x2, y2)) - nazwa_pliku = f"{nazwa} min.png" + try: + nazwa_pliku = f"{nazwa} min.png" # {nazwa} + #print(nazwa_pliku) + img_org = Image.open(nazwa_pliku) + except: + nazwa_pliku = f"obraz_tk_3.png" + img_org = Image.open(nazwa_pliku) - img_org = Image.open(nazwa_pliku) + img_org.thumbnail( + (size_x, size_y), + Image.Resampling.LANCZOS + ) img_tk = ImageTk.PhotoImage(img_org) sprite = canvas.create_image( - 300, - 200, + event.x, + event.y, image=img_tk ) + if strona == "USA": + obrocony = img_org.rotate( + 180, + expand=True, + resample=Image.Resampling.BICUBIC + ) + img_tk = ImageTk.PhotoImage(obrocony) + canvas.itemconfig( + sprite, + image=img_tk + ) jednostki.append({ "nazwa": nazwa, "strona": strona, @@ -254,7 +282,7 @@ def ustaw_pojazd(event): "img_org": img_org, "img_tk": img_tk, - "kat": 0, + "kat": 0 if strona == "GER" else 180, "hp": 100, @@ -435,7 +463,7 @@ def start(): else: SKALA_JEDNOSTKI = 3 mnoznik_ruchu = 0.3 - + SKALA_JEDNOSTKI *= 3 BONUS_RUCHU = int( predkosc_ruchu.get().replace("x", "") ) @@ -530,18 +558,18 @@ kolejnosc_pojazdow = [ ] pojazdy = [ # ==================== USA (Po kolei numerycznie) ==================== - {"naz": "M3 St.", "x": 0, "y": 0, "wys": 2, "sze": 2, "ruch": 120}, - {"naz": "M22", "x": 0, "y": 0, "wys": 1, "sze": 2, "ruch": 140}, - {"naz": "M3 GMC", "x": 0, "y": 0, "wys": 2, "sze": 3, "ruch": 110}, - {"naz": "M15 CGMC", "x": 0, "y": 0, "wys": 2, "sze": 3, "ruch": 100}, - {"naz": "M3 Lee", "x": 0, "y": 0, "wys": 2, "sze": 3, "ruch": 80}, - {"naz": "LVT", "x": 0, "y": 0, "wys": 3, "sze": 3, "ruch": 70}, + {"naz": "M3 St.", "x": 0, "y": 0, "wys": 2, "sze": 3, "ruch": 120}, + {"naz": "M22", "x": 0, "y": 0, "wys": 2, "sze": 3, "ruch": 140}, + {"naz": "M3 GMC", "x": 0, "y": 0, "wys": 2, "sze": 4, "ruch": 110}, + {"naz": "M15 CGMC", "x": 0, "y": 0, "wys": 2, "sze": 4, "ruch": 100}, + {"naz": "M3 Lee", "x": 0, "y": 0, "wys": 3, "sze": 3, "ruch": 80}, + {"naz": "LVT", "x": 0, "y": 0, "wys": 3, "sze": 4, "ruch": 70}, {"naz": "M4A3", "x": 0, "y": 0, "wys": 2, "sze": 3, "ruch": 90}, - {"naz": "sd.KFz.222", "x": 0, "y": 0, "wys": 1, "sze": 2, "ruch": 130}, + {"naz": "sd.KFz.222", "x": 0, "y": 0, "wys": 2, "sze": 3, "ruch": 130}, {"naz": "sd.KFz.251-9", "x": 0, "y": 0, "wys": 2, "sze": 3, "ruch": 100}, - {"naz": "Pz.IIIF", "x": 0, "y": 0, "wys": 2, "sze": 2, "ruch": 95}, - {"naz": "Pz.IIIC", "x": 0, "y": 0, "wys": 2, "sze": 2, "ruch": 105}, + {"naz": "Pz.IIIF", "x": 0, "y": 0, "wys": 2, "sze": 3, "ruch": 95}, + {"naz": "Pz.IIIC", "x": 0, "y": 0, "wys": 2, "sze": 3, "ruch": 105}, {"naz": "Stug IIIb", "x": 0, "y": 0, "wys": 2, "sze": 4, "ruch": 70}, {"naz": "Beutepanzer IV", "x": 0, "y": 0, "wys": 3, "sze": 4, "ruch": 40}, {"naz": "A7V", "x": 0, "y": 0, "wys": 4, "sze": 6, "ruch": 30}, @@ -615,7 +643,7 @@ def planowanie(event): for j in jednostki: - if j["rect"] in klikniete or j["text"] in klikniete: + if j["sprite"] in klikniete: if j["strona"] != aktualna_strona: return @@ -625,11 +653,6 @@ def planowanie(event): wybrana_jednostka = j - canvas.itemconfig( - j["rect"], - outline="yellow", - width=3 - ) global zasieg_podglad if zasieg_podglad: @@ -645,7 +668,7 @@ def planowanie(event): fill="chartreuse3", stipple="gray50", activestipple="gray12", - outline="green", + outline="forestgreen", width=2 ) lbl_aktywny_pojazd.config( @@ -658,7 +681,7 @@ def planowanie(event): dy = event.y - wybrana_jednostka["y"] wybrana_jednostka["kat_docelowy"] = degrees( atan2(dy, dx) - ) + )+180 odleglosc = (dx * dx + dy * dy) ** 0.5 if odleglosc > wybrana_jednostka["ruch"]: @@ -681,25 +704,21 @@ def planowanie(event): for j in jednostki: if j["wykonal_ruch"]: + #canvas.delete("linie") if j["linia"]["nazwa"] is None: - j["linia"]["dash"]["kropka"] = rand(2, 10) - j["linia"]["dash"]["przerwa"] = rand(3, 6) - j["linia"]["nazwa"] = canvas.create_line( - j["cel_x"], - j["cel_y"], - j["x"], - j["y"], - fill="yellow", - dash=(j["linia"]["dash"]["kropka"], j["linia"]["dash"]["przerwa"]), - dashoffset=0, - capstyle="round", - tags="plan") - - canvas.itemconfig( - wybrana_jednostka["rect"], - outline="black", - width=1 - ) + j["linia"]["dash"]["kropka"] = 10 + j["linia"]["dash"]["przerwa"] = 8 + j["linia"]["nazwa"] = canvas.create_line( + j["cel_x"], + j["cel_y"], + j["x"], + j["y"], + fill="gold", + dash=(j["linia"]["dash"]["kropka"], j["linia"]["dash"]["przerwa"]), + width=2, + dashoffset=0, + capstyle="round", + tags="linie") wybrana_jednostka = None if zasieg_podglad: diff --git a/Sand_2.py b/Sand_2.py new file mode 100644 index 0000000..ceae397 --- /dev/null +++ b/Sand_2.py @@ -0,0 +1,606 @@ +import arcade +import arcade.gui +import random +# ===================================================== +# USTAWIENIA +# ===================================================== + +CELL_SIZE = 5 + +GRID_WIDTH = 240 +GRID_HEIGHT = 160 + +SCREEN_WIDTH = GRID_WIDTH * CELL_SIZE +SCREEN_HEIGHT = GRID_HEIGHT * CELL_SIZE + +TITLE = "Silnik Piaskownicy" + +FPS = 60 + +# ===================================================== +# MATERIAŁY +# ===================================================== + +PUSTE = 0 +PIASEK = 1 +ZWIR = 2 +WODA = 3 +KAMIEN = 4 +MOKRY_PIASEK = 5 +AIR=6 +LAWA=7 + +KOLORY = { + PUSTE: arcade.color.BLACK, + PIASEK: (235, 210, 70), + ZWIR: (140, 140, 140), + WODA: (50, 120, 255), + KAMIEN: (80, 80, 80), + MOKRY_PIASEK: (205,180,40), + AIR:(248,248,248), + LAWA: (200,40,40) +} + +# ===================================================== +# KLASA ŚWIATA +# ===================================================== + +class World: + + def __init__(self): + + self.width = GRID_WIDTH + self.height = GRID_HEIGHT + + # Szybka tablica 1D + self.grid = [PUSTE] * (self.width * self.height) + + def index(self, x, y): + x = int(x) + y = int(y) + + return y * self.width + x + + def inside(self, x, y): + return ( + 0 <= x < self.width and + 0 <= y < self.height + ) + + def get(self, x, y): + + if not self.inside(x, y): + return PUSTE + + return self.grid[self.index(x, y)] + + def set(self, x, y, value): + + if not self.inside(x, y): + return + + self.grid[self.index(x, y)] = value + + def clear(self): + + self.grid[:] = [PUSTE] * (self.width * self.height) + + def swap(self, x1, y1, x2, y2): + + i1 = self.index(x1, y1) + i2 = self.index(x2, y2) + + self.grid[i1], self.grid[i2] = ( + self.grid[i2], + self.grid[i1] + ) + +# ===================================================== +# GŁÓWNE OKNO +# ===================================================== + +class Game(arcade.Window): + + def __init__(self): + + super().__init__( + SCREEN_WIDTH, + SCREEN_HEIGHT, + TITLE, + update_rate=1 / FPS + ) + + arcade.set_background_color(arcade.color.BLACK) + + self.world_old = World() + self.world_new = World() + + # Wybrany materiał + self.current_material = PIASEK + + # Rozmiar pędzla + self.brush_size = 3 + + # Czy mysz jest wciśnięta + self.mouse_down = False + + # Pozycja myszy + self.mouse_x = 0 + self.mouse_y = 0 + + # Stan gry + self.paused = False + + # Tekst interfejsu + self.info_text = arcade.Text( + "", + 10, + SCREEN_HEIGHT - 25, + arcade.color.WHITE, + 14 + ) + self.manager = arcade.gui.UIManager() + self.manager.enable() + + self.manager = arcade.gui.UIManager() + self.manager.enable() + + # Główny układ pozycjonujący (zastępuje UIAnchorWidget) + self.anchor_layout = arcade.gui.UIAnchorLayout() + + # Układ pionowy dla elementów wewnątrz menu + self.v_box = arcade.gui.UIBoxLayout() + + # Poprawione: definicja opcji pisana małą literą + opcje = ["Piasek", "Żwir", "Woda","Kamień","Mokry piasek","Powietrze","Lawa"] + + # Tworzenie widgetu listy wybieranej + self.dropdown = arcade.gui.UIDropdown( + default=opcje[0], # Wartość domyślna (pierwszy element) + options=opcje, # Lista dostępnych opcji + width=200 + ) + + # Przypisanie akcji po zmianie wyboru + self.dropdown.on_change = self.on_dropdown_change + + # Dodanie listy wybieranej do pionowego kontenera + self.v_box.add(self.dropdown) + + self.anchor_layout.add( + child=self.v_box, + anchor_x="right", + anchor_y="top" + ) + + # Dodanie całego układu do menedżera UI + self.manager.add(self.anchor_layout) + + def can_move(self, x, y): + return self.world_old.get(x, y) == PUSTE and self.world_new.get(x, y) == PUSTE + + def on_dropdown_change(self, event: arcade.gui.UIOnChangeEvent): + print(f"Zmieniono z: {event.old_value} na: {event.new_value}") + if event.new_value=="Piasek": + self.current_material = PIASEK + elif event.new_value=="Żwir": + self.current_material = ZWIR + elif event.new_value=="Woda": + self.current_material = WODA + elif event.new_value=="Kamień": + self.current_material = KAMIEN + elif event.new_value=="Mokry piasek": + self.current_material = MOKRY_PIASEK + elif event.new_value=="Powietrze": + self.current_material = AIR + elif event.new_value=="Lawa": + self.current_material = LAWA + + + def update_info(self): + + self.info_text.text = ( + f"Materiał: {self.material_name()} | " + f"Pędzel: {self.brush_size} | " + f"Pauza: {self.paused}" + ) + + def material_name(self): + + nazwy = { + PUSTE: "Puste", + PIASEK: "Piasek", + ZWIR: "Żwir", + WODA: "Woda", + KAMIEN: "Kamień", + MOKRY_PIASEK: "Mokry piasek", + AIR:"Powietrze", + LAWA:"Lawa" + } + + return nazwy[self.current_material] + # ============================================== + + def on_update(self, delta_time): + + if self.paused: + return + + world_old = self.world_old + world_new = self.world_new + + # Najpierw kopiujemy cały stan starego świata + world_new.grid[:] = world_old.grid[:] + + for y in range(1, world_old.height): + for x in range(1, world_old.width): + + material = world_old.get(x, y) + + if material == PIASEK: + self.update_sand(x, y) + + elif material == ZWIR: + self.update_zwir(x, y) + + elif material == KAMIEN: + self.update_rock(x, y) + + elif material == WODA: + self.update_woda(x, y) + + elif material == MOKRY_PIASEK: + self.update_wet_sand(x,y) + + elif material == AIR: + self.update_air(x,y) + + elif material == LAWA: + self.update_lawa(x,y) + + # Zamiana światów po zakończeniu całej klatki + self.world_old, self.world_new = ( + self.world_new, + self.world_old + ) + + if self.mouse_down: + gx = int(self.mouse_x // CELL_SIZE) + gy = int(self.mouse_y // CELL_SIZE) + + self.paint(gx, gy) + + # ============================================== + + def on_draw(self): + + self.clear() + + world = self.world_old + + for y in range(world.height): + for x in range(world.width): + + material = world.get(x, y) + + if material == PUSTE: + continue + + arcade.draw_rect_filled( + arcade.LBWH( + x * CELL_SIZE, + y * CELL_SIZE, + CELL_SIZE, + CELL_SIZE + ), + KOLORY[material] + ) + + # reszta rysowania... + + gx = self.mouse_x // CELL_SIZE + gy = self.mouse_y // CELL_SIZE + + brush_pixels = self.brush_size * CELL_SIZE + + center_x = gx * CELL_SIZE + CELL_SIZE / 2 + center_y = gy * CELL_SIZE + CELL_SIZE / 2 + + rect = arcade.XYWH( + center_x, + center_y, + brush_pixels, + brush_pixels, + ) + + arcade.draw_rect_outline( + rect, + arcade.color.WHITE, + border_width=2, + ) + + self.update_info() + + self.info_text.draw() + + self.manager.draw() + + self.world_old=self.world_new + + def czy_dotyka(self,x,y,czego,na_co): + world_old = self.world_old + world_new = self.world_new + if world_old.get(x, y - 1) == czego: + world_new.set(x, y, na_co) + elif world_old.get(x - 1, y - 1) == czego: + world_new.set(x, y, na_co) + elif world_old.get(x + 1, y - 1) == czego: + world_new.set(x, y, na_co) + elif world_old.get(x + 1, y) == czego: + world_new.set(x, y, na_co) + elif world_old.get(x - 1, y) == czego: + world_new.set(x, y, na_co) + elif world_old.get(x - 1, y + 1) == czego: + world_new.set(x, y, na_co) + elif world_old.get(x, y + 1) == czego: + world_new.set(x, y, na_co) + elif world_old.get(x + 1, y + 1) == czego: + world_new.set(x, y, na_co) + + def update_sand(self, x, y): + + world_old = self.world_old + world_new = self.world_new + + kierunek = random.choice([-1, 1]) + szansa_w_wodzie=random.choice([True, False]) + # dół + if world_old.get(x, y - 1) == PUSTE: + world_new.swap(x,y,x,y - 1) + + + # dół-lewo / dół-prawo + elif PUSTE == world_old.get(x + kierunek, y - 1): + if self.can_move(x + kierunek, y - 1): + world_new.swap(x, y, x + kierunek, y - 1) + elif world_old.get( x - kierunek, y - 1) == PUSTE: + if self.can_move(x - kierunek, y - 1): + world_new.swap(x, y, x - kierunek, y - 1) + + # W wodzie + elif world_old.get(x, y - 1) == WODA and szansa_w_wodzie: + world_new.swap(x,y,x,y - 1) + world_new.set(x,y-1,MOKRY_PIASEK) + elif world_old.get( x + kierunek, y - 1) == WODA and szansa_w_wodzie: + world_new.swap(x, y, x + kierunek, y - 1) + world_new.set(x+kierunek, y - 1, MOKRY_PIASEK) + elif world_old.get( x - kierunek, y - 1) == WODA and szansa_w_wodzie: + world_new.swap(x, y, x - kierunek, y - 1) + world_new.set(x - kierunek, y - 1, MOKRY_PIASEK) + elif world_old.get( x +1, y-1) == WODA or world_old.get( x , y - 1) == WODA or world_old.get( x-1, y-1) == WODA or world_old.get( x - 1, y) == WODA or world_old.get( x - 1, y + 1) == WODA or world_old.get( x, y+1) == WODA or world_old.get( x +1, y +1) == WODA or world_old.get( x +1, y) == WODA: + world_new.set(x, y, MOKRY_PIASEK) + szansa_na_znikniencie_wody=random.choice([True, False]) + if szansa_na_znikniencie_wody: + self.czy_dotyka(x,y,WODA,MOKRY_PIASEK) + + def update_zwir(self,x,y): + world_old = self.world_old + world_new = self.world_new + if world_old.get(x, y - 1) == PUSTE: + world_new.swap(x,y,x, y - 1) + for kierunek in random.choice([-1, 1]), random.choice([1, -1]): + skos_x = x + kierunek + skos_y = y - 1 + + dol_x = x + kierunek + dol_y = y - 2 + + if world_old.get(skos_x, skos_y) == PUSTE and world_old.get(dol_x, dol_y) == PUSTE: + if self.can_move(skos_x, skos_y): + world_new.swap( x, y, skos_x, skos_y) + break + def update_rock(self,x,y): + world_new = self.world_new + world_old = self.world_old + if world_old.get(x, y - 1) == PUSTE and self.can_move(x,y-1): + world_new.swap(x, y, x, y - 1) + + def update_woda(self, x, y): + world_new = self.world_new + world_old = self.world_old + kierunek = random.choice([-1, 1]) + # dół + if world_old.get(x, y - 1) == PUSTE: + world_new.swap(x,y,x,y - 1) + + # dół-lewo / dół-prawo + elif world_old.get( x +1, y - 1) == PUSTE: + world_new.swap(x, y, x + 1, y - 1) + elif world_old.get( x - 1, y - 1) == PUSTE: + world_new.swap(x, y, x - 1, y - 1) + + # lewo/prawo + elif ( + world_old.get(x - 1, y) == PUSTE + and world_old.get(x + 1, y) == PUSTE + ): + world_new.swap(x, y, x + 1, y) + + elif world_old.get(x + kierunek, y) == PUSTE: + world_new.swap(x, y, x + kierunek, y) + + elif world_old.get(x - kierunek, y) == PUSTE: + world_new.swap(x, y, x - kierunek, y) + + self.czy_dotyka(x,y,LAWA,AIR) + + def update_wet_sand(self, x, y): + + world_old = self.world_old + world_new = self.world_new + + kierunek = random.choice([-1, 1]) + szansa_w_wodzie=random.choice([True, False]) + if world_old.get(x, y - 1) == PUSTE: + world_new.swap(x,y,x,y - 1) + + + # dół-lewo / dół-prawo + elif PUSTE == world_old.get(x + kierunek, y - 1): + if self.can_move(x + kierunek, y - 1): + world_new.swap(x, y, x + kierunek, y - 1) + elif world_old.get( x + kierunek, y - 1) == PUSTE: + if self.can_move(x + kierunek, y - 1): + world_new.swap(x, y, x + kierunek, y - 1) + # W wodzie + elif world_old.get(x, y - 1) == WODA and szansa_w_wodzie: + world_new.swap(x,y,x,y - 1) + elif world_old.get( x + kierunek, y - 1) == WODA and szansa_w_wodzie: + world_new.swap(x, y, x + kierunek, y - 1) + elif world_old.get( x + kierunek, y - 1) == WODA and szansa_w_wodzie: + world_new.swap(x, y, x + kierunek, y - 1) + + def update_air(self,x,y): + world_old = self.world_old + world_new = self.world_new + kierunekx = random.choice([-1,0, 1]) + kieruneky = random.choice([-1,0, 1]) + lista = [False] * 10 + [True] + czy_ruszyc = random.choice(lista) + if world_old.get(x, y + 1) != PUSTE: + world_new.swap(x, y, x, y + 1) + elif self.can_move(x + kierunekx, y +kieruneky) and czy_ruszyc: + world_new.swap(x, y, x + kierunekx, y+kieruneky) + + def update_lawa(self,x,y): + world_new = self.world_new + world_old = self.world_old + kierunek = random.choice([-1, 1]) + if random.random() < 0.9: + return + # dół + if world_old.get(x, y - 1) == PUSTE: + world_new.swap(x, y, x, y - 1) + + # dół-lewo / dół-prawo + elif world_old.get(x + 1, y - 1) == PUSTE: + world_new.swap(x, y, x + 1, y - 1) + elif world_old.get(x - 1, y - 1) == PUSTE: + world_new.swap(x, y, x - 1, y - 1) + + # lewo/prawo + elif ( + world_old.get(x - 1, y) == PUSTE + and world_old.get(x + 1, y) == PUSTE + ): + world_new.swap(x, y, x + 1, y) + + elif world_old.get(x + kierunek, y) == PUSTE: + world_new.swap(x, y, x + kierunek, y) + + elif world_old.get(x - kierunek, y) == PUSTE: + world_new.swap(x, y, x - kierunek, y) + + self.czy_dotyka(x,y,WODA,KAMIEN) + + def on_key_press(self,key, modifiers): + + if key == arcade.key.KEY_1: + self.current_material = PIASEK + + elif key == arcade.key.KEY_2: + self.current_material = ZWIR + + elif key == arcade.key.KEY_3: + self.current_material = WODA + + elif key == arcade.key.KEY_4: + self.current_material = KAMIEN + + elif key == arcade.key.KEY_5: + self.current_material = MOKRY_PIASEK + + elif key == arcade.key.KEY_6: + self.current_material = AIR + + elif key == arcade.key.KEY_7: + self.current_material = LAWA + + elif key == arcade.key.C: + self.world_old.clear() + + elif key == arcade.key.SPACE: + self.paused = not self.paused + # ============================================== + + def on_mouse_press(self, x, y, button, modifiers): + + self.mouse_down = True + + self.mouse_x = x + self.mouse_y = y + + gx = x // CELL_SIZE + gy = y // CELL_SIZE + + self.paint(gx, gy) + + def on_mouse_release(self, x, y, button, modifiers): + + self.mouse_down = False + + def on_mouse_motion(self, x, y, dx, dy): + + self.mouse_x = x + self.mouse_y = y + + def on_mouse_drag(self, x, y, dx, dy, buttons, modifiers): + + self.mouse_x = x + self.mouse_y = y + + def on_mouse_scroll(self, x, y, scroll_x, scroll_y): + + self.brush_size += scroll_y + + if self.brush_size < 1: + self.brush_size = 1 + + if self.brush_size > 20: + self.brush_size = 20 + + def paint(self, grid_x, grid_y): + + grid_x = int(grid_x) + grid_y = int(grid_y) + + r = int(self.brush_size) + + for dy in range(-r, r + 1): + for dx in range(-r, r + 1): + + if dx * dx + dy * dy > r * r: + continue + + x = grid_x + dx + y = grid_y + dy + + self.world_old.set( + x, + y, + self.current_material + ) + +# ===================================================== +# START PROGRAMU +# ===================================================== + +def main(): + + Game() + + arcade.run() + + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/sand.py b/sand.py index 41ed892..67df4cf 100644 --- a/sand.py +++ b/sand.py @@ -1,95 +1,284 @@ -from tkinter import * -from random import randrange - -promien = 5 -listapixeli = [] +from random import random +import arcade -def zmien_promien(wartosc): - global promien - promien = int(wartosc) - skrajny_x = root.winfo_pointerx() - skrajny_y = root.winfo_pointery() - canvas_x = skrajny_x - canvas.winfo_rootx() - canvas_y = skrajny_y - canvas.winfo_rooty() - odswiez_pozycje_kropki(canvas_x, canvas_y) + +CELL_SIZE = 5 + +GRID_WIDTH = 240 +GRID_HEIGHT = 160 + +WIDTH = GRID_WIDTH * CELL_SIZE +HEIGHT = GRID_HEIGHT * CELL_SIZE -def odswiez_pozycje_kropki(x, y): - global promien - canvas.coords(podonzaj, x - promien, y - promien, x + promien, y + promien) +PUSTE = 0 +PIASEK = 1 +ZWIR = 2 +WODA = 3 +KAMIEN = 4 -def on_mouse_motion(event): - odswiez_pozycje_kropki(event.x, event.y) + +KOLORY = { + PIASEK: arcade.color.YELLOW, + ZWIR: arcade.color.GRAY, + WODA: arcade.color.BLUE, + KAMIEN: arcade.color.DARK_GRAY, +} -def skroluj_suwak(event): - obecna = vertical_scale.get() +class Gra(arcade.Window): - if event.num == 4: - nowa = obecna + 1 - elif event.num == 5: - nowa = obecna - 1 - else: - nowa = obecna + def __init__(self): + super().__init__(WIDTH, HEIGHT, "Mini Sand") - vertical_scale.set(nowa) + # płaska tablica zamiast listy list + self.grid = [0] * (GRID_WIDTH * GRID_HEIGHT) + + self.wybrany = PIASEK + self.rozmiar_pedzla = 3 -def lewywci(event): - canvas.create_rectangle(event.x, event.y, event.x + 1, event.y + 1) - listapixeli.append([event.x, event.y]) -def czas(event=None): - canvas.delete("all") - global t - global listapixeli - for x, y in listapixeli: - listapixeli.remove([x, y]) - if y == canvas.winfo_height() - 100: - listapixeli.append([x, y]) - canvas.create_rectangle(x, y, x + 1, y + 1) - elif [x, y + 1] not in listapixeli: - listapixeli.append([x, y + 1]) - canvas.create_rectangle(x, y + 1, x + 1, y + 2) - elif [x + 1, y + 1] not in listapixeli and [x - 1, y + 1] not in listapixeli: - if t: - listapixeli.append([x + 1, y + 1]) - canvas.create_rectangle(x + 1, y + 1, x + 2, y + 2) - t=False - else: - listapixeli.append([x - 1, y + 1]) - canvas.create_rectangle(x - 1, y + 1, x, y + 2) - t=True - elif [x + 1, y + 1] not in listapixeli: - listapixeli.append([x + 1, y + 1]) - canvas.create_rectangle(x + 1, y + 1, x + 2, y + 2) - elif [x - 1, y + 1] not in listapixeli: - listapixeli.append([x - 1, y + 1]) - canvas.create_rectangle(x - 1, y + 1, x, y + 2) - else: - listapixeli.append([x, y]) - canvas.create_rectangle(x, y, x + 1, y + 1) + self.info = arcade.Text( + "", + 10, + HEIGHT - 25, + arcade.color.WHITE, + 14 + ) - # print(listapixeli) + self.aktualizuj_napis() -t = True -root = Tk() -canvas = Canvas(root, bg="white", highlightthickness=0) -canvas.pack(fill="both", expand=True) + def indeks(self,x,y): + return y * GRID_WIDTH + x -vertical_scale = Scale(root, from_=1, to=50) # , command=zmien_promien) -vertical_scale.place(x=0, rely=0.5, anchor='sw') -vertical_scale.set(1) + def on_draw(self): + self.clear((30, 30, 30)) -podonzaj = canvas.create_rectangle(100, 100, 110, 110, fill="green") + piasek = [] + zwir = [] -root.bind("", lambda e: [on_mouse_motion, czas]) -# root.bind_all("", skroluj_suwak) -# root.bind_all("", skroluj_suwak) -root.bind("", lewywci) -root.bind("", czas) -root.mainloop() + for y in range(GRID_HEIGHT-1,-1,-1): + for x in range(GRID_WIDTH): + + material = self.grid[y * GRID_WIDTH + x] + + if material == PIASEK: + piasek.append( + ( + x * CELL_SIZE + CELL_SIZE / 2, + y * CELL_SIZE + CELL_SIZE / 2 + ) + ) + + elif material == ZWIR: + zwir.append( + ( + x * CELL_SIZE + CELL_SIZE / 2, + y * CELL_SIZE + CELL_SIZE / 2 + ) + ) + + if piasek: + arcade.draw_points( + piasek, + arcade.color.YELLOW, + CELL_SIZE + ) + + if zwir: + arcade.draw_points( + zwir, + arcade.color.GRAY, + CELL_SIZE + ) + + self.info.draw() + + + + def aktualizuj_napis(self): + + material = "Piasek" if self.wybrany == PIASEK else "Żwir" + + self.info.text = ( + f"1 Piasek | 2 Żwir | {material} | Pędzel {self.rozmiar_pedzla}" + ) + + + + def on_key_press(self,key,mod): + + if key == arcade.key.KEY_1: + self.wybrany = PIASEK + + elif key == arcade.key.KEY_2: + self.wybrany = ZWIR + + + elif key == arcade.key.BRACKETLEFT: + self.rozmiar_pedzla=max( + 1, + self.rozmiar_pedzla-1 + ) + + + elif key == arcade.key.BRACKETRIGHT: + self.rozmiar_pedzla+=1 + + + self.aktualizuj_napis() + + + + def on_mouse_scroll(self,x,y,sx,sy): + + self.rozmiar_pedzla += sy + + self.rozmiar_pedzla=max( + 1, + self.rozmiar_pedzla + ) + + self.aktualizuj_napis() + + + + def on_mouse_press(self,x,y,b,m): + self.dodaj(x,y) + + + def on_mouse_drag(self,x,y,dx,dy,b,m): + self.dodaj(x,y) + + + + def dodaj(self,x,y): + + gx=int(x/CELL_SIZE) + gy=int(y/CELL_SIZE) + + r=self.rozmiar_pedzla + + + for yy in range(-r,r+1): + for xx in range(-r,r+1): + + if xx*xx+yy*yy <= r*r: + + nx=gx+xx + ny=gy+yy + + if ( + 0 <= nx < GRID_WIDTH + and + 0 <= ny < GRID_HEIGHT + ): + self.grid[ny * GRID_WIDTH + nx] = self.wybrany + + def on_update(self, dt): + + for y in range(1, GRID_HEIGHT): + for x in range(GRID_WIDTH): + + material = self.grid[self.indeks(x, y)] + + if material == PUSTE: + continue + + if material == PIASEK: + self.ruch_piasku(x, y) + + elif material == ZWIR: + self.ruch_zwiru(x, y) + + elif material == WODA: + self.ruch_wody(x, y) + elif material == KAMIEN: + self.ruch_kamienia(x, y) + + def puste(self, x, y): + if x < 0 or x >= GRID_WIDTH: + return False + + if y < 0 or y >= GRID_HEIGHT: + return False + + return self.grid[self.indeks(x, y)] == PUSTE + + def ruch_piasku(self, x, y): + + if y == 0: + return + + if self.puste(x, y - 1): + self.zamien(x, y, x, y - 1) + return + + strony = [-1, 1] + + random.shuffle(strony) + + for dx in strony: + + nx = x + dx + + if 0 <= nx < GRID_WIDTH: + + if self.puste(nx, y - 1): + self.zamien(x, y, nx, y - 1) + return + + def ruch_zwiru(self, x, y): + + if y == 0: + return + + if self.puste(x, y - 1): + self.zamien(x, y, x, y - 1) + + def ruch_wody(self, x, y): + + if y == 0: + return + + if self.puste(x, y - 1): + self.zamien(x, y, x, y - 1) + return + + strony = [-1, 1] + + random.shuffle(strony) + + for dx in strony: + + nx = x + dx + + if 0 <= nx < GRID_WIDTH: + + if self.puste(nx, y): + self.zamien(x, y, nx, y) + return + + def ruch_kamienia(self, x, y): + + if y == 0: + return + + if self.puste(x, y - 1): + self.zamien(x, y, x, y - 1) + def zamien(self, x1, y1, x2, y2): + + i1 = self.indeks(x1, y1) + i2 = self.indeks(x2, y2) + + self.grid[i1], self.grid[i2] = self.grid[i2], self.grid[i1] + + + +Gra() +arcade.run() \ No newline at end of file diff --git a/testy.py b/testy.py index 11ebb31..1586420 100644 --- a/testy.py +++ b/testy.py @@ -1,49 +1 @@ -from tkinter import * - -root = Tk() -root.geometry("300x200") - - -def aktualizuj_kolor(wartosc_z_suwaka): - v = float(wartosc_z_suwaka) - - if v > 0.4: - b = "00" - elif v < 0.38: - b = "FF" - else: - procent = (v - 0.38) / 0.02 - odwrocona_wartosc = int((1 - procent) * 255) - odwrocona_wartosc = max(0, min(255, odwrocona_wartosc)) - b = f"{odwrocona_wartosc:02X}" - if v < 0.40 or v > 0.45: - r = "00" - else: - if v <= 0.425: - procent = (v - 0.40) / 0.025 - else: - procent = (0.45 - v) / 0.025 - - wartosc_r = int(procent * 255) - wartosc_r = max(0, min(255, wartosc_r)) - - r = f"{wartosc_r:02X}" - g = "00" - if abs(v - 0.4) < 0.005: - b = "FF" - r = "FF" - g = "FF" - - kolor = f"#{r}{g}{b}" - canvas.itemconfig(c, fill=kolor) - - -canvas = Canvas(root, bg="white", highlightthickness=0, width=150, height=150) -canvas.pack(side=LEFT, padx=20) - -c = canvas.create_rectangle(20, 20, 120, 120, fill="#FF00FF") - -val = Scale(root, from_=0.0, to=1.0, resolution=0.01, command=aktualizuj_kolor) -val.pack(side=RIGHT, padx=20) - -root.mainloop() +print (*([False] * 10 + [True]),sep=', ') \ No newline at end of file