pygame moveimg objects

This commit is contained in:
Dmitry Belyaev 2024-03-29 22:29:54 +03:00
parent 0f7fbc2fca
commit efa19e3398

View File

@ -8,16 +8,17 @@
Зависимости: pygame pillow Зависимости: pygame pillow
""" """
import pygame
import os import os
import shutil import shutil
import tempfile import tempfile
import urllib.request import urllib.request
from abc import ABC, abstractmethod
from contextlib import contextmanager from contextlib import contextmanager
from typing import NamedTuple from typing import NamedTuple, Optional
import PIL import PIL
from PIL import Image, ImageDraw import pygame
from PIL import ImageDraw
def download_asset(asset, path): def download_asset(asset, path):
@ -117,6 +118,10 @@ class Coords(NamedTuple):
def transform(self, ref: "Coords"): def transform(self, ref: "Coords"):
return self * ref return self * ref
@classmethod
def zero(cls):
return cls(0, 0)
def resize_img(assets: dict, name: str, sz: Coords): def resize_img(assets: dict, name: str, sz: Coords):
""" """
@ -143,41 +148,138 @@ def choose_plural(amount, declensions):
return f"{amount} {declensions[i]}" return f"{amount} {declensions[i]}"
def draw_background_image(screen, filename): class GameObject(ABC):
background = pygame.image.load(filename) """обобщение игрового элемента"""
screen.blit(background, (0, 0))
coords = property(
lambda self: self.get_coords(), lambda self, c: self.set_coords(c)
)
def __init__(
self,
coords: Coords,
parent: Optional["GameObject"] = None,
assets: dict | None = None,
):
self.parent = parent
self._coords = coords
self.assets = assets or (parent.assets if parent else None)
self._surface = None
@property
def surface(self) -> pygame.Surface | None:
return self._surface or (self.parent.surface if self.parent else None)
def get_coords(self) -> Coords:
return self._coords
def set_coords(self, coords: Coords):
if self.parent:
if self.parent.surface:
if not (
coords.x >= 0
and coords.x < self.parent.surface.get_width()
and coords.y >= 0
and coords.y < self.parent.surface.get_height()
):
return
self._coords = coords
@abstractmethod
def draw(self):
pass
@abstractmethod
def handle_event(self, event: pygame.event.Event):
pass
class Hero(GameObject):
"""объект главного героя"""
def __init__(
self,
coords: Coords,
parent: GameObject,
assets: dict | None = None,
):
super().__init__(coords, parent, assets)
screen_sz = Coords(*parent.surface.get_size())
ghost_sz = screen_sz // 10
resize_img(self.assets, "ghost.png", ghost_sz)
self._surface = pygame.image.load(self.assets["ghost.png"])
self.rect = self.surface.get_rect()
self.coords = coords
def set_coords(self, coords: Coords):
super().set_coords(coords)
self.rect.topleft = self.coords
def draw(self):
self.parent.surface.blit(self.surface, self.rect)
def handle_event(self, event: pygame.event.Event):
delta = 10
if event.type == pygame.KEYDOWN:
match event.key:
case pygame.K_UP | pygame.K_w:
self.coords += Coords(0, -1) * delta
case pygame.K_DOWN | pygame.K_s:
self.coords += Coords(0, 1) * delta
case pygame.K_LEFT | pygame.K_a:
self.coords += Coords(-1, 0) * delta
case pygame.K_RIGHT | pygame.K_d:
self.coords += Coords(1, 0) * delta
class Scene(GameObject):
"""основной игровой объект"""
# кнопки для выхода из игры
exit_keys = (pygame.K_ESCAPE, pygame.K_q)
def __init__(self, assets: dict, sz: Coords):
super().__init__(Coords.zero(), None, assets)
self._surface = pygame.display.set_mode(sz)
self.hero = Hero(Coords(100, 100), self)
resize_img(assets, "bg1k.png", sz)
self.background = pygame.image.load(self.assets["bg1k.png"])
self.done = False
def draw(self):
if self.done:
return
self.surface.blit(self.background, self.coords)
self.hero.draw()
def handle_event(self, event: pygame.event.Event):
if self.done:
return
if (
event.type == pygame.QUIT
or event.type == pygame.KEYDOWN
and event.key in self.exit_keys
):
self.done = True
if not self.done:
self.hero.handle_event(event)
def event_loop(self):
while not self.done:
event = pygame.event.wait()
self.handle_event(event)
self.draw()
pygame.display.flip()
def game(assets): def game(assets):
pygame.init() pygame.init()
width, height = screen_sz = Coords(1000, 1000) screen_sz = Coords(1000, 1000)
screen = pygame.display.set_mode(screen_sz)
pygame.display.set_caption("Движение рисунка на Pygame") pygame.display.set_caption("Движение рисунка на Pygame")
ghost_sz = screen_sz // 10 scene = Scene(assets, screen_sz)
scene.event_loop()
resize_img(assets, "bg1k.png", screen_sz)
speed = [2, 2]
resize_img(assets, "ghost.png", ghost_sz)
ghost = pygame.image.load(assets["ghost.png"])
ghostrect = ghost.get_rect()
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
ghostrect = ghostrect.move(speed)
if ghostrect.left < 0 or ghostrect.right > width:
speed[0] = -speed[0]
if ghostrect.top < 0 or ghostrect.bottom > height:
speed[1] = -speed[1]
draw_background_image(screen, assets["bg1k.png"])
screen.blit(ghost, ghostrect)
pygame.display.flip()
pygame.quit() pygame.quit()
@ -190,4 +292,5 @@ def main():
with get_assets(assets) as assets: with get_assets(assets) as assets:
game(assets) game(assets)
main()
main()