This commit is contained in:
tymek 2026-08-04 13:19:11 +02:00
parent a3e3f33c80
commit e8214d71a3
5 changed files with 941 additions and 175 deletions

View file

@ -4,7 +4,7 @@
<content url="file://$MODULE_DIR$"> <content url="file://$MODULE_DIR$">
<excludeFolder url="file://$MODULE_DIR$/.venv" /> <excludeFolder url="file://$MODULE_DIR$/.venv" />
</content> </content>
<orderEntry type="jdk" jdkName="Python 3.12" jdkType="Python SDK" /> <orderEntry type="jdk" jdkName="Python 3.10 (zolwik)" jdkType="Python SDK" />
<orderEntry type="sourceFolder" forTests="false" /> <orderEntry type="sourceFolder" forTests="false" />
</component> </component>
</module> </module>

View file

@ -44,15 +44,17 @@ def animuj(krok):
j["x"] = j["cel_x"] j["x"] = j["cel_x"]
j["y"] = j["cel_y"] j["y"] = j["cel_y"]
j["linia"]["nazwa"] = None
j["linia"]["prze"] = 0
koniec_planowania = True koniec_planowania = True
canvas.delete("linie")
return return
for j in jednostki: for j in jednostki:
dx = (j["cel_x"] - j["x"]) / (ANIMACJA_KROKI - krok) dx = (j["cel_x"] - j["x"]) / (ANIMACJA_KROKI - krok)
dy = (j["cel_y"] - j["y"]) / (ANIMACJA_KROKI - krok) dy = (j["cel_y"] - j["y"]) / (ANIMACJA_KROKI - krok)
canvas.move(j["rect"], dx, dy) canvas.move(j["sprite"], dx, dy)
canvas.move(j["text"], dx, dy)
j["x"] += dx j["x"] += dx
j["y"] += dy j["y"] += dy
@ -66,11 +68,23 @@ def animuj(krok):
else: else:
roznica += 360 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)) root.after(15, lambda: animuj(krok + 1))
def zmien_predkosc(*args): def zmien_predkosc(*args):
if not jednostki: if not jednostki:
return return
@ -97,12 +111,6 @@ def zmien_predkosc(*args):
j["cel_x"] = j["x"] j["cel_x"] = j["x"]
j["cel_y"] = j["y"] j["cel_y"] = j["y"]
canvas.itemconfig(
j["rect"],
outline="black",
width=1
)
wybrana_jednostka = None wybrana_jednostka = None
aktualna_strona = "USA" aktualna_strona = "USA"
@ -227,18 +235,38 @@ def ustaw_pojazd(event):
placed_units.append((x1, y1, x2, y2)) 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) img_org = Image.open(nazwa_pliku)
except:
nazwa_pliku = f"obraz_tk_3.png"
img_org = Image.open(nazwa_pliku)
img_org.thumbnail(
(size_x, size_y),
Image.Resampling.LANCZOS
)
img_tk = ImageTk.PhotoImage(img_org) img_tk = ImageTk.PhotoImage(img_org)
sprite = canvas.create_image( sprite = canvas.create_image(
300, event.x,
200, event.y,
image=img_tk 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({ jednostki.append({
"nazwa": nazwa, "nazwa": nazwa,
"strona": strona, "strona": strona,
@ -254,7 +282,7 @@ def ustaw_pojazd(event):
"img_org": img_org, "img_org": img_org,
"img_tk": img_tk, "img_tk": img_tk,
"kat": 0, "kat": 0 if strona == "GER" else 180,
"hp": 100, "hp": 100,
@ -435,7 +463,7 @@ def start():
else: else:
SKALA_JEDNOSTKI = 3 SKALA_JEDNOSTKI = 3
mnoznik_ruchu = 0.3 mnoznik_ruchu = 0.3
SKALA_JEDNOSTKI *= 3
BONUS_RUCHU = int( BONUS_RUCHU = int(
predkosc_ruchu.get().replace("x", "") predkosc_ruchu.get().replace("x", "")
) )
@ -530,18 +558,18 @@ kolejnosc_pojazdow = [
] ]
pojazdy = [ pojazdy = [
# ==================== USA (Po kolei numerycznie) ==================== # ==================== USA (Po kolei numerycznie) ====================
{"naz": "M3 St.", "x": 0, "y": 0, "wys": 2, "sze": 2, "ruch": 120}, {"naz": "M3 St.", "x": 0, "y": 0, "wys": 2, "sze": 3, "ruch": 120},
{"naz": "M22", "x": 0, "y": 0, "wys": 1, "sze": 2, "ruch": 140}, {"naz": "M22", "x": 0, "y": 0, "wys": 2, "sze": 3, "ruch": 140},
{"naz": "M3 GMC", "x": 0, "y": 0, "wys": 2, "sze": 3, "ruch": 110}, {"naz": "M3 GMC", "x": 0, "y": 0, "wys": 2, "sze": 4, "ruch": 110},
{"naz": "M15 CGMC", "x": 0, "y": 0, "wys": 2, "sze": 3, "ruch": 100}, {"naz": "M15 CGMC", "x": 0, "y": 0, "wys": 2, "sze": 4, "ruch": 100},
{"naz": "M3 Lee", "x": 0, "y": 0, "wys": 2, "sze": 3, "ruch": 80}, {"naz": "M3 Lee", "x": 0, "y": 0, "wys": 3, "sze": 3, "ruch": 80},
{"naz": "LVT", "x": 0, "y": 0, "wys": 3, "sze": 3, "ruch": 70}, {"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": "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": "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.IIIF", "x": 0, "y": 0, "wys": 2, "sze": 3, "ruch": 95},
{"naz": "Pz.IIIC", "x": 0, "y": 0, "wys": 2, "sze": 2, "ruch": 105}, {"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": "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": "Beutepanzer IV", "x": 0, "y": 0, "wys": 3, "sze": 4, "ruch": 40},
{"naz": "A7V", "x": 0, "y": 0, "wys": 4, "sze": 6, "ruch": 30}, {"naz": "A7V", "x": 0, "y": 0, "wys": 4, "sze": 6, "ruch": 30},
@ -615,7 +643,7 @@ def planowanie(event):
for j in jednostki: for j in jednostki:
if j["rect"] in klikniete or j["text"] in klikniete: if j["sprite"] in klikniete:
if j["strona"] != aktualna_strona: if j["strona"] != aktualna_strona:
return return
@ -625,11 +653,6 @@ def planowanie(event):
wybrana_jednostka = j wybrana_jednostka = j
canvas.itemconfig(
j["rect"],
outline="yellow",
width=3
)
global zasieg_podglad global zasieg_podglad
if zasieg_podglad: if zasieg_podglad:
@ -645,7 +668,7 @@ def planowanie(event):
fill="chartreuse3", fill="chartreuse3",
stipple="gray50", stipple="gray50",
activestipple="gray12", activestipple="gray12",
outline="green", outline="forestgreen",
width=2 width=2
) )
lbl_aktywny_pojazd.config( lbl_aktywny_pojazd.config(
@ -658,7 +681,7 @@ def planowanie(event):
dy = event.y - wybrana_jednostka["y"] dy = event.y - wybrana_jednostka["y"]
wybrana_jednostka["kat_docelowy"] = degrees( wybrana_jednostka["kat_docelowy"] = degrees(
atan2(dy, dx) atan2(dy, dx)
) )+180
odleglosc = (dx * dx + dy * dy) ** 0.5 odleglosc = (dx * dx + dy * dy) ** 0.5
if odleglosc > wybrana_jednostka["ruch"]: if odleglosc > wybrana_jednostka["ruch"]:
@ -681,25 +704,21 @@ def planowanie(event):
for j in jednostki: for j in jednostki:
if j["wykonal_ruch"]: if j["wykonal_ruch"]:
#canvas.delete("linie")
if j["linia"]["nazwa"] is None: if j["linia"]["nazwa"] is None:
j["linia"]["dash"]["kropka"] = rand(2, 10) j["linia"]["dash"]["kropka"] = 10
j["linia"]["dash"]["przerwa"] = rand(3, 6) j["linia"]["dash"]["przerwa"] = 8
j["linia"]["nazwa"] = canvas.create_line( j["linia"]["nazwa"] = canvas.create_line(
j["cel_x"], j["cel_x"],
j["cel_y"], j["cel_y"],
j["x"], j["x"],
j["y"], j["y"],
fill="yellow", fill="gold",
dash=(j["linia"]["dash"]["kropka"], j["linia"]["dash"]["przerwa"]), dash=(j["linia"]["dash"]["kropka"], j["linia"]["dash"]["przerwa"]),
width=2,
dashoffset=0, dashoffset=0,
capstyle="round", capstyle="round",
tags="plan") tags="linie")
canvas.itemconfig(
wybrana_jednostka["rect"],
outline="black",
width=1
)
wybrana_jednostka = None wybrana_jednostka = None
if zasieg_podglad: if zasieg_podglad:

606
Sand_2.py Normal file
View file

@ -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()

339
sand.py
View file

@ -1,95 +1,284 @@
from tkinter import * from random import random
from random import randrange import arcade
promien = 5
listapixeli = []
def zmien_promien(wartosc):
global promien CELL_SIZE = 5
promien = int(wartosc)
skrajny_x = root.winfo_pointerx() GRID_WIDTH = 240
skrajny_y = root.winfo_pointery() GRID_HEIGHT = 160
canvas_x = skrajny_x - canvas.winfo_rootx()
canvas_y = skrajny_y - canvas.winfo_rooty() WIDTH = GRID_WIDTH * CELL_SIZE
odswiez_pozycje_kropki(canvas_x, canvas_y) HEIGHT = GRID_HEIGHT * CELL_SIZE
def odswiez_pozycje_kropki(x, y): PUSTE = 0
global promien PIASEK = 1
canvas.coords(podonzaj, x - promien, y - promien, x + promien, y + promien) 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): class Gra(arcade.Window):
obecna = vertical_scale.get()
if event.num == 4: def __init__(self):
nowa = obecna + 1 super().__init__(WIDTH, HEIGHT, "Mini Sand")
elif event.num == 5:
nowa = obecna - 1
else:
nowa = obecna
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): self.info = arcade.Text(
canvas.delete("all") "",
global t 10,
global listapixeli HEIGHT - 25,
for x, y in listapixeli: arcade.color.WHITE,
listapixeli.remove([x, y]) 14
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)
# print(listapixeli) self.aktualizuj_napis()
t = True def indeks(self,x,y):
root = Tk() return y * GRID_WIDTH + x
canvas = Canvas(root, bg="white", highlightthickness=0)
canvas.pack(fill="both", expand=True)
vertical_scale = Scale(root, from_=1, to=50) # , command=zmien_promien) def on_draw(self):
vertical_scale.place(x=0, rely=0.5, anchor='sw') self.clear((30, 30, 30))
vertical_scale.set(1)
podonzaj = canvas.create_rectangle(100, 100, 110, 110, fill="green") piasek = []
zwir = []
root.bind("<Motion>", lambda e: [on_mouse_motion, czas]) for y in range(GRID_HEIGHT-1,-1,-1):
# root.bind_all("<Button-4>", skroluj_suwak) for x in range(GRID_WIDTH):
# root.bind_all("<Button-5>", skroluj_suwak)
root.bind("<B1-Motion>", lewywci) material = self.grid[y * GRID_WIDTH + x]
root.bind("<KeyPress>", czas)
root.mainloop() 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()

View file

@ -1,49 +1 @@
from tkinter import * print (*([False] * 10 + [True]),sep=', ')
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()