Zbuduj Grę z Asteroidami
Kurs Pygame dla Pasjonatów Gier
python3 i pip3.python3 zamiast python.Configure Display Languagetest.py w swoim folderze, wklej poniższy kod i kliknij ▶ Run.import pygame
pygame.init()
ekran = pygame.display.set_mode((800, 600))
pygame.display.set_caption("Test Devostro — Pygame dziala!")
ekran.fill((0, 0, 30))
font = pygame.font.SysFont("Arial", 36)
napis = font.render("Pygame dziala! Mozemy zaczac.", True, (0, 200, 255))
ekran.blit(napis, (150, 270))
pygame.display.flip()
pygame.time.wait(3000)
pygame.quit()
print("Test OK! Srodowisko gotowe.")
Test OK!devdev → Nowy Folder → asteroidyasteroidy → Nowy Plik → test.pyasteroidy, gra_01.pymoja_gra, moja-gramoja gra — powodują błędy w terminalućwiczenia — mogą powodować problemyAsteroidy — niekonwencjonalne
asteroidy
gra_01.py
python gra_01.py
while i forint, float, bool, strpygame.init() — funkcja bez argumentówekran.fill((0,0,30)) — funkcja z argumentempygame.display.flip() — funkcja bez argumentówpygame.draw.rect(ekran, kolor, (x,y,w,h)) — funkcja z wieloma argumentamidev/asteroidy/lekcja1 (który stworzyłeś w Etapie 0). Jeśli nie masz — stwórz go teraz.cwiczenie_2_1.py → Enterpython cwiczenie_2_1.py
cwiczenie_2_1.py, cwiczenie_2_2.py...def)def, dajesz nazwę i dwukropek. Python zapamiętuje kod wewnątrz — ale jeszcze nic nie wykonuje. To tylko zapisanie przepisu.nazwa())# KROK 1 — definicja: Python ZAPAMIĘTUJE, ale NIE wykonuje
def przywitaj():
print("To się nie wykona od razu!")
# Tu jeszcze nic nie ma w terminalu.
# KROK 2 — wywołanie: dopiero teraz Python to WYKONUJE
przywitaj() # ← nawiasy () są obowiązkowe!
przywitaj() # ← można wywołać wielokrotnie
przywitaj()
przywitaj bez nawiasów — Python nie wykona funkcji, tylko pokaże że ona istnieje. Zawsze przywitaj() z nawiasami, żeby ją wywołać.
def przywitaj():
print("Cześć, jestem funkcją bez argumentów!")
# Definicja powyżej nic nie wypisała.
# Dopiero wywołanie uruchamia kod:
przywitaj()
def przywitaj(): — Python zapamiętuje funkcję.przywitaj() — Python ją uruchamia.def przywitaj(): bez wywołania — terminal byłby pusty!
pozegnaj(), która wypisze pożegnanie. Pamiętaj o wywołaniu: pozegnaj().def nazwa():)nazwa()def powiedz(imie):
print("Hej", imie)
powiedz("Ala")
powiedz("Bartek")
imie to parametr — dziura w przepisie do uzupełnienia przy wywołaniu.powiedz("Ala") — wywołujesz z argumentem "Ala". Python podstawia go w miejsce imie.powiedz_wiek(wiek), która wypisze "Mam X lat". Wywołaj ją z kilkoma różnymi wartościami.def przedstaw(imie, wiek):
print("Nazywam się", imie, "i mam", wiek, "lat.")
przedstaw("Bartek", 15)
przedstaw("Anna", 22)
pozycja(x, y) wypisującą pozycję gracza.def dodaj(a, b):
return a + b
wynik = dodaj(3, 5)
print("Wynik:", wynik)
pole_kwadratu(bok) zwracającą pole.return żeby zwrócić wartośćprint() od returndef powiedz_hello(imie):
return "Cześć " + imie + "!"
# return daje wartość z powrotem — żeby ją ZOBACZYĆ, musisz użyć print()!
wynik = powiedz_hello("Bartek")
print(wynik)
# albo krócej — w jednej linii:
print(powiedz_hello("Ala"))
return oddaje wartość temu kto wywołał funkcję — ale jej nie wypisuje.print().return to kelner który przynosi danie na stół. print() to Ty, który je zjada (widzi). Bez Ciebie danie leży niewidoczne.
opis_statku(x, y) zwracającą tekst "Statek na pozycji X, Y". Wypisz wynik przez print(opis_statku(100, 200)).returnprint(funkcja(...))return i print() to różne operacjepozycja = (100, 200) # x=100, y=200
wymiary = (800, 600) # szerokość, wysokość okna
punkt = (0, 0) # lewy górny róg ekranu
(R, G, B) — ile czerwonego, zielonego, niebieskiego(0, 0, 30) # ciemny niebieski — tło kosmosu
(255, 0, 0) # czerwony
(0, 200, 255) # jasny błękit — nasz statek
(160, 160, 160) # szary — asteroida
(255, 255, 255) # biały
(0, 0, 0) # czarny
def kolor_niebieski():
return (0, 0, 255)
# Pamiętaj: żeby zobaczyć wynik — użyj print()!
kolor = kolor_niebieski()
print("Kolor:", kolor)
True i False to wartości logiczne. Można je wypisać przez print(),
zapisać do zmiennej, albo użyć bezpośrednio w if — bez porównywania!
czy_wiekszy(a, b) zwracającą True jeśli a > b. Wypisz wynik dla kilku par liczb.def oblicz_punkty(trafienia, mnozmik):
return trafienia * mnozmik
wynik = oblicz_punkty(5, 10)
print("Punkty:", wynik)
premia_za_fale(numer_fali), która zwraca numer_fali * 50. Wypisz premię dla fali 1, 2 i 3.licznik = 0
while True:
print("Klatka:", licznik)
licznik += 1
if licznik > 5:
break
licznik > 10. Sprawdź ile razy pętla się wykona.szerokosc = 800
wysokosc = 600
kolor = (0, 0, 30)
print("Rozmiar okna:", szerokosc, "x", wysokosc)
tytul = "Moja gra" i wypisz ją.File "cwiczenie.py", line 5, in
print(wynik)
NameError: name 'wynik' is not defined
NameError) — co poszło nie takname 'wynik' is not defined) — szczegółyline 5) — gdzie szukać w kodzie# NameError — literówka lub zapomniana definicja
print(wynik) # błąd: 'wynik' nie istnieje
wynik = 42
print(wynik) # OK — najpierw definiujemy
# TypeError — mieszanie typów
punkty = 10
napis = "Zdobyłeś " + punkty # błąd: int + str
napis = "Zdobyłeś " + str(punkty) # OK
# IndexError — za duży indeks
lista = [1, 2, 3]
print(lista[5]) # błąd: lista ma tylko 3 elementy (0,1,2)
print(lista[2]) # OK — ostatni element
statek_x = 350
print("DEBUG statek_x:", statek_x) # sprawdzamy wartość
for i in range(5):
print("DEBUG i =", i) # śledzimy pętlę
print("DEBUG...").
# Ten kod ma 3 błędy — znajdź je i napraw!
def podwoj(liczba)
return liczba * 2
wynik = podwoj(5)
print("Podwojona wartość:", Wynik)
imie = "Bartek"
powitanie = "Cześć " + imie + "! Masz " + wiek + " lat."
print(powitanie)
print("DEBUG wynik:", wynik) przed ostatnią linią. Usuń gdy wszystko działa.while True i zmiennej pętlipygame.init() uruchamia silnik, set_mode() tworzy okno, pętla while True obsługuje zdarzenia i odświeża ekran przez flip().gra_01.py w folderze kursu.
import pygame # wczytujemy bibliotekę do gier
pygame.init() # uruchamiamy wszystkie moduły Pygame (grafika, dźwięk, itp.)
SZEROKOSC = 800 # szerokość okna w pikselach (duże litery = stała)
WYSOKOSC = 600 # wysokość okna w pikselach
# set_mode tworzy okno gry — argument to krotka (szerokosc, wysokosc)
ekran = pygame.display.set_mode((SZEROKOSC, WYSOKOSC))
pygame.display.set_caption("Asteroidy — Lekcja 1!") # tytuł na pasku okna
zegar = pygame.time.Clock() # zegar do kontroli FPS (klatek na sekundę)
while True: # główna pętla gry — działa bez końca
for zdarzenie in pygame.event.get(): # sprawdź czy coś się stało (klik, klawisz...)
if zdarzenie.type == pygame.QUIT: # jeśli kliknięto X w rogu okna...
pygame.quit() # ...zamknij Pygame
exit() # ...i zakończ program
ekran.fill((0, 0, 30)) # pomaluj tło na ciemny niebieski (R=0, G=0, B=30)
pygame.display.flip() # wyświetl gotową klatkę na ekranie
zegar.tick(60) # czekaj — nie przekraczaj 60 klatek/sekundę
gra_01.py i uruchom: python gra_01.pyfill() i flip()fill() — malujesz nową klatkę w pamięci komputera (niewidoczna).flip() — zamieniasz pamięć na widoczny ekran. Dopiero teraz gracz coś widzi.import pygame
pygame.init()
import pygame — mówisz Pythonowi: „będziemy używać biblioteki do gier".pygame.init() — funkcja bez argumentów, uruchamia moduły Pygame (grafikę, dźwięk itd.).przywitaj() — tylko robi dużo rzeczy „pod maską".
SZEROKOSC = 800
WYSOKOSC = 600
szerokosc, wysokosc.ekran = pygame.display.set_mode((SZEROKOSC, WYSOKOSC))
(szerokość, wysokość). Zwraca obiekt „ekran" — powierzchnię, na której rysujemy.
To jest jak kartka, na której będziemy malować kosmos, statek, asteroidy.
pygame.display.set_caption("Asteroidy — Lekcja 1: Pierwsze Okno!")
zegar = pygame.time.Clock()
while True:
for zdarzenie in pygame.event.get():
if zdarzenie.type == pygame.QUIT:
pygame.quit()
exit()
pygame.event.get() — funkcja zwracająca listę zdarzeń (np. kliknięcie X).pygame.QUIT → zamykamy grę.for będziemy dokładnie omawiać i ćwiczyć w następnej lekcji — na razie wpisz ten blok tak jak jest.
ekran.fill((0, 0, 30))
fill(...) — funkcja z argumentem: krotką (R, G, B). Każda wartość od 0 do 255.(0, 0, 30) — prawie czarny, ciemny niebieski (kosmos).(255, 0, 0) — czerwony. (255, 255, 255) — biały. (0, 0, 0) — czarny. pygame.display.flip()
flip() zamienia je miejscami — gotowa klatka pojawia się na ekranie, a stary ekran staje się nowym buforem do rysowania. zegar.tick(60)
zegar.tick(60) mówi: „odczekaj tyle czasu, żeby pętla nie wykonała się więcej niż 60 razy na sekundę".tick(60) sprawia że gra działa tak samo wszędzie.
pygame.display.flip():ekran.fill((0, 0, 30)) na (255, 0, 0) — czerwone tło. Potem (0, 255, 0) — zielone. Jak zmieszać kolory?pygame.display.flip() i uruchom — co się dzieje? Przywróć ją.ekran.fill() dwa razy z różnymi kolorami — który z nich "wygrywa"?for przechodzi przez zakres wartości jeden po jednym:for i in range(5):
print("Krok:", i)
# Wypisze: 0, 1, 2, 3, 4
range() może przyjmować 1, 2 lub 3 argumenty:range(5) # 0, 1, 2, 3, 4
range(2, 6) # 2, 3, 4, 5
range(0, 800, 100) # 0, 100, 200, 300, 400, 500, 600, 700 ← pozycje X na ekranie!
cwiczenie_for_1.py i cwiczenie_for_2.py — wpisuj kod ręcznie i uruchamiaj: python cwiczenie_for_1.py
for i in range(5):
print("Krok:", i)
range(10). Potem wypisz każdą wartość × 2: print("Krok:", i * 2).range(n) i wypisywać każdą wartośćrange()for x in range(0, 800, 100):
print("Pozycja X:", x)
50. Potem napisz to samo dla osi Y: range(0, 600, 100).range(a, b, krok) do generowania pozycji na ekraniefor — znajdź go w kodzie poniżej i sprawdź gdzie w Lekcji 2 będziemy coś doklejać:
import pygame
pygame.init()
SZEROKOSC = 800
WYSOKOSC = 600
ekran = pygame.display.set_mode((SZEROKOSC, WYSOKOSC))
pygame.display.set_caption("Asteroidy — Lekcja 1: Pierwsze Okno!")
zegar = pygame.time.Clock()
# <-- TUTAJ DODAMY ZMIENNE STATKU (Lekcja 2, krok 4.4)
while True:
for zdarzenie in pygame.event.get(): # <-- ta petla for dziala jak range()!
if zdarzenie.type == pygame.QUIT:
pygame.quit()
exit()
ekran.fill((0, 0, 30))
# <-- TUTAJ NARYSUJEMY STATEK (Lekcja 2, krok 4.5)
pygame.display.flip()
zegar.tick(60)
for — czas narysować statek.
gra_01.py i zapisz kopię jako gra_02.py."Asteroidy — Lekcja 2: Pierwszy Statek!"statek_x, statek_y, statek_szerokosc, statek_wysokosc) przekazujemy do pygame.draw.rect().(0, 0) to lewy górny róg. X rośnie w prawo, Y rośnie w dół:
(0,0) ──────────────────────► X rośnie (0 → 799)
│
│
▼
Y rośnie (0 → 599)
(0, 0) — lewy górny róg(800, 0) — prawy górny róg(0, 600) — lewy dolny róg(350, 500) — prawie na dole, lekko z lewej → tam stanie nasz statek
(x, y, szerokość, wysokość)(350, 500, 40, 50) → x=350, y=500, szerokość=40, wysokość=50
pygame.draw.rect(
ekran, # gdzie rysujemy
(0, 200, 255), # kolor RGB (niebieski)
(statek_x, statek_y, statek_szerokosc, statek_wysokosc) # rect: x,y,w,h
)
ekran (nasza „kartka do rysowania")(0, 200, 255) = jasny niebieski(x, y, szerokość, wysokość) opisująca prostokąt
gra_02.py znajdź linię zegar = pygame.time.Clock() i wklej zaraz pod nią:
# --- ZMIENNE STATKU ---
statek_x = 350 # pozycja pozioma (od lewej)
statek_y = 500 # pozycja pionowa (od góry)
statek_szerokosc = 40 # szerokość statku w pikselach
statek_wysokosc = 50 # wysokość statku w pikselach
while True, zaraz po ekran.fill((0, 0, 30)), wklej:
# --- RYSOWANIE STATKU ---
pygame.draw.rect(
ekran,
(0, 200, 255),
(statek_x, statek_y, statek_szerokosc, statek_wysokosc)
)
python gra_02.py — niebieski prostokąt na dole ekranu. To Twój pierwszy obiekt w grze!
import pygame
pygame.init()
SZEROKOSC = 800
WYSOKOSC = 600
ekran = pygame.display.set_mode((SZEROKOSC, WYSOKOSC))
pygame.display.set_caption("Asteroidy — Lekcja 2: Pierwszy Statek!")
zegar = pygame.time.Clock()
# --- ZMIENNE STATKU ---
statek_x = 350
statek_y = 500
statek_szerokosc = 40
statek_wysokosc = 50
while True:
for zdarzenie in pygame.event.get():
if zdarzenie.type == pygame.QUIT:
pygame.quit()
exit()
ekran.fill((0, 0, 30))
# --- RYSOWANIE STATKU ---
pygame.draw.rect(
ekran,
(0, 200, 255),
(statek_x, statek_y, statek_szerokosc, statek_wysokosc)
)
pygame.display.flip()
zegar.tick(60)
(255, 255, 0) — żółty. Potem (255, 0, 255) — fioletowy.statek_x = -20 — czy statek może wyjść poza ekran?ekran.fill((0, 0, 30)) — co się dzieje z kolejnymi klatkami?SZEROKOSC // 2 - statek_szerokosc // 2pygame.draw.circle(ekran, (255, 255, 0), (400, 300), 40)pygame.draw.ellipse(ekran, (0, 100, 255), (statek_x + 10, statek_y + 45, 20, 10))pygame.draw.line(ekran, (255, 0, 0), (0, 600), (800, 0), 3)+, -, *. Oto reszta:print(800 / 2) # 400.0 — wynik z ułamkiem (float)
print(800 // 2) # 400 — dzielenie całkowite (int), bez ułamka
print(7 // 2) # 3 — zaokrągla w dół
print(7 % 2) # 1 — reszta z dzielenia
print(2 ** 8) # 256 — potęgowanie
// jest ważne? Pozycja piksela musi być liczbą całkowitą — ułamków pikseli nie ma. Dlatego do centrowania używamy //, nie /.
cwiczenie_op_1.py, cwiczenie_op_2.py, cwiczenie_format_1.py, cwiczenie_format_2.py — wpisuj i uruchamiaj każdy z osobna.
print("Dzielenie:", 800 / 2)
print("Dzielenie calkowite:", 800 // 2)
print("Reszta:", 7 % 2)
print("Potega:", 2 ** 8)
//. Ile to pikseli dla X? Ile dla Y?/ (wynik float) od // (wynik int)% do reszty z dzielenia** do potęgowaniaszerokosc = 800
statek_szer = 40
srodek_x = szerokosc // 2 - statek_szer // 2
print("Statek startuje na X:", srodek_x)
szerokosc = 600 — jaki jest nowy środek? Czy statek nadal jest wycentrowany?szerokosc // 2 - szer // 2// do pozycjonowania obiektów.format() wstawia wartości zmiennych w miejsce {} — po kolei:imie = "Bartek"
poziom = 3
print("Gracz: {} | Poziom: {}".format(imie, poziom))
# Wypisze: Gracz: Bartek | Poziom: 3
{} — tyle argumentów w .format().
imie = "Bartek"
poziom = 3
print("Gracz: {} | Poziom: {}".format(imie, poziom))
punkty = 150 i dopisz ją do wypisywanego tekstu: "Gracz: {} | Poziom: {} | Punkty: {}".{}.format() do wstawiania wartości w tekstx = 380
y = 520
zycia = 3
print("Pozycja: X={} Y={}".format(x, y))
print("Zycia: {}".format(zycia))
fala = 1 i wyświetl ją w osobnej linii. Potem zmień wartości x, y i sprawdź wynik.format()input() pyta użytkownika o dane — ale zawsze zwraca tekst (string), nawet gdy wpiszesz liczbę:wiek = input("Ile masz lat? ")
print(type(wiek)) # — to tekst, nie liczba!
# Aby użyć jako liczby — konwertuj:
wiek_int = int(wiek)
print("Za rok będziesz mieć:", wiek_int + 1)
int("42") # "42" → 42 (tekst → liczba całkowita)
float("3.14") # "3.14" → 3.14 (tekst → liczba z ułamkiem)
str(100) # 100 → "100" (liczba → tekst)
# Klasyczny błąd:
punkty = 10
print("Masz " + punkty + " punktów") # BŁĄD — str + int!
print("Masz " + str(punkty) + " punktów") # OK
print("Masz {} punktów".format(punkty)) # też OK — format robi to automatycznie
a = int(input("Podaj pierwszą liczbę: "))
b = int(input("Podaj drugą liczbę: "))
print("Suma:", a + b)
print("Różnica:", a - b)
print("Iloczyn:", a * b)
print("Wynik jako tekst:", str(a + b))
(a + b) / 2. Potem spróbuj wpisać tekst zamiast liczby — przeczytaj komunikat błędu.input() do pobierania danych od użytkownikaint()gra_02.py i zapisz kopię jako gra_03.py."Asteroidy — Lekcja 3: Środek Ekranu"SZEROKOSC // 2 - statek_szerokosc // 2. Tekst przez font.render() + blit() z .format().// działa dla każdego rozmiaru okna — zmień SZEROKOSC i statek nadal jest na środku bez żadnych poprawek.zegar = pygame.time.Clock()
# --- ZMIENNE STATKU ---
statek_x = 350 # <-- ZAMIENIMY NA WZOR Z // (krok 4.1)
statek_y = 500 # <-- ZAMIENIMY NA WYSOKOSC - 80 (krok 4.1)
statek_szerokosc = 40
statek_wysokosc = 50
# <-- TUTAJ DODAMY FONT (krok 4.2)
while True:
for zdarzenie in pygame.event.get():
if zdarzenie.type == pygame.QUIT:
pygame.quit()
exit()
ekran.fill((0, 0, 30))
pygame.draw.rect(ekran, (0, 200, 255),
(statek_x, statek_y, statek_szerokosc, statek_wysokosc))
# <-- TUTAJ WYSWIETLIMY TEKST (kroki 4.3–4.6)
pygame.display.flip()
zegar.tick(60)
gra_03.py zamień dwie linie zmiennych statku:
statek_x = SZEROKOSC // 2 - statek_szerokosc // 2
statek_y = WYSOKOSC - 80 # blisko dołu ekranu
SZEROKOSC // 2 → środek ekranu w poziomie- statek_szerokosc // 2 → cofamy o połowę szerokości statku, żeby jego środek był na środku ekranuSZEROKOSC automatycznie przesuwa statek — nie trzeba nic poprawiać ręcznie.
font = pygame.font.SysFont("Arial", 24)
napis = font.render("Tekst", True, (255, 255, 255))
font.render() zwraca Surface — obrazek z tekstem.ekran.blit(napis, (10, 10))
blit() naklejia Surface na ekran w pozycji (x, y).ekran.fill() i przed pygame.display.flip().
tekst = "Pozycja statku: X={} Y={}".format(statek_x, statek_y)
napis = font.render(tekst, True, (255, 255, 255))
ekran.blit(napis, (10, 10))
.format() z ćwiczenia 2.4 + render() + blit() — wszystko razem.
tekst2 = "Srodek: X={} Y={}".format(SZEROKOSC // 2, WYSOKOSC // 2)
napis2 = font.render(tekst2, True, (100, 200, 100))
ekran.blit(napis2, (10, 40))
python gra_03.py — statek na środku, dwa napisy w lewym górnym rogu!
import pygame
pygame.init()
SZEROKOSC = 800
WYSOKOSC = 600
ekran = pygame.display.set_mode((SZEROKOSC, WYSOKOSC))
pygame.display.set_caption("Asteroidy — Lekcja 3: Srodek Ekranu")
zegar = pygame.time.Clock()
statek_szerokosc = 40
statek_wysokosc = 50
statek_x = SZEROKOSC // 2 - statek_szerokosc // 2
statek_y = WYSOKOSC - 80
font = pygame.font.SysFont("Arial", 24)
while True:
for zdarzenie in pygame.event.get():
if zdarzenie.type == pygame.QUIT:
pygame.quit()
exit()
ekran.fill((0, 0, 30))
pygame.draw.rect(ekran, (0, 200, 255),
(statek_x, statek_y, statek_szerokosc, statek_wysokosc))
tekst = "Pozycja statku: X={} Y={}".format(statek_x, statek_y)
napis = font.render(tekst, True, (255, 255, 255))
ekran.blit(napis, (10, 10))
tekst2 = "Srodek: X={} Y={}".format(SZEROKOSC // 2, WYSOKOSC // 2)
napis2 = font.render(tekst2, True, (100, 200, 100))
ekran.blit(napis2, (10, 40))
pygame.display.flip()
zegar.tick(60)
SZEROKOSC = 800 na 600 — czy statek nadal jest na środku? Dlaczego?24 na 6, potem na 72.(255, 255, 0) — żółty. Potem (255, 100, 100).ekran.blit(napis, (10, WYSOKOSC - 40))statek_y = WYSOKOSC // 2 - statek_wysokosc // 2punkty = 0 i wyświetl ją jako trzeci wiersz HUD: "Punkty: {}""ASTEROIDY" na środku ekranu — utwórz drugi font rozmiaru 52 i wycentruj go poziomoekran.blit(napis_imie, (SZEROKOSC - 150, WYSOKOSC - 30))== z warunków. Oto pełna rodzina:x = 350
print(x > 0) # True — większe od 0?
print(x < 0) # False — mniejsze od 0?
print(x == 350) # True — równe 350? (== nie = !)
print(x != 350) # False — różne od 350?
print(x >= 350) # True — większe LUB równe?
print(x <= 100) # False — mniejsze LUB równe?
= to przypisanie (daj wartość), == to porównanie (czy równe?). To częsty błąd!
cwiczenie_if_1.py, cwiczenie_if_2.py, cwiczenie_ruch_1.py — wpisuj i uruchamiaj każdy z osobna.
x = 350
if x > 400:
print("statek za daleko w prawo")
else:
print("statek jest OK")
x = 900 — co się wypisze? Potem x = -10. Potem dodaj trzeci warunek: wypisz komunikat gdy x == 0.>, <, == w warunkachif/elseTrue/False porównaniax = 400
x += 5 # to samo co: x = x + 5 → x staje się 405
x -= 3 # to samo co: x = x - 3 → x staje się 402
x *= 2 # to samo co: x = x * 2 → x staje się 804
+= i -= w każdej klatce — to serce animacji.
pozycja_x = 0
predkosc = 50
pozycja_x += predkosc
print("Krok 1 (w prawo):", pozycja_x) # 50
pozycja_x += predkosc
print("Krok 2 (w prawo):", pozycja_x) # 100
pozycja_x += predkosc
print("Krok 3 (w prawo):", pozycja_x) # 150
pozycja_x -= predkosc
print("Krok 4 (w lewo):", pozycja_x) # 100
predkosc = 100. Ile kroków w prawo żeby dojść do pozycji 800? Ile kroków z powrotem do 0?+= i -= do aktualizacji pozycjix = 700 # startujemy blisko prawej krawędzi
predkosc = 5
szerokosc = 800
szer_statku = 40
# Chcemy wykonać 20 kroków ruchu — jak 20 klatek animacji
for klatka in range(20):
x += predkosc # przesuń o predkosc pikseli w prawo
# Granica prawa:
# szerokosc - szer_statku = 800 - 40 = 760
# Gdy x > 760, prawa krawędź statku (x + 40) przekracza 800 — wychodzi za ekran!
if x > szerokosc - szer_statku:
x = szerokosc - szer_statku # siłą cofamy do ostatniej dozwolonej pozycji
print("Krok", klatka, "| x =", x, "| prawa krawedz =", x + szer_statku)
range(20) — chcemy wykonać dokładnie 20 kroków (jak 20 klatek animacji). Zmienna klatka liczy od 0 do 19.if x > szerokosc - szer_statku — rozbijmy to na liczby:szerokosc - szer_statku = 800 - 40 = 760x = 760, prawa krawędź statku = 760 + 40 = 800 — dokładnie na granicy ekranu.x = 761, prawa krawędź = 801 — już jeden piksel za ekranem!x przekroczył tę ostatnią dozwoloną pozycję (760)?x = szerokosc - szer_statku — gdy warunek prawdziwy, siłą ustawiamy x na 760. Statek „przykleja się" do prawej ściany — nie może iść dalej.print(...) — wypisujemy oba: x (lewa krawędź) i x + szer_statku (prawa krawędź). Obserwuj jak prawa krawędź zatrzymuje się dokładnie na 800.
kolor_szary(jasnosc) która zwraca (jasnosc, jasnosc, jasnosc). Wypisz wynik dla jasności 100 i 200.def czy_parzysta(n):
return n % 2 == 0
wynik = czy_parzysta(4)
print("Czy 4 jest parzyste?", wynik) # True
if czy_parzysta(7):
print("7 jest parzyste")
else:
print("7 jest nieparzyste")
pada_deszcz = True # lub False
if pada_deszcz:
print("Biorę parasol")
else:
print("Nie biorę parasola")
print("Idę na spacer")
if. Lewa gałąź (TAK) → blok if. Prawa (NIE) → else. Kod pod blokiem = wspólny koniec.
760 = SZEROKOSC - statek_szerokosc.
+=/-= → aktualizacja pozycji. if → reakcja na klawisze.gra_03.py, zapisz kopię jako gra_04.py."Asteroidy — Lekcja 4: Ruch Statku!"predkosc = 5 # <-- DODAJEMY (krok 4.1)
font = pygame.font.SysFont("Arial", 22)
while True:
for zdarzenie in pygame.event.get():
if zdarzenie.type == pygame.QUIT: ...
# <-- TUTAJ: pygame.key.get_pressed() + ruch (kroki 4.2–4.3)
# <-- TUTAJ: granice ekranu (krok 4.5)
ekran.fill((0, 0, 30))
pygame.draw.rect(...)
ekran.blit(napis, (10, 10))
pygame.display.flip()
zegar.tick(60)
pygame.key.get_pressed() sprawdza stan klawiszy co klatkę; +=/-= zmienia pozycję. Cztery bloki if po ruchu korygują pozycję gdy przekracza granicę.predkosc = 5 # pikseli na klatkę
predkosc = 5?predkosc = 1 → bardzo wolno (60px/s). predkosc = 20 → bardzo szybko (1200px/s).statek_szerokosc = 40).
Rysujemy go od punktu x, ale jego prawa krawędź sięga do x + 40.
Przy szybkim ruchu w prawo może „wyskoczyć" za ekran nawet gdy x wygląda na OK — to wrócimy w kroku 4.5.predkosc = 5 jest w jednym miejscu — zmiana jednej liczby zmienia szybkość w całej grze.
klawisze = pygame.key.get_pressed()
get_pressed() zwraca listę ~512 wartości True/False — jedną dla każdego klawisza:# Co "widzi" Python po wywołaniu get_pressed():
# klawisze = [False, False, ..., True, ..., False, ...]
# ^
# ten jeden True = strzałka lewa jest wciśnięta
Każdy slot to: True = klawisz wciśnięty, False = klawisz zwolniony.pygame.K_LEFT to stała o wartości 276 — po prostu numer klawisza strzałki lewej.klawisze[pygame.K_LEFT] = klawisze[276] — sprawdzasz slot 276 na liście True/False.True → klawisz jest teraz wciśnięty. Jeśli = False → nie jest.lista = [False, False, True, False]
print(lista[2]) # True — jak sprawdzasz element o indeksie 2
# get_pressed działa tak samo:
klawisze = pygame.key.get_pressed()
print(klawisze[pygame.K_LEFT]) # True jeśli lewa strzałka wciśnięta
print(pygame.K_LEFT) # 276 — strzałka lewa
print(pygame.K_RIGHT) # 275 — strzałka prawa
print(pygame.K_UP) # 273 — strzałka górna
print(pygame.K_DOWN) # 274 — strzałka dolna
print(pygame.K_SPACE) # 32 — spacja
klawisze[276] piszemy klawisze[pygame.K_LEFT] — czytelnie i bezpiecznie.pygame.K_ + mała litera. Zawsze małe!pygame.K_a # klawisz A
pygame.K_d # klawisz D
pygame.K_w # klawisz W
pygame.K_s # klawisz S
pygame.K_A (z wielką literą) — litery są zawsze małe, od K_a do K_z.klawisze = pygame.key.get_pressed()
if klawisze[pygame.K_LEFT]:
statek_x -= predkosc
if klawisze[pygame.K_RIGHT]:
statek_x += predkosc
if klawisze[pygame.K_UP]:
statek_y -= predkosc
if klawisze[pygame.K_DOWN]:
statek_y += predkosc
statek_x -= predkosc → zmieniamy współrzędną X o 5 pikseli w lewo.statek_x += predkosc → zmieniamy X o 5 pikseli w prawo.statek_y (nie X!).ekran.fill() — ekran zostaje wyczyszczony, i pygame.draw.rect() rysuje statek od nowa — ale już w nowych współrzędnych. Dlatego statek wydaje się poruszać.statek_x | góra/dół zmieniają statek_y.
python gra_04.py# Lecimy w lewo przez chwilę:
statek_x = -60 # statek całkowicie poza ekranem, niewidoczny
statek_x = -800 # daleko "po lewej stronie" — Pygame rysuje poza oknem
# Lecimy w prawo:
statek_x = 1200 # gdzieś daleko w prawo, też niewidoczny
if które sprawdzają i korygują pozycję po każdym ruchu.
statek_x spadnie poniżej 0 → wróć na 0.
if statek_x < 0:
statek_x = 0
SZEROKOSC - statek_szerokosc?statek_x to współrzędna lewej krawędzi prostokąta (tak działa draw.rect).statek_x + statek_szerokoscstatek_x + statek_szerokosc ≤ SZEROKOSCstatek_x ≤ SZEROKOSC - statek_szerokosc → (800 - 40 = 760)
# Diagram: ekran 800px, statek 40px
# |←── statek_x ──→|←─ 40 ─→|
# 0 760 800
#
# statek_x może być maksymalnie 760 — wtedy prawa krawędź jest na 800
if statek_x > SZEROKOSC - statek_szerokosc:
statek_x = SZEROKOSC - statek_szerokosc
if statek_x < 0:
statek_x = 0
if statek_x > SZEROKOSC - statek_szerokosc:
statek_x = SZEROKOSC - statek_szerokosc
if statek_y < 0:
statek_y = 0
if statek_y > WYSOKOSC - statek_wysokosc:
statek_y = WYSOKOSC - statek_wysokosc
import pygame
pygame.init()
SZEROKOSC = 800
WYSOKOSC = 600
ekran = pygame.display.set_mode((SZEROKOSC, WYSOKOSC))
pygame.display.set_caption("Asteroidy — Lekcja 4: Ruch Statku!")
zegar = pygame.time.Clock()
statek_szerokosc = 40
statek_wysokosc = 50
statek_x = SZEROKOSC // 2 - statek_szerokosc // 2
statek_y = WYSOKOSC - 80
predkosc = 5
font = pygame.font.SysFont("Arial", 22)
while True:
for zdarzenie in pygame.event.get():
if zdarzenie.type == pygame.QUIT:
pygame.quit()
exit()
klawisze = pygame.key.get_pressed()
if klawisze[pygame.K_LEFT]:
statek_x -= predkosc
if klawisze[pygame.K_RIGHT]:
statek_x += predkosc
if klawisze[pygame.K_UP]:
statek_y -= predkosc
if klawisze[pygame.K_DOWN]:
statek_y += predkosc
if statek_x < 0:
statek_x = 0
if statek_x > SZEROKOSC - statek_szerokosc:
statek_x = SZEROKOSC - statek_szerokosc
if statek_y < 0:
statek_y = 0
if statek_y > WYSOKOSC - statek_wysokosc:
statek_y = WYSOKOSC - statek_wysokosc
ekran.fill((0, 0, 30))
pygame.draw.rect(ekran, (0, 200, 255),
(statek_x, statek_y, statek_szerokosc, statek_wysokosc))
napis = font.render("Steruj strzalkami | X={} Y={}".format(statek_x, statek_y),
True, (200, 200, 200))
ekran.blit(napis, (10, 10))
pygame.display.flip()
zegar.tick(60)
predkosc = 5 na 25 — prawie niemożliwe do kontrolowania. Na 1 — ultra precyzja.SZEROKOSC // 2 — statek nie może wejść do prawej połowy ekranu.0 na 100 — statek nie podchodzi do lewej ściany.K_a (lewo), K_d (prawo), K_w (góra), K_s (dół)predkosc_y = 3 — wolniejszy ruch pionowy"X={} Y={} | V={}".format(statek_x, statek_y, predkosc)statek_x = 0 wpisz predkosc = -predkoscrandom)True/False) do wykrywania kolizji i nietykalnościprint, range...), ale do wyspecjalizowanych zadań
używamy modułów — gotowych zestawów funkcji napisanych przez innych programistów:import random # moduł do losowania liczb
import math # moduł do obliczeń matematycznych
# import pygame — to też jest moduł!
import musi być na początku pliku — zanim użyjemy czegokolwiek z modułu.random.nazwa_funkcji().
import random
print(random.randint(1, 10)) # losowa liczba od 1 do 10 włącznie
print(random.randint(0, 799)) # losowa pozycja X na ekranie 800px
print(random.randint(20, 55)) # losowy rozmiar asteroidy
randint zawiera oba końce zakresu — randint(1, 10) może dać 1 i może dać 10.cwiczenie_random_1.py, cwiczenie_random_2.py, cwiczenie_random_3.py — wpisuj i uruchamiaj każdy z osobna.
import random
liczba = random.randint(1, 10)
print("Wylosowana liczba:", liczba)
(1, 100), potem na (500, 800).randomrandom.randint(a, b) do losowania liczbimport random
szerokosc = 800
wysokosc = 600
x = random.randint(0, szerokosc - 50)
y = random.randint(0, wysokosc // 2)
rozmiar = random.randint(20, 55)
print("Asteroida:")
print(" x =", x)
print(" y =", y)
print(" rozmiar=", rozmiar)
print(" prawa krawedz =", x + rozmiar)
y żeby asteroida pojawiała się tylko w górnej ćwiartce (0–150). Zmień max rozmiar na 150 — czy prawa krawędź mieści się w ekranie?x + rozmiarimport random
print("Losujemy 5 asteroid:")
for i in range(5):
x = random.randint(0, 760)
y = random.randint(0, 300)
rozmiar = random.randint(20, 55)
print("Asteroida", i, "→ x={} y={} rozmiar={}".format(x, y, rozmiar))
for z L02 i random z tej lekcji. Za kilka lekcji użyjemy tego samego wzorca do tworzenia wielu asteroid w grze!
x -= predkosc i startuj od x = 50. Dodaj granicę lewą: if x < 0: x = 0. Teraz prawa krawędź to po prostu x + szer_statku.SZEROKOSC - szer_statku+=) z warunkiem granicy (if)import pygame, dodaj:import random
random.randint(...) wywoła błąd: NameError: name 'random' is not defined.
# --- ASTEROIDA (losujemy raz przy uruchomieniu) ---
asteroida_x = random.randint(0, SZEROKOSC - 50)
asteroida_y = random.randint(50, 250)
asteroida_rozmiar = random.randint(20, 55)
x, y) i jak duży (rozmiar).SZEROKOSC - 50? Żeby prawa krawędź asteroidy (x + ~50) nie wychodziła poza ekran.
while True:
# ŹLE — te linie SĄ W PĘTLI:
asteroida_x = random.randint(0, SZEROKOSC - 50) # losuje 60x na sekundę!
asteroida_y = random.randint(50, 250)
...
pygame.draw.rect(ekran, (160,160,160), (asteroida_x, asteroida_y, ...))
Efekt: Asteroida teleportuje się w losowe miejsce co klatkę — 60 razy na sekundę. Zamiast jednej nieruchomej asteroidy widzisz chaotyczny migający prostokąt wszędzie na ekranie.pygame.draw.rect(ekran, (160, 160, 160),
(asteroida_x, asteroida_y, asteroida_rozmiar, asteroida_rozmiar))
(160, 160, 160) — szary (wszystkie trzy wartości RGB równe = szarość).asteroida_rozmiar.
napis = font.render("Asteroida X={} Y={} rozmiar={}".format(
asteroida_x, asteroida_y, asteroida_rozmiar), True, (200, 200, 200))
ekran.blit(napis, (10, 10))
python gra_05.py. Obserwuj pozycję i rozmiar asteroidy w HUD.random — każda rozgrywka wygląda inaczej.
import pygame
import random
pygame.init()
SZEROKOSC = 800
WYSOKOSC = 600
ekran = pygame.display.set_mode((SZEROKOSC, WYSOKOSC))
pygame.display.set_caption("Asteroidy — Lekcja 5: Pierwsza Asteroida!")
zegar = pygame.time.Clock()
statek_szerokosc = 40
statek_wysokosc = 50
statek_x = SZEROKOSC // 2 - statek_szerokosc // 2
statek_y = WYSOKOSC - 80
predkosc = 5
asteroida_x = random.randint(0, SZEROKOSC - 50)
asteroida_y = random.randint(50, 250)
asteroida_rozmiar = random.randint(20, 55)
font = pygame.font.SysFont("Arial", 22)
while True:
for zdarzenie in pygame.event.get():
if zdarzenie.type == pygame.QUIT:
pygame.quit()
exit()
klawisze = pygame.key.get_pressed()
if klawisze[pygame.K_LEFT]: statek_x -= predkosc
if klawisze[pygame.K_RIGHT]: statek_x += predkosc
if klawisze[pygame.K_UP]: statek_y -= predkosc
if klawisze[pygame.K_DOWN]: statek_y += predkosc
if statek_x < 0: statek_x = 0
if statek_x > SZEROKOSC - statek_szerokosc: statek_x = SZEROKOSC - statek_szerokosc
if statek_y < 0: statek_y = 0
if statek_y > WYSOKOSC - statek_wysokosc: statek_y = WYSOKOSC - statek_wysokosc
ekran.fill((0, 0, 30))
pygame.draw.rect(ekran, (0, 200, 255),
(statek_x, statek_y, statek_szerokosc, statek_wysokosc))
pygame.draw.rect(ekran, (160, 160, 160),
(asteroida_x, asteroida_y, asteroida_rozmiar, asteroida_rozmiar))
napis = font.render("Asteroida X={} Y={} rozmiar={}".format(
asteroida_x, asteroida_y, asteroida_rozmiar), True, (200, 200, 200))
ekran.blit(napis, (10, 10))
pygame.display.flip()
zegar.tick(60)
(0, 100) — asteroida zawsze blisko lewej. Potem (700, 760) — blisko prawej.(5, 200) — jakie monstrum może wylosować?random.randint(400, 400) — co zwraca gdy a == b?asteroida2_x, asteroida2_y, asteroida2_rozmiar i narysuj jąjasnosc = random.randint(100, 255) → kolor (jasnosc, jasnosc, jasnosc)y tak, żeby asteroida nigdy nie pojawiała się w dolnej połowie ekranu (gdzie jest statek)while True działa 60 razy na sekundę. Każde przejście przez pętlę to jedna klatka animacji.y = 0 # pozycja startowa
predkosc = 3 # pikseli na klatkę
# Wyobraź sobie 30 klatek animacji:
for klatka in range(30):
y += predkosc # przesuwamy o 3 piksele
print("Klatka", klatka, "→ y =", y)
y = 90. W grze przy 60 FPS: 60 × 3 = 180 pikseli na sekundę.
y = 0
predkosc = 3
wysokosc_ekranu = 600
for klatka in range(300):
y += predkosc
if y > wysokosc_ekranu: # wyleciał poza dół
y = -50 # teleportuj nad ekran
print("Klatka", klatka, "→ y =", y)
y = -50? Bo chcemy żeby obiekt wjechał z góry ekranu — zaczyna ponad krawędzią.
cwiczenie_animacja_1.py i cwiczenie_animacja_2.py — wpisuj i uruchamiaj każdy z osobna.
y = 0
predkosc = 3
for klatka in range(30):
y += predkosc
if y > 600:
y = -50 # reset nad ekran
print("Klatka {:2d} → y = {}".format(klatka, y))
predkosc na 50 — po ilu klatkach pierwszy reset? Zmień na 200 — co się dzieje?y += predkosc w każdej klatcey1 = 0
y2 = 0
predkosc1 = 3
predkosc2 = 7
for klatka in range(20):
y1 += predkosc1
y2 += predkosc2
if y1 > 600: y1 = -50
if y2 > 600: y2 = -50
print("Klatka {:2d} → y1={:4d} y2={:4d}".format(klatka, y1, y2))
predkosc2 = 7 na predkosc2 = predkosc1 * 2 — czy wynik się zmienia?gra_05.py, zapisz kopię jako gra_06.py."Asteroidy — Lekcja 6: Spadajaca Asteroida!"
asteroida_y += asteroida_predkosc. Gdy y > WYSOKOSC: reset y do wartości ujemnej i nowe losowe x.import pygame
import random
...
predkosc = 5
# Asteroida — ZMIENIAMY: startuje ponad ekranem
asteroida_x = random.randint(0, SZEROKOSC - 50)
asteroida_y = -50 # <-- ZMIENIAMY (krok 4.1)
asteroida_rozmiar = random.randint(25, 55)
asteroida_predkosc = 3 # <-- DODAJEMY (krok 4.1)
font = pygame.font.SysFont("Arial", 22)
while True:
...
# <-- DODAJEMY ruch asteroidy (krok 4.2)
# <-- DODAJEMY reset gdy wyleci z ekranu (krok 4.3)
ekran.fill((0, 0, 30))
pygame.draw.rect(...) # statek
pygame.draw.rect(...) # asteroida
pygame.display.flip()
zegar.tick(60)
y = -50 (ponad ekranem) i dodaj zmienną prędkości:asteroida_x = random.randint(0, SZEROKOSC - 50)
asteroida_y = -50 # startuje ponad ekranem
asteroida_rozmiar = random.randint(25, 55)
asteroida_predkosc = 3 # 3 piksele na klatkę
-50? Chcemy żeby asteroida wpłynęła z góry — zanim pojawi się na ekranie, lecąc od góry.asteroida_predkosc = 3) zamiast wpisanego 3 w pętli — łatwo zmienić jedną liczbą.
# --- NOWE: poruszamy asteroidą w dół ---
asteroida_y += asteroida_predkosc # += to skrót: asteroida_y = asteroida_y + asteroida_predkosc
y rośnie o 3. Przy 60 FPS: 180 pikseli na sekundę.
asteroida_y += ... dodaj blok resetu:# --- NOWE: reset asteroidy gdy wyleci za dolną krawędź ---
if asteroida_y > WYSOKOSC:
asteroida_y = -asteroida_rozmiar # teleportuj nad ekran
asteroida_x = random.randint(0, SZEROKOSC - asteroida_rozmiar) # nowa pozycja X
asteroida_rozmiar = random.randint(25, 55) # nowy losowy rozmiar
-asteroida_rozmiar? Żeby asteroida zaczęła wchodzić od góry, a nie pojawiła się nagle w połowie ekranu.import pygame
import random
# === LEKCJA 6: Ruch Asteroidy ===
# Cel: asteroida spada z góry i resetuje się na nowej pozycji!
pygame.init()
SZEROKOSC = 800
WYSOKOSC = 600
ekran = pygame.display.set_mode((SZEROKOSC, WYSOKOSC))
pygame.display.set_caption("Asteroidy — Lekcja 6: Spadajaca Asteroida!")
zegar = pygame.time.Clock()
# Statek
statek_szerokosc = 40
statek_wysokosc = 50
statek_x = SZEROKOSC // 2 - statek_szerokosc // 2
statek_y = WYSOKOSC - 80
predkosc = 5
# Asteroida — zaczyna poza ekranem (nad górą)
asteroida_x = random.randint(0, SZEROKOSC - 50)
asteroida_y = -50
asteroida_rozmiar = random.randint(25, 55)
asteroida_predkosc = 3
font = pygame.font.SysFont("Arial", 22)
while True:
for zdarzenie in pygame.event.get():
if zdarzenie.type == pygame.QUIT:
pygame.quit()
exit()
klawisze = pygame.key.get_pressed()
if klawisze[pygame.K_LEFT]:
statek_x -= predkosc
if klawisze[pygame.K_RIGHT]:
statek_x += predkosc
if klawisze[pygame.K_UP]:
statek_y -= predkosc
if klawisze[pygame.K_DOWN]:
statek_y += predkosc
if statek_x < 0: statek_x = 0
if statek_x > SZEROKOSC - statek_szerokosc: statek_x = SZEROKOSC - statek_szerokosc
if statek_y < 0: statek_y = 0
if statek_y > WYSOKOSC - statek_wysokosc: statek_y = WYSOKOSC - statek_wysokosc
# --- NOWE: poruszamy asteroidą w dół ---
asteroida_y += asteroida_predkosc
# --- NOWE: reset asteroidy gdy wyleci za dolną krawędź ---
if asteroida_y > WYSOKOSC:
asteroida_y = -asteroida_rozmiar
asteroida_x = random.randint(0, SZEROKOSC - asteroida_rozmiar)
asteroida_rozmiar = random.randint(25, 55)
ekran.fill((0, 0, 30))
pygame.draw.rect(ekran, (0, 200, 255), (statek_x, statek_y, statek_szerokosc, statek_wysokosc))
pygame.draw.rect(ekran, (160, 160, 160), (asteroida_x, asteroida_y, asteroida_rozmiar, asteroida_rozmiar))
napis = font.render("Unikaj asteroidy! Predkosc={}".format(asteroida_predkosc), True, (255, 255, 100))
ekran.blit(napis, (10, 10))
pygame.display.flip()
zegar.tick(60)
asteroida_predkosc = 3 na 10 — o ile szybciej spada? Oblicz piksele na sekundę.1 — jak długo trwa jedno przejście przez ekran?asteroida_predkosc = 0 — co się dzieje? Dlaczego asteroid nie widać?(200, 50, 50) — jak wygląda czerwona skała?asteroida2_x, asteroida2_y, asteroida2_predkosc i własnym resetemrandom.randint(2, 7)True (tak/włączone) lub False (nie/wyłączone).trafiony = False # statek nie jest trafiony
# Gdy nastąpi trafienie:
trafiony = True
# Sprawdzamy stan:
if trafiony:
print("Statek trafiony!")
else:
print("Statek cały.")
and (oba muszą być True), not (odwraca wartość):zycia = 3
trafiony = False
if zycia > 0 and not trafiony:
print("Gra trwa!")
cwiczenie_flaga_1.py i cwiczenie_flaga_2.py — wpisuj i uruchamiaj każdy z osobna.
trafiony = False
zycia = 3
print("Stan startowy:")
print(" trafiony =", trafiony)
print(" zycia =", zycia)
# Symulujemy trafienie
trafiony = True
zycia -= 1
print("\nPo trafieniu:")
print(" trafiony =", trafiony)
print(" zycia =", zycia)
# Sprawdzamy warunek
if zycia > 0 and not trafiony:
print("\nMozna strzelac!")
else:
print("\nNie mozna — trafiony lub brak zyc!")
trafiony = False i zycia = 1 — jaki komunikat? Zmień na trafiony = True i zycia = 5 — co wtedy?True/Falseifand notnietykalny = False
licznik_nietykalnosci = 0
for klatka in range(20):
if klatka == 5: # w klatce 5 dostajemy cios
nietykalny = True
licznik_nietykalnosci = 0
if nietykalny:
licznik_nietykalnosci += 1
if licznik_nietykalnosci >= 8: # 8 klatek nietykalności
nietykalny = False
stan = "NIETYKALNY" if nietykalny else "normalny"
print("Klatka {:2d} → {}".format(klatka, stan))
pygame.time.get_ticks().
range(5) na range(10). Dopisz wypisywanie prawej krawędzi (x + rozmiar) i sprawdź czy żadna nie wychodzi poza 800.for z losowaniem przez randomrandint(a, b) losuje liczbę całkowitą. Są też inne przydatne funkcje z modułu random:import random
# choice() — losuje jeden element z listy
kolory = ["czerwony", "zielony", "niebieski", "żółty"]
wybrany = random.choice(kolory)
print("Losowy kolor:", wybrany)
# choice() z listą liczb
rozmiary = [20, 30, 40, 50, 60]
rozmiar = random.choice(rozmiary)
print("Losowy rozmiar asteroidy:", rozmiar)
# uniform(a, b) — losuje liczbę z ułamkiem między a i b
predkosc = random.uniform(1.5, 4.0)
print("Losowa prędkość:", predkosc) # np. 2.847...
random.choice() przyda się do losowania koloru wroga, typu asteroidy, kierunku ruchu.
gra_04.py, zapisz kopię jako gra_05.py."Asteroidy — Lekcja 5: Pierwsza Asteroida!"
import pygame
import random # <-- DODAJEMY (krok 4.1)
...
predkosc = 5
# <-- TUTAJ DODAMY ZMIENNE ASTEROIDY (krok 4.2)
font = pygame.font.SysFont("Arial", 22)
while True:
...
ekran.fill((0, 0, 30))
pygame.draw.rect(...) # statek
# <-- TUTAJ NARYSUJEMY ASTEROIDĘ (krok 4.3)
# <-- TUTAJ DODAMY JEJ DANE DO HUD (krok 4.4)
pygame.display.flip()
zegar.tick(60)
asteroida_x, asteroida_y, asteroida_rozmiar) losujemy przez random.randint() przed pętlą gry.gra_05.py, zaraz pod import pygame, dodaj:import random
random.randint(...) wywoła błąd: NameError: name 'random' is not defined.
font = ...), dodaj trzy zmienne asteroidy:# --- NOWE: losowa asteroida ---
asteroida_x = random.randint(0, SZEROKOSC - 50)
asteroida_y = random.randint(50, 250)
asteroida_rozmiar = random.randint(20, 55)
x, y) i jak duży (rozmiar).SZEROKOSC - 50? Żeby prawa krawędź asteroidy (x + ~50) nie wychodziła poza ekran.
while True:
# ŹLE — te linie SĄ W PĘTLI:
asteroida_x = random.randint(0, SZEROKOSC - 50) # losuje 60x na sekundę!
asteroida_y = random.randint(50, 250)
pygame.draw.rect(ekran, (160,160,160), (asteroida_x, asteroida_y, ...))
Efekt: Asteroida teleportuje się w losowe miejsce 60 razy na sekundę — widzisz migający chaos zamiast jednej nieruchomej asteroidy.# --- NOWE: rysujemy asteroidę (szary prostokąt) ---
pygame.draw.rect(ekran, (160, 160, 160),
(asteroida_x, asteroida_y, asteroida_rozmiar, asteroida_rozmiar))
(160, 160, 160) — szary (wszystkie trzy wartości RGB równe = szarość).asteroida_rozmiar. Dokładnie to samo draw.rect co statek z G02!
napis = font.render("Asteroida X={} Y={} rozmiar={}".format(
asteroida_x, asteroida_y, asteroida_rozmiar), True, (200, 200, 200))
ekran.blit(napis, (10, 10))
random.
import pygame
import random
# === LEKCJA 5: Losowość i Pierwsza Asteroida ===
pygame.init()
SZEROKOSC = 800
WYSOKOSC = 600
ekran = pygame.display.set_mode((SZEROKOSC, WYSOKOSC))
pygame.display.set_caption("Asteroidy — Lekcja 5: Pierwsza Asteroida!")
zegar = pygame.time.Clock()
statek_szerokosc = 40
statek_wysokosc = 50
statek_x = SZEROKOSC // 2 - statek_szerokosc // 2
statek_y = WYSOKOSC - 80
predkosc = 5
asteroida_x = random.randint(0, SZEROKOSC - 50)
asteroida_y = random.randint(50, 250)
asteroida_rozmiar = random.randint(20, 55)
font = pygame.font.SysFont("Arial", 22)
while True:
for zdarzenie in pygame.event.get():
if zdarzenie.type == pygame.QUIT:
pygame.quit()
exit()
klawisze = pygame.key.get_pressed()
if klawisze[pygame.K_LEFT]: statek_x -= predkosc
if klawisze[pygame.K_RIGHT]: statek_x += predkosc
if klawisze[pygame.K_UP]: statek_y -= predkosc
if klawisze[pygame.K_DOWN]: statek_y += predkosc
if statek_x < 0: statek_x = 0
if statek_x > SZEROKOSC - statek_szerokosc: statek_x = SZEROKOSC - statek_szerokosc
if statek_y < 0: statek_y = 0
if statek_y > WYSOKOSC - statek_wysokosc: statek_y = WYSOKOSC - statek_wysokosc
ekran.fill((0, 0, 30))
pygame.draw.rect(ekran, (0, 200, 255),
(statek_x, statek_y, statek_szerokosc, statek_wysokosc))
pygame.draw.rect(ekran, (160, 160, 160),
(asteroida_x, asteroida_y, asteroida_rozmiar, asteroida_rozmiar))
napis = font.render("Asteroida X={} Y={} rozmiar={}".format(
asteroida_x, asteroida_y, asteroida_rozmiar), True, (200, 200, 200))
ekran.blit(napis, (10, 10))
napis2 = font.render("Zamknij i uruchom ponownie — inna asteroida!", True, (255, 255, 100))
ekran.blit(napis2, (10, 40))
pygame.display.flip()
zegar.tick(60)
random.randint(0, 100) — asteroida zawsze blisko lewej. Potem (700, 760) — blisko prawej.(5, 200) — jakie monstrum może wylosować?random.randint(400, 400) — co zwraca gdy a == b?asteroida2_x, asteroida2_y, asteroida2_rozmiar i narysuj ją w innym kolorzejasnosc = random.randint(100, 255) → kolor (jasnosc, jasnosc, jasnosc)y tak, żeby asteroida nigdy nie pojawiała się w dolnej połowie ekranu (gdzie jest statek)if/elif/else żeby rozróżnić trafienie wroga (20 pkt) od asteroidy (10 pkt)zycia = 3
laser_aktywny = False
# and — oba muszą być True
if zycia > 0 and laser_aktywny:
print("Laser leci i grasz")
# not — odwraca wartość
if not laser_aktywny:
print("Laser jest gotowy do strzału")
# and not — połączenie
if zycia > 0 and not laser_aktywny:
print("Możesz strzelać!")
and:True and True → True | True and False → False | False and True → False
cwiczenie_and_1.py i cwiczenie_and_2.py — wpisuj i uruchamiaj każdy z osobna.
zycia = 3
tarczа = True
laser_aktywny = False
print("zycia > 0:", zycia > 0)
print("not laser_aktywny:", not laser_aktywny)
print("zycia > 0 and not laser_aktywny:", zycia > 0 and not laser_aktywny)
print("tarcza and not laser_aktywny:", tarcza and not laser_aktywny)
# Zmień wartości i sprawdź co się zmienia:
laser_aktywny = True
print("\nPo zmianie laser_aktywny = True:")
print("zycia > 0 and not laser_aktywny:", zycia > 0 and not laser_aktywny)
zycia = 0 — co zwraca pierwszy warunek? Zmień tarcza = False — jak zmienia się wynik złożonych warunków?and, or, notTruelaser_aktywny = False
zycia = 3
spacja_wcisnięta = True # symulujemy wciśnięcie SPACJI
for klatka in range(10):
# Strzelamy tylko gdy SPACJA i laser NIE jest aktywny
if spacja_wcisnięta and not laser_aktywny:
laser_aktywny = True
print("Klatka {}: STRZAL! laser leci.".format(klatka))
if laser_aktywny:
print("Klatka {}: laser w powietrzu".format(klatka))
if klatka >= 5: # po klatce 5 laser dociera do góry
laser_aktywny = False
print("Klatka {}: laser zniknal".format(klatka))
and not laser_aktywny blokuje drugi strzał dopóki pierwszy nie zniknie.
4 — krótka nietykalność. Zmień na 15 — długa. Dodaj drugie trafienie w klatce 12.and wymaga żeby oba warunki były prawdziwe. or wymaga żeby przynajmniej jeden był prawdziwy:stan = "game_over"
# or — prawda gdy CHOĆ JEDEN warunek jest spełniony
if stan == "start" or stan == "game_over":
print("Jesteśmy w menu — czekamy na ENTER")
# and — prawda gdy OBA warunki są spełnione
hp = 0
trafiony = True
if hp == 0 and trafiony:
print("Gracz pokonany")
# not — odwraca warunek
laser_aktywny = False
if not laser_aktywny:
print("Można strzelić")
True and True → TrueTrue and False → FalseTrue or False → TrueFalse or False → Falsenot True → False
pygame.Rect + colliderect() zastąpią ręczne sprawdzanie pozycji.gra_06.py, zapisz kopię jako gra_07.py."Asteroidy — Lekcja 7: Kolizje!"
pygame.Rect + colliderect() wykrywa zachodzenie prostokątów. Flaga trafiony = True aktywuje efekt i blokuje kolejne trafienia przez 600 ms....
asteroida_predkosc = 3
# <-- DODAJEMY system żyć i flagę (krok 4.1)
# zycia = 3, trafiony = False, czas_trafienia = 0
while True:
...
asteroida_y += asteroida_predkosc
if asteroida_y > WYSOKOSC: ...
# <-- TUTAJ: pygame.Rect i colliderect (krok 4.2)
# <-- TUTAJ: obsługa trafienia i flagi (krok 4.3)
# <-- ZMIENIAMY: kolor tła i kolor statku (krok 4.4)
ekran.fill(...)
pygame.draw.rect(ekran, kolor_statku, ...)
...
font = ...) dodaj zmienne systemu żyć:zycia = 3
trafiony = False # czy właśnie dostaliśmy cios?
czas_trafienia = 0 # kiedy dostaliśmy cios (ms)
font = pygame.font.SysFont("Arial", 26)
font_duzy = pygame.font.SysFont("Arial", 64)
trafiony = False — flaga logiczna. Gdy True: statek jest w trybie nietykalności.czas_trafienia — zapamiętamy tu moment trafienia w milisekundach.font do HUD, font_duzy do napisu "BUM!" na środku ekranu.
# --- NOWE: tworzymy prostokąty do sprawdzania kolizji ---
statek_rect = pygame.Rect(statek_x, statek_y, statek_szerokosc, statek_wysokosc)
asteroida_rect = pygame.Rect(asteroida_x, asteroida_y, asteroida_rozmiar, asteroida_rozmiar)
pygame.Rect(x, y, szerokosc, wysokosc) — tworzy niewidoczny prostokąt w podanym miejscu.# --- NOWE: czy prostokąty się nakrywają? ---
if statek_rect.colliderect(asteroida_rect) and not trafiony:
zycia -= 1
trafiony = True
czas_trafienia = pygame.time.get_ticks() # zapisz czas trafienia w ms
# Resetuj asteroidę — nowa pozycja
asteroida_y = -asteroida_rozmiar
asteroida_x = random.randint(0, SZEROKOSC - asteroida_rozmiar)
# Efekt trafienia kończy się po 600 ms
if trafiony and pygame.time.get_ticks() - czas_trafienia > 600:
trafiony = False
colliderect() zwraca True gdy dwa prostokąty się nakrywają.and not trafiony — blokuje kolejne trafienia przez 600 ms. Bez tego gracz traciłby 3 życia w ułamku sekundy (kolizja wykrywana 60× na sekundę przez kilka klatek z rzędu).
# ŹLE — brak "and not trafiony":
if statek_rect.colliderect(asteroida_rect):
zycia -= 1 # odpala 60x na sekundę przez kilka klatek!
Efekt: Klatka 1: -1, klatka 2: -1, klatka 3: -1. Gra kończy się zanim gracz zdąży zareagować.trafiony daje 600 ms nietykalności po każdym ciosie — klasyczny wzorzec i-frames.
ekran.fill i rysowanie statku wersją reagującą na flagę:# Tło — czerwone po trafieniu, normalne podczas gry
if trafiony:
ekran.fill((80, 0, 0))
else:
ekran.fill((0, 0, 30))
# Kolor statku zmienia się po trafieniu
kolor_statku = (255, 80, 80) if trafiony else (0, 200, 255)
pygame.draw.rect(ekran, kolor_statku, (statek_x, statek_y, statek_szerokosc, statek_wysokosc))
pygame.draw.rect(ekran, (160, 160, 160), (asteroida_x, asteroida_y, asteroida_rozmiar, asteroida_rozmiar))
# HUD z życiami i napisem BUM!
zycia_tekst = "Zycia: " + ("* " * zycia)
ekran.blit(font.render(zycia_tekst, True, (255, 80, 80)), (10, 10))
if trafiony:
bum = font_duzy.render("BUM!", True, (255, 255, 0))
ekran.blit(bum, (SZEROKOSC // 2 - 70, WYSOKOSC // 2 - 50))
(255, 80, 80) if trafiony else (0, 200, 255) — skrócony if/else w jednej linii (wyrażenie warunkowe).pygame.display.flip(), dodaj sprawdzenie:if zycia <= 0:
ekran.fill((0, 0, 0))
koniec = font_duzy.render("KONIEC GRY!", True, (255, 50, 50))
ekran.blit(koniec, (SZEROKOSC // 2 - 180, WYSOKOSC // 2 - 50))
pygame.display.flip()
pygame.time.wait(3000) # czekamy 3 sekundy
pygame.quit()
exit()
pygame.time.wait(3000) — zatrzymuje program na 3000 ms = 3 sekundy, żeby gracz zdążył przeczytać wynik.pygame.quit() i exit() zamykają grę.
import pygame
import random
# === LEKCJA 7: Kolizje! ===
pygame.init()
SZEROKOSC = 800
WYSOKOSC = 600
ekran = pygame.display.set_mode((SZEROKOSC, WYSOKOSC))
pygame.display.set_caption("Asteroidy — Lekcja 7: Kolizje!")
zegar = pygame.time.Clock()
statek_szerokosc = 40
statek_wysokosc = 50
statek_x = SZEROKOSC // 2 - statek_szerokosc // 2
statek_y = WYSOKOSC - 80
predkosc = 5
asteroida_x = random.randint(0, SZEROKOSC - 50)
asteroida_y = -50
asteroida_rozmiar = random.randint(30, 55)
asteroida_predkosc = 3
zycia = 3
trafiony = False
czas_trafienia = 0
font = pygame.font.SysFont("Arial", 26)
font_duzy = pygame.font.SysFont("Arial", 64)
while True:
for zdarzenie in pygame.event.get():
if zdarzenie.type == pygame.QUIT:
pygame.quit()
exit()
klawisze = pygame.key.get_pressed()
if klawisze[pygame.K_LEFT]: statek_x -= predkosc
if klawisze[pygame.K_RIGHT]: statek_x += predkosc
if klawisze[pygame.K_UP]: statek_y -= predkosc
if klawisze[pygame.K_DOWN]: statek_y += predkosc
if statek_x < 0: statek_x = 0
if statek_x > SZEROKOSC - statek_szerokosc: statek_x = SZEROKOSC - statek_szerokosc
if statek_y < 0: statek_y = 0
if statek_y > WYSOKOSC - statek_wysokosc: statek_y = WYSOKOSC - statek_wysokosc
asteroida_y += asteroida_predkosc
if asteroida_y > WYSOKOSC:
asteroida_y = -asteroida_rozmiar
asteroida_x = random.randint(0, SZEROKOSC - asteroida_rozmiar)
asteroida_rozmiar = random.randint(30, 55)
statek_rect = pygame.Rect(statek_x, statek_y, statek_szerokosc, statek_wysokosc)
asteroida_rect = pygame.Rect(asteroida_x, asteroida_y, asteroida_rozmiar, asteroida_rozmiar)
if statek_rect.colliderect(asteroida_rect) and not trafiony:
zycia -= 1
trafiony = True
czas_trafienia = pygame.time.get_ticks()
asteroida_y = -asteroida_rozmiar
asteroida_x = random.randint(0, SZEROKOSC - asteroida_rozmiar)
if trafiony and pygame.time.get_ticks() - czas_trafienia > 600:
trafiony = False
if trafiony:
ekran.fill((80, 0, 0))
else:
ekran.fill((0, 0, 30))
kolor_statku = (255, 80, 80) if trafiony else (0, 200, 255)
pygame.draw.rect(ekran, kolor_statku, (statek_x, statek_y, statek_szerokosc, statek_wysokosc))
pygame.draw.rect(ekran, (160, 160, 160), (asteroida_x, asteroida_y, asteroida_rozmiar, asteroida_rozmiar))
zycia_tekst = "Zycia: " + ("* " * zycia)
ekran.blit(font.render(zycia_tekst, True, (255, 80, 80)), (10, 10))
if trafiony:
bum = font_duzy.render("BUM!", True, (255, 255, 0))
ekran.blit(bum, (SZEROKOSC // 2 - 70, WYSOKOSC // 2 - 50))
if zycia <= 0:
ekran.fill((0, 0, 0))
koniec = font_duzy.render("KONIEC GRY!", True, (255, 50, 50))
ekran.blit(koniec, (SZEROKOSC // 2 - 180, WYSOKOSC // 2 - 50))
pygame.display.flip()
pygame.time.wait(3000)
pygame.quit()
exit()
pygame.display.flip()
zegar.tick(60)
zycia = 3 na 5 — więcej szans. Ile asteroid możesz ominąć?600 na 100 — krótka nietykalność. Trudniej czy łatwiej?600 na 2000 — 2 sekundy nietykalności. Czy asteroida może trafić gdy jesteś nietykalny?(255, 255, 0) na biały — jaki wygląda lepiej?asteroida_predkosc += 0.5 wewnątrz bloku kolizjimax(0, 600 - (pygame.time.get_ticks() - czas_trafienia))"HP: {}"owoce = ["jabłko", "banan", "gruszka"]
print(owoce[0]) # jabłko — indeksy zaczynają się od 0!
print(owoce[1]) # banan
print(owoce[2]) # gruszka
print(len(owoce)) # 3 — liczba elementów
[0], nie [1]!
owoce = [] # pusta lista
owoce.append("jabłko") # ["jabłko"]
owoce.append("banan") # ["jabłko", "banan"]
owoce.append("gruszka") # ["jabłko", "banan", "gruszka"]
print(owoce)
print("Mam", len(owoce), "owoce")
owoce = ["jabłko", "banan", "gruszka"]
for owoc in owoce:
print("Lubię:", owoc)
liczby = [10, 20, 30, 40]
for n in liczby:
print(n * 2) # 20, 40, 60, 80
kwadraty = []
for i in range(1, 6):
kwadraty.append(i * i)
print(kwadraty) # [1, 4, 9, 16, 25]
punkty = [
[10, 20],
[30, 40],
[50, 60]
]
print(punkty[0]) # [10, 20] — cały pierwszy element
print(punkty[0][0]) # 10 — x pierwszego punktu
print(punkty[0][1]) # 20 — y pierwszego punktu
print(punkty[1][0]) # 30 — x drugiego punktu
for p in punkty:
print("X:", p[0], "Y:", p[1])
plansza = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
]
for wiersz in plansza:
for element in wiersz:
print(element, end=" ") # end=" " nie robi nowej linii
print() # nowa linia po każdym wierszu
Wynik:1 2 34 5 67 8 9
asteroidy = [
[100, 50, 40],
[300, 80, 30],
[500, 120, 50]
]
for ast in asteroidy:
print("Asteroida X:{} Y:{} rozmiar:{}".format(ast[0], ast[1], ast[2]))
lasery = [[400, 500], [410, 480], [420, 460]]
for laser in lasery:
laser[1] -= 9 # każdy leci w górę o 9 pikseli
wrogowie = [
["zielony", 200, 50],
["czerwony", 300, 80],
["fioletowy", 450, 120]
]
for wrog in wrogowie:
print("Wróg:", wrog[0], "pozycja:", wrog[1], wrog[2])
tablica = []
for y in range(4):
wiersz = []
for x in range(4):
wiersz.append(x + y * 4) # każde pole ma unikalny numer
tablica.append(wiersz)
# Wyświetlamy
for wiersz in tablica:
print(wiersz)
mapa = [
[0, 0, 1, 0],
[1, 0, 1, 0],
[0, 0, 0, 1],
[1, 1, 0, 0]
]
for y in range(len(mapa)):
for x in range(len(mapa[y])):
if mapa[y][x] == 1:
print("Ściana na: x={} y={}".format(x, y))
plansza = []
for y in range(5):
wiersz = []
for x in range(5):
wiersz.append((x, y)) # krotka (x, y)
plansza.append(wiersz)
for wiersz in plansza:
print(wiersz)
Wynik:[(0,0), (1,0), (2,0), (3,0), (4,0)][(0,1), (1,1), (2,1), (3,1), (4,1)]def generuj_asteroidy(n):
lista = []
for i in range(n):
lista.append([i * 100, 50, 40]) # x, y, rozmiar
return lista
asteroidy = generuj_asteroidy(5)
for ast in asteroidy:
print("Asteroida:", ast)
cwiczenie_lista_1.py do cwiczenie_lista_5.py — wpisuj i uruchamiaj każdy z osobna.
wyniki = []
wyniki.append(10)
wyniki.append(25)
wyniki.append(5)
print("Lista:", wyniki)
print("Liczba wyników:", len(wyniki))
print("Pierwszy:", wyniki[0])
print("Ostatni:", wyniki[len(wyniki) - 1])
suma = 0
for w in wyniki:
suma += w
print("Suma:", suma)
append(). Potem stwórz listę kwadraty zawierającą kwadraty liczb 1–5 używając pętli for i in range(1, 6).append()len() i indeksowania [0]forasteroidy = [
[100, 50, 40],
[300, 80, 30],
[500, 120, 50]
]
print("Ile asteroid:", len(asteroidy))
print("Pierwsza asteroida:", asteroidy[0])
print("X pierwszej:", asteroidy[0][0])
print("Y pierwszej:", asteroidy[0][1])
for ast in asteroidy:
print("Asteroida X:{} Y:{} rozmiar:{}".format(ast[0], ast[1], ast[2]))
append([700, 200, 60]). Potem zmień y każdej asteroidy o +10 w pętli: ast[1] += 10.[i][j]forlasery = []
lasery.append([400, 500])
lasery.append([100, 480])
lasery.append([700, 490])
print("Lasery przed ruchem:")
for laser in lasery:
print(" x={} y={}".format(laser[0], laser[1]))
# Symulacja 5 klatek
for klatka in range(5):
for laser in lasery:
laser[1] -= 9 # każdy laser leci w górę
print("Lasery po 5 klatkach:")
for laser in lasery:
print(" x={} y={}".format(laser[0], laser[1]))
klatka >= 2 — szybszy laser. Zmień spacja_wcisnięta = False — czy strzał następuje?and not jako warunku strzału laseraand not laser_aktywny bezpośrednio trafi do kodu gry.gra_07.py, zapisz kopię jako gra_08.py."Asteroidy — Lekcja 8: Pierwszy Laser!"
laser_aktywny + dwie zmienne pozycji. Warunek and not laser_aktywny blokuje nowy strzał gdy poprzedni jeszcze leci....
zycia = 3
# <-- DODAJEMY zmienne lasera (krok 4.1)
font = pygame.font.SysFont("Arial", 24)
while True:
...
klawisze = pygame.key.get_pressed()
...
# <-- DODAJEMY strzał na SPACJĘ (krok 4.2)
# <-- DODAJEMY ruch lasera (krok 4.3)
# <-- DODAJEMY dezaktywację (krok 4.4)
...
ekran.fill((0, 0, 30))
pygame.draw.rect(...) # statek
pygame.draw.rect(...) # asteroida
# <-- DODAJEMY rysowanie lasera (krok 4.4)
...
font = ...) dodaj cztery zmienne lasera:# --- NOWE: laser ---
laser_x = 0
laser_y = 0
laser_aktywny = False # czy laser jest w powietrzu?
laser_predkosc = 9 # laser leci szybciej niż statek
laser_aktywny = False — flaga: na starcie nie ma żadnego lasera w powietrzu.laser_predkosc = 9 — trzy razy szybciej niż statek (predkosc = 5). Szybki laser = łatwiej trafić.laser_x, laser_y — pozycja lasera (aktualizowane przy strzale).
# --- NOWE: strzał laserem ---
# Strzelamy tylko gdy SPACJA wciśnięta I laser NIE jest aktywny
if klawisze[pygame.K_SPACE] and not laser_aktywny:
laser_aktywny = True
laser_x = statek_x + statek_szerokosc // 2 - 3 # środek statku
laser_y = statek_y # na górze statku
and not laser_aktywny — blokuje nowy strzał gdy poprzedni laser jeszcze leci.statek_x + statek_szerokosc // 2 - 3 — środek statku (42 px) minus połowa lasera (3 px). Laser wychodzi dokładnie ze środka.
# ŹLE — brak "and not laser_aktywny":
if klawisze[pygame.K_SPACE]:
laser_aktywny = True
laser_x = statek_x + ...
laser_y = statek_y # resetuje pozycję co klatkę!
Efekt: Trzymasz SPACJĘ — laser co klatkę teleportuje się z powrotem na statek i nigdy nie doleci do celu.laser_aktywny sprawia że nowy strzał jest możliwy dopiero gdy poprzedni zniknie.
# --- NOWE: poruszamy laserem w górę ---
if laser_aktywny:
laser_y -= laser_predkosc
# Gdy laser wylatuje poza górę ekranu — deaktywujemy
if laser_y < -20:
laser_aktywny = False
laser_y -= 9 — laser porusza się w górę (y maleje). Minus bo y=0 jest na górze ekranu.laser_y < -20 — gdy laser w całości wyleciał poza górę: flaga z powrotem na False. Można strzelić następny!
# --- NOWE: rysujemy laser (czerwony prostokąt) ---
if laser_aktywny:
pygame.draw.rect(ekran, (255, 50, 50), (laser_x, laser_y, 6, 22))
stan_lasera = "AKTYWNY" if laser_aktywny else "gotowy"
napis = font.render("Zycia: {} SPACJA=strzal Laser: {}".format(
zycia, stan_lasera), True, (255, 255, 255))
ekran.blit(napis, (10, 10))
(255, 50, 50)."gotowy" gdy można strzelić, "AKTYWNY" gdy laser leci.
import pygame
import random
# === LEKCJA 8: Pierwszy Laser ===
pygame.init()
SZEROKOSC = 800
WYSOKOSC = 600
ekran = pygame.display.set_mode((SZEROKOSC, WYSOKOSC))
pygame.display.set_caption("Asteroidy — Lekcja 8: Pierwszy Laser!")
zegar = pygame.time.Clock()
statek_szerokosc = 40
statek_wysokosc = 50
statek_x = SZEROKOSC // 2 - statek_szerokosc // 2
statek_y = WYSOKOSC - 80
predkosc = 5
asteroida_x = random.randint(0, SZEROKOSC - 50)
asteroida_y = -50
asteroida_rozmiar = random.randint(30, 55)
asteroida_predkosc = 3
zycia = 3
laser_x = 0
laser_y = 0
laser_aktywny = False
laser_predkosc = 9
font = pygame.font.SysFont("Arial", 24)
while True:
for zdarzenie in pygame.event.get():
if zdarzenie.type == pygame.QUIT:
pygame.quit()
exit()
klawisze = pygame.key.get_pressed()
if klawisze[pygame.K_LEFT]: statek_x -= predkosc
if klawisze[pygame.K_RIGHT]: statek_x += predkosc
if klawisze[pygame.K_UP]: statek_y -= predkosc
if klawisze[pygame.K_DOWN]: statek_y += predkosc
if statek_x < 0: statek_x = 0
if statek_x > SZEROKOSC - statek_szerokosc: statek_x = SZEROKOSC - statek_szerokosc
if statek_y < 0: statek_y = 0
if statek_y > WYSOKOSC - statek_wysokosc: statek_y = WYSOKOSC - statek_wysokosc
if klawisze[pygame.K_SPACE] and not laser_aktywny:
laser_aktywny = True
laser_x = statek_x + statek_szerokosc // 2 - 3
laser_y = statek_y
if laser_aktywny:
laser_y -= laser_predkosc
if laser_y < -20:
laser_aktywny = False
asteroida_y += asteroida_predkosc
if asteroida_y > WYSOKOSC:
asteroida_y = -asteroida_rozmiar
asteroida_x = random.randint(0, SZEROKOSC - asteroida_rozmiar)
statek_rect = pygame.Rect(statek_x, statek_y, statek_szerokosc, statek_wysokosc)
asteroida_rect = pygame.Rect(asteroida_x, asteroida_y, asteroida_rozmiar, asteroida_rozmiar)
if statek_rect.colliderect(asteroida_rect):
zycia -= 1
asteroida_y = -asteroida_rozmiar
asteroida_x = random.randint(0, SZEROKOSC - asteroida_rozmiar)
ekran.fill((0, 0, 30))
pygame.draw.rect(ekran, (0, 200, 255), (statek_x, statek_y, statek_szerokosc, statek_wysokosc))
pygame.draw.rect(ekran, (160, 160, 160), (asteroida_x, asteroida_y, asteroida_rozmiar, asteroida_rozmiar))
if laser_aktywny:
pygame.draw.rect(ekran, (255, 50, 50), (laser_x, laser_y, 6, 22))
stan_lasera = "AKTYWNY" if laser_aktywny else "gotowy"
napis = font.render("Zycia: {} SPACJA=strzal Laser: {}".format(
zycia, stan_lasera), True, (255, 255, 255))
ekran.blit(napis, (10, 10))
pygame.display.flip()
zegar.tick(60)
laser_predkosc = 9 na 2 — wolny laser. Czy trudniej trafić asteroidę?(255, 255, 0) — jak wygląda żółty laser?(6, 22) na (20, 5) — szeroki i płaski pocisk.laser_y < -20 na laser_y < WYSOKOSC // 2 — laser znika w połowie ekranu.laser_x = statek_xliczba_strzalow = 0 i zwiększaj ją przy każdym strzale. Wyświetl w HUD.laser_y -= laser_predkosc na += i dostosuj warunek dezaktywacjipygame.K_z) z osobnymi zmiennymi laser2_*in:owoce = ["jabłko", "banan", "gruszka"]
if "banan" in owoce:
print("Banan jest na liście!")
if "mango" not in owoce:
print("Nie mamy mango")
.index():indeks = owoce.index("gruszka")
print("Gruszka jest na pozycji:", indeks) # 2
wrogowie = ["zielony", "czerwony", "fioletowy"]
if "czerwony" in wrogowie:
print("Uwaga — czerwony wróg!")
owoce = ["jabłko", "banan", "gruszka", "mango"]
# 1. Usuń po wartości (remove)
owoce.remove("banan") # szuka i usuwa pierwsze wystąpienie
print(owoce) # ["jabłko", "gruszka", "mango"]
# 2. Usuń po indeksie (del)
del owoce[1] # usuwa element o indeksie 1
print(owoce) # ["jabłko", "mango"]
# 3. Usuń i zwróć element (pop)
ostatni = owoce.pop() # domyślnie usuwa ostatni
print("Usunięto:", ostatni) # mango
print(owoce) # ["jabłko"]
pierwszy = owoce.pop(0) # usuwa element o indeksie 0
print("Usunięto:", pierwszy) # jabłko
for to błąd! Zamiast tego — filtrowanie (sekcja 4).
liczby = [1, 2, 3, 2, 2, 5, 2]
print(liczby.count(2)) # 4 — liczba 2 pojawia się 4 razy
akcje = ["strzal", "ruch", "strzal", "strzal", "ruch"]
print(akcje.count("strzal")) # 3
hp_wrogow = [100, 0, 80, 0, 50, 0]
martwi = 0
for hp in hp_wrogow:
if hp == 0:
martwi += 1
print("Martwych wrogów:", martwi) # 3
liczby = [5, -3, 8, -1, 2, -7, 4]
pozostale = []
for liczba in liczby:
if liczba > 0: # warunek zachowania
pozostale.append(liczba)
liczby = pozostale
print(liczby) # [5, 8, 2, 4]
aktywne = []
for laser in lasery:
if laser[1] > -30: # laser wciąż na ekranie
aktywne.append(laser)
lasery = aktywne
plansza = [
[1, 0, 1, 0],
[0, 1, 0, 1],
[1, 1, 0, 0]
]
# Wyświetlanie
for wiersz in plansza:
for pole in wiersz:
print(pole, end=" ")
print()
# Zliczanie jedynek
licznik = 0
for wiersz in plansza:
for pole in wiersz:
if pole == 1:
licznik += 1
print("Jedynek:", licznik)
asteroidy = [
[100, 50, 40], # x, y, rozmiar
[300, 80, 30],
[500, 120, 50]
]
# Przesuń wszystkie w dół
for ast in asteroidy:
ast[1] += 10
# Usuń asteroidę o rozmiarze 30 (filtrowanie)
asteroidy = [ast for ast in asteroidy if ast[2] != 30]
# Policz duże asteroidy (rozmiar > 40)
duze = 0
for ast in asteroidy:
if ast[2] > 40:
duze += 1
print("Duże asteroidy:", duze)
cwiczenie_szukanie_1.py, cwiczenie_usuwanie_1.py, cwiczenie_zliczanie_1.py, cwiczenie_filtr_1.py, cwiczenie_filtr_2.py, cwiczenie_gra_1.py, cwiczenie_fala_1.py.
kolory = ["czerwony", "zielony", "niebieski", "żółty"]
# Sprawdź czy jest "zielony"
if "zielony" in kolory:
print("Zielony jest na liście!")
# Znajdź indeks
indeks = kolory.index("niebieski")
print("Niebieski jest na pozycji:", indeks)
# Sprawdź czego nie ma
if "fioletowy" not in kolory:
print("Fioletowego brak")
"czerwony" jest w liście i wypisz jego indeks. Napisz funkcję czy_jest(lista, element) zwracającą True/False.in do sprawdzania obecności elementu.index()not in do sprawdzania braku elementupunkty = [10, 30, 50, 20, 40]
print("Przed:", punkty)
# Usuń wartość 30
punkty.remove(30)
print("Po remove(30):", punkty)
# Usuń element o indeksie 0
del punkty[0]
print("Po del[0]:", punkty)
# Usuń i zwróć ostatni element
ostatni = punkty.pop()
print("Usunięto pop():", ostatni)
print("Zostało:", punkty)
[5, 10, 15, 20, 25] wszystkie liczby większe niż 10 używając filtrowania (pętla + nowa lista, nie remove)..remove())del lista[i]).pop()strzaly = ["trafil", "pudlo", "trafil", "trafil", "pudlo"]
trafienia = strzaly.count("trafil")
pudla = strzaly.count("pudlo")
print("Trafień:", trafienia)
print("Pudel:", pudla)
hp_wrogow = [100, 0, 80, 0, 50, 0, 30]
zywi = 0
for hp in hp_wrogow:
if hp > 0:
zywi += 1
print("Żywych wrogów:", zywi)
[1,2,3,4,5,6,7,8,9,10] używając pętli i warunku n % 2 == 0..count() do liczenia wystąpień.count() a pętlą z ifwyniki = [10, -5, 20, -3, 0, 15, -8, 7]
print("Przed:", wyniki, "— elementów:", len(wyniki))
pozostale = []
for w in wyniki:
if w > 0:
pozostale.append(w)
wyniki = pozostale
print("Po (tylko > 0):", wyniki, "— elementów:", len(wyniki))
w >= 10. Potem zmień na w != 0. Ile elementów zostaje w każdym przypadku?pozostale = []; for x in lista: if warunek: pozostale.append(x)lasery = [[400, 500], [200, -40], [100, 300], [600, -100], [350, 200]]
print("Przed filtrowaniem:")
for laser in lasery:
print(" x={} y={}".format(laser[0], laser[1]))
aktywne = []
for laser in lasery:
if laser[1] > -30: # laser wciąż widoczny
aktywne.append(laser)
lasery = aktywne
print("\nPo filtrowaniu (y > -30):")
for laser in lasery:
print(" x={} y={}".format(laser[0], laser[1]))
generuj_wrogow(6). Potem przesuń wszystkich wrogów o 5 w prawo: wrog[0] += 5 w pętli.range do obliczania równomiernego rozmieszczeniageneruj_fale()laser_aktywny na listę lasery = []. Nowy laser = nowy element listy.gra_08.py, zapisz kopię jako gra_09.py."Asteroidy — Lekcja 9: Wiele Laserow!"
lasery = [] zastępuje pojedyncze zmienne. append([x, y]) dodaje laser, pętla for porusza wszystkimi naraz....
zycia = 3
# <-- ZAMIENIAMY laser_aktywny/laser_x/laser_y na listę (krok 4.1)
font = pygame.font.SysFont("Arial", 22)
while True:
...
teraz = pygame.time.get_ticks()
# <-- ZAMIENIAMY strzał: append nowego lasera (krok 4.2)
# <-- ZAMIENIAMY ruch: for laser in lasery (krok 4.3)
...
# <-- ZAMIENIAMY rysowanie: for laser in lasery (krok 4.4)
# <-- DODAJEMY len(lasery) do HUD (krok 4.5)
...
laser_x, laser_y, laser_aktywny) i zastąp je listą z cooldownem:# --- NOWE: lista laserów ---
lasery = [] # pusta lista — każdy laser to [x, y]
laser_predkosc = 9
czas_ostatniego_strzalu = 0
opoznienie_strzalu = 180 # ms między strzałami
lasery = [] — jedna lista zastępuje trzy osobne zmienne. Każdy laser to mała lista [x, y].opoznienie_strzalu = 180 — bez cooldownu trzymając SPACJĘ wstawialibyśmy 60 laserów na sekundę!
teraz = pygame.time.get_ticks()
# --- NOWE: dodajemy nowy laser do listy ---
if klawisze[pygame.K_SPACE] and teraz - czas_ostatniego_strzalu > opoznienie_strzalu:
nowy_laser = [statek_x + statek_szerokosc // 2 - 3, statek_y]
lasery.append(nowy_laser) # append = "dodaj na koniec listy"
czas_ostatniego_strzalu = teraz
lasery.append(nowy_laser) — dodaje element na koniec listy. Każde naciśnięcie SPACJI (z cooldownem) = jeden nowy laser w liście.teraz - czas_ostatniego_strzalu > 180 — minęło co najmniej 180 ms od ostatniego strzału.
# --- NOWE: poruszamy WSZYSTKIMI laserami ---
for laser in lasery:
laser[1] -= laser_predkosc # laser[1] to pozycja Y (drugi element)
laser[0] = X, laser[1] = Y. Indeksy zamiast osobnych zmiennych.
# --- NOWE: rysujemy WSZYSTKIE lasery z listy ---
for laser in lasery:
pygame.draw.rect(ekran, (255, 50, 50), (laser[0], laser[1], 6, 22))
for laser in lasery działa tak samo dla rysowania jak dla poruszania.
napis = font.render("Zycia: {} Laserow w powietrzu: {} SPACJA=strzal".format(
zycia, len(lasery)), True, (255, 255, 255))
ekran.blit(napis, (10, 10))
len(lasery) — liczba laserów aktualnie na liście.# ŹLE — lasery nigdy nie są usuwane z listy:
while True:
if K_SPACE: lasery.append([x, y]) # dodajemy co klatkę
for laser in lasery: laser[1] -= 9 # poruszamy wszystkimi
# Laser wylatuje za górę? Zostaje w liście na zawsze!
# Po 1 minucie: 300+ obiektów, gra zwalnia
Efekt: Po kilku minutach gry lista ma setki "martwych" laserów (niewidocznych, ale istniejących w pamięci). Gra zwalnia, potem zawiesza się.nowe_lasery = [l for l in lasery if l[1] > -30]
import pygame
import random
# === LEKCJA 9: Wiele Laserów — LISTY! ===
pygame.init()
SZEROKOSC = 800
WYSOKOSC = 600
ekran = pygame.display.set_mode((SZEROKOSC, WYSOKOSC))
pygame.display.set_caption("Asteroidy — Lekcja 9: Wiele Laserow!")
zegar = pygame.time.Clock()
statek_szerokosc = 40
statek_wysokosc = 50
statek_x = SZEROKOSC // 2 - statek_szerokosc // 2
statek_y = WYSOKOSC - 80
predkosc = 5
asteroida_x = random.randint(0, SZEROKOSC - 50)
asteroida_y = -50
asteroida_rozmiar = random.randint(30, 55)
asteroida_predkosc = 3
zycia = 3
lasery = []
laser_predkosc = 9
czas_ostatniego_strzalu = 0
opoznienie_strzalu = 180
font = pygame.font.SysFont("Arial", 22)
while True:
for zdarzenie in pygame.event.get():
if zdarzenie.type == pygame.QUIT:
pygame.quit()
exit()
klawisze = pygame.key.get_pressed()
if klawisze[pygame.K_LEFT]: statek_x -= predkosc
if klawisze[pygame.K_RIGHT]: statek_x += predkosc
if klawisze[pygame.K_UP]: statek_y -= predkosc
if klawisze[pygame.K_DOWN]: statek_y += predkosc
if statek_x < 0: statek_x = 0
if statek_x > SZEROKOSC - statek_szerokosc: statek_x = SZEROKOSC - statek_szerokosc
if statek_y < 0: statek_y = 0
if statek_y > WYSOKOSC - statek_wysokosc: statek_y = WYSOKOSC - statek_wysokosc
teraz = pygame.time.get_ticks()
if klawisze[pygame.K_SPACE] and teraz - czas_ostatniego_strzalu > opoznienie_strzalu:
nowy_laser = [statek_x + statek_szerokosc // 2 - 3, statek_y]
lasery.append(nowy_laser)
czas_ostatniego_strzalu = teraz
for laser in lasery:
laser[1] -= laser_predkosc
asteroida_y += asteroida_predkosc
if asteroida_y > WYSOKOSC:
asteroida_y = -asteroida_rozmiar
asteroida_x = random.randint(0, SZEROKOSC - asteroida_rozmiar)
asteroida_rozmiar = random.randint(30, 55)
statek_rect = pygame.Rect(statek_x, statek_y, statek_szerokosc, statek_wysokosc)
asteroida_rect = pygame.Rect(asteroida_x, asteroida_y, asteroida_rozmiar, asteroida_rozmiar)
if statek_rect.colliderect(asteroida_rect):
zycia -= 1
asteroida_y = -asteroida_rozmiar
asteroida_x = random.randint(0, SZEROKOSC - asteroida_rozmiar)
ekran.fill((0, 0, 30))
pygame.draw.rect(ekran, (0, 200, 255), (statek_x, statek_y, statek_szerokosc, statek_wysokosc))
pygame.draw.rect(ekran, (160, 160, 160), (asteroida_x, asteroida_y, asteroida_rozmiar, asteroida_rozmiar))
for laser in lasery:
pygame.draw.rect(ekran, (255, 50, 50), (laser[0], laser[1], 6, 22))
napis = font.render("Zycia: {} Laserow w powietrzu: {} SPACJA=strzal".format(
zycia, len(lasery)), True, (255, 255, 255))
ekran.blit(napis, (10, 10))
pygame.display.flip()
zegar.tick(60)
opoznienie_strzalu = 180 na 50 — szybkie strzelanie! Obserwuj licznik.600 — wolne strzelanie. Ile laserów maks. jest na ekranie jednocześnie?predkosc = 1 — ile laserów zbierze się na liście?laser_predkosc = 9 na 1 — wolne lasery. Ile masz naraz na ekranie?append sprawdź if len(lasery) < 5[x, y, r] gdzie r = random.randint(100, 255)if len(lasery) > rekord: rekord = len(lasery))# Stary zapis — pętla + append
dodatnie = []
for x in liczby:
if x > 0:
dodatnie.append(x)
# List comprehension — to samo w jednej linii!
dodatnie = [x for x in liczby if x > 0]
[co wrzucić for element in lista if warunek]liczby = [1, 2, 3, 4, 5, 6, 7, 8]
# 1. Transformacja (bez warunku)
kwadraty = [x**2 for x in liczby]
# [1, 4, 9, 16, 25, 36, 49, 64]
# 2. Filtrowanie (z warunkiem)
parzyste = [x for x in liczby if x % 2 == 0]
# [2, 4, 6, 8]
# 3. Transformacja + filtr
kwadraty_parzystych = [x**2 for x in liczby if x % 2 == 0]
# [4, 16, 36, 64]
# Stary zapis (poznałeś w T10):
aktywne = []
for laser in lasery:
if laser[1] > -30:
aktywne.append(laser)
lasery = aktywne
# List comprehension — identyczny efekt, jedna linia:
lasery = [l for l in lasery if l[1] > -30]
# A nawet krócej z przypisaniem w miejscu:
lasery[:] = [l for l in lasery if l[1] > -30]
lasery[:] to specjalny zapis — modyfikuje listę w miejscu zamiast tworzyć nową referencję. W praktyce dla prostych przypadków różnica jest niewidoczna, ale to konwencja stosowana w kodzie Pygame.
cwiczenie_comprehension_1.py — wpisuj i uruchamiaj.
liczby = [5, -3, 8, -1, 2, -7, 4]
# Stary zapis
pozostale_stary = []
for x in liczby:
if x > 0:
pozostale_stary.append(x)
# List comprehension
pozostale_nowy = [x for x in liczby if x > 0]
print("Stary:", pozostale_stary)
print("Nowy: ", pozostale_nowy)
print("Takie same?", pozostale_stary == pozostale_nowy)
[x for x in lista if warunek]lasery[:] = [l for l in lasery if l[1] > -30] w kodzie gryget_ticks() — timer odrodzenia wroga po zestrzeleniugeneruj_fale(numer)punkty = 75
# Wiele ifów — sprawdza KAŻDY niezależnie
if punkty >= 90: print("bdb")
if punkty >= 70: print("dobry") # też się wyświetli!
if punkty >= 50: print("dostateczny") # i to też!
# elif — sprawdza kolejny tylko gdy poprzedni False
if punkty >= 90:
print("bdb")
elif punkty >= 70:
print("dobry") # tylko to się wyświetli
elif punkty >= 50:
print("dostateczny")
else:
print("niedostateczny")
if/elif/else wykonuje się dokładnie jeden blok.
cwiczenie_elif_1.py i cwiczenie_elif_2.py — wpisuj i uruchamiaj każdy z osobna.
punkty = 65 # zmień tę wartość i sprawdzaj wynik
if punkty >= 90:
ocena = "bdb (5)"
elif punkty >= 75:
ocena = "dobry (4)"
elif punkty >= 60:
ocena = "dostateczny (3)"
elif punkty >= 40:
ocena = "dopuszczający (2)"
else:
ocena = "niedostateczny (1)"
print("Punkty:", punkty)
print("Ocena:", ocena)
dobry zaczynał od 70. Co się stanie gdy ustawisz punkty = 90 — bdb czy dobry?if/elif/elsey = 350 # pozycja Y obiektu na ekranie (0-600)
if y < 150:
strefa = "NIEBEZPIECZNA (wrogowie)"
elif y < 350:
strefa = "środkowa (asteroidy)"
elif y < 500:
strefa = "bezpieczna"
else:
strefa = "strefa statku gracza"
print("Y =", y, "→ strefa:", strefa)
[1,2,3,4,5], (b) filtruje słowa dłuższe niż 4 litery z ["kot","astronauta","dom","Pygame","X"].[wyrażenie for x in lista if warunek]lasery[:] = [l for l in lasery if l[1] > -30] w kodzie grygra_09.py, zapisz kopię jako gra_10.py."Asteroidy — Lekcja 10: Trafienie!"
colliderect()....
zycia = 3
punkty = 0 # <-- DODAJEMY (krok 4.4)
while True:
...
for laser in lasery:
laser[1] -= laser_predkosc
# <-- DODAJEMY usuwanie laserów poza ekranem (krok 4.1)
...
asteroida_rect = pygame.Rect(...)
# <-- DODAJEMY kolizja laser-asteroida (krok 4.2 + 4.3)
...
# --- NOWE: usuwamy lasery które wyleciały poza ekran ---
nowe_lasery = []
for laser in lasery:
if laser[1] > -30: # laser wciąż na ekranie
nowe_lasery.append(laser)
lasery = nowe_lasery # zastępujemy starą listę nową
-30? Laser ma wysokość 22 px — przy y = -30 jest całkowicie poza ekranem.punkty = 0 obok zycia = 3. Po ruchu asteroidy dodaj jej Rect i pętlę kolizji:asteroida_rect = pygame.Rect(asteroida_x, asteroida_y, asteroida_rozmiar, asteroida_rozmiar)
# --- NOWE: kolizja laser-asteroida ---
lasery_po = []
for laser in lasery:
laser_rect = pygame.Rect(laser[0], laser[1], 6, 22)
if laser_rect.colliderect(asteroida_rect):
punkty += 10
asteroida_y = -asteroida_rozmiar
asteroida_x = random.randint(0, SZEROKOSC - asteroida_rozmiar)
asteroida_rozmiar = random.randint(30, 55)
asteroida_rect = pygame.Rect(asteroida_x, asteroida_y, asteroida_rozmiar, asteroida_rozmiar)
else:
lasery_po.append(laser) # laser NIE trafił — zostaje
lasery = lasery_po
asteroida_rect aktualizujemy po resecie, żeby kolejny laser w pętli sprawdzał nową pozycję.
napis = font.render("Zycia: {} Punkty: {} Laserow: {}".format(
zycia, punkty, len(lasery)), True, (255, 255, 255))
ekran.blit(napis, (10, 10))
len(lasery) nie rośnie bez końca — lista jest czyszczona co klatkę. Obserwuj jak licznik trzyma się w ryzach!
import pygame
import random
# === LEKCJA 10: Usuwanie Laserów i Trafienie Asteroidy ===
pygame.init()
SZEROKOSC = 800
WYSOKOSC = 600
ekran = pygame.display.set_mode((SZEROKOSC, WYSOKOSC))
pygame.display.set_caption("Asteroidy — Gra 10: Trafienie!")
zegar = pygame.time.Clock()
statek_szerokosc = 40
statek_wysokosc = 50
statek_x = SZEROKOSC // 2 - statek_szerokosc // 2
statek_y = WYSOKOSC - 80
predkosc = 5
asteroida_x = random.randint(0, SZEROKOSC - 50)
asteroida_y = -50
asteroida_rozmiar = random.randint(30, 55)
asteroida_predkosc = 3
wrog_x = 120
wrog_y = 80
wrog_szerokosc = 45
wrog_wysokosc = 35
zycia = 3
punkty = 0
lasery = []
laser_predkosc = 9
czas_ostatniego_strzalu = 0
opoznienie_strzalu = 180
font = pygame.font.SysFont("Arial", 22)
while True:
for zdarzenie in pygame.event.get():
if zdarzenie.type == pygame.QUIT:
pygame.quit()
exit()
klawisze = pygame.key.get_pressed()
if klawisze[pygame.K_LEFT]:
statek_x -= predkosc
if klawisze[pygame.K_RIGHT]:
statek_x += predkosc
if klawisze[pygame.K_UP]:
statek_y -= predkosc
if klawisze[pygame.K_DOWN]:
statek_y += predkosc
if statek_x < 0: statek_x = 0
if statek_x > SZEROKOSC - statek_szerokosc: statek_x = SZEROKOSC - statek_szerokosc
if statek_y < 0: statek_y = 0
if statek_y > WYSOKOSC - statek_wysokosc: statek_y = WYSOKOSC - statek_wysokosc
teraz = pygame.time.get_ticks()
if klawisze[pygame.K_SPACE] and teraz - czas_ostatniego_strzalu > opoznienie_strzalu:
lasery.append([statek_x + statek_szerokosc // 2 - 3, statek_y])
czas_ostatniego_strzalu = teraz
for laser in lasery:
laser[1] -= laser_predkosc
nowe_lasery = []
for laser in lasery:
if laser[1] > -30:
nowe_lasery.append(laser)
lasery = nowe_lasery
asteroida_y += asteroida_predkosc
if asteroida_y > WYSOKOSC:
asteroida_y = -asteroida_rozmiar
asteroida_x = random.randint(0, SZEROKOSC - asteroida_rozmiar)
statek_rect = pygame.Rect(statek_x, statek_y, statek_szerokosc, statek_wysokosc)
asteroida_rect = pygame.Rect(asteroida_x, asteroida_y, asteroida_rozmiar, asteroida_rozmiar)
wrog_rect = pygame.Rect(wrog_x, wrog_y, wrog_szerokosc, wrog_wysokosc)
if statek_rect.colliderect(asteroida_rect):
zycia -= 1
asteroida_y = -asteroida_rozmiar
asteroida_x = random.randint(0, SZEROKOSC - asteroida_rozmiar)
pozostale = []
for laser in lasery:
laser_rect = pygame.Rect(laser[0], laser[1], 6, 22)
if laser_rect.colliderect(wrog_rect):
punkty += 30 # wróg: 30 pkt (3x więcej niż asteroida)
elif laser_rect.colliderect(asteroida_rect):
punkty += 10
asteroida_y = -asteroida_rozmiar
asteroida_x = random.randint(0, SZEROKOSC - asteroida_rozmiar)
else:
pozostale.append(laser)
lasery = pozostale
ekran.fill((0, 0, 30))
pygame.draw.rect(ekran, (0, 200, 255), (statek_x, statek_y, statek_szerokosc, statek_wysokosc))
pygame.draw.rect(ekran, (160, 160, 160), (asteroida_x, asteroida_y, asteroida_rozmiar, asteroida_rozmiar))
pygame.draw.rect(ekran, (255, 100, 0), (wrog_x, wrog_y, wrog_szerokosc, wrog_wysokosc))
for laser in lasery:
pygame.draw.rect(ekran, (255, 50, 50), (laser[0], laser[1], 6, 22))
napis = font.render("Zycia: {} Punkty: {} Laserow: {}".format(
zycia, punkty, len(lasery)), True, (255, 255, 255))
ekran.blit(napis, (10, 10))
pygame.display.flip()
zegar.tick(60)
Laserow: X w HUD — teraz nie rośnie bez końca! Porównaj z G09.punkty += 10 na 25 — więcej punktów za strzał. Ile zdobędziesz w 30 sekund?asteroida_predkosc = 5 — szybsza asteroida, trudniejszy cel.-30 na 0 — laser znika szybciej?if punkty > rekord: rekord = punktyasteroida_predkosc += 0.2trafienia = 0 i zwiększaj przy każdym punkty += 10"Celnosc: {}%".format(trafienia * 100 // max(strzaly, 1))kierunek:x = 400
predkosc = 3
kierunek = 1 # 1 = prawo, -1 = lewo
for klatka in range(10):
x += predkosc * kierunek # jeden wzór dla obu kierunków!
print("Klatka {}: x = {}".format(klatka, x))
if x > 800: # doszedł do prawej krawędzi
kierunek = -1 # zawróć — teraz odejmuje
if x < 0: # doszedł do lewej krawędzi
kierunek = 1 # zawróć — teraz dodaje
cwiczenie_kierunek_1.py i cwiczenie_kierunek_2.py — wpisuj i uruchamiaj każdy z osobna.
x = 0
predkosc = 50
kierunek = 1
szerokosc = 800
for klatka in range(25):
x += predkosc * kierunek
if x >= szerokosc:
kierunek = -1
print("Klatka {}: ODBICIE od prawej! x = {}".format(klatka, x))
elif x <= 0:
kierunek = 1
print("Klatka {}: ODBICIE od lewej! x = {}".format(klatka, x))
else:
print("Klatka {:2d}: x = {}".format(klatka, x))
predkosc = 50 na 200 — ile razy odbija się w 25 klatkach? Zmień x = 700 — gdzie będzie pierwsze odbicie?x += predkosc * kierunekx1 = 100
x2 = 700
kierunek1 = 1 # startuje w prawo
kierunek2 = -1 # startuje w lewo
predkosc = 60
for klatka in range(15):
x1 += predkosc * kierunek1
x2 += predkosc * kierunek2
if x1 >= 800: kierunek1 = -1
if x1 <= 0: kierunek1 = 1
if x2 >= 800: kierunek2 = -1
if x2 <= 0: kierunek2 = 1
print("Klatka {:2d}: x1={:4d} x2={:4d}".format(klatka, x1, x2))
kierunek w liście [x, y, kierunek].
y < 50 — "poza ekranem górnym".elif do mapowania pozycji Y na strefyelif do kategoryzowania obiektów gryelif pojawi się w sprawdzaniu kolizji — laser najpierw sprawdza wroga, potem asteroidę. Nie może trafić obu naraz.gra_10.py, zapisz kopię jako gra_11.py."Asteroidy — Lekcja 11: Pierwszy Wrog!"
pygame.Rect w kolizji. elif gwarantuje że laser trafia albo wroga, albo asteroidę — nie obu....
zycia = 3
punkty = 0
# <-- DODAJEMY zmienne wroga (krok 4.1)
lasery = []
...
while True:
...
asteroida_rect = pygame.Rect(...)
# <-- DODAJEMY wrog_rect (krok 4.1)
# <-- ZMIENIAMY kolizję laserów: elif dla wroga (krok 4.2 + 4.3)
...
ekran.fill((0, 0, 30))
pygame.draw.rect(...) # statek
pygame.draw.rect(...) # asteroida
# <-- DODAJEMY rysowanie wroga (krok 4.2)
...
punkty = 0 (przed pętlą) dodaj cztery zmienne wroga:# --- NOWE: wróg ---
wrog_x = 120
wrog_y = 80
wrog_szerokosc = 45
wrog_wysokosc = 35
x, y) i rozmiar.# --- NOWE: wróg — pomarańczowy prostokąt ---
pygame.draw.rect(ekran, (255, 100, 0), (wrog_x, wrog_y, wrog_szerokosc, wrog_wysokosc))
(255, 100, 0) — pomarańczowy. Wyróżnia się od szarej asteroidy i niebieskiego statku.wrog_rect i zmień logikę na elif:wrog_rect = pygame.Rect(wrog_x, wrog_y, wrog_szerokosc, wrog_wysokosc)
pozostale = []
for laser in lasery:
laser_rect = pygame.Rect(laser[0], laser[1], 6, 22)
if laser_rect.colliderect(wrog_rect):
punkty += 20 # wróg wart 20 pkt (2x więcej niż asteroida)
elif laser_rect.colliderect(asteroida_rect):
punkty += 10
asteroida_y = -asteroida_rozmiar
asteroida_x = random.randint(0, SZEROKOSC - asteroida_rozmiar)
else:
pozostale.append(laser)
lasery = pozostale
elif — laser może trafić tylko jeden obiekt na klatkę. Sprawdzamy najpierw wroga (wyższe punkty), potem asteroidę.import pygame
import random
# === LEKCJA 11: Pierwszy Wróg! ===
pygame.init()
SZEROKOSC = 800
WYSOKOSC = 600
ekran = pygame.display.set_mode((SZEROKOSC, WYSOKOSC))
pygame.display.set_caption("Asteroidy — Lekcja 11: Pierwszy Wrog!")
zegar = pygame.time.Clock()
statek_szerokosc = 40
statek_wysokosc = 50
statek_x = SZEROKOSC // 2 - statek_szerokosc // 2
statek_y = WYSOKOSC - 80
predkosc = 5
asteroida_x = random.randint(0, SZEROKOSC - 50)
asteroida_y = -50
asteroida_rozmiar = random.randint(30, 55)
asteroida_predkosc = 3
wrog_x = 120
wrog_y = 80
wrog_szerokosc = 45
wrog_wysokosc = 35
wrog_predkosc = 2
wrog_kierunek = 1
zycia = 3
punkty = 0
lasery = []
laser_predkosc = 9
czas_ostatniego_strzalu = 0
opoznienie_strzalu = 180
font = pygame.font.SysFont("Arial", 22)
while True:
for zdarzenie in pygame.event.get():
if zdarzenie.type == pygame.QUIT:
pygame.quit()
exit()
klawisze = pygame.key.get_pressed()
if klawisze[pygame.K_LEFT]:
statek_x -= predkosc
if klawisze[pygame.K_RIGHT]:
statek_x += predkosc
if klawisze[pygame.K_UP]:
statek_y -= predkosc
if klawisze[pygame.K_DOWN]:
statek_y += predkosc
if statek_x < 0: statek_x = 0
if statek_x > SZEROKOSC - statek_szerokosc: statek_x = SZEROKOSC - statek_szerokosc
if statek_y < 0: statek_y = 0
if statek_y > WYSOKOSC - statek_wysokosc: statek_y = WYSOKOSC - statek_wysokosc
teraz = pygame.time.get_ticks()
if klawisze[pygame.K_SPACE] and teraz - czas_ostatniego_strzalu > opoznienie_strzalu:
lasery.append([statek_x + statek_szerokosc // 2 - 3, statek_y])
czas_ostatniego_strzalu = teraz
for laser in lasery:
laser[1] -= laser_predkosc
nowe_lasery = []
for laser in lasery:
if laser[1] > -30:
nowe_lasery.append(laser)
lasery = nowe_lasery
# --- NOWE: AI wroga ---
wrog_x += wrog_predkosc * wrog_kierunek
if wrog_x > SZEROKOSC - wrog_szerokosc:
wrog_kierunek = -1
if wrog_x < 0:
wrog_kierunek = 1
asteroida_y += asteroida_predkosc
if asteroida_y > WYSOKOSC:
asteroida_y = -asteroida_rozmiar
asteroida_x = random.randint(0, SZEROKOSC - asteroida_rozmiar)
statek_rect = pygame.Rect(statek_x, statek_y, statek_szerokosc, statek_wysokosc)
asteroida_rect = pygame.Rect(asteroida_x, asteroida_y, asteroida_rozmiar, asteroida_rozmiar)
wrog_rect = pygame.Rect(wrog_x, wrog_y, wrog_szerokosc, wrog_wysokosc)
if statek_rect.colliderect(asteroida_rect):
zycia -= 1
asteroida_y = -asteroida_rozmiar
asteroida_x = random.randint(0, SZEROKOSC - asteroida_rozmiar)
pozostale = []
for laser in lasery:
laser_rect = pygame.Rect(laser[0], laser[1], 6, 22)
if laser_rect.colliderect(wrog_rect):
punkty += 30 # wróg: 30 pkt (3x więcej niż asteroida)
elif laser_rect.colliderect(asteroida_rect):
punkty += 10
asteroida_y = -asteroida_rozmiar
asteroida_x = random.randint(0, SZEROKOSC - asteroida_rozmiar)
else:
pozostale.append(laser)
lasery = pozostale
ekran.fill((0, 0, 30))
pygame.draw.rect(ekran, (0, 200, 255), (statek_x, statek_y, statek_szerokosc, statek_wysokosc))
pygame.draw.rect(ekran, (160, 160, 160), (asteroida_x, asteroida_y, asteroida_rozmiar, asteroida_rozmiar))
pygame.draw.rect(ekran, (255, 100, 0), (wrog_x, wrog_y, wrog_szerokosc, wrog_wysokosc))
for laser in lasery:
pygame.draw.rect(ekran, (255, 50, 50), (laser[0], laser[1], 6, 22))
kierunek_str = ">>>" if wrog_kierunek == 1 else "<<<"
napis = font.render("Zycia: {} Punkty: {} Wrog: {}".format(zycia, punkty, kierunek_str), True, (255, 255, 255))
ekran.blit(napis, (10, 10))
pygame.display.flip()
zegar.tick(60)
wrog_x = 120 i wrog_y = 80 na inne wartości — przesuń wroga.(200, 0, 200) — wyróżnia się lepiej?wrog_szerokosc = 80 — łatwiejszy cel. wrog_szerokosc = 15 — bardzo trudny!20 na 50 — ile zdobędziesz w 30 sekund?wrog2_x = 600, wrog2_y = 120 i jego kolizję w kolejnym elifekran.blit(font.render("WROG", True, (255,255,255)), (wrog_x, wrog_y-20))wrog_x = SZEROKOSC // 2 - wrog_szerokosc // 2 — wróg zawsze na środkupygame.time.get_ticks() zwraca czas od uruchomienia programu w milisekundach.import time
# Symulacja (bez pygame — czas w sekundach * 1000 = ms)
teraz = 0
# Zdarzenie nastąpiło w "chwili 500 ms"
czas_zdarzenia = 500
czas_trwania = 2000 # 2 sekundy = 2000 ms
# Co klatkę sprawdzamy:
for klatka in range(30):
teraz += 100 # symulujemy upływ 100ms na klatkę
if teraz > czas_zdarzenia + czas_trwania:
print("Klatka {}: timer dobiegł końca!".format(klatka))
break
elif teraz > czas_zdarzenia:
print("Klatka {}: timer w toku ({} ms minęło)".format(klatka, teraz - czas_zdarzenia))
else:
print("Klatka {}: przed zdarzeniem".format(klatka))
cwiczenie_timer_1.py i cwiczenie_timer_2.py — wpisuj i uruchamiaj każdy z osobna.
zyje = True
czas_odrodzenia = 0
teraz = 0
czas_trwania_smierci = 2000 # 2000 ms = 2 sekundy
for klatka in range(40):
teraz += 100 # każda klatka = 100ms
# W klatce 10 — wróg ginie
if klatka == 10 and zyje:
zyje = False
czas_odrodzenia = teraz + czas_trwania_smierci
print("Klatka {}: wróg POKONANY! Odrodzi się za 2s.".format(klatka))
# Sprawdzamy odrodzenie
if not zyje and teraz > czas_odrodzenia:
zyje = True
print("Klatka {}: wróg ODRODZONY!".format(klatka))
stan = "ŻYJE" if zyje else "martwy"
print(" t={}ms stan={}".format(teraz, stan))
czas_trwania_smierci na 1000 — szybkie odrodzenie. Na 5000 — powolne. W której klatce nastąpi odrodzenie w każdym przypadku?czas_odrodzenia = teraz + opóźnienieteraz = 0
czas_zapisany = None # jeszcze nie zapisaliśmy
for klatka in range(20):
teraz += 150 # każda klatka = 150ms
# W klatce 5 zapisujemy czas
if klatka == 5:
czas_zapisany = teraz
print("Klatka {}: ZAPISANO czas = {}ms".format(klatka, czas_zapisany))
# Sprawdzamy czy minęło 1000ms od zapisu
if czas_zapisany is not None and teraz - czas_zapisany > 1000:
print("Klatka {}: minęło >1000ms od zapisu!".format(klatka))
czas_zapisany = None # resetuj żeby nie wypisywać co klatkę
teraz - czas_zapisany > 1000 to dokładnie to co używamy w grze dla trafiony (L07) i odrodzenia wroga!
x1 == x2 w którymś momencie (dodaj if x1 == x2: print("ZDERZENIE!")).wrog_x += wrog_predkosc * wrog_kierunek trafi bezpośrednio do pętli gry.gra_11.py, zapisz kopię jako gra_12.py."Asteroidy — Lekcja 12: AI Przeciwnika!"
wrog_x += wrog_predkosc * wrog_kierunek gdzie wrog_kierunek to 1 (prawo) lub -1 (lewo). Przy ścianie: zmiana znaku na przeciwny.if zamiast dwóch osobnych logik ruchu. Wróg staje się wyzwaniem bo jego pozycja jest nieprzewidywalna....
wrog_szerokosc = 45
wrog_wysokosc = 35
# <-- DODAJEMY predkosc i kierunek wroga (krok 4.1)
...
while True:
...
# <-- DODAJEMY ruch AI wroga (krok 4.2)
# <-- DODAJEMY odbicie od ścian (krok 4.3)
...
wrog_wysokosc = 35) dodaj prędkość i kierunek:wrog_predkosc = 2
wrog_kierunek = 1 # 1 = prawo, -1 = lewo
wrog_kierunek = 1 — wróg startuje ruchem w prawo.kierunek (±1) to elegancki wzorzec — jeden wzór dla obu kierunków. Zmiana AI = zmiana znaku.
# --- NOWE: AI wroga — automatyczny ruch ---
wrog_x += wrog_predkosc * wrog_kierunek
kierunek = 1: x += 2 (prawo). kierunek = -1: x -= 2 (lewo).
# Odbicie od ścian — zmień kierunek gdy dojdzie do krawędzi
if wrog_x > SZEROKOSC - wrog_szerokosc:
wrog_kierunek = -1 # zawróć w lewo
if wrog_x < 0:
wrog_kierunek = 1 # zawróć w prawo
SZEROKOSC - wrog_szerokosc? Bo wrog_x to LEWA krawędź wroga. Prawa krawędź = wrog_x + wrog_szerokosc. Gdy prawa przekroczy 800 — zawracamy."Wrog: {}" gdzie ">>>" gdy wrog_kierunek == 1.
# --- NOWE: rysujemy wroga lub wybuch ---
if wrog_zyje:
pygame.draw.rect(ekran, (255, 100, 0), (wrog_x, wrog_y, wrog_szerokosc, wrog_wysokosc))
else:
czas_do_odrodzenia = (wrog_odrodzenie - teraz) // 1000
wybuch = font_duzy.render("BOOM! +{}s".format(czas_do_odrodzenia + 1), True, (255, 200, 0))
ekran.blit(wybuch, (wrog_x - 30, wrog_y - 30))
(wrog_odrodzenie - teraz) // 1000 — ile całych sekund pozostało do odrodzenia. Wyświetlamy odliczanie!
import pygame
import random
# === LEKCJA 12: AI Przeciwnika ===
pygame.init()
SZEROKOSC = 800
WYSOKOSC = 600
ekran = pygame.display.set_mode((SZEROKOSC, WYSOKOSC))
pygame.display.set_caption("Asteroidy — Lekcja 12: AI Przeciwnika!")
zegar = pygame.time.Clock()
statek_szerokosc = 40
statek_wysokosc = 50
statek_x = SZEROKOSC // 2 - statek_szerokosc // 2
statek_y = WYSOKOSC - 80
predkosc = 5
asteroida_x = random.randint(0, SZEROKOSC - 50)
asteroida_y = -50
asteroida_rozmiar = random.randint(30, 55)
asteroida_predkosc = 3
wrog_x = 120
wrog_y = 80
wrog_szerokosc = 45
wrog_wysokosc = 35
wrog_predkosc = 2
wrog_kierunek = 1
wrog_zyje = True
wrog_odrodzenie = 0
zycia = 3
punkty = 0
lasery = []
laser_predkosc = 9
czas_ostatniego_strzalu = 0
opoznienie_strzalu = 180
font = pygame.font.SysFont("Arial", 22)
font_duzy = pygame.font.SysFont("Arial", 52)
while True:
for zdarzenie in pygame.event.get():
if zdarzenie.type == pygame.QUIT:
pygame.quit()
exit()
klawisze = pygame.key.get_pressed()
if klawisze[pygame.K_LEFT]:
statek_x -= predkosc
if klawisze[pygame.K_RIGHT]:
statek_x += predkosc
if klawisze[pygame.K_UP]:
statek_y -= predkosc
if klawisze[pygame.K_DOWN]:
statek_y += predkosc
if statek_x < 0: statek_x = 0
if statek_x > SZEROKOSC - statek_szerokosc: statek_x = SZEROKOSC - statek_szerokosc
if statek_y < 0: statek_y = 0
if statek_y > WYSOKOSC - statek_wysokosc: statek_y = WYSOKOSC - statek_wysokosc
teraz = pygame.time.get_ticks()
if klawisze[pygame.K_SPACE] and teraz - czas_ostatniego_strzalu > opoznienie_strzalu:
lasery.append([statek_x + statek_szerokosc // 2 - 3, statek_y])
czas_ostatniego_strzalu = teraz
for laser in lasery:
laser[1] -= laser_predkosc
nowe_lasery = []
for laser in lasery:
if laser[1] > -30:
nowe_lasery.append(laser)
lasery = nowe_lasery
if wrog_zyje:
wrog_x += wrog_predkosc * wrog_kierunek
if wrog_x > SZEROKOSC - wrog_szerokosc:
wrog_kierunek = -1
if wrog_x < 0:
wrog_kierunek = 1
else:
if teraz > wrog_odrodzenie:
wrog_zyje = True
wrog_x = random.randint(50, SZEROKOSC - wrog_szerokosc - 50)
wrog_y = random.randint(50, 180)
asteroida_y += asteroida_predkosc
if asteroida_y > WYSOKOSC:
asteroida_y = -asteroida_rozmiar
asteroida_x = random.randint(0, SZEROKOSC - asteroida_rozmiar)
statek_rect = pygame.Rect(statek_x, statek_y, statek_szerokosc, statek_wysokosc)
asteroida_rect = pygame.Rect(asteroida_x, asteroida_y, asteroida_rozmiar, asteroida_rozmiar)
if statek_rect.colliderect(asteroida_rect):
zycia -= 1
asteroida_y = -asteroida_rozmiar
asteroida_x = random.randint(0, SZEROKOSC - asteroida_rozmiar)
pozostale_lasery = []
for laser in lasery:
laser_rect = pygame.Rect(laser[0], laser[1], 6, 22)
trafil = False
if wrog_zyje:
wrog_rect = pygame.Rect(wrog_x, wrog_y, wrog_szerokosc, wrog_wysokosc)
if laser_rect.colliderect(wrog_rect):
punkty += 20
wrog_zyje = False
wrog_odrodzenie = teraz + 2000
trafil = True
if laser_rect.colliderect(asteroida_rect) and not trafil:
punkty += 10
asteroida_y = -asteroida_rozmiar
asteroida_x = random.randint(0, SZEROKOSC - asteroida_rozmiar)
trafil = True
if not trafil:
pozostale_lasery.append(laser)
lasery = pozostale_lasery
ekran.fill((0, 0, 30))
pygame.draw.rect(ekran, (0, 200, 255), (statek_x, statek_y, statek_szerokosc, statek_wysokosc))
pygame.draw.rect(ekran, (160, 160, 160), (asteroida_x, asteroida_y, asteroida_rozmiar, asteroida_rozmiar))
if wrog_zyje:
pygame.draw.rect(ekran, (255, 100, 0), (wrog_x, wrog_y, wrog_szerokosc, wrog_wysokosc))
else:
czas_do_odrodzenia = (wrog_odrodzenie - teraz) // 1000
wybuch = font_duzy.render("BOOM! +{}s".format(czas_do_odrodzenia + 1), True, (255, 200, 0))
ekran.blit(wybuch, (wrog_x - 30, wrog_y - 30))
for laser in lasery:
pygame.draw.rect(ekran, (255, 50, 50), (laser[0], laser[1], 6, 22))
napis = font.render("Zycia: {} Punkty: {} SPACJA=strzal".format(zycia, punkty), True, (255, 255, 255))
ekran.blit(napis, (10, 10))
pygame.display.flip()
zegar.tick(60)
wrog_predkosc = 2 na 6 — szybki wróg! Czy trudniej go zestrzelić?wrog_y = 80 na 300 — wróg bliżej gracza. Jak zmienia to trudność?wrog_kierunek = 1 na -1 — wróg startuje w lewo.>>> i <<< zmieniające się przy odbiciach.wrog_kierunek_y = 1 i wrog_y += wrog_predkosc * wrog_kierunek_y z odbiciami od Y=50 i Y=200wrog_predkosc = 0 na start — po pierwszym trafieniu ustaw na 3"Predkosc: {}".format(wrog_predkosc)def przywitaj(imie): # def = definicja, imie = parametr
napis = "Cześć, " + imie + "!"
return napis # return = zwróć wynik
wynik = przywitaj("Ania") # wywołanie funkcji
print(wynik) # "Cześć, Ania!"
print(przywitaj("Kacper")) # "Cześć, Kacper!"
def generuj_pozycje(ile):
pozycje = []
for i in range(ile):
pozycje.append(i * 100)
return pozycje
fala1 = generuj_pozycje(3) # [0, 100, 200]
fala2 = generuj_pozycje(5) # [0, 100, 200, 300, 400]
print(fala1)
print(fala2)
cwiczenie_def_1.py i cwiczenie_def_2.py — wpisuj i uruchamiaj każdy z osobna.
def oblicz_wynik(trafienia, bonus):
return trafienia * 10 + bonus
wynik1 = oblicz_wynik(5, 50)
wynik2 = oblicz_wynik(3, 0)
wynik3 = oblicz_wynik(10, 100)
print("5 trafień + bonus 50 =", wynik1)
print("3 trafienia + bonus 0 =", wynik2)
print("10 trafień + bonus 100 =", wynik3)
# Możemy wywoływać wielokrotnie z różnymi argumentami!
for trafienia in range(1, 6):
print(" {} trafień → {}".format(trafienia, oblicz_wynik(trafienia, 25)))
mnoznik i zmień wzór na trafienia * mnoznik + bonus. Wywołaj z mnoznik=20 i mnoznik=5.returnSZEROKOSC = 800
wrog_szerokosc = 44
def generuj_fale(numer):
nowi = []
liczba = 3 + numer # fala 1 = 4 wrogów, fala 2 = 5 itd.
for i in range(liczba):
odst = SZEROKOSC // (liczba + 1)
x = odst * (i + 1) - wrog_szerokosc // 2
y = 40 + (i % 2) * 35 # naprzemienne wysokości
nowi.append([x, y, 1]) # [x, y, kierunek]
return nowi
fala1 = generuj_fale(1)
fala2 = generuj_fale(2)
fala3 = generuj_fale(3)
print("Fala 1 ({} wrogów):".format(len(fala1)))
for w in fala1:
print(" x={} y={} kier={}".format(w[0], w[1], w[2]))
print("\nFala 2 ({} wrogów):".format(len(fala2)))
print("Fala 3 ({} wrogów):".format(len(fala3)))
1000 na 600. W której klatce teraz pojawia się komunikat? Zmień krok czasu na 100 ms — ile klatek potrzeba na 600ms?teraz - czas_zapisany > prógwrog_odrodzenie = teraz + 2000 zapisuje "kiedy odrodzić", if teraz > wrog_odrodzenie sprawdza czy czas nadszedł.gra_12.py, zapisz kopię jako gra_13.py."Asteroidy — Lekcja 13: Zestrzel Wroga!"
wrog_zyje kontroluje stan. Timer: zapisujemy pygame.time.get_ticks() przy trafieniu i sprawdzamy czy minęły 2000 ms.get_ticks() to podstawa wszelkich opóźnionych akcji w grach — nietykalność, animacje wybuchu, odliczanie. Jeden wzorzec, tysiące zastosowań....
wrog_kierunek = 1
# <-- DODAJEMY wrog_zyje i wrog_odrodzenie (krok 4.1)
...
font_duzy = pygame.font.SysFont("Arial", 52) # <-- DODAJEMY
while True:
...
teraz = pygame.time.get_ticks()
# <-- ZMIENIAMY ruch wroga: tylko gdy zyje (krok 4.2)
# <-- ZMIENIAMY kolizję lasera: ustaw wrog_zyje = False (krok 4.3)
# <-- DODAJEMY sprawdzenie odrodzenia (krok 4.4)
# <-- ZMIENIAMY rysowanie wroga: if wrog_zyje else BOOM (krok 4.5)
...
wrog_kierunek = 1 dodaj flagę i timer, a przed pętlą dodaj drugi font:wrog_zyje = True # czy wróg żyje?
wrog_odrodzenie = 0 # kiedy się odrodzi (w ms)
font_duzy = pygame.font.SysFont("Arial", 52)
wrog_zyje = True — flaga logiczna: na starcie wróg żyje.wrog_odrodzenie = 0 — zapamiętamy tu chwilę "2 sekundy od teraz". Przy odrodzeniu: teraz > wrog_odrodzenie → True.font_duzy — do wyświetlania napisu "BOOM!" po trafieniu.
if wrog_zyje i dodaj gałąź else z odrodzeniem:# --- ZMIENIAMY: ruch wroga tylko gdy żyje ---
if wrog_zyje:
wrog_x += wrog_predkosc * wrog_kierunek
if wrog_x > SZEROKOSC - wrog_szerokosc:
wrog_kierunek = -1
if wrog_x < 0:
wrog_kierunek = 1
else:
# Sprawdzamy czy czas odrodzenia minął
if teraz > wrog_odrodzenie:
wrog_zyje = True
wrog_x = random.randint(50, SZEROKOSC - wrog_szerokosc - 50)
wrog_y = random.randint(50, 180)
teraz > wrog_odrodzenie — właśnie tego wzorca użyliśmy dla trafiony w G07!
and wrog_zyje i ustaw flagę przy trafieniu:pozostale = []
for laser in lasery:
laser_rect = pygame.Rect(laser[0], laser[1], 6, 22)
trafil_wroga = False
if wrog_zyje:
wrog_rect = pygame.Rect(wrog_x, wrog_y, wrog_szerokosc, wrog_wysokosc)
if laser_rect.colliderect(wrog_rect):
punkty += 20
wrog_zyje = False
wrog_odrodzenie = teraz + 2000 # odrodzi się za 2 sekundy
trafil_wroga = True
if laser_rect.colliderect(asteroida_rect) and not trafil_wroga:
punkty += 10
asteroida_y = -asteroida_rozmiar
asteroida_x = random.randint(0, SZEROKOSC - asteroida_rozmiar)
trafil_wroga = True
if not trafil_wroga:
pozostale.append(laser)
lasery = pozostale
wrog_odrodzenie = teraz + 2000 — zapisujemy "2 sekundy od teraz" w ms. Potem porównujemy z teraz co klatkę.trafil_wroga — laser może trafić tylko jeden cel na klatkę.
# --- ZMIENIAMY: rysujemy wroga lub wybuch ---
if wrog_zyje:
pygame.draw.rect(ekran, (255, 100, 0), (wrog_x, wrog_y, wrog_szerokosc, wrog_wysokosc))
else:
czas_do_odrodzenia = (wrog_odrodzenie - teraz) // 1000
wybuch = font_duzy.render("BOOM! +{}s".format(czas_do_odrodzenia + 1), True, (255, 200, 0))
ekran.blit(wybuch, (wrog_x - 30, wrog_y - 30))
(wrog_odrodzenie - teraz) // 1000 — ile całych sekund zostało do odrodzenia. Wyświetlamy odliczanie: BOOM! +2s → BOOM! +1s → wróg wraca!
import pygame
import random
# === LEKCJA 13: Zestrzelenie Wroga! ===
pygame.init()
SZEROKOSC = 800
WYSOKOSC = 600
ekran = pygame.display.set_mode((SZEROKOSC, WYSOKOSC))
pygame.display.set_caption("Asteroidy — Lekcja 13: Zestrzel Wroga!")
zegar = pygame.time.Clock()
statek_szerokosc = 40
statek_wysokosc = 50
statek_x = SZEROKOSC // 2 - statek_szerokosc // 2
statek_y = WYSOKOSC - 80
predkosc = 5
asteroida_x = random.randint(0, SZEROKOSC - 50)
asteroida_y = -50
asteroida_rozmiar = random.randint(30, 55)
asteroida_predkosc = 3
wrog_x = 120
wrog_y = 80
wrog_szerokosc = 45
wrog_wysokosc = 35
wrog_predkosc = 2
wrog_kierunek = 1
wrog_zyje = True
wrog_odrodzenie = 0
zycia = 3
punkty = 0
lasery = []
laser_predkosc = 9
czas_ostatniego_strzalu = 0
opoznienie_strzalu = 180
font = pygame.font.SysFont("Arial", 22)
font_duzy = pygame.font.SysFont("Arial", 52)
while True:
for zdarzenie in pygame.event.get():
if zdarzenie.type == pygame.QUIT:
pygame.quit()
exit()
klawisze = pygame.key.get_pressed()
if klawisze[pygame.K_LEFT]: statek_x -= predkosc
if klawisze[pygame.K_RIGHT]: statek_x += predkosc
if klawisze[pygame.K_UP]: statek_y -= predkosc
if klawisze[pygame.K_DOWN]: statek_y += predkosc
if statek_x < 0: statek_x = 0
if statek_x > SZEROKOSC - statek_szerokosc: statek_x = SZEROKOSC - statek_szerokosc
if statek_y < 0: statek_y = 0
if statek_y > WYSOKOSC - statek_wysokosc: statek_y = WYSOKOSC - statek_wysokosc
teraz = pygame.time.get_ticks()
if klawisze[pygame.K_SPACE] and teraz - czas_ostatniego_strzalu > opoznienie_strzalu:
lasery.append([statek_x + statek_szerokosc // 2 - 3, statek_y])
czas_ostatniego_strzalu = teraz
for laser in lasery:
laser[1] -= laser_predkosc
nowe_lasery = []
for laser in lasery:
if laser[1] > -30:
nowe_lasery.append(laser)
lasery = nowe_lasery
if wrog_zyje:
wrog_x += wrog_predkosc * wrog_kierunek
if wrog_x > SZEROKOSC - wrog_szerokosc:
wrog_kierunek = -1
if wrog_x < 0:
wrog_kierunek = 1
else:
if teraz > wrog_odrodzenie:
wrog_zyje = True
wrog_x = random.randint(50, SZEROKOSC - wrog_szerokosc - 50)
wrog_y = random.randint(50, 180)
asteroida_y += asteroida_predkosc
if asteroida_y > WYSOKOSC:
asteroida_y = -asteroida_rozmiar
asteroida_x = random.randint(0, SZEROKOSC - asteroida_rozmiar)
statek_rect = pygame.Rect(statek_x, statek_y, statek_szerokosc, statek_wysokosc)
asteroida_rect = pygame.Rect(asteroida_x, asteroida_y, asteroida_rozmiar, asteroida_rozmiar)
if statek_rect.colliderect(asteroida_rect):
zycia -= 1
asteroida_y = -asteroida_rozmiar
asteroida_x = random.randint(0, SZEROKOSC - asteroida_rozmiar)
pozostale = []
for laser in lasery:
laser_rect = pygame.Rect(laser[0], laser[1], 6, 22)
trafil_wroga = False
if wrog_zyje:
wrog_rect = pygame.Rect(wrog_x, wrog_y, wrog_szerokosc, wrog_wysokosc)
if laser_rect.colliderect(wrog_rect):
punkty += 20
wrog_zyje = False
wrog_odrodzenie = teraz + 2000
trafil_wroga = True
if laser_rect.colliderect(asteroida_rect) and not trafil_wroga:
punkty += 10
asteroida_y = -asteroida_rozmiar
asteroida_x = random.randint(0, SZEROKOSC - asteroida_rozmiar)
trafil_wroga = True
if not trafil_wroga:
pozostale.append(laser)
lasery = pozostale
ekran.fill((0, 0, 30))
pygame.draw.rect(ekran, (0, 200, 255), (statek_x, statek_y, statek_szerokosc, statek_wysokosc))
pygame.draw.rect(ekran, (160, 160, 160), (asteroida_x, asteroida_y, asteroida_rozmiar, asteroida_rozmiar))
if wrog_zyje:
pygame.draw.rect(ekran, (255, 100, 0), (wrog_x, wrog_y, wrog_szerokosc, wrog_wysokosc))
else:
czas_do_odrodzenia = (wrog_odrodzenie - teraz) // 1000
wybuch = font_duzy.render("BOOM! +{}s".format(czas_do_odrodzenia + 1), True, (255, 200, 0))
ekran.blit(wybuch, (wrog_x - 30, wrog_y - 30))
for laser in lasery:
pygame.draw.rect(ekran, (255, 50, 50), (laser[0], laser[1], 6, 22))
napis = font.render("Zycia: {} Punkty: {} SPACJA=strzal".format(zycia, punkty), True, (255, 255, 255))
ekran.blit(napis, (10, 10))
pygame.display.flip()
zegar.tick(60)
+ 2000 na + 500 — krótkie odrodzenie. Trudniejsza gra?+ 2000 na + 5000 — długie 5 sekund. Obserwuj odliczanie BOOM! +4s → +3s → +2s → +1s.punkty += 50. Jak zmienia to strategię?wrog_x = SZEROKOSC // 2 zamiast losowego.wrog_predkosc += 0.5 wewnątrz bloku odrodzeniazestrzeleni = 0 i zestrzeleni += 1 przy każdym trafieniu"Wrog: {}s"wrogowie = [] i funkcję def generuj_fale(numer).gra_13.py, zapisz kopię jako gra_14.py."Asteroidy — Lekcja 14: Fala Wrogow!"
wrogowie = [[x, y, kierunek], ...] + funkcja generuj_fale(numer) tworzy formację. Pętle zagnieżdżone sprawdzają każdy laser vs każdy wróg.generuj_fale() kapsułkuje logikę tworzenia formacji — to wzorzec używany w finałowej grze....
# <-- ZAMIENIAMY asteroida na lista asteroidy[] (krok 4.1)
# <-- ZAMIENIAMY wrog_x/y/itd na wrogowie=[] (krok 4.1)
# <-- DODAJEMY def generuj_fale(numer) (krok 4.2)
wrogowie = generuj_fale(numer_fali)
...
while True:
...
# <-- DODAJEMY ruch wszystkich wrogów (krok 4.3)
# <-- DODAJEMY ruch asteroid z listy (krok 4.3)
# <-- ZMIENIAMY kolizję: pętla zagnieżdżona laser-wrogowie (krok 4.4)
# <-- DODAJEMY sprawdzenie końca fali (krok 4.5)
...
# G13 — jeden wróg = trzy zmienne
wrog_x = SZEROKOSC // 2
wrog_y = 60
wrog_kierunek = 1
# Ruch
wrog_x += wrog_predkosc * wrog_kierunek
if wrog_x > SZEROKOSC - wrog_szerokosc: wrog_kierunek = -1
if wrog_x < 0: wrog_kierunek = 1
# G14 — wielu wrogów = lista list [x, y, kierunek]
wrogowie = [[100, 60, 1], [200, 60, 1], [300, 60, -1]]
# Ruch WSZYSTKICH — jedna pętla zastępuje 3 zmienne × N wrogów
for wrog in wrogowie:
wrog[0] += wrog_predkosc * wrog[2]
if wrog[0] > SZEROKOSC - wrog_szerokosc: wrog[2] = -1
if wrog[0] < 0: wrog[2] = 1
wrogowie = generuj_fale(1) # fala 1: 4 wrogów
wrogowie = generuj_fale(2) # fala 2: 5 wrogów, trudniej
wrogowie = generuj_fale(5) # fala 5: 8 wrogów!
# Asteroidy jako lista — każda: [x, y, rozmiar]
asteroidy = []
for i in range(2):
asteroidy.append([
random.randint(0, SZEROKOSC - 50),
random.randint(-400, -30),
random.randint(28, 55)
])
# Wrogowie jako lista — każdy: [x, y, kierunek]
wrog_szerokosc = 44
wrog_wysokosc = 32
wrog_predkosc = 2
numer_fali = 1
[x, y, kierunek] — wrog[0]=x, wrog[1]=y, wrog[2]=kierunek.
wrogowie = ..., zdefiniuj funkcję:def generuj_fale(numer):
nowi = []
liczba = 3 + numer # każda fala ma więcej wrogów
for i in range(liczba):
odst = SZEROKOSC // (liczba + 1)
x = odst * (i + 1) - wrog_szerokosc // 2
y = 40 + (i % 2) * 35 # co drugi wróg trochę niżej
nowi.append([x, y, 1]) # [x, y, kierunek=prawo]
return nowi
wrogowie = generuj_fale(numer_fali)
def musi być przed pierwszym wywołaniem! Równomierne rozmieszczenie: SZEROKOSC // (liczba+1) dzieli ekran na równe odcinki.
# --- NOWE: ruch wszystkich wrogów ---
for wrog in wrogowie:
wrog[0] += wrog_predkosc * wrog[2]
if wrog[0] > SZEROKOSC - wrog_szerokosc:
wrog[2] = -1
if wrog[0] < 0:
wrog[2] = 1
# --- NOWE: ruch wszystkich asteroid ---
for ast in asteroidy:
ast[1] += 3
if ast[1] > WYSOKOSC:
ast[1] = random.randint(-300, -30)
ast[0] = random.randint(0, SZEROKOSC - ast[2])
# --- NOWE: lasery vs wrogowie (pętle zagnieżdżone) ---
pozostale_lasery = []
trafieni_idx = []
for laser in lasery:
laser_rect = pygame.Rect(laser[0], laser[1], 6, 22)
trafil = False
for j in range(len(wrogowie)):
if j not in trafieni_idx:
wrog_rect = pygame.Rect(wrogowie[j][0], wrogowie[j][1], wrog_szerokosc, wrog_wysokosc)
if laser_rect.colliderect(wrog_rect):
trafieni_idx.append(j)
punkty += 20
trafil = True
break
if not trafil:
for ast in asteroidy:
ast_rect = pygame.Rect(ast[0], ast[1], ast[2], ast[2])
if laser_rect.colliderect(ast_rect) and not trafil:
punkty += 10
ast[1] = random.randint(-300, -30)
trafil = True
if not trafil:
pozostale_lasery.append(laser)
lasery = pozostale_lasery
# Usuwamy trafionych wrogów (od końca — indeksy się nie przesuną)
for j in sorted(trafieni_idx, reverse=True):
wrogowie.pop(j)
trafieni_idx zapobiega trafieniu tego samego wroga dwoma laserami w jednej klatce.
# --- NOWE: gdy wszyscy wrogowie pokonani — nowa fala! ---
if len(wrogowie) == 0:
numer_fali += 1
punkty += 50 # bonus za ukończenie fali
wrogowie = generuj_fale(numer_fali)
wrog_predkosc = min(2 + numer_fali, 7) # z każdą falą szybciej (max 7)
min(2 + numer_fali, 7) — prędkość rośnie z falami, ale nigdy nie przekroczy 7. Fala 1: 3, Fala 5: 7, Fala 10: 7.
import pygame
import random
# === LEKCJA 14: Wielu Wrogów — Fale! ===
pygame.init()
SZEROKOSC = 800
WYSOKOSC = 600
ekran = pygame.display.set_mode((SZEROKOSC, WYSOKOSC))
pygame.display.set_caption("Asteroidy — Lekcja 14: Fala Wrogow!")
zegar = pygame.time.Clock()
statek_szerokosc = 40
statek_wysokosc = 50
statek_x = SZEROKOSC // 2 - statek_szerokosc // 2
statek_y = WYSOKOSC - 80
predkosc = 5
asteroidy = []
for i in range(2):
asteroidy.append([
random.randint(0, SZEROKOSC - 50),
random.randint(-400, -30),
random.randint(28, 55)
])
wrog_szerokosc = 44
wrog_wysokosc = 32
wrog_predkosc = 2
numer_fali = 1
def generuj_fale(numer):
nowi = []
liczba = 3 + numer
for i in range(liczba):
odst = SZEROKOSC // (liczba + 1)
x = odst * (i + 1) - wrog_szerokosc // 2
y = 40 + (i % 2) * 35
nowi.append([x, y, 1])
return nowi
wrogowie = generuj_fale(numer_fali)
zycia = 3
punkty = 0
lasery = []
laser_predkosc = 9
czas_ostatniego_strzalu = 0
opoznienie_strzalu = 160
font = pygame.font.SysFont("Arial", 22)
font_duzy = pygame.font.SysFont("Arial", 52)
while True:
for zdarzenie in pygame.event.get():
if zdarzenie.type == pygame.QUIT:
pygame.quit()
exit()
klawisze = pygame.key.get_pressed()
if klawisze[pygame.K_LEFT]:
statek_x -= predkosc
if klawisze[pygame.K_RIGHT]:
statek_x += predkosc
if klawisze[pygame.K_UP]:
statek_y -= predkosc
if klawisze[pygame.K_DOWN]:
statek_y += predkosc
if statek_x < 0: statek_x = 0
if statek_x > SZEROKOSC - statek_szerokosc: statek_x = SZEROKOSC - statek_szerokosc
if statek_y < 0: statek_y = 0
if statek_y > WYSOKOSC - statek_wysokosc: statek_y = WYSOKOSC - statek_wysokosc
teraz = pygame.time.get_ticks()
if klawisze[pygame.K_SPACE] and teraz - czas_ostatniego_strzalu > opoznienie_strzalu:
lasery.append([statek_x + statek_szerokosc // 2 - 3, statek_y])
czas_ostatniego_strzalu = teraz
for laser in lasery:
laser[1] -= laser_predkosc
nowe_lasery = []
for laser in lasery:
if laser[1] > -30:
nowe_lasery.append(laser)
lasery = nowe_lasery
for wrog in wrogowie:
wrog[0] += wrog_predkosc * wrog[2]
if wrog[0] > SZEROKOSC - wrog_szerokosc:
wrog[2] = -1
if wrog[0] < 0:
wrog[2] = 1
for ast in asteroidy:
ast[1] += 3
if ast[1] > WYSOKOSC:
ast[1] = random.randint(-300, -30)
ast[0] = random.randint(0, SZEROKOSC - ast[2])
statek_rect = pygame.Rect(statek_x, statek_y, statek_szerokosc, statek_wysokosc)
for ast in asteroidy:
ast_rect = pygame.Rect(ast[0], ast[1], ast[2], ast[2])
if statek_rect.colliderect(ast_rect):
zycia -= 1
ast[1] = random.randint(-300, -30)
pozostale_lasery = []
trafieni_idx = []
for laser in lasery:
laser_rect = pygame.Rect(laser[0], laser[1], 6, 22)
trafil = False
for j in range(len(wrogowie)):
if j not in trafieni_idx:
wrog_rect = pygame.Rect(wrogowie[j][0], wrogowie[j][1], wrog_szerokosc, wrog_wysokosc)
if laser_rect.colliderect(wrog_rect):
trafieni_idx.append(j)
punkty += 20
trafil = True
break
if not trafil:
for ast in asteroidy:
ast_rect = pygame.Rect(ast[0], ast[1], ast[2], ast[2])
if laser_rect.colliderect(ast_rect) and not trafil:
punkty += 10
ast[1] = random.randint(-300, -30)
ast[0] = random.randint(0, SZEROKOSC - ast[2])
trafil = True
if not trafil:
pozostale_lasery.append(laser)
lasery = pozostale_lasery
for j in sorted(trafieni_idx, reverse=True):
wrogowie.pop(j)
if len(wrogowie) == 0:
numer_fali += 1
punkty += 50
wrogowie = generuj_fale(numer_fali)
wrog_predkosc = min(2 + numer_fali, 7)
ekran.fill((0, 0, 30))
pygame.draw.rect(ekran, (0, 200, 255), (statek_x, statek_y, statek_szerokosc, statek_wysokosc))
for ast in asteroidy:
pygame.draw.rect(ekran, (160, 160, 160), (ast[0], ast[1], ast[2], ast[2]))
for wrog in wrogowie:
pygame.draw.rect(ekran, (255, 100, 0), (wrog[0], wrog[1], wrog_szerokosc, wrog_wysokosc))
for laser in lasery:
pygame.draw.rect(ekran, (255, 50, 50), (laser[0], laser[1], 6, 22))
napis = font.render("Zycia: {} Punkty: {} Fala: {} Wrogow: {}".format(
zycia, punkty, numer_fali, len(wrogowie)), True, (255, 255, 255))
ekran.blit(napis, (10, 10))
if zycia <= 0:
ekran.fill((0, 0, 0))
ekran.blit(font_duzy.render("KONIEC GRY!", True, (255, 50, 50)), (240, 230))
ekran.blit(font.render("Wynik koncowy: {} Fala: {}".format(punkty, numer_fali), True, (255, 255, 255)), (260, 310))
pygame.display.flip()
pygame.time.wait(4000)
pygame.quit()
exit()
pygame.display.flip()
zegar.tick(60)
3 + numer na 2 + numer — mniej wrogów w każdej fali. Ile fal możesz przeżyć?50 na 100 — wyższy wynik za ukończenie fali.min(2 + numer_fali, 7) na min(1 + numer_fali, 10) — inne tempo przyspieszania.asteroidy dopisując kolejny append przed pętlą.generuj_fale żeby wrogowie w parzystych falach startowali z kierunkiem -1 (w lewo)def sprawdz_rekord(punkty, rekord) która zwraca nowy rekord i wyświetl go w KONIEC GRYglobal w funkcjach które muszą zmieniać stan gryx = 5 wewnątrz funkcji, tworzysz lokalną zmienną — nie zmienisz tej zewnętrznej.x = 100
def zmien():
x = 999 # tworzy LOKALNĄ zmienną x, zewnętrzna bez zmian!
print("w funkcji:", x)
zmien()
print("poza funkcja:", x) # nadal 100!
global mówi funkcji: „ta zmienna pochodzi spoza mnie":
x = 100
def zmien():
global x
x = 999 # teraz modyfikujemy ZEWNĘTRZNĄ zmienną
print("w funkcji:", x)
zmien()
print("poza funkcja:", x) # 999!
cwiczenie_global_1.py i cwiczenie_global_2.py.
zycia = 3
def strac_zycie():
global zycia
zycia -= 1
print("Pozostalo zyc:", zycia)
strac_zycie()
strac_zycie()
print("Koniec:", zycia)
global zycia i uruchom — co się stanie? Przywróć ją.global aby modyfikować zmienną zewnętrznąglobalpunkty = 0
numer_fali = 1
def nowa_fala():
global punkty, numer_fali
punkty += 50
numer_fali += 1
print("Fala {} | Punkty: {}".format(numer_fali, punkty))
nowa_fala()
nowa_fala()
nowa_fala()
wrog_predkosc = 2 i zwiększ ją w nowa_fala() (max 7).nowa_fala() aktualizującą stan gryglobal mogą zastąpić bezpośrednią modyfikacjęgra_14.py, zapisz jako gra_15.py i wytnij logikę do funkcji."Asteroidy — Lekcja 15: Funkcje i global!"ruch_statku(), strzal(), sprawdz_kolizje(). Słowo global pozwala funkcjom modyfikować zmienne zewnętrzne.def ruch_statku(klawisze):
global statek_x, statek_y
if klawisze[pygame.K_LEFT] or klawisze[pygame.K_a]: statek_x -= predkosc
if klawisze[pygame.K_RIGHT] or klawisze[pygame.K_d]: statek_x += predkosc
if klawisze[pygame.K_UP] or klawisze[pygame.K_w]: statek_y -= predkosc
if klawisze[pygame.K_DOWN] or klawisze[pygame.K_s]: statek_y += predkosc
if statek_x < 0: statek_x = 0
if statek_x > SZEROKOSC - statek_szerokosc: statek_x = SZEROKOSC - statek_szerokosc
if statek_y < 0: statek_y = 0
if statek_y > WYSOKOSC - statek_wysokosc: statek_y = WYSOKOSC - statek_wysokosc
global statek_x, statek_y — funkcja musi mieć dostęp do tych zmiennych żeby je zmieniać.def strzal(teraz):
global czas_ostatniego_strzalu
if teraz - czas_ostatniego_strzalu > opoznienie_strzalu:
lasery.append([statek_x + statek_szerokosc // 2 - 3, statek_y])
czas_ostatniego_strzalu = teraz
def aktualizuj_lasery():
for laser in lasery:
laser[1] -= laser_predkosc
lasery[:] = [l for l in lasery if l[1] > -30]
global dla list — listy są mutowalne, ich zawartość można zmieniać bez global. Tylko proste zmienne (int, str) wymagają global przy przypisaniu.def sprawdz_kolizje():
global zycia, punkty, trafiony_czas, numer_fali, wrog_predkosc
# ... cała logika kolizji z L14 ...
global.while True:
teraz = pygame.time.get_ticks()
# zdarzenia...
klawisze = pygame.key.get_pressed()
ruch_statku(klawisze)
if klawisze[pygame.K_SPACE]:
strzal(teraz)
aktualizuj_lasery()
aktualizuj_asteroidy()
aktualizuj_wrogow()
sprawdz_kolizje()
# rysowanie...
import pygame
import random
pygame.init()
SZEROKOSC = 800
WYSOKOSC = 600
ekran = pygame.display.set_mode((SZEROKOSC, WYSOKOSC))
pygame.display.set_caption("Asteroidy — Lekcja 15: Funkcje i global!")
zegar = pygame.time.Clock()
statek_szerokosc = 40
statek_wysokosc = 50
statek_x = SZEROKOSC // 2 - statek_szerokosc // 2
statek_y = WYSOKOSC - 80
predkosc = 5
asteroidy = []
for _ in range(2):
asteroidy.append([random.randint(0, SZEROKOSC-50), random.randint(-400,-30), random.randint(28,55)])
wrog_szerokosc = 44
wrog_wysokosc = 32
wrog_predkosc = 2
numer_fali = 1
def generuj_fale(numer):
nowi = []
liczba = 3 + numer
for i in range(liczba):
odst = SZEROKOSC // (liczba + 1)
nowi.append([odst*(i+1) - wrog_szerokosc//2, 40 + (i%2)*35, 1])
return nowi
wrogowie = generuj_fale(numer_fali)
zycia = 3
punkty = 0
lasery = []
laser_predkosc = 9
czas_ostatniego_strzalu = 0
opoznienie_strzalu = 160
trafiony_czas = 0
CZAS_TRAFIENIA = 500
font = pygame.font.SysFont("Arial", 22)
font_duzy = pygame.font.SysFont("Arial", 52)
def ruch_statku(klawisze):
global statek_x, statek_y
if klawisze[pygame.K_LEFT] or klawisze[pygame.K_a]: statek_x -= predkosc
if klawisze[pygame.K_RIGHT] or klawisze[pygame.K_d]: statek_x += predkosc
if klawisze[pygame.K_UP] or klawisze[pygame.K_w]: statek_y -= predkosc
if klawisze[pygame.K_DOWN] or klawisze[pygame.K_s]: statek_y += predkosc
if statek_x < 0: statek_x = 0
if statek_x > SZEROKOSC-statek_szerokosc: statek_x = SZEROKOSC-statek_szerokosc
if statek_y < 0: statek_y = 0
if statek_y > WYSOKOSC-statek_wysokosc: statek_y = WYSOKOSC-statek_wysokosc
def strzal(teraz):
global czas_ostatniego_strzalu
if teraz - czas_ostatniego_strzalu > opoznienie_strzalu:
lasery.append([statek_x+statek_szerokosc//2-3, statek_y])
czas_ostatniego_strzalu = teraz
def aktualizuj_lasery():
for l in lasery: l[1] -= laser_predkosc
lasery[:] = [l for l in lasery if l[1] > -30]
def aktualizuj_asteroidy():
for ast in asteroidy:
ast[1] += 3
if ast[1] > WYSOKOSC:
ast[1] = random.randint(-300,-30)
ast[0] = random.randint(0,SZEROKOSC-ast[2])
def aktualizuj_wrogow():
for w in wrogowie:
w[0] += wrog_predkosc * w[2]
if w[0] > SZEROKOSC-wrog_szerokosc: w[2] = -1
if w[0] < 0: w[2] = 1
def sprawdz_kolizje():
global zycia, punkty, trafiony_czas, numer_fali, wrog_predkosc
teraz = pygame.time.get_ticks()
sr = pygame.Rect(statek_x, statek_y, statek_szerokosc, statek_wysokosc)
if teraz - trafiony_czas > CZAS_TRAFIENIA:
for ast in asteroidy:
if sr.colliderect(pygame.Rect(ast[0],ast[1],ast[2],ast[2])):
zycia -= 1; trafiony_czas = teraz; ast[1] = random.randint(-300,-30)
pozostale = []; trafieni = []
for laser in lasery:
lr = pygame.Rect(laser[0],laser[1],6,22); trafil = False
for j in range(len(wrogowie)):
if j not in trafieni and lr.colliderect(pygame.Rect(wrogowie[j][0],wrogowie[j][1],wrog_szerokosc,wrog_wysokosc)):
trafieni.append(j); punkty += 20; trafil = True; break
if not trafil:
for ast in asteroidy:
if lr.colliderect(pygame.Rect(ast[0],ast[1],ast[2],ast[2])):
punkty += 10; ast[1]=random.randint(-300,-30); ast[0]=random.randint(0,SZEROKOSC-ast[2]); trafil=True; break
if not trafil: pozostale.append(laser)
lasery[:] = pozostale
for j in sorted(trafieni,reverse=True): wrogowie.pop(j)
if len(wrogowie)==0:
numer_fali+=1; punkty+=50; wrog_predkosc=min(2+numer_fali,7); wrogowie.extend(generuj_fale(numer_fali))
while True:
teraz = pygame.time.get_ticks()
for z in pygame.event.get():
if z.type == pygame.QUIT: pygame.quit(); exit()
klawisze = pygame.key.get_pressed()
ruch_statku(klawisze)
if klawisze[pygame.K_SPACE]: strzal(teraz)
aktualizuj_lasery(); aktualizuj_asteroidy(); aktualizuj_wrogow(); sprawdz_kolizje()
if zycia <= 0:
ekran.fill((0,0,0)); ekran.blit(font_duzy.render("KONIEC GRY!",True,(255,50,50)),(240,230))
ekran.blit(font.render("Wynik: {} Fala: {}".format(punkty,numer_fali),True,(255,255,255)),(270,310))
pygame.display.flip(); pygame.time.wait(3000); pygame.quit(); exit()
trafiony = teraz - trafiony_czas < CZAS_TRAFIENIA
kolor_s = (255,80,80) if trafiony else (0,200,255)
ekran.fill((0,0,30))
pygame.draw.rect(ekran,kolor_s,(statek_x,statek_y,statek_szerokosc,statek_wysokosc))
for ast in asteroidy: pygame.draw.rect(ekran,(160,160,160),(ast[0],ast[1],ast[2],ast[2]))
for w in wrogowie: pygame.draw.rect(ekran,(255,100,0),(w[0],w[1],wrog_szerokosc,wrog_wysokosc))
for l in lasery: pygame.draw.rect(ekran,(255,50,50),(l[0],l[1],6,22))
ekran.blit(font.render("Zycia:{} Pkt:{} Fala:{}".format(zycia,punkty,numer_fali),True,(255,255,255)),(10,10))
pygame.display.flip(); zegar.tick(60)
global statek_x, statek_y z ruch_statku() — co się stanie?print("strzal!") do funkcji strzal() — sprawdź czy się wywołujepredkosc = 5 na 10 — czy działa tak samo jak w L14?wyswietl_hud() która rysuje tekst z życiami i punktamirysuj_scene(trafiony)dodaj_asteroidy(ile) przyjmującą ile asteroid dodaćsprawdz_kolizje() przed aktualizuj_wrogow()? Co się zmienia?generuj_fale() parametr predkosc_bazowa z domyślną wartością 2stan = "menu" # "menu", "gra", "koniec"
if stan == "menu":
print("Pokazuj ekran startowy")
elif stan == "gra":
print("Uruchamiaj logike gry")
elif stan == "koniec":
print("Pokazuj game over")
continue w pętli — przeskakuje resztę bieżącej iteracji i zaczyna następną:
for i in range(5):
if i == 2:
continue # przeskocz gdy i==2
print(i) # wypisze 0, 1, 3, 4
W grze: continue po obsłudze ekranu menu sprawia że kod gry NIE wykonuje się gdy jesteśmy w menu.
cwiczenie_stan_1.py i cwiczenie_stan_2.py.
stan = "menu"
while True:
if stan == "menu":
print("=== MENU === (wpisz 's' aby zaczac)")
inp = input()
if inp == "s":
stan = "gra"
elif stan == "gra":
print("=== GRA === (wpisz 'k' aby skonczyc)")
inp = input()
if inp == "k":
stan = "koniec"
elif stan == "koniec":
print("=== KONIEC === gra sie skonczyla")
break
"pauza" — gdy gracz wpisze 'p' przechodzi do pauzy, 'p' znowu — wraca do gry.stan = "menu"
klatka = 0
while klatka < 10:
klatka += 1
if stan == "menu":
print("Klatka", klatka, "— menu, brak logiki gry")
if klatka == 3:
stan = "gra"
continue # przeskocz resztę — nie wykonuj logiki gry
# To wykonuje się tylko gdy stan == "gra"
print("Klatka", klatka, "— gra dziala!")
klatka == 5. Sprawdź kiedy pojawia się "gra dziala!".continue do pomijania logiki gry w stanie menucontinue nie wykonuje się w danej iteracjicontinue w pętli grygra_15.py → zapisz jako gra_16.py. Dodamy stan_gry, nowa_gra() i dwa ekrany.
"Asteroidy — Lekcja 16: Stany Gry!"
stan_gry = "start"/"gra"/"game_over" + continue przeskakuje logikę gry gdy jesteśmy w menu. nowa_gra() resetuje wszystko.continue jest czystszy niż zagnieżdżone if/else — gdy stan to menu, reszta pętli w ogóle się nie wykonuje.stan_gry = "start" # "start", "gra", "game_over"
najlepszy_wynik = 0
def nowa_gra():
global zycia, punkty, numer_fali, wrog_predkosc
global lasery, asteroidy, wrogowie, trafiony_czas, statek_x, statek_y
zycia = 3; punkty = 0; numer_fali = 1; wrog_predkosc = 2
lasery = []; trafiony_czas = 0
statek_x = SZEROKOSC // 2 - statek_szerokosc // 2
statek_y = WYSOKOSC - 80
asteroidy.clear()
for _ in range(2):
asteroidy.append([random.randint(0,SZEROKOSC-50), random.randint(-400,-30), random.randint(28,55)])
wrogowie.clear()
wrogowie.extend(generuj_fale(numer_fali))
for zdarzenie in pygame.event.get():
if zdarzenie.type == pygame.QUIT: ...
if zdarzenie.type == pygame.KEYDOWN:
if zdarzenie.key == pygame.K_RETURN:
if stan_gry in ("start", "game_over"):
nowa_gra()
stan_gry = "gra"
if stan_gry == "start":
ekran_startowy()
pygame.display.flip()
zegar.tick(60)
continue # przeskocz logikę gry!
if stan_gry == "game_over":
ekran_game_over()
pygame.display.flip()
zegar.tick(60)
continue
pygame.KEYDOWN odpala się raz gdy klawisz jest naciśnięty (nie 60× gdy trzymasz).get_pressed() daje stan w każdej klatce — dobre do ruchu. KEYDOWN — do pojedynczych akcji (start, pauza).
if zycia <= 0:
najlepszy_wynik = max(najlepszy_wynik, punkty)
stan_gry = "game_over" # nie exit() — tylko zmień stan!
import pygame
import random
# === LEKCJA 16: Stany Gry — start / gra / koniec ===
pygame.init()
SZEROKOSC = 800
WYSOKOSC = 600
ekran = pygame.display.set_mode((SZEROKOSC, WYSOKOSC))
pygame.display.set_caption("Asteroidy — Gra 16: Stany Gry!")
zegar = pygame.time.Clock()
stan_gry = "start" # mozliwe wartosci: "start", "gra", "game_over"
statek_szerokosc = 40
statek_wysokosc = 50
statek_x = SZEROKOSC // 2 - statek_szerokosc // 2
statek_y = WYSOKOSC - 80
predkosc = 5
wrog_szerokosc = 44
wrog_wysokosc = 32
wrog_predkosc = 2
numer_fali = 1
zycia = 3
punkty = 0
najlepszy_wynik = 0
lasery = []
laser_predkosc = 9
czas_ostatniego_strzalu = 0
opoznienie_strzalu = 160
asteroidy = []
wrogowie = []
trafiony_czas = 0
CZAS_TRAFIENIA = 500
font = pygame.font.SysFont("Arial", 22)
font_sredni = pygame.font.SysFont("Arial", 32)
font_duzy = pygame.font.SysFont("Arial", 52)
def generuj_fale(numer):
nowi = []
liczba = 3 + numer
for i in range(liczba):
odst = SZEROKOSC // (liczba + 1)
x = odst * (i + 1) - wrog_szerokosc // 2
y = 40 + (i % 2) * 35
nowi.append([x, y, 1])
return nowi
def nowa_gra():
global zycia, punkty, numer_fali, wrog_predkosc
global lasery, asteroidy, wrogowie, trafiony_czas, statek_x, statek_y
zycia = 3
punkty = 0
numer_fali = 1
wrog_predkosc = 2
lasery = []
trafiony_czas = 0
statek_x = SZEROKOSC // 2 - statek_szerokosc // 2
statek_y = WYSOKOSC - 80
asteroidy.clear()
for _ in range(2):
asteroidy.append([random.randint(0, SZEROKOSC - 50),
random.randint(-400, -30),
random.randint(28, 55)])
wrogowie.clear()
wrogowie.extend(generuj_fale(numer_fali))
def ruch_statku(klawisze):
global statek_x, statek_y
if klawisze[pygame.K_LEFT] or klawisze[pygame.K_a]: statek_x -= predkosc
if klawisze[pygame.K_RIGHT] or klawisze[pygame.K_d]: statek_x += predkosc
if klawisze[pygame.K_UP] or klawisze[pygame.K_w]: statek_y -= predkosc
if klawisze[pygame.K_DOWN] or klawisze[pygame.K_s]: statek_y += predkosc
if statek_x < 0: statek_x = 0
if statek_x > SZEROKOSC - statek_szerokosc: statek_x = SZEROKOSC - statek_szerokosc
if statek_y < 0: statek_y = 0
if statek_y > WYSOKOSC - statek_wysokosc: statek_y = WYSOKOSC - statek_wysokosc
def strzal(teraz):
global czas_ostatniego_strzalu
if teraz - czas_ostatniego_strzalu > opoznienie_strzalu:
lasery.append([statek_x + statek_szerokosc // 2 - 3, statek_y])
czas_ostatniego_strzalu = teraz
def aktualizuj_lasery():
for laser in lasery:
laser[1] -= laser_predkosc
lasery[:] = [l for l in lasery if l[1] > -30]
def aktualizuj_asteroidy():
for ast in asteroidy:
ast[1] += 3
if ast[1] > WYSOKOSC:
ast[1] = random.randint(-300, -30)
ast[0] = random.randint(0, SZEROKOSC - ast[2])
def aktualizuj_wrogow():
for wrog in wrogowie:
wrog[0] += wrog_predkosc * wrog[2]
if wrog[0] > SZEROKOSC - wrog_szerokosc: wrog[2] = -1
if wrog[0] < 0: wrog[2] = 1
def sprawdz_kolizje():
global zycia, punkty, trafiony_czas, numer_fali, wrog_predkosc
teraz = pygame.time.get_ticks()
statek_rect = pygame.Rect(statek_x, statek_y, statek_szerokosc, statek_wysokosc)
if teraz - trafiony_czas > CZAS_TRAFIENIA:
for ast in asteroidy:
if statek_rect.colliderect(pygame.Rect(ast[0], ast[1], ast[2], ast[2])):
zycia -= 1
trafiony_czas = teraz
ast[1] = random.randint(-300, -30)
pozostale = []
trafieni = []
for laser in lasery:
lr = pygame.Rect(laser[0], laser[1], 6, 22)
trafil = False
for j in range(len(wrogowie)):
if j not in trafieni:
if lr.colliderect(pygame.Rect(wrogowie[j][0], wrogowie[j][1],
wrog_szerokosc, wrog_wysokosc)):
trafieni.append(j)
punkty += 20
trafil = True
break
if not trafil:
for ast in asteroidy:
if lr.colliderect(pygame.Rect(ast[0], ast[1], ast[2], ast[2])):
punkty += 10
ast[1] = random.randint(-300, -30)
ast[0] = random.randint(0, SZEROKOSC - ast[2])
trafil = True
break
if not trafil:
pozostale.append(laser)
lasery[:] = pozostale
for j in sorted(trafieni, reverse=True):
wrogowie.pop(j)
if len(wrogowie) == 0:
numer_fali += 1
punkty += 50
wrog_predkosc = min(2 + numer_fali, 7)
wrogowie.extend(generuj_fale(numer_fali))
def ekran_startowy():
ekran.fill((0, 0, 25))
tytul = font_duzy.render("ASTEROIDY", True, (255, 220, 50))
ekran.blit(tytul, (SZEROKOSC // 2 - tytul.get_width() // 2, 200))
info = font_sredni.render("Nacisnij ENTER aby zaczac!", True, (50, 220, 50))
ekran.blit(info, (SZEROKOSC // 2 - info.get_width() // 2, 320))
sterowanie = font.render("Strzalki/WSAD — ruch | SPACJA — strzal", True, (200, 200, 200))
ekran.blit(sterowanie, (SZEROKOSC // 2 - sterowanie.get_width() // 2, 400))
def ekran_game_over():
ekran.fill((0, 0, 0))
koniec = font_duzy.render("KONIEC GRY", True, (255, 60, 60))
ekran.blit(koniec, (SZEROKOSC // 2 - koniec.get_width() // 2, 180))
wynik = font_sredni.render("Twoj wynik: {}".format(punkty), True, (255, 220, 50))
ekran.blit(wynik, (SZEROKOSC // 2 - wynik.get_width() // 2, 270))
rekord = font.render("Rekord sesji: {}".format(najlepszy_wynik), True, (200, 200, 200))
ekran.blit(rekord, (SZEROKOSC // 2 - rekord.get_width() // 2, 330))
fala = font.render("Dotarles do fali: {}".format(numer_fali), True, (200, 200, 200))
ekran.blit(fala, (SZEROKOSC // 2 - fala.get_width() // 2, 370))
restart = font_sredni.render("ENTER = zagraj ponownie", True, (50, 220, 50))
ekran.blit(restart, (SZEROKOSC // 2 - restart.get_width() // 2, 450))
while True:
teraz = pygame.time.get_ticks()
for zdarzenie in pygame.event.get():
if zdarzenie.type == pygame.QUIT:
pygame.quit()
exit()
if zdarzenie.type == pygame.KEYDOWN:
if zdarzenie.key == pygame.K_RETURN:
if stan_gry in ("start", "game_over"):
nowa_gra()
stan_gry = "gra"
if stan_gry == "start":
ekran_startowy()
pygame.display.flip()
zegar.tick(60)
continue
if stan_gry == "game_over":
ekran_game_over()
pygame.display.flip()
zegar.tick(60)
continue
klawisze = pygame.key.get_pressed()
ruch_statku(klawisze)
if klawisze[pygame.K_SPACE]:
strzal(teraz)
aktualizuj_lasery()
aktualizuj_asteroidy()
aktualizuj_wrogow()
sprawdz_kolizje()
if zycia <= 0:
najlepszy_wynik = max(najlepszy_wynik, punkty)
stan_gry = "game_over"
trafiony = teraz - trafiony_czas < CZAS_TRAFIENIA
kolor_statku = (255, 80, 80) if trafiony else (0, 200, 255)
ekran.fill((0, 0, 30))
pygame.draw.rect(ekran, kolor_statku,
(statek_x, statek_y, statek_szerokosc, statek_wysokosc))
for ast in asteroidy:
pygame.draw.rect(ekran, (160, 160, 160), (ast[0], ast[1], ast[2], ast[2]))
for wrog in wrogowie:
pygame.draw.rect(ekran, (255, 100, 0),
(wrog[0], wrog[1], wrog_szerokosc, wrog_wysokosc))
for laser in lasery:
pygame.draw.rect(ekran, (255, 50, 50), (laser[0], laser[1], 6, 22))
ekran.blit(font.render("Zycia: {} Pkt: {} Fala: {}".format(zycia, punkty, numer_fali),
True, (255, 255, 255)), (10, 10))
pygame.display.flip()
zegar.tick(60)
K_RETURN na K_SPACEnajlepszy_wynik"pauza" — klawisz P zatrzymuje grę, P znowu ją wznawiaKOLOR_TLO = (0, 0, 25)
KOLOR_STATEK = (0, 200, 255)
SZEROKOSC = 800
# Stary sposób (z L10):
nowe = []
for laser in lasery:
if laser[1] > -30:
nowe.append(laser)
lasery = nowe
# List comprehension — to samo w jednej linii:
lasery[:] = [l for l in lasery if l[1] > -30]
Czytaj jako: „zostaw te l z lasery dla których l[1] > -30".
cwiczenie_listcomp_1.py i cwiczenie_listcomp_2.py.
liczby = [5, -3, 8, -1, 0, 12, -7, 4]
# Zostaw tylko dodatnie
dodatnie = [x for x in liczby if x > 0]
print("Dodatnie:", dodatnie)
# Tylko parzyste
parzyste = [x for x in liczby if x % 2 == 0]
print("Parzyste:", parzyste)
[100, -50, 200, 850, 300, -10, 760] zostaw tylko liczby z zakresu 0–800 (symulacja pozycji X na ekranie).if[x for x in lista if warunek]for + appendlasery = [[100, 500], [200, -10], [300, 200], [150, -50], [400, 100]]
# Zostaw lasery wciąż na ekranie (y > -30)
lasery[:] = [l for l in lasery if l[1] > -30]
print("Lasery na ekranie:", lasery)
l[1] < 600.lasery[:] = [...] zamiast lasery = [...] (modyfikacja w miejscu)gra_16.py → zapisz jako gra_17.py. Nowe funkcje rysujące zastąpią draw.rect.
draw.polygon() rysuje kształt z listy punktów (x, y). Gwiazdki to lista 80 losowych [x, y, rozmiar] + pętla draw.circle(). Stałe KOLOR_* zastępują dosłowne krotki RGB.rysuj_statek(), rysuj_asteroide()) kapsułkują wygląd — zmiana grafiki nie dotyka logiki gry. Stałe kolorów = jeden zmieniamy w jednym miejscu.KOLOR_TLO = (0, 0, 25)
KOLOR_STATEK = (0, 200, 255)
KOLOR_LASER = (255, 60, 60)
KOLOR_WROG = (255, 100, 0)
gwiazdki = []
for _ in range(80):
gwiazdki.append([random.randint(0, SZEROKOSC),
random.randint(0, WYSOKOSC),
random.randint(1, 3)])
def rysuj_statek(trafiony):
kolor = (255, 80, 80) if trafiony else KOLOR_STATEK
# Dziob
pygame.draw.polygon(ekran, kolor, [
(statek_x + 21, statek_y),
(statek_x, statek_y + 22),
(statek_x + 42, statek_y + 22)
])
# Kadlub
pygame.draw.rect(ekran, kolor, (statek_x + 12, statek_y + 16, 18, 30))
# Skrzydla
pygame.draw.polygon(ekran, (0, 140, 200), [
(statek_x, statek_y + 22),
(statek_x - 8, statek_y + 52),
(statek_x + 16, statek_y + 40)
])
draw.polygon(ekran, kolor, lista_punktow) rysuje wielokąt przez podaną listę punktów (x, y). Krawędzie są łączone automatycznie.def rysuj_asteroide(x, y, rozmiar):
pts = [
(x + rozmiar*0.5, y),
(x + rozmiar, y + rozmiar*0.3),
(x + rozmiar*0.9, y + rozmiar),
(x + rozmiar*0.3, y + rozmiar*0.95),
(x, y + rozmiar*0.6),
(x + rozmiar*0.1, y + rozmiar*0.2),
]
pygame.draw.polygon(ekran, (155, 155, 155), pts)
pygame.draw.polygon(ekran, (120, 120, 120), pts, 2) # kontur
def wyswietl_hud():
pygame.draw.rect(ekran, (0, 0, 60), (0, 0, SZEROKOSC, 36))
ekran.blit(font_maly.render("ZYCIA: " + ("* "*max(zycia,0)), True, (255,60,60)), (10, 9))
ekran.blit(font_maly.render("PUNKTY: {}".format(punkty), True, (255,220,50)), (220, 9))
ekran.blit(font_maly.render("FALA: {}".format(numer_fali), True, (50,220,50)), (420, 9))
import pygame
import random
# === LEKCJA 17: Wielokąty, gwiazdki i stałe kolorów ===
pygame.init()
SZEROKOSC = 800
WYSOKOSC = 600
ekran = pygame.display.set_mode((SZEROKOSC, WYSOKOSC))
pygame.display.set_caption("Asteroidy — Gra 17: Wielokaty i Gwiazdy!")
zegar = pygame.time.Clock()
KOLOR_TLO = (0, 0, 25)
KOLOR_STATEK = (0, 200, 255)
KOLOR_LASER = (255, 60, 60)
KOLOR_WROG = (255, 100, 0)
KOLOR_BIALY = (255, 255, 255)
KOLOR_ZOLTY = (255, 220, 50)
KOLOR_ZIELONY = (50, 220, 50)
KOLOR_CZERWONY= (255, 60, 60)
stan_gry = "start"
statek_szerokosc = 42
statek_wysokosc = 52
statek_x = SZEROKOSC // 2 - statek_szerokosc // 2
statek_y = WYSOKOSC - 90
predkosc = 5
wrog_szerokosc = 44
wrog_wysokosc = 32
wrog_predkosc = 2
numer_fali = 1
zycia = 3
punkty = 0
najlepszy_wynik = 0
lasery = []
laser_predkosc = 10
czas_ostatniego_strzalu = 0
opoznienie_strzalu = 160
asteroidy = []
wrogowie = []
trafiony_czas = 0
CZAS_TRAFIENIA = 500
font_maly = pygame.font.SysFont("Arial", 20)
font_sredni= pygame.font.SysFont("Arial", 32)
font_duzy = pygame.font.SysFont("Arial", 52)
font_wielki= pygame.font.SysFont("Arial", 72)
gwiazdki = []
for _ in range(80):
gwiazdki.append([random.randint(0, SZEROKOSC),
random.randint(0, WYSOKOSC),
random.randint(1, 3)])
def generuj_fale(numer):
nowi = []
liczba = 3 + numer
for i in range(liczba):
odst = SZEROKOSC // (liczba + 1)
x = odst * (i + 1) - wrog_szerokosc // 2
y = 40 + (i % 2) * 38
nowi.append([x, y, 1])
return nowi
def nowa_gra():
global zycia, punkty, numer_fali, wrog_predkosc
global lasery, asteroidy, wrogowie, trafiony_czas, statek_x, statek_y
zycia = 3; punkty = 0; numer_fali = 1; wrog_predkosc = 2
lasery = []; trafiony_czas = 0
statek_x = SZEROKOSC // 2 - statek_szerokosc // 2
statek_y = WYSOKOSC - 90
asteroidy.clear()
dodaj_asteroidy(3)
wrogowie.clear()
wrogowie.extend(generuj_fale(numer_fali))
def dodaj_asteroidy(ile):
for _ in range(ile):
rozmiar = random.randint(28, 55)
asteroidy.append([random.randint(0, SZEROKOSC - rozmiar),
random.randint(-350, -rozmiar),
rozmiar,
random.uniform(2.0, 3.5)])
def ruch_statku(klawisze):
global statek_x, statek_y
if klawisze[pygame.K_LEFT] or klawisze[pygame.K_a]: statek_x -= predkosc
if klawisze[pygame.K_RIGHT] or klawisze[pygame.K_d]: statek_x += predkosc
if klawisze[pygame.K_UP] or klawisze[pygame.K_w]: statek_y -= predkosc
if klawisze[pygame.K_DOWN] or klawisze[pygame.K_s]: statek_y += predkosc
if statek_x < 0: statek_x = 0
if statek_x > SZEROKOSC - statek_szerokosc: statek_x = SZEROKOSC - statek_szerokosc
if statek_y < 0: statek_y = 0
if statek_y > WYSOKOSC - statek_wysokosc: statek_y = WYSOKOSC - statek_wysokosc
def strzal(teraz):
global czas_ostatniego_strzalu
if teraz - czas_ostatniego_strzalu > opoznienie_strzalu:
lasery.append([statek_x + statek_szerokosc // 2 - 3, statek_y])
czas_ostatniego_strzalu = teraz
def aktualizuj_lasery():
for laser in lasery:
laser[1] -= laser_predkosc
lasery[:] = [l for l in lasery if l[1] > -30]
def aktualizuj_asteroidy():
for ast in asteroidy:
ast[1] += ast[3]
if ast[1] > WYSOKOSC:
ast[1] = random.randint(-300, -ast[2])
ast[0] = random.randint(0, SZEROKOSC - ast[2])
ast[2] = random.randint(28, 55)
ast[3] = random.uniform(2.0, 3.5)
def aktualizuj_wrogow():
for wrog in wrogowie:
wrog[0] += wrog_predkosc * wrog[2]
if wrog[0] > SZEROKOSC - wrog_szerokosc: wrog[2] = -1
if wrog[0] < 0: wrog[2] = 1
def sprawdz_kolizje():
global zycia, punkty, trafiony_czas, numer_fali, wrog_predkosc
teraz = pygame.time.get_ticks()
sr = pygame.Rect(statek_x, statek_y, statek_szerokosc, statek_wysokosc)
if teraz - trafiony_czas > CZAS_TRAFIENIA:
for ast in asteroidy:
if sr.colliderect(pygame.Rect(ast[0], ast[1], ast[2], ast[2])):
zycia -= 1; trafiony_czas = teraz
ast[1] = random.randint(-300, -ast[2])
pozostale = []; trafieni = []
for laser in lasery:
lr = pygame.Rect(laser[0], laser[1], 6, 22)
trafil = False
for j in range(len(wrogowie)):
if j not in trafieni:
if lr.colliderect(pygame.Rect(wrogowie[j][0], wrogowie[j][1],
wrog_szerokosc, wrog_wysokosc)):
trafieni.append(j); punkty += 20; trafil = True; break
if not trafil:
for ast in asteroidy:
if lr.colliderect(pygame.Rect(ast[0], ast[1], ast[2], ast[2])):
punkty += 10
ast[1] = random.randint(-300, -ast[2])
ast[0] = random.randint(0, SZEROKOSC - ast[2])
trafil = True; break
if not trafil:
pozostale.append(laser)
lasery[:] = pozostale
for j in sorted(trafieni, reverse=True):
wrogowie.pop(j)
if len(wrogowie) == 0:
numer_fali += 1; punkty += 50
wrog_predkosc = min(2 + numer_fali, 8)
wrogowie.extend(generuj_fale(numer_fali))
def rysuj_gwiazdki():
for gw in gwiazdki:
pygame.draw.circle(ekran, (180, 180, 180), (gw[0], gw[1]), 1)
def rysuj_statek(trafiony):
kolor = (255, 80, 80) if trafiony else KOLOR_STATEK
pygame.draw.rect(ekran, kolor, (statek_x + 12, statek_y + 16, 18, 30))
pygame.draw.polygon(ekran, kolor, [
(statek_x + 21, statek_y),
(statek_x, statek_y + 22),
(statek_x + 42, statek_y + 22)
])
pygame.draw.polygon(ekran, (0, 140, 200), [
(statek_x, statek_y + 22),
(statek_x - 8, statek_y + 52),
(statek_x + 16, statek_y + 40)
])
pygame.draw.polygon(ekran, (0, 140, 200), [
(statek_x + 42, statek_y + 22),
(statek_x + 50, statek_y + 52),
(statek_x + 26, statek_y + 40)
])
def rysuj_asteroide(x, y, rozmiar):
pts = [
(x + rozmiar * 0.5, y),
(x + rozmiar, y + rozmiar * 0.3),
(x + rozmiar * 0.9, y + rozmiar),
(x + rozmiar * 0.3, y + rozmiar * 0.95),
(x, y + rozmiar * 0.6),
(x + rozmiar * 0.1, y + rozmiar * 0.2),
]
pygame.draw.polygon(ekran, (155, 155, 155), pts)
pygame.draw.polygon(ekran, (120, 120, 120), pts, 2)
def rysuj_wroga(x, y):
pygame.draw.rect(ekran, KOLOR_WROG, (x + 8, y, wrog_szerokosc - 16, wrog_wysokosc))
pygame.draw.polygon(ekran, (220, 80, 0), [
(x + wrog_szerokosc // 2, y + wrog_wysokosc),
(x, y + 8),
(x + wrog_szerokosc, y + 8)
])
pygame.draw.circle(ekran, (255, 200, 50), (x + wrog_szerokosc // 2, y + 10), 5)
def wyswietl_hud():
pygame.draw.rect(ekran, (0, 0, 60), (0, 0, SZEROKOSC, 36))
ekran.blit(font_maly.render("ZYCIA: " + ("* " * max(zycia, 0)), True, KOLOR_CZERWONY), (10, 9))
ekran.blit(font_maly.render("PUNKTY: {}".format(punkty), True, KOLOR_ZOLTY), (220, 9))
ekran.blit(font_maly.render("FALA: {}".format(numer_fali), True, KOLOR_ZIELONY), (420, 9))
ekran.blit(font_maly.render("WROGOW: {}".format(len(wrogowie)), True, KOLOR_BIALY), (580, 9))
def ekran_startowy():
ekran.fill(KOLOR_TLO)
rysuj_gwiazdki()
tytul = font_wielki.render("ASTEROIDY", True, KOLOR_ZOLTY)
ekran.blit(tytul, (SZEROKOSC // 2 - tytul.get_width() // 2, 180))
info = font_sredni.render("Nacisnij ENTER aby zaczac!", True, KOLOR_ZIELONY)
ekran.blit(info, (SZEROKOSC // 2 - info.get_width() // 2, 330))
ster = font_maly.render("Strzalki/WSAD — ruch | SPACJA — strzal", True, KOLOR_BIALY)
ekran.blit(ster, (SZEROKOSC // 2 - ster.get_width() // 2, 400))
def ekran_game_over():
ekran.fill((0, 0, 0))
rysuj_gwiazdki()
koniec = font_wielki.render("KONIEC GRY", True, KOLOR_CZERWONY)
ekran.blit(koniec, (SZEROKOSC // 2 - koniec.get_width() // 2, 150))
wynik = font_duzy.render("Twoj wynik: {}".format(punkty), True, KOLOR_ZOLTY)
ekran.blit(wynik, (SZEROKOSC // 2 - wynik.get_width() // 2, 270))
rekord = font_sredni.render("Rekord: {}".format(najlepszy_wynik), True, KOLOR_BIALY)
ekran.blit(rekord, (SZEROKOSC // 2 - rekord.get_width() // 2, 350))
restart = font_sredni.render("ENTER = zagraj ponownie", True, KOLOR_ZIELONY)
ekran.blit(restart, (SZEROKOSC // 2 - restart.get_width() // 2, 450))
while True:
teraz = pygame.time.get_ticks()
for zdarzenie in pygame.event.get():
if zdarzenie.type == pygame.QUIT:
pygame.quit()
exit()
if zdarzenie.type == pygame.KEYDOWN:
if zdarzenie.key == pygame.K_RETURN:
if stan_gry in ("start", "game_over"):
nowa_gra()
stan_gry = "gra"
if stan_gry == "start":
ekran_startowy()
pygame.display.flip()
zegar.tick(60)
continue
if stan_gry == "game_over":
ekran_game_over()
pygame.display.flip()
zegar.tick(60)
continue
klawisze = pygame.key.get_pressed()
ruch_statku(klawisze)
if klawisze[pygame.K_SPACE]:
strzal(teraz)
aktualizuj_lasery()
aktualizuj_asteroidy()
aktualizuj_wrogow()
sprawdz_kolizje()
if zycia <= 0:
najlepszy_wynik = max(najlepszy_wynik, punkty)
stan_gry = "game_over"
trafiony = teraz - trafiony_czas < CZAS_TRAFIENIA
ekran.fill(KOLOR_TLO)
rysuj_gwiazdki()
for ast in asteroidy:
rysuj_asteroide(ast[0], ast[1], ast[2])
for wrog in wrogowie:
rysuj_wroga(wrog[0], wrog[1])
for laser in lasery:
pygame.draw.rect(ekran, KOLOR_LASER, (laser[0], laser[1], 6, 22))
rysuj_statek(trafiony)
wyswietl_hud()
pygame.display.flip()
zegar.tick(60)
KOLOR_STATEK — jaki kolor lubisz?draw.polygon)rysuj_wroga(x, y) z draw.polygon i draw.circle[x, y, rozmiar, predkosc] — każda asteroida spada z własną prędkością"WROGOW: {}"najlepszy = 0
wynik = 150
najlepszy = max(najlepszy, wynik)
print(najlepszy) # 150
wynik = 80
najlepszy = max(najlepszy, wynik)
print(najlepszy) # nadal 150 — rekord nie spada!
# get_pressed() — stan w każdej klatce (do ruchu, strzału)
klawisze = pygame.key.get_pressed()
if klawisze[pygame.K_LEFT]: x -= 5 # odpala 60x/s gdy trzymasz
# KEYDOWN — zdarzenie gdy klawisz jest naciśnięty (1 raz)
if zdarzenie.type == pygame.KEYDOWN:
if zdarzenie.key == pygame.K_RETURN:
stan = "gra" # odpala się raz przy naciśnięciu
cwiczenie_rekord_1.py.
import random
najlepszy = 0
for rozgrywka in range(5):
wynik = random.randint(10, 200)
print("Rozgrywka {}: wynik = {}".format(rozgrywka + 1, wynik))
if wynik > najlepszy:
najlepszy = wynik
print(" NOWY REKORD!")
print("Rekord sesji:", najlepszy)
max() zamiast if wynik > najlepszy. Wyświetl "NOWY REKORD!" tylko gdy wynik == najlepszy i najlepszy > 0.max(a, b) do aktualizowania rekordugra_17.py → zapisz jako gra_18.py. Trzy małe zmiany = pełna gra.
max(najlepszy_wynik, punkty) aktualizuje rekord bez if. Warunek punkty >= najlepszy and punkty > 0 odróżnia rekord od zerowego wyniku przy pierwszej grze.gra_18.py jest identyczny z gra_asteroidy.py — ukończyłeś kurs!if zycia <= 0:
najlepszy_wynik = max(najlepszy_wynik, punkty) # NOWE: max()
stan_gry = "game_over"
def ekran_startowy():
ekran.fill(KOLOR_TLO)
rysuj_gwiazdki()
tytul = font_wielki.render("ASTEROIDY", True, KOLOR_ZOLTY)
ekran.blit(tytul, (SZEROKOSC//2 - tytul.get_width()//2, 130))
linie = [
"Strzalki / WSAD — ruch statku",
"SPACJA — strzal laserem",
"Wrog = 20 pkt | Skala = 10 pkt | Fala = +50 pkt",
]
for i, l in enumerate(linie):
n = font_maly.render(l, True, KOLOR_BIALY)
ekran.blit(n, (SZEROKOSC//2 - n.get_width()//2, 310 + i*32))
start = font_duzy.render("Nacisnij ENTER aby zaczac!", True, KOLOR_ZIELONY)
ekran.blit(start, (SZEROKOSC//2 - start.get_width()//2, 480))
def ekran_game_over():
ekran.fill((0, 0, 0))
rysuj_gwiazdki()
koniec = font_wielki.render("KONIEC GRY", True, KOLOR_CZERWONY)
ekran.blit(koniec, (SZEROKOSC//2 - koniec.get_width()//2, 150))
wynik = font_duzy.render("Twoj wynik: {}".format(punkty), True, KOLOR_ZOLTY)
ekran.blit(wynik, (SZEROKOSC//2 - wynik.get_width()//2, 250))
rekord = font_sredni.render("Rekord: {}".format(najlepszy_wynik), True, KOLOR_BIALY)
ekran.blit(rekord, (SZEROKOSC//2 - rekord.get_width()//2, 320))
if punkty >= najlepszy_wynik and punkty > 0: # NOWE
nr = font_sredni.render("NOWY REKORD!", True, KOLOR_ZIELONY)
ekran.blit(nr, (SZEROKOSC//2 - nr.get_width()//2, 360))
punkty >= najlepszy_wynik and punkty > 0 — sprawdzamy że wynik jest najlepszym i że jest >0 (nie chcemy "NOWY REKORD!" dla 0 punktów przy pierwszej grze).
import pygame
import random
# === LEKCJA 18: Rekord, pełny ekran startowy — FINAŁ! ===
# Ten plik jest identyczny z gra_asteroidy.py!
pygame.init()
SZEROKOSC = 800
WYSOKOSC = 600
ekran = pygame.display.set_mode((SZEROKOSC, WYSOKOSC))
pygame.display.set_caption("ASTEROIDY — Pelna Gra!")
zegar = pygame.time.Clock()
KOLOR_TLO = (0, 0, 25)
KOLOR_STATEK = (0, 200, 255)
KOLOR_LASER = (255, 60, 60)
KOLOR_WROG = (255, 100, 0)
KOLOR_BIALY = (255, 255, 255)
KOLOR_ZOLTY = (255, 220, 50)
KOLOR_ZIELONY = (50, 220, 50)
KOLOR_CZERWONY= (255, 60, 60)
stan_gry = "start"
statek_szerokosc = 42
statek_wysokosc = 52
statek_x = SZEROKOSC // 2 - statek_szerokosc // 2
statek_y = WYSOKOSC - 90
predkosc_statku = 5
wrog_szerokosc = 44
wrog_wysokosc = 32
wrog_predkosc = 2
numer_fali = 1
poziom = 1
zycia = 3
punkty = 0
najlepszy_wynik = 0
lasery = []
laser_predkosc = 10
czas_ostatniego_strzalu = 0
opoznienie_strzalu = 160
asteroidy = []
wrogowie = []
trafiony_czas = 0
CZAS_TRAFIENIA = 500
gwiazdki = []
for _ in range(80):
gwiazdki.append([random.randint(0, SZEROKOSC),
random.randint(0, WYSOKOSC),
random.randint(1, 3)])
font_maly = pygame.font.SysFont("Arial", 20)
font_sredni= pygame.font.SysFont("Arial", 28)
font_duzy = pygame.font.SysFont("Arial", 52)
font_wielki= pygame.font.SysFont("Arial", 72)
def generuj_fale(numer):
nowi = []
liczba = 3 + numer
for i in range(liczba):
odst = SZEROKOSC // (liczba + 1)
x = odst * (i + 1) - wrog_szerokosc // 2
y = 40 + (i % 2) * 38
nowi.append([x, y, 1])
return nowi
def nowa_gra():
global zycia, punkty, numer_fali, wrog_predkosc, poziom
global lasery, asteroidy, wrogowie, trafiony_czas, statek_x, statek_y
zycia = 3; punkty = 0; numer_fali = 1; poziom = 1; wrog_predkosc = 2
lasery = []; trafiony_czas = 0
statek_x = SZEROKOSC // 2 - statek_szerokosc // 2
statek_y = WYSOKOSC - 90
asteroidy.clear()
dodaj_asteroidy(3)
wrogowie.clear()
wrogowie.extend(generuj_fale(numer_fali))
def dodaj_asteroidy(ile):
for _ in range(ile):
rozmiar = random.randint(28, 58)
asteroidy.append([random.randint(0, SZEROKOSC - rozmiar),
random.randint(-350, -rozmiar),
rozmiar,
random.uniform(2.0, 3.5 + poziom * 0.4)])
def ruch_statku(klawisze):
global statek_x, statek_y
if klawisze[pygame.K_LEFT] or klawisze[pygame.K_a]: statek_x -= predkosc_statku
if klawisze[pygame.K_RIGHT] or klawisze[pygame.K_d]: statek_x += predkosc_statku
if klawisze[pygame.K_UP] or klawisze[pygame.K_w]: statek_y -= predkosc_statku
if klawisze[pygame.K_DOWN] or klawisze[pygame.K_s]: statek_y += predkosc_statku
if statek_x < 0: statek_x = 0
if statek_x > SZEROKOSC - statek_szerokosc: statek_x = SZEROKOSC - statek_szerokosc
if statek_y < 0: statek_y = 0
if statek_y > WYSOKOSC - statek_wysokosc: statek_y = WYSOKOSC - statek_wysokosc
def strzal(teraz):
global czas_ostatniego_strzalu
if teraz - czas_ostatniego_strzalu > opoznienie_strzalu:
lasery.append([statek_x + statek_szerokosc // 2 - 3, statek_y])
czas_ostatniego_strzalu = teraz
def aktualizuj_lasery():
for laser in lasery:
laser[1] -= laser_predkosc
lasery[:] = [l for l in lasery if l[1] > -30]
def aktualizuj_asteroidy():
for ast in asteroidy:
ast[1] += ast[3]
if ast[1] > WYSOKOSC:
ast[1] = random.randint(-300, -ast[2])
ast[0] = random.randint(0, SZEROKOSC - ast[2])
ast[2] = random.randint(28, 58)
ast[3] = random.uniform(2.0, 3.5 + poziom * 0.4)
def aktualizuj_wrogow():
for wrog in wrogowie:
wrog[0] += wrog_predkosc * wrog[2]
if wrog[0] > SZEROKOSC - wrog_szerokosc: wrog[2] = -1
if wrog[0] < 0: wrog[2] = 1
def sprawdz_kolizje():
global zycia, punkty, trafiony_czas, numer_fali, wrog_predkosc
teraz = pygame.time.get_ticks()
sr = pygame.Rect(statek_x, statek_y, statek_szerokosc, statek_wysokosc)
if teraz - trafiony_czas > CZAS_TRAFIENIA:
for ast in asteroidy:
if sr.colliderect(pygame.Rect(ast[0], ast[1], ast[2], ast[2])):
zycia -= 1; trafiony_czas = teraz
ast[1] = random.randint(-300, -ast[2])
ast[0] = random.randint(0, SZEROKOSC - ast[2])
pozostale = []; trafieni = []
for laser in lasery:
lr = pygame.Rect(laser[0], laser[1], 6, 22)
trafil = False
for j in range(len(wrogowie)):
if j not in trafieni:
if lr.colliderect(pygame.Rect(wrogowie[j][0], wrogowie[j][1],
wrog_szerokosc, wrog_wysokosc)):
trafieni.append(j); punkty += 20; trafil = True; break
if not trafil:
for ast in asteroidy:
if lr.colliderect(pygame.Rect(ast[0], ast[1], ast[2], ast[2])):
punkty += 10
ast[1] = random.randint(-300, -ast[2])
ast[0] = random.randint(0, SZEROKOSC - ast[2])
trafil = True; break
if not trafil:
pozostale.append(laser)
lasery[:] = pozostale
for j in sorted(trafieni, reverse=True):
wrogowie.pop(j)
if len(wrogowie) == 0:
numer_fali += 1; punkty += 50
wrog_predkosc = min(2 + numer_fali, 8)
wrogowie.extend(generuj_fale(numer_fali))
def rysuj_gwiazdki():
for gw in gwiazdki:
pygame.draw.circle(ekran, (180, 180, 180), (gw[0], gw[1]), 1)
def rysuj_statek(trafiony):
kolor = (255, 80, 80) if trafiony else KOLOR_STATEK
pygame.draw.rect(ekran, kolor, (statek_x + 12, statek_y + 16, 18, 30))
pygame.draw.polygon(ekran, kolor, [
(statek_x + 21, statek_y),
(statek_x, statek_y + 22),
(statek_x + 42, statek_y + 22)
])
pygame.draw.polygon(ekran, (0, 140, 200), [
(statek_x, statek_y + 22),
(statek_x - 8, statek_y + 52),
(statek_x + 16, statek_y + 40)
])
pygame.draw.polygon(ekran, (0, 140, 200), [
(statek_x + 42, statek_y + 22),
(statek_x + 50, statek_y + 52),
(statek_x + 26, statek_y + 40)
])
def rysuj_asteroide(x, y, rozmiar):
pts = [
(x + rozmiar * 0.5, y),
(x + rozmiar, y + rozmiar * 0.3),
(x + rozmiar * 0.9, y + rozmiar),
(x + rozmiar * 0.3, y + rozmiar * 0.95),
(x, y + rozmiar * 0.6),
(x + rozmiar * 0.1, y + rozmiar * 0.2),
]
pygame.draw.polygon(ekran, (155, 155, 155), pts)
pygame.draw.polygon(ekran, (120, 120, 120), pts, 2)
def rysuj_wroga(x, y):
pygame.draw.rect(ekran, KOLOR_WROG, (x + 8, y, wrog_szerokosc - 16, wrog_wysokosc))
pygame.draw.polygon(ekran, (220, 80, 0), [
(x + wrog_szerokosc // 2, y + wrog_wysokosc),
(x, y + 8),
(x + wrog_szerokosc, y + 8)
])
pygame.draw.circle(ekran, (255, 200, 50), (x + wrog_szerokosc // 2, y + 10), 5)
def wyswietl_hud():
pygame.draw.rect(ekran, (0, 0, 60), (0, 0, SZEROKOSC, 36))
ekran.blit(font_maly.render("ZYCIA: " + ("* " * max(zycia, 0)), True, KOLOR_CZERWONY), (10, 9))
ekran.blit(font_maly.render("PUNKTY: {}".format(punkty), True, KOLOR_ZOLTY), (220, 9))
ekran.blit(font_maly.render("FALA: {}".format(numer_fali), True, KOLOR_ZIELONY), (420, 9))
ekran.blit(font_maly.render("WROGOW: {}".format(len(wrogowie)), True, KOLOR_BIALY), (580, 9))
def ekran_startowy():
ekran.fill(KOLOR_TLO)
rysuj_gwiazdki()
tytul = font_wielki.render("ASTEROIDY", True, KOLOR_ZOLTY)
ekran.blit(tytul, (SZEROKOSC // 2 - tytul.get_width() // 2, 130))
pod = font_sredni.render("Uratuj galaktyke przed inwazja!", True, KOLOR_BIALY)
ekran.blit(pod, (SZEROKOSC // 2 - pod.get_width() // 2, 220))
linie = [
"Strzalki / WSAD — ruch statku",
"SPACJA — strzal laserem",
"Wrog = 20 pkt | Skala = 10 pkt | Fala = +50 pkt",
]
for i, l in enumerate(linie):
n = font_maly.render(l, True, KOLOR_BIALY)
ekran.blit(n, (SZEROKOSC // 2 - n.get_width() // 2, 310 + i * 32))
start = font_duzy.render("Nacisnij ENTER aby zaczac!", True, KOLOR_ZIELONY)
ekran.blit(start, (SZEROKOSC // 2 - start.get_width() // 2, 480))
def ekran_game_over():
ekran.fill((0, 0, 0))
rysuj_gwiazdki()
koniec = font_wielki.render("KONIEC GRY", True, KOLOR_CZERWONY)
ekran.blit(koniec, (SZEROKOSC // 2 - koniec.get_width() // 2, 150))
wynik = font_duzy.render("Twoj wynik: {}".format(punkty), True, KOLOR_ZOLTY)
ekran.blit(wynik, (SZEROKOSC // 2 - wynik.get_width() // 2, 250))
rekord = font_sredni.render("Rekord: {}".format(najlepszy_wynik), True, KOLOR_BIALY)
ekran.blit(rekord, (SZEROKOSC // 2 - rekord.get_width() // 2, 320))
if punkty >= najlepszy_wynik and punkty > 0:
nr = font_sredni.render("NOWY REKORD!", True, KOLOR_ZIELONY)
ekran.blit(nr, (SZEROKOSC // 2 - nr.get_width() // 2, 360))
fala_t = font_maly.render("Dotarles do fali: {}".format(numer_fali), True, KOLOR_BIALY)
ekran.blit(fala_t, (SZEROKOSC // 2 - fala_t.get_width() // 2, 410))
pn = font_duzy.render("ENTER = zagraj ponownie", True, KOLOR_ZIELONY)
ekran.blit(pn, (SZEROKOSC // 2 - pn.get_width() // 2, 480))
while True:
teraz = pygame.time.get_ticks()
for zdarzenie in pygame.event.get():
if zdarzenie.type == pygame.QUIT:
pygame.quit()
exit()
if zdarzenie.type == pygame.KEYDOWN:
if zdarzenie.key == pygame.K_RETURN:
if stan_gry in ("start", "game_over"):
nowa_gra()
stan_gry = "gra"
if stan_gry == "start":
ekran_startowy()
pygame.display.flip()
zegar.tick(60)
continue
if stan_gry == "game_over":
ekran_game_over()
pygame.display.flip()
zegar.tick(60)
continue
klawisze = pygame.key.get_pressed()
ruch_statku(klawisze)
if klawisze[pygame.K_SPACE]:
strzal(teraz)
aktualizuj_lasery()
aktualizuj_asteroidy()
aktualizuj_wrogow()
sprawdz_kolizje()
if zycia <= 0:
najlepszy_wynik = max(najlepszy_wynik, punkty)
stan_gry = "game_over"
trafiony = teraz - trafiony_czas < CZAS_TRAFIENIA
ekran.fill(KOLOR_TLO)
rysuj_gwiazdki()
for ast in asteroidy:
rysuj_asteroide(ast[0], ast[1], ast[2])
for wrog in wrogowie:
rysuj_wroga(wrog[0], wrog[1])
for laser in lasery:
pygame.draw.rect(ekran, KOLOR_LASER, (laser[0], laser[1], 6, 22))
rysuj_statek(trafiony)
wyswietl_hud()
pygame.display.flip()
zegar.tick(60)
najlepszy_wynik)gra_18.py z gra_asteroidy.py — co jeszcze jest inne?open("rekord.txt", "w").write(str(najlepszy_wynik))open("rekord.txt").read()gra_18.py z gra_asteroidy.py i przepisz brakujące różnicenowa_gra() — resetuje stan gryruch_statku(klawisze) — logika ruchusprawdz_kolizje() — wszystkie kolizjerysuj_statek(trafiony) — rysuje wielokątem (nie prostokątem!)wyswietl_hud() — pasek z życiami i punktamiekran_startowy() i ekran_game_over()stan_gry = "start" / "gra" / "game_over"najlepszy_wynik — zapamiętuje najlepszy wynik sesji
import pygame
import random
pygame.init()
SZEROKOSC = 800
WYSOKOSC = 600
ekran = pygame.display.set_mode((SZEROKOSC, WYSOKOSC))
pygame.display.set_caption("ASTEROIDY — Pelna Gra!")
zegar = pygame.time.Clock()
font_maly = pygame.font.SysFont("Arial", 20)
font_sredni = pygame.font.SysFont("Arial", 28)
font_duzy = pygame.font.SysFont("Arial", 52)
font_wielki = pygame.font.SysFont("Arial", 72)
KOLOR_TLO = (0, 0, 25)
KOLOR_STATEK = (0, 200, 255)
KOLOR_LASER = (255, 60, 60)
KOLOR_WROG = (255, 100, 0)
KOLOR_ASTEROIDA = (155, 155, 155)
KOLOR_BIALY = (255, 255, 255)
KOLOR_ZOLTY = (255, 220, 50)
KOLOR_CZERWONY = (255, 60, 60)
KOLOR_ZIELONY = (50, 220, 50)
# ---- Stan gry ----
stan_gry = "start"
statek_szerokosc = 42
statek_wysokosc = 52
statek_x = SZEROKOSC // 2 - statek_szerokosc // 2
statek_y = WYSOKOSC - 90
predkosc_statku = 5
zycia = 3
punkty = 0
najlepszy_wynik = 0
poziom = 1
wrog_predkosc = 2
lasery = []
laser_predkosc = 10
czas_ostatniego_strzalu = 0
opoznienie_strzalu = 160
asteroidy = []
wrogowie = []
wrog_szerokosc = 44
wrog_wysokosc = 32
numer_fali = 1
trafiony_czas = 0
CZAS_TRAFIENIA = 500
gwiazdki = []
for _ in range(80):
gwiazdki.append([random.randint(0, SZEROKOSC),
random.randint(0, WYSOKOSC),
random.randint(1, 3)])
def resetuj_statek():
global statek_x, statek_y
statek_x = SZEROKOSC // 2 - statek_szerokosc // 2
statek_y = WYSOKOSC - 90
def nowa_gra():
global zycia, punkty, poziom, numer_fali, wrog_predkosc
global lasery, asteroidy, wrogowie, trafiony_czas
zycia = 3
punkty = 0
poziom = 1
numer_fali = 1
wrog_predkosc = 2
lasery = []
trafiony_czas = 0
resetuj_statek()
asteroidy.clear()
dodaj_asteroidy(3)
wrogowie.clear()
wrogowie.extend(generuj_fale(numer_fali))
def dodaj_asteroidy(ile):
for _ in range(ile):
rozmiar = random.randint(28, 58)
x = random.randint(0, SZEROKOSC - rozmiar)
y = random.randint(-350, -rozmiar)
pred = random.uniform(2.0, 3.5 + poziom * 0.4)
asteroidy.append([x, y, rozmiar, pred])
def generuj_fale(numer):
nowi = []
liczba = 3 + numer
for i in range(liczba):
odst = SZEROKOSC // (liczba + 1)
x = odst * (i + 1) - wrog_szerokosc // 2
y = 40 + (i % 2) * 38
nowi.append([x, y, 1])
return nowi
def ruch_statku(klawisze):
global statek_x, statek_y
if klawisze[pygame.K_LEFT] or klawisze[pygame.K_a]: statek_x -= predkosc_statku
if klawisze[pygame.K_RIGHT] or klawisze[pygame.K_d]: statek_x += predkosc_statku
if klawisze[pygame.K_UP] or klawisze[pygame.K_w]: statek_y -= predkosc_statku
if klawisze[pygame.K_DOWN] or klawisze[pygame.K_s]: statek_y += predkosc_statku
if statek_x < 0: statek_x = 0
if statek_x > SZEROKOSC - statek_szerokosc: statek_x = SZEROKOSC - statek_szerokosc
if statek_y < 0: statek_y = 0
if statek_y > WYSOKOSC - statek_wysokosc: statek_y = WYSOKOSC - statek_wysokosc
def strzal(teraz):
global czas_ostatniego_strzalu
if teraz - czas_ostatniego_strzalu > opoznienie_strzalu:
lasery.append([statek_x + statek_szerokosc // 2 - 3, statek_y])
czas_ostatniego_strzalu = teraz
def aktualizuj_lasery():
for laser in lasery:
laser[1] -= laser_predkosc
lasery[:] = [l for l in lasery if l[1] > -30]
def aktualizuj_asteroidy():
for ast in asteroidy:
ast[1] += ast[3]
if ast[1] > WYSOKOSC:
ast[1] = random.randint(-300, -ast[2])
ast[0] = random.randint(0, SZEROKOSC - ast[2])
ast[2] = random.randint(28, 58)
ast[3] = random.uniform(2.0, 3.5 + poziom * 0.4)
def aktualizuj_wrogow():
for wrog in wrogowie:
wrog[0] += wrog_predkosc * wrog[2]
if wrog[0] > SZEROKOSC - wrog_szerokosc: wrog[2] = -1
if wrog[0] < 0: wrog[2] = 1
def sprawdz_kolizje():
global zycia, punkty, trafiony_czas, numer_fali, wrog_predkosc
teraz = pygame.time.get_ticks()
statek_rect = pygame.Rect(statek_x, statek_y, statek_szerokosc, statek_wysokosc)
if teraz - trafiony_czas > CZAS_TRAFIENIA:
for ast in asteroidy:
ast_rect = pygame.Rect(ast[0], ast[1], ast[2], ast[2])
if statek_rect.colliderect(ast_rect):
zycia -= 1
trafiony_czas = teraz
ast[1] = random.randint(-300, -ast[2])
ast[0] = random.randint(0, SZEROKOSC - ast[2])
pozostale_lasery = []
trafieni_wrogowie = []
for laser in lasery:
laser_rect = pygame.Rect(laser[0], laser[1], 6, 22)
trafil = False
for j in range(len(wrogowie)):
if j not in trafieni_wrogowie:
wrog_rect = pygame.Rect(wrogowie[j][0], wrogowie[j][1],
wrog_szerokosc, wrog_wysokosc)
if laser_rect.colliderect(wrog_rect):
trafieni_wrogowie.append(j)
punkty += 20
trafil = True
break
if not trafil:
for ast in asteroidy:
ast_rect = pygame.Rect(ast[0], ast[1], ast[2], ast[2])
if laser_rect.colliderect(ast_rect):
punkty += 10
ast[1] = random.randint(-300, -ast[2])
ast[0] = random.randint(0, SZEROKOSC - ast[2])
trafil = True
break
if not trafil:
pozostale_lasery.append(laser)
lasery[:] = pozostale_lasery
for j in sorted(trafieni_wrogowie, reverse=True):
wrogowie.pop(j)
if len(wrogowie) == 0:
numer_fali += 1
punkty += 50
wrog_predkosc = min(2 + numer_fali, 8)
wrogowie.extend(generuj_fale(numer_fali))
def rysuj_gwiazdki():
for gw in gwiazdki:
pygame.draw.circle(ekran, (180, 180, 180), (gw[0], gw[1]), 1)
def rysuj_statek(trafiony):
kolor = (255, 80, 80) if trafiony else KOLOR_STATEK
pygame.draw.polygon(ekran, kolor, [
(statek_x + 21, statek_y),
(statek_x, statek_y + 22),
(statek_x + 42, statek_y + 22)
])
pygame.draw.rect(ekran, kolor, (statek_x + 12, statek_y + 16, 18, 30))
pygame.draw.polygon(ekran, (0, 140, 200), [
(statek_x, statek_y + 22),
(statek_x - 8, statek_y + 52),
(statek_x + 16, statek_y + 40)
])
pygame.draw.polygon(ekran, (0, 140, 200), [
(statek_x + 42, statek_y + 22),
(statek_x + 50, statek_y + 52),
(statek_x + 26, statek_y + 40)
])
def rysuj_asteroide(x, y, rozmiar):
pts = [
(x + rozmiar * 0.5, y),
(x + rozmiar, y + rozmiar * 0.3),
(x + rozmiar * 0.9, y + rozmiar),
(x + rozmiar * 0.3, y + rozmiar * 0.95),
(x, y + rozmiar * 0.6),
(x + rozmiar * 0.1, y + rozmiar * 0.2),
]
pygame.draw.polygon(ekran, KOLOR_ASTEROIDA, pts)
pygame.draw.polygon(ekran, (120, 120, 120), pts, 2)
def rysuj_wroga(x, y):
pygame.draw.rect(ekran, KOLOR_WROG, (x + 8, y, wrog_szerokosc - 16, wrog_wysokosc))
pygame.draw.polygon(ekran, (220, 80, 0), [
(x + wrog_szerokosc // 2, y + wrog_wysokosc),
(x, y + 8),
(x + wrog_szerokosc, y + 8)
])
pygame.draw.circle(ekran, (255, 200, 50), (x + wrog_szerokosc // 2, y + 10), 5)
def wyswietl_hud():
pygame.draw.rect(ekran, (0, 0, 60), (0, 0, SZEROKOSC, 36))
ekran.blit(font_maly.render("ZYCIA: " + ("♥ " * max(zycia, 0)),
True, KOLOR_CZERWONY), (10, 9))
ekran.blit(font_maly.render("PUNKTY: {}".format(punkty),
True, KOLOR_ZOLTY), (220, 9))
ekran.blit(font_maly.render("FALA: {}".format(numer_fali),
True, KOLOR_ZIELONY), (420, 9))
ekran.blit(font_maly.render("WROGOW: {}".format(len(wrogowie)),
True, KOLOR_BIALY), (580, 9))
def ekran_startowy():
ekran.fill(KOLOR_TLO)
rysuj_gwiazdki()
tytul = font_wielki.render("ASTEROIDY", True, KOLOR_ZOLTY)
ekran.blit(tytul, (SZEROKOSC // 2 - tytul.get_width() // 2, 130))
pod = font_sredni.render("Uratuj galaktyke przed inwazja!", True, KOLOR_BIALY)
ekran.blit(pod, (SZEROKOSC // 2 - pod.get_width() // 2, 220))
linie = [
"Strzalki / WSAD — ruch statku",
"SPACJA — strzal laserem",
"Wrog = 20 pkt | Skala = 10 pkt | Fala = +50 pkt",
]
for i, l in enumerate(linie):
n = font_maly.render(l, True, KOLOR_BIALY)
ekran.blit(n, (SZEROKOSC // 2 - n.get_width() // 2, 310 + i * 32))
start = font_duzy.render("Nacisnij ENTER aby zaczac!", True, KOLOR_ZIELONY)
ekran.blit(start, (SZEROKOSC // 2 - start.get_width() // 2, 510))
def ekran_game_over():
ekran.fill((0, 0, 0))
rysuj_gwiazdki()
koniec = font_wielki.render("KONIEC GRY", True, KOLOR_CZERWONY)
ekran.blit(koniec, (SZEROKOSC // 2 - koniec.get_width() // 2, 150))
wynik = font_duzy.render("Twoj wynik: {}".format(punkty), True, KOLOR_ZOLTY)
ekran.blit(wynik, (SZEROKOSC // 2 - wynik.get_width() // 2, 250))
rekord = font_sredni.render("Rekord: {}".format(najlepszy_wynik), True, KOLOR_BIALY)
ekran.blit(rekord, (SZEROKOSC // 2 - rekord.get_width() // 2, 320))
if punkty >= najlepszy_wynik and punkty > 0:
nr = font_sredni.render("NOWY REKORD!", True, KOLOR_ZIELONY)
ekran.blit(nr, (SZEROKOSC // 2 - nr.get_width() // 2, 360))
fala_t = font_maly.render("Dotarles do fali: {}".format(numer_fali), True, KOLOR_BIALY)
ekran.blit(fala_t, (SZEROKOSC // 2 - fala_t.get_width() // 2, 410))
pn = font_duzy.render("ENTER = zagraj ponownie", True, KOLOR_ZIELONY)
ekran.blit(pn, (SZEROKOSC // 2 - pn.get_width() // 2, 480))
# ---- Główna pętla ----
while True:
teraz = pygame.time.get_ticks()
for zdarzenie in pygame.event.get():
if zdarzenie.type == pygame.QUIT:
pygame.quit()
exit()
if zdarzenie.type == pygame.KEYDOWN:
if zdarzenie.key == pygame.K_RETURN:
if stan_gry in ("start", "game_over"):
nowa_gra()
stan_gry = "gra"
if stan_gry == "start":
ekran_startowy()
pygame.display.flip()
zegar.tick(60)
continue
if stan_gry == "game_over":
ekran_game_over()
pygame.display.flip()
zegar.tick(60)
continue
# ---- Logika gry ----
klawisze = pygame.key.get_pressed()
ruch_statku(klawisze)
if klawisze[pygame.K_SPACE]:
strzal(teraz)
aktualizuj_lasery()
aktualizuj_asteroidy()
aktualizuj_wrogow()
sprawdz_kolizje()
if zycia <= 0:
najlepszy_wynik = max(najlepszy_wynik, punkty)
stan_gry = "game_over"
# ---- Rysowanie ----
ekran.fill(KOLOR_TLO)
rysuj_gwiazdki()
for ast in asteroidy:
rysuj_asteroide(ast[0], ast[1], ast[2])
for wrog in wrogowie:
rysuj_wroga(wrog[0], wrog[1])
for laser in lasery:
pygame.draw.rect(ekran, KOLOR_LASER, (laser[0], laser[1], 6, 22))
trafiony = teraz - trafiony_czas < CZAS_TRAFIENIA
rysuj_statek(trafiony)
wyswietl_hud()
pygame.display.flip()
zegar.tick(60)
pygame.mixer.Sound("strzal.wav").play()open("rekord.txt", "w").write(str(punkty))def nazwa_funkcji(): — definicja. nazwa_funkcji() — wywołanie.
Funkcje pomagają podzielić długi kod na czytelne, małe kawałki.
global pozwala funkcji zmieniać zmienne spoza niej — używamy gdy musimy, ale ostrożnie!
aktualizuj_asteroidy() zmień 3.5 + poziom * 0.4 na 3.5 + poziom * 0.8. Poczuj różnicę na fali 5.range(2) użyj range(2 + numer_fali // 2). Każde dwie fale = jedna nowa asteroida.CZAS_TRAFIENIA z 1500ms na 800ms. Gracz dostaje mniej czasu na "schowanie się" po trafieniu.min(2 + numer_fali, 8) na min(2 + numer_fali * 1.5, 12). Od fali 4 wrogowie są dwa razy szybsi.lasery_wrogow = []. Co N sekund losowy wróg strzela w kierunku aktualnej pozycji gracza. Jeśli laser wroga trafi statek → zycia -= 1.strzal(teraz) już masz dla gracza — napisz strzal_wroga(teraz) który losuje wroga i dodaje laser do lasery_wrogow.
rozmiar // 2) lecącymi w różnych kierunkach. Małe asteroidy poruszają się szybciej.dx = gracz_x - wrog_x, dy = gracz_y - wrog_y). Potem wraca do poziomego ruchu.x = 0 lub x = SZEROKOSC i leci po przekątnej (dodaj ast[4] = predkosc_x dla ruchu poziomego). Środek ekranu przestaje być bezpieczną kryjówką.