tanks/sand.py

284 lines
5.5 KiB
Python
Raw Normal View History

2026-08-04 13:19:11 +02:00
from random import random
import arcade
CELL_SIZE = 5
GRID_WIDTH = 240
GRID_HEIGHT = 160
WIDTH = GRID_WIDTH * CELL_SIZE
HEIGHT = GRID_HEIGHT * CELL_SIZE
PUSTE = 0
PIASEK = 1
ZWIR = 2
WODA = 3
KAMIEN = 4
KOLORY = {
PIASEK: arcade.color.YELLOW,
ZWIR: arcade.color.GRAY,
WODA: arcade.color.BLUE,
KAMIEN: arcade.color.DARK_GRAY,
}
class Gra(arcade.Window):
def __init__(self):
super().__init__(WIDTH, HEIGHT, "Mini Sand")
# płaska tablica zamiast listy list
self.grid = [0] * (GRID_WIDTH * GRID_HEIGHT)
self.wybrany = PIASEK
self.rozmiar_pedzla = 3
self.info = arcade.Text(
"",
10,
HEIGHT - 25,
arcade.color.WHITE,
14
)
self.aktualizuj_napis()
def indeks(self,x,y):
return y * GRID_WIDTH + x
def on_draw(self):
self.clear((30, 30, 30))
piasek = []
zwir = []
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()