pygame moveimg objects
This commit is contained in:
parent
0f7fbc2fca
commit
efa19e3398
@ -8,16 +8,17 @@
|
||||
Зависимости: pygame pillow
|
||||
"""
|
||||
|
||||
import pygame
|
||||
import os
|
||||
import shutil
|
||||
import tempfile
|
||||
import urllib.request
|
||||
from abc import ABC, abstractmethod
|
||||
from contextlib import contextmanager
|
||||
from typing import NamedTuple
|
||||
from typing import NamedTuple, Optional
|
||||
|
||||
import PIL
|
||||
from PIL import Image, ImageDraw
|
||||
import pygame
|
||||
from PIL import ImageDraw
|
||||
|
||||
|
||||
def download_asset(asset, path):
|
||||
@ -117,6 +118,10 @@ class Coords(NamedTuple):
|
||||
def transform(self, ref: "Coords"):
|
||||
return self * ref
|
||||
|
||||
@classmethod
|
||||
def zero(cls):
|
||||
return cls(0, 0)
|
||||
|
||||
|
||||
def resize_img(assets: dict, name: str, sz: Coords):
|
||||
"""
|
||||
@ -143,41 +148,138 @@ def choose_plural(amount, declensions):
|
||||
return f"{amount} {declensions[i]}"
|
||||
|
||||
|
||||
def draw_background_image(screen, filename):
|
||||
background = pygame.image.load(filename)
|
||||
screen.blit(background, (0, 0))
|
||||
class GameObject(ABC):
|
||||
"""обобщение игрового элемента"""
|
||||
|
||||
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):
|
||||
pygame.init()
|
||||
width, height = screen_sz = Coords(1000, 1000)
|
||||
screen = pygame.display.set_mode(screen_sz)
|
||||
screen_sz = Coords(1000, 1000)
|
||||
pygame.display.set_caption("Движение рисунка на Pygame")
|
||||
|
||||
ghost_sz = screen_sz // 10
|
||||
|
||||
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()
|
||||
scene = Scene(assets, screen_sz)
|
||||
scene.event_loop()
|
||||
|
||||
pygame.quit()
|
||||
|
||||
@ -190,4 +292,5 @@ def main():
|
||||
with get_assets(assets) as assets:
|
||||
game(assets)
|
||||
|
||||
|
||||
main()
|
Loading…
Reference in New Issue
Block a user