python-arcade-oo/dzien3_4_platformowka/gra.py

168 lines
5.7 KiB
Python
Raw Normal View History

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