2026-06-24 21:49:01 +02:00
from tkinter import *
from random import randrange as rand
from tkinter import ttk
from tkinter import messagebox
from PIL import ImageTk , Image
from noise import pnoise2
from random import uniform as uni
from math import radians , cos , sin , atan2 , sqrt , pi , degrees
from tkinter import PhotoImage
import os
def pobierz_obrazek_jednostki ( nazwa ) :
plik = f " { nazwa } min.png "
if plik not in obrazki_jednostek :
try :
obrazki_jednostek [ plik ] = PhotoImage ( file = plik )
except Exception as e :
print ( " Brak obrazka: " , plik , e )
return None
return obrazki_jednostek [ plik ]
def zawsze ( ) :
global jednostki
for j in jednostki :
if j [ " linia " ] [ " nazwa " ] is not None :
canvas . itemconfig ( j [ " linia " ] [ " nazwa " ] , dashoffset = j [ " linia " ] [ " prze " ] )
j [ " linia " ] [ " prze " ] + = 1
if j [ " linia " ] [ " prze " ] > = j [ " linia " ] [ " dash " ] [ " kropka " ] + j [ " linia " ] [ " dash " ] [ " przerwa " ] :
j [ " linia " ] [ " prze " ] = 0
root . after ( 60 , zawsze )
def animuj ( krok ) :
ANIMACJA_KROKI = 100
if krok > = ANIMACJA_KROKI :
global koniec_planowania
for j in jednostki :
j [ " x " ] = j [ " cel_x " ]
j [ " y " ] = j [ " cel_y " ]
koniec_planowania = True
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 )
j [ " x " ] + = dx
j [ " y " ] + = dy
if " kat_docelowy " in j :
roznica = j [ " kat_docelowy " ] - j [ " kat " ]
if abs ( roznica ) > 180 :
if roznica > 0 :
roznica - = 360
else :
roznica + = 360
j [ " kat " ] + = roznica * 0.15
root . after ( 15 , lambda : animuj ( krok + 1 ) )
def zmien_predkosc ( * args ) :
if not jednostki :
return
global BONUS_RUCHU
global aktualna_strona
global wybrana_jednostka
nowy_bonus = int (
predkosc_ruchu . get ( ) . replace ( " x " , " " )
)
BONUS_RUCHU = nowy_bonus
for j in jednostki :
dane = pobierz_dane_pojazdu ( j [ " nazwa " ] )
j [ " ruch " ] = int (
dane [ " ruch " ]
* mnoznik_ruchu
* BONUS_RUCHU
)
j [ " wykonal_ruch " ] = False
j [ " cel_x " ] = j [ " x " ]
j [ " cel_y " ] = j [ " y " ]
canvas . itemconfig (
j [ " rect " ] ,
outline = " black " ,
width = 1
)
wybrana_jednostka = None
aktualna_strona = " USA "
canvas . delete ( " plan " )
if jednostki :
lbl_aktywny_pojazd . config (
text = " Wybierz jednostkę USA "
)
global zasieg_podglad
if zasieg_podglad :
canvas . delete ( zasieg_podglad )
zasieg_podglad = None
def pobierz_dane_pojazdu ( nazwa ) :
BAZA_POJAZDOW = { p [ " naz " ] : p for p in pojazdy }
return BAZA_POJAZDOW . get ( nazwa )
def strona_pojazdu ( nazwa ) :
if nazwa in usa :
return " USA "
elif nazwa in IIIRzesza :
return " GER "
return None
def check_collision ( x1 , y1 , x2 , y2 ) :
for ux1 , uy1 , ux2 , uy2 in placed_units :
if not (
x2 + ODSTEP < ux1 or
x1 - ODSTEP > ux2 or
y2 + ODSTEP < uy1 or
y1 - ODSTEP > uy2
) :
return True
return False
def update_ghost ( event ) :
global ghost
if not pojazdy_do_ustawienia :
return
nazwa = pojazdy_do_ustawienia [ 0 ]
dane = pobierz_dane_pojazdu ( nazwa )
size_x = dane [ " sze " ] * SKALA_JEDNOSTKI
size_y = dane [ " wys " ] * SKALA_JEDNOSTKI
strona = strona_pojazdu ( nazwa )
kolor = " lime "
w = canvas . winfo_width ( )
granica_usa = w * 0.125
granica_ger = w * 0.875
if strona == " USA " and event . x > granica_usa :
kolor = " red "
if strona == " GER " and event . x < granica_ger :
kolor = " red "
if ghost :
canvas . delete ( ghost )
ghost = canvas . create_rectangle (
event . x - size_x / / 2 ,
event . y - size_y / / 2 ,
event . x + size_x / / 2 ,
event . y + size_y / / 2 ,
outline = kolor ,
fill = " " ,
width = 3
)
def ustaw_pojazd ( event ) :
global pojazdy_do_ustawienia , aktualny_plan , kolejka_planowania , mnoznik_ruchu
if not pojazdy_do_ustawienia :
return
nazwa = pojazdy_do_ustawienia [ 0 ]
dane = pobierz_dane_pojazdu ( nazwa )
size_x = dane [ " sze " ] * SKALA_JEDNOSTKI
size_y = dane [ " wys " ] * SKALA_JEDNOSTKI
strona = strona_pojazdu ( nazwa )
w = canvas . winfo_width ( )
granica_usa = w * 0.125
granica_ger = w * 0.875
if strona == " USA " and event . x > granica_usa :
messagebox . showwarning (
" RTS " ,
" USA można ustawiać tylko w lewej strefie! "
)
return
if strona == " GER " and event . x < granica_ger :
messagebox . showwarning (
" RTS " ,
" III Rzesza może być ustawiana tylko w prawej strefie! "
)
return
x1 = event . x - size_x / / 2
y1 = event . y - size_y / / 2
x2 = event . x + size_x / / 2
y2 = event . y + size_y / / 2
if check_collision ( x1 , y1 , x2 , y2 ) :
messagebox . showwarning ( " RTS " , " Kolizja! " )
return
placed_units . append ( ( x1 , y1 , x2 , y2 ) )
nazwa_pliku = f " { nazwa } min.png "
img_org = Image . open ( nazwa_pliku )
img_tk = ImageTk . PhotoImage ( img_org )
sprite = canvas . create_image (
300 ,
200 ,
image = img_tk
)
jednostki . append ( {
" nazwa " : nazwa ,
" strona " : strona ,
" x " : event . x ,
" y " : event . y ,
" cel_x " : event . x ,
" cel_y " : event . y ,
" sprite " : sprite ,
" img_org " : img_org ,
" img_tk " : img_tk ,
" kat " : 0 ,
" hp " : 100 ,
" wykonal_ruch " : False ,
" ruch " : int (
dane [ " ruch " ]
* mnoznik_ruchu
* BONUS_RUCHU
) ,
" linia " : { " nazwa " : None , " dash " : { " kropka " : None , " przerwa " : None } , " prze " : 0 }
} )
pojazdy_do_ustawienia . pop ( 0 )
if pojazdy_do_ustawienia :
lbl_aktywny_pojazd . config ( text = f " Ustaw: { pojazdy_do_ustawienia [ 0 ] } " )
else :
messagebox . showinfo (
" RTS " ,
" Wszystkie jednostki rozmieszczone. Rozpoczyna się planowanie. "
)
aktualny_plan = 0
kolejka_planowania . clear ( )
canvas . bind ( " <Button-1> " , planowanie )
lbl_aktywny_pojazd . config (
text = " Ustaw jednoske USA "
)
def generuj_mape_noise ( ) :
bazowe_x = canvas . winfo_toplevel ( ) . winfo_screenwidth ( )
bazowe_y = canvas . winfo_toplevel ( ) . winfo_screenheight ( )
x_w = bazowe_x
y_w = bazowe_y
wybor = jakosc_mapy . get ( )
if " Bardzo wysoka " in wybor :
pixel = 1
skala = 0.0133
elif " Wysoka " in wybor :
pixel = 2
skala = 0.0266
elif " Preferowana " in wybor :
pixel = 3
skala = 0.04
elif " Niska " in wybor :
pixel = 4
skala = 0.0533
else :
pixel = 5
skala = 0.0666
rozmiar = rozmiar_mapy . get ( )
if rozmiar == " Mała " :
pixel * = 2
skala / = 2
elif rozmiar == " Średnia " :
pass
elif rozmiar == " Duża " :
pixel = max ( 1 , round ( pixel * 0.75 ) )
skala / = 0.75
else : # Ogromna
pixel = max ( 1 , round ( pixel * 0.5 ) )
skala * = 2
max_y = y_w / / pixel
seed_x = uni ( 0 , 1000 )
seed_y = uni ( 0 , 1000 )
# print(f"Seed: {seed_x, seed_y}")
for x in range ( x_w / / pixel ) :
for y in range ( max_y ) :
szum = pnoise2 ( seed_x + x * skala , seed_y + y * skala , octaves = 3 )
val = ( szum + 1 ) / 2
v = val
g_start = 122
g_end = 160
if v < 0.28 :
r , g , b = " 00 " , " 00 " , " FF "
elif v < = 0.30 :
procent = ( v - 0.28 ) / 0.02
wygladzenie = ( 1.0 - cos ( procent * pi ) ) / 2.0
r_val = int ( wygladzenie * 255 )
g_val = int ( wygladzenie * 255 )
b_val = int ( ( 1.0 - wygladzenie ) * 255 )
r = f " { max ( 0 , min ( 255 , r_val ) ) : 02X } "
g = f " { max ( 0 , min ( 255 , g_val ) ) : 02X } "
b = f " { max ( 0 , min ( 255 , b_val ) ) : 02X } "
elif v < = 0.33 :
procent = ( v - 0.30 ) / 0.03
wygladzenie = ( 1.0 - cos ( procent * pi ) ) / 2.0
r_val = int ( ( 1.0 - wygladzenie ) * 255 )
g_val = int ( 255 - wygladzenie * ( 255 - g_start ) )
r = f " { max ( 0 , min ( 255 , r_val ) ) : 02X } "
g = f " { max ( 0 , min ( 255 , g_val ) ) : 02X } "
b = " 00 "
else :
r = " 00 "
b = " 00 "
procent_g = ( v - 0.33 ) / ( 1.0 - 0.33 )
wartosc_g = int ( g_start + procent_g * ( g_end - g_start ) )
g = f " { max ( g_start , min ( g_end , wartosc_g ) ) : 02X } "
kolor = f " # { r } { g } { b } "
canvas . create_rectangle ( x * pixel , y * pixel , ( x + 1 ) * pixel , ( y + 1 ) * pixel , fill = kolor , outline = " " )
def rysuj_pojazdy ( ) :
pixel = 1
x_w = canvas . winfo_toplevel ( ) . winfo_screenwidth ( )
y_w = canvas . winfo_toplevel ( ) . winfo_screenheight ( )
if len ( usa ) > 0 :
dzielnik_usa = ( len ( usa ) - 1 ) if len ( usa ) > 1 else 1
u = int ( y_w / ( dzielnik_usa + 1 ) )
for c in kolejnosc_pojazdow :
if c in usa :
canvas . create_rectangle (
15 ,
u - 7 ,
30 ,
u + 8 ,
fill = " black " ,
)
if len ( usa ) > 1 :
u + = int ( y_w / ( len ( usa ) + 1 ) )
if len ( IIIRzesza ) > 0 :
dzielnik_rzesza = ( len ( IIIRzesza ) - 1 ) if len ( IIIRzesza ) > 1 else 1
I = int ( y_w / ( dzielnik_rzesza + 1 ) )
for c in kolejnosc_pojazdow :
if c in IIIRzesza :
canvas . create_rectangle (
x_w - 30 ,
I - 7 ,
x_w - 15 ,
I + 8 ,
fill = " black " ,
outline = " " ,
)
if len ( IIIRzesza ) > 1 :
I + = int ( y_w / ( len ( IIIRzesza ) + 1 ) )
def start ( ) :
global SKALA_JEDNOSTKI , mnoznik_ruchu , BONUS_RUCHU
canvas . master . update_idletasks ( )
canvas . delete ( " all " )
if rozmiar_mapy . get ( ) == " Mała " :
SKALA_JEDNOSTKI = 6
mnoznik_ruchu = 1.3
elif rozmiar_mapy . get ( ) == " Średnia " :
SKALA_JEDNOSTKI = 5
mnoznik_ruchu = 1.0
elif rozmiar_mapy . get ( ) == " Duża " :
SKALA_JEDNOSTKI = 4
mnoznik_ruchu = 0.7
else :
SKALA_JEDNOSTKI = 3
mnoznik_ruchu = 0.3
BONUS_RUCHU = int (
predkosc_ruchu . get ( ) . replace ( " x " , " " )
)
for j in jednostki :
j [ " ruch " ] = int ( j [ " ruch " ] * mnoznik_ruchu )
generuj_mape_noise ( )
if pojazdy_do_ustawienia :
lbl_aktywny_pojazd . config ( text = f " Ustaw: { pojazdy_do_ustawienia [ 0 ] } " )
canvas . bind ( " <Button-1> " , ustaw_pojazd )
zawsze ( )
# --- INICJALIZACJA UTWORZENIA OKNA I BAZY DANYCH ---
root = Tk ( )
root . geometry ( " 1000x700 " )
root . attributes ( " -fullscreen " , True )
root . update ( )
root . update_idletasks ( )
kwadraty_lewe = [ " LVT " , " M3 St. " , " M3 GMC " , " M3 Lee " , " M4A3 " , " M15 CGMC " , " M22 " ]
kwadraty_prawa = [ " sd.KFz.222 " , " sd.KFz.251-9 " , " Pz.IIIF " , " Pz.IIIC " , " A7V " , " Stug IIIb " , " Beutepanzer IV " ]
zmienne_lewa = [ ]
zmienne_prawa = [ ]
baza_podgladu = {
" M3 St. " : {
" foto " : " M3.png " ,
" lista " : " Nr 1: M3 Stuart \n Zasięg: 500m | Damage: 35 | Kierunek: Obrotowy | Ilość: 1 \n HP: 200 \n Prędkość: 58 km/h \n Opis: Amerykański lekki czołg, niezwykle szybki i zwrotny na polu bitwy. \n Ciekawostka: Brytyjskie załogi nazywały go czule ' Honey ' ze względu na płynną jazdę. "
} ,
" M22 " : {
" foto " : " M22.png " ,
" lista " : " Nr 2: M22 Locust \n Zasięg: 450m | Damage: 30 | Kierunek: Obrotowy | Ilość: 1 \n HP: 160 \n Prędkość: 64 km/h \n Opis: Ultra lekki czołg zaprojektowany specjalnie z myślą o transporcie drogą powietrzną przez szybowce. \n Ciekawostka: Aby zmieścił się pod szybowcem Hamilcar, trzeba było demontować mu wieżę na czas lotu. "
} ,
" sd.KFz.222 " : {
" foto " : " sd.KFz.222.png " ,
" lista " : " Nr 3: sd.KFz.222 \n Zasięg: 500m | Damage: 25 | Kierunek: Obrotowy | Ilość: 1 \n HP: 100 \n Prędkość: 80 km/h \n Opis: Lekki czterokołowy pojazd opancerzony, wykorzystywany przez Wehrmacht do szybkiego zwiadu. \n Ciekawostka: Posiadał charakterystyczną drucianą siatkę nad wieżą chroniącą przed granatami ręcznymi. "
} ,
" M3 GMC " : {
" foto " : " M3 GMC.png " ,
" lista " : " Nr 4: M3 GMC \n Zasięg: 700m | Damage: 75 | Kierunek: Przód | Ilość: 1 \n HP: 120 \n Prędkość: 70 km/h \n Opis: Samobieżne działo przeciwpancerne zbudowane na bazie podwozia typu Halftrack. \n Ciekawostka: Był kluczową bronią USA w walkach z czołgami Rommla w Afryce Północnej. "
} ,
" M15 CGMC " : {
" foto " : " M15 CGMC.png " ,
" lista " : " Nr 5: M15 CGMC \n Zasięg: 800m | Damage: 30 | Kierunek: Obrotowy | Ilość: 3 \n HP: 140 \n Prędkość: 65 km/h \n Opis: Samobieżne działo przeciwlotnicze wyposażone w automatyczną armatę i dwa karabiny maszynowe. \n Ciekawostka: Jego siła ognia była tak duża, że często używano go do niszczenia piechoty wroga. "
} ,
" sd.KFz.251-9 " : {
" foto " : " sd.KFz.251-9.png " ,
" lista " : " Nr 6: sd.KFz.251-9 \n Zasięg: 550m | Damage: 50 | Kierunek: Przód (Wąski) | Ilość: 1 \n HP: 160 \n Prędkość: 50 km/h \n Opis: Półgąsienicowy transporter opancerzony wyposażony w krótkolufowe działo 7,5 cm KwK 37 L/24. \n Ciekawostka: Ze względu na charakterystyczny kształt krótkiej, grubej lufy, niemieccy żołnierze nazywali ten pojazd ' Stummel ' (Kikut). "
} ,
" Pz.IIIF " : {
" foto " : " Pz.IIIF.png " ,
" lista " : " Nr 7: Pz.IIIF \n Zasięg: 600m | Damage: 45 | Kierunek: Obrotowy | Ilość: 1 \n HP: 320 \n Prędkość: 35 km/h \n Opis: Niemiecki czołg średni, wersja Ausf. F otrzymała ulepszone chłodzenie i armatę 50mm KwK 38. \n Ciekawostka: Był kręgosłupem dywizji pancernych podczas początkowej fazy ataku na Związek Radziecki. "
} ,
" Pz.IIIC " : {
" foto " : " Pz.IIIC.png " ,
" lista " : " Nr 8: Pz.IIIC \n Zasięg: 450m | Damage: 20 | Kierunek: Obrotowy | Ilość: 1 \n HP: 250 \n Prędkość: 40 km/h \n Opis: Wczesna, rzadka wersja Panzer III o skomplikowanym zawieszeniu złożonym z 8 małych kół jezdnych. \n Ciekawostka: Wyprodukowano zaledwie kilkadziesiąt sztuk, zanim system zawieszenia zmieniono na drążki skrętne. "
} ,
" M3 Lee " : {
" foto " : " M3 Lee.png " ,
" lista " : " Nr 9: M3 Lee \n Zasięg: 600m | Damage: 55 | Kierunek: Boczny + Obrotowy | Ilość: 2 \n HP: 300 \n Prędkość: 38 km/h \n Opis: Czołg średni o nietypowej konstrukcji z głównym działem zamontowanym w kadłubie. \n Ciekawostka: Posiadał tak wysoką sylwetkę, że załogi nazywały go ' katedrą na gąsienicach ' . "
} ,
" LVT " : {
" foto " : " LVT.png " ,
" lista " : " Nr 10: LVT \n Zasięg: 400m | Damage: 40 | Kierunek: Przód | Ilość: 1 \n HP: 150 \n Prędkość: 40 km/h \n Opis: Amfibijny pojazd gąsienicowy używany do operacji desantowych na Pacyfiku. \n Ciekawostka: Początkowo został zaprojektowany jako cywilny pojazd ratunkowy na Florydzie. "
} ,
" M4A3 " : {
" foto " : " M4A3.png " ,
" lista " : " Nr 11: M4A3 Sherman \n Zasięg: 650m | Damage: 60 | Kierunek: Obrotowy | Ilość: 1 \n HP: 400 \n Prędkość: 45 km/h \n Opis: Kultowa wersja amerykańskiego czołgu średniego wyposażona w ulepszony silnik Ford GAA. \n Ciekawostka: Wersje te stały się bazą dla słynnych czołgów ' Easy Eight ' z nowym zawieszeniem HVSS. "
} ,
" Stug IIIb " : {
" foto " : " Stug IIIb.png " ,
" lista " : " Nr 12: Stug IIIb \n Zasięg: 580m | Damage: 65 | Kierunek: Przód (Wąski) | Ilość: 1 \n HP: 350 \n Prędkość: 40 km/h \n Opis: Działo szturmowe pozbawione obrotowej wieży, zaprojektowane do bezpośredniego wspierania piechoty. \n Ciekawostka: Z powodu braku wieży był tańszy w produkcji niż czołgi, stając się najskuteczniejszą bronią pancerną Niemiec. "
} ,
" Beutepanzer IV " : {
" foto " : " Beutepanzer IV.png " ,
" lista " : " Nr 13: Beutepanzer IV \n Zasięg: 450m | Damage: 60 | Kierunek: Boki i Przód | Ilość: 2 \n HP: 450 \n Prędkość: 6 km/h \n Opis: Brytyjski czołg ciężki Mark IV zdobyty podczas I wojny światowej, przebudowany i wcielony do armii niemieckiej. \n Ciekawostka: Niemcy zamontowali w nim własne działa 5,7 cm oraz zmienili układ chłodzenia, tworząc z niego ruchomą fortecę. "
} ,
" A7V " : {
" foto " : " A7V.png " ,
" lista " : " Nr 14: A7V \n Zasięg: 550m | Damage: 70 | Kierunek: Przód i Boki | Ilość: 6 \n HP: 500 \n Prędkość: 15 km/h \n Opis: Konstrukcja wzorowana na jedynym niemieckim czołgu z okresu I Wojny Światowej (A7V). \n Ciekawostka: Do obsługi tego giganta w wersji bojowej wymagana była monstrualna załoga licząca aż 18 osób. "
}
}
kolejnosc_pojazdow = [
" M3 St. " , " M22 " , " sd.KFz.222 " , " M3 GMC " , " M15 CGMC " , " sd.KFz.251-9 " ,
" Pz.IIIF " , " Pz.IIIC " , " M3 Lee " , " LVT " , " M4A3 " , " Stug IIIb " ,
" Beutepanzer IV " , " A7V "
]
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 " : " 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.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 " : " 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 } ,
]
zaladowane_obrazki = { }
obrazki_jednostek = { }
zasieg_podglad = None
# --- INTERFEJS I LOGIKA WYBORU ---
def sprawdz_limit ( strona , zmienna_kliknieta ) :
lista_zmiennych = [ para [ 0 ] for para in ( zmienne_lewa if strona == " USA " else zmienne_prawa ) ]
zaznaczone_count = sum ( z . get ( ) for z in lista_zmiennych )
if zaznaczone_count > 4 :
zmienna_kliknieta . set ( False )
messagebox . showwarning ( " Limit " , f " Możesz wybrać maksymalnie 4 elementy w { strona } " )
def pokaz_podglad ( event , nazwa_opcji ) :
dane = baza_podgladu . get ( nazwa_opcji , { " lista " : " Brak opisu " , " foto " : " " } )
lbl_tekstowy . config ( text = dane [ " lista " ] )
lbl_tekstowy . place ( relx = 0.5 , rely = 0.35 , anchor = " center " )
# lbl_graficzny.place(x=500, y=300)
lbl_graficzny . config ( bd = 2 , relief = " solid " )
try :
nazwa_pliku = f " { nazwa_opcji } .png "
if nazwa_pliku not in zaladowane_obrazki :
zaladowane_obrazki [ nazwa_pliku ] = PhotoImage ( file = nazwa_pliku )
img = zaladowane_obrazki [ nazwa_pliku ]
lbl_graficzny . config ( image = img )
lbl_graficzny . image = img
except Exception as e :
print ( e )
lbl_graficzny . config ( image = " " , text = " [ Podgląd Obrazka ] " , bg = " lightgray " )
# root.update_idletasks()
# print(lbl_graficzny.image,dane["foto"],lbl_graficzny.winfo_ismapped())
lbl_graficzny . place ( relx = 0.5 , rely = 0.60 , anchor = " center " )
def ukryj_podglad ( event ) :
lbl_tekstowy . place_forget ( )
lbl_graficzny . place_forget ( )
aktualny_plan = 0
kolejka_planowania = [ ]
wybrana_jednostka = None
aktualna_strona = " USA "
def planowanie ( event ) :
global wybrana_jednostka , aktualna_strona , koniec_planowania , zasieg_podglad
if koniec_planowania :
klikniete = canvas . find_overlapping (
event . x ,
event . y ,
event . x ,
event . y
)
if wybrana_jednostka is None :
for j in jednostki :
if j [ " rect " ] in klikniete or j [ " text " ] in klikniete :
if j [ " strona " ] != aktualna_strona :
return
if j [ " wykonal_ruch " ] :
return
wybrana_jednostka = j
canvas . itemconfig (
j [ " rect " ] ,
outline = " yellow " ,
width = 3
)
global zasieg_podglad
if zasieg_podglad :
canvas . delete ( zasieg_podglad )
r = j [ " ruch " ]
zasieg_podglad = canvas . create_oval (
j [ " x " ] - r ,
j [ " y " ] - r ,
j [ " x " ] + r ,
j [ " y " ] + r ,
fill = " chartreuse3 " ,
stipple = " gray50 " ,
activestipple = " gray12 " ,
outline = " green " ,
width = 2
)
lbl_aktywny_pojazd . config (
text = f " Wybierz cel dla { j [ ' nazwa ' ] } "
)
return
else :
dx = event . x - wybrana_jednostka [ " x " ]
dy = event . y - wybrana_jednostka [ " y " ]
wybrana_jednostka [ " kat_docelowy " ] = degrees (
atan2 ( dy , dx )
)
odleglosc = ( dx * dx + dy * dy ) * * 0.5
if odleglosc > wybrana_jednostka [ " ruch " ] :
skala = wybrana_jednostka [ " ruch " ] / odleglosc
event_x = int ( wybrana_jednostka [ " x " ] + dx * skala )
event_y = int ( wybrana_jednostka [ " y " ] + dy * skala )
else :
event_x = event . x
event_y = event . y
wybrana_jednostka [ " cel_x " ] = event_x
wybrana_jednostka [ " cel_y " ] = event_y
wybrana_jednostka [ " wykonal_ruch " ] = True
canvas . delete ( " plan " )
for j in jednostki :
if j [ " wykonal_ruch " ] :
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
)
wybrana_jednostka = None
if zasieg_podglad :
canvas . delete ( zasieg_podglad )
zasieg_podglad = None
aktualna_strona = (
" GER "
if aktualna_strona == " USA "
else " USA "
)
lbl_aktywny_pojazd . config (
text = f " Wybierz jednostkę { aktualna_strona } "
)
if all ( j [ " wykonal_ruch " ] for j in jednostki ) :
canvas . delete ( " plan " )
koniec_planowania = False
animuj ( 0 )
for j in jednostki :
j [ " wykonal_ruch " ] = False
aktualna_strona = " USA "
lbl_aktywny_pojazd . config (
text = " Wybierz jednostkę USA "
)
kontener = Frame ( root )
kontener . pack ( pady = 20 , expand = True , fill = " both " )
lbl_tekstowy = Label ( root , text = " " , font = ( " Arial " , 11 ) , bg = " #f0f0f0 " , bd = 2 , relief = " groove " , padx = 10 , pady = 10 )
lbl_graficzny = Label ( root , text = " " )
koniec_planowania = True
kolumna_lewa = Frame ( kontener )
kolumna_lewa . pack ( side = " left " , expand = True , padx = 20 )
Label ( kolumna_lewa , text = " USA " , font = ( " Arial " , 12 , " bold " ) ) . pack ( pady = 10 )
for txt_kwadrat in kwadraty_lewe :
wiersz = Frame ( kolumna_lewa )
wiersz . pack ( pady = 4 , anchor = " w " )
stan = BooleanVar ( )
zmienne_lewa . append ( ( stan , txt_kwadrat ) )
chk = Checkbutton (
wiersz ,
text = txt_kwadrat ,
variable = stan ,
indicatoron = False ,
width = 18 ,
selectcolor = " lightblue " ,
command = lambda s = stan : sprawdz_limit ( " USA " , s )
)
chk . pack ( side = " left " )
chk . bind ( " <Enter> " , lambda event , nazwa = txt_kwadrat : pokaz_podglad ( event , nazwa ) )
chk . bind ( " <Leave> " , ukryj_podglad )
kolumna_prawa = Frame ( kontener )
kolumna_prawa . pack ( side = " right " , expand = True , padx = 20 )
Label ( kolumna_prawa , text = " III Rzesza " , font = ( " Arial " , 12 , " bold " ) ) . pack ( pady = 10 )
for txt_kwadrat in kwadraty_prawa :
wiersz = Frame ( kolumna_prawa )
wiersz . pack ( pady = 4 , anchor = " w " )
stan = BooleanVar ( )
zmienne_prawa . append ( ( stan , txt_kwadrat ) )
chk = Checkbutton (
wiersz ,
text = txt_kwadrat ,
variable = stan ,
indicatoron = False ,
width = 18 ,
selectcolor = " lightgreen " ,
command = lambda s = stan : sprawdz_limit ( " GER " , s )
)
chk . pack ( side = " left " )
chk . bind ( " <Enter> " , lambda event , nazwa = txt_kwadrat : pokaz_podglad ( event , nazwa ) )
chk . bind ( " <Leave> " , ukryj_podglad )
canvas = Canvas ( root , bg = " white " , highlightthickness = 0 )
usa = [ ]
IIIRzesza = [ ]
def zatwierdz ( ) :
global usa , IIIRzesza , pojazdy_do_ustawienia
if tryb_gry . get ( ) == " PvAI " :
messagebox . showinfo (
" PvAI " ,
" AI Wkrótce dostępne! "
)
return
usa = [ nazwa for stan , nazwa in zmienne_lewa if stan . get ( ) ]
IIIRzesza = [ nazwa for stan , nazwa in zmienne_prawa if stan . get ( ) ]
pojazdy_do_ustawienia = usa + IIIRzesza
if not usa or not IIIRzesza :
messagebox . showwarning ( " Brak wyboru " , " Musisz wybrać przynajmniej jeden pojazd w USA i w III Rzeszy, aby rozpocząć! " )
return
decyzja = messagebox . askokcancel ( " Potwierdzenie " , " Czy chcesz wygenerować mapę z wybranymi jednostkami? " )
if decyzja :
do_ukrycia = [ kontener , btn_koniec , lbl_tekstowy , lbl_graficzny , tryb , pvp , pvai , jakosc , menu_jakosci , rozmiar , menu_rozmiaru ]
for widget in do_ukrycia :
widget . pack_forget ( )
lbl_tekstowy . place_forget ( )
lbl_graficzny . place_forget ( )
canvas . pack ( fill = " both " , expand = True )
lbl_aktywny_pojazd . pack ( pady = 5 )
lbl_aktywny_pojazd . config ( text = f " Ustaw: { pojazdy_do_ustawienia [ 0 ] } " )
root . update ( )
start ( )
jakosc = Label ( root , text = " Jakość mapy " , font = ( " Arial " , 11 , " bold " ) )
rozmiar = Label ( root , text = " Rozmiar mapy " , font = ( " Arial " , 11 , " bold " ) )
jakosc_mapy = StringVar ( value = " Preferowana " )
rozmiar_mapy = StringVar ( value = " Średnia " )
opcje_jakosci = [
" Bardzo wysoka " ,
" Wysoka " ,
" Preferowana " ,
" Niska " ,
" Bardzo niska "
]
opcje_rozmiaru = [
" Mała " ,
" Średnia " ,
" Duża " ,
" Ogromna "
]
menu_jakosci = OptionMenu ( root , jakosc_mapy , * opcje_jakosci )
menu_rozmiaru = OptionMenu ( root , rozmiar_mapy , * opcje_rozmiaru )
tryb_gry = StringVar ( value = " PvP " )
tryb = Label ( root , text = " Tryb gry " , font = ( " Arial " , 11 , " bold " ) )
pvp = Radiobutton (
root ,
text = " PvP " ,
variable = tryb_gry ,
value = " PvP "
)
pvai = Radiobutton (
root ,
text = " PvAI " ,
variable = tryb_gry ,
value = " PvAI "
)
jakosc . pack ( )
menu_jakosci . pack ( )
rozmiar . pack ( )
menu_rozmiaru . pack ( )
mnoznik_ruchu = 0
tryb . pack ( )
pvp . pack ( )
pvai . pack ( )
btn_koniec = Button ( root , text = " Zatwierdź wybór " , command = zatwierdz , bg = " gold " , font = ( " Arial " , 10 , " bold " ) )
btn_koniec . pack ( pady = 20 )
aktualny_pojazd = None
pojazdy_do_ustawienia = [ ]
placed_units = [ ]
ghost = None
jednostki = [ ]
kolej_tury = [ ]
ODSTEP = 15
SKALA_JEDNOSTKI = 10
lbl_aktywny_pojazd = Label ( root , text = " Kliknij, aby rozpocząć ustawianie " , font = ( " Arial " , 12 , " bold " ) )
aktualny_index = 0
BONUS_RUCHU = 1
opcje_predkosci = [
" x1 " ,
" x2 " ,
" x3 " ,
" x4 " ,
" x5 "
]
predkosc_ruchu = StringVar ( value = " x1 " )
predkosc_ruchu . trace_add ( " write " , zmien_predkosc )
menu_predkosci = OptionMenu (
root ,
predkosc_ruchu ,
* opcje_predkosci
)
Label ( root , text = " Zasięg ruchu " ) . pack ( )
menu_predkosci . pack ( )
canvas . bind ( " <Button-1> " , ustaw_pojazd )
canvas . bind ( " <Motion> " , update_ghost )
root . bind ( " <Escape> " , lambda event : root . destroy ( ) )
root . mainloop ( )