168 lines
5.7 KiB
Python
168 lines
5.7 KiB
Python
"""
|
|
Dni 3-4 — platformówka. Szkielet do rozbudowy.
|
|
|
|
To jest CELOWO prawie pusty plik: przez dwa dni wypełniasz go krok po kroku
|
|
według oficjalnego tutoriala (lista kroków w README.md obok).
|
|
|
|
Uruchom teraz — otworzy się puste okno z podpowiedzią. To znaczy, że
|
|
środowisko działa i można zaczynać.
|
|
|
|
python dzien3_4_platformowka/gra.py
|
|
"""
|
|
|
|
import arcade
|
|
|
|
SZEROKOSC = 1280
|
|
WYSOKOSC = 720
|
|
TYTUL = "Platformówka"
|
|
|
|
# Skala i stałe fizyki — przydadzą się od kroku 4 tutoriala.
|
|
SKALA_KAFELKA = 0.5
|
|
SKALA_GRACZA = 1.0
|
|
PREDKOSC_GRACZA = 5
|
|
GRAWITACJA = 1
|
|
SILA_SKOKU = 20
|
|
|
|
|
|
class GameView(arcade.View):
|
|
"""
|
|
Widok rozgrywki.
|
|
|
|
Dziedziczymy po arcade.View, a nie po arcade.Window, bo w dniu 4 dojdzie
|
|
drugi widok (ekran końca gry) i będziemy się między nimi przełączać przez
|
|
self.window.show_view(...). Jedno okno, wiele widoków.
|
|
|
|
arcade.View ma te same metody-haki co Window: on_draw, on_update,
|
|
on_key_press, on_key_release — plus on_show_view (wołane, gdy widok
|
|
staje się aktywny).
|
|
"""
|
|
|
|
def __init__(self):
|
|
super().__init__()
|
|
self.background_color = arcade.color.DARK_BLUE
|
|
|
|
# --- Miejsce na atrybuty gry ---------------------------------------
|
|
# Deklarujemy je (na razie jako None / puste listy) już teraz, żeby
|
|
# z jednego miejsca było widać, z czego składa się gra.
|
|
|
|
# Krok 3: listy sprite'ów (albo od kroku 11: self.scene = None)
|
|
self.player_list = None
|
|
self.wall_list = None
|
|
|
|
# Krok 2-3: gracz
|
|
self.player_sprite = None
|
|
|
|
# Krok 5: silnik fizyki — KOMPOZYCJA: widok MA silnik, nie JEST silnikiem
|
|
self.physics_engine = None
|
|
|
|
# Krok 7: kamery — jedna jedzie za graczem, druga stoi (napisy)
|
|
self.camera = None
|
|
self.camera_gui = None
|
|
|
|
# Krok 10: punkty
|
|
self.punkty = 0
|
|
|
|
self.setup()
|
|
|
|
def setup(self):
|
|
"""
|
|
Ustawia grę w stan początkowy — wołane z __init__ oraz przy restarcie
|
|
(krok 6 tutoriala). Cała zawartość poziomu powstaje TUTAJ, nie w __init__.
|
|
"""
|
|
self.punkty = 0
|
|
|
|
# TODO krok 3: self.player_list = arcade.SpriteList()
|
|
# self.wall_list = arcade.SpriteList(use_spatial_hash=True)
|
|
|
|
# TODO krok 2: utwórz gracza, np.
|
|
# self.player_sprite = arcade.Sprite(
|
|
# ":resources:images/animated_characters/female_adventurer/femaleAdventurer_idle.png",
|
|
# scale=SKALA_GRACZA,
|
|
# )
|
|
# self.player_sprite.center_x = 64
|
|
# self.player_sprite.center_y = 128
|
|
# self.player_list.append(self.player_sprite)
|
|
|
|
# TODO krok 3: ułóż podłogę w pętli
|
|
# for x in range(0, 1250, 64):
|
|
# kafelek = arcade.Sprite(":resources:images/tiles/grassMid.png",
|
|
# scale=SKALA_KAFELKA)
|
|
# kafelek.center_x = x
|
|
# kafelek.center_y = 32
|
|
# self.wall_list.append(kafelek)
|
|
|
|
# TODO krok 5: self.physics_engine = arcade.PhysicsEnginePlatformer(
|
|
# self.player_sprite,
|
|
# walls=self.wall_list,
|
|
# gravity_constant=GRAWITACJA,
|
|
# )
|
|
|
|
# TODO krok 7: self.camera = arcade.Camera2D()
|
|
# self.camera_gui = arcade.Camera2D()
|
|
|
|
def on_draw(self):
|
|
"""Rysowanie. Wołane automatycznie ~60 razy na sekundę."""
|
|
self.clear() # arcade 3.x — NIE arcade.start_render()
|
|
|
|
# TODO krok 7: self.camera.use() <- od tego miejsca rysujemy "w świecie"
|
|
# TODO krok 3: self.wall_list.draw()
|
|
# self.player_list.draw()
|
|
|
|
# TODO krok 7: self.camera_gui.use() <- napisy: nie jadą razem z kamerą
|
|
# TODO krok 10: arcade.draw_text(f"Punkty: {self.punkty}", 10, 10,
|
|
# arcade.color.WHITE, 18)
|
|
|
|
arcade.draw_text(
|
|
"Pusty szkielet — otwórz README.md obok i zacznij od kroku 1",
|
|
x=SZEROKOSC / 2,
|
|
y=WYSOKOSC / 2,
|
|
color=arcade.color.WHITE,
|
|
font_size=20,
|
|
anchor_x="center",
|
|
)
|
|
|
|
def on_update(self, delta_time: float):
|
|
"""Logika gry. Tu zmieniamy stan, w on_draw tylko go pokazujemy."""
|
|
# TODO krok 5: self.physics_engine.update()
|
|
# Uwaga: gdy używasz silnika fizyki, NIE wołaj player_list.update() —
|
|
# silnik sam przesuwa gracza. Inaczej ruch policzy się dwa razy.
|
|
|
|
# TODO krok 8: kolizje z monetami (check_for_collision_with_list)
|
|
# TODO krok 7: przesuń kamerę za graczem
|
|
pass
|
|
|
|
def on_key_press(self, symbol: int, modifiers: int):
|
|
# TODO krok 4: strzałki LEFT/RIGHT -> self.player_sprite.change_x
|
|
# TODO krok 5: skok
|
|
# if symbol == arcade.key.UP and self.physics_engine.can_jump():
|
|
# self.player_sprite.change_y = SILA_SKOKU
|
|
if symbol == arcade.key.ESCAPE:
|
|
self.window.close()
|
|
|
|
def on_key_release(self, symbol: int, modifiers: int):
|
|
# TODO krok 4: zeruj change_x po puszczeniu strzałki
|
|
pass
|
|
|
|
|
|
# TODO dzień 4: druga klasa widoku — ekran końca gry.
|
|
#
|
|
# class GameOverView(arcade.View):
|
|
# def on_draw(self):
|
|
# self.clear()
|
|
# arcade.draw_text("KONIEC GRY - ENTER", SZEROKOSC / 2, WYSOKOSC / 2,
|
|
# arcade.color.WHITE, 40, anchor_x="center")
|
|
#
|
|
# def on_key_press(self, symbol, modifiers):
|
|
# if symbol == arcade.key.ENTER:
|
|
# self.window.show_view(GameView()) # nowa gra od zera
|
|
|
|
|
|
def main():
|
|
okno = arcade.Window(SZEROKOSC, WYSOKOSC, TYTUL)
|
|
okno.show_view(GameView())
|
|
arcade.run()
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|