Код IT
← Каталог

Python — диаблоид — `engine/renderer.py`

Фрагмент из «Python — диаблоид»: `engine/renderer.py`.

python spinoffencyclopedia9-04-razrabotka-igr-praktikum-razrabotki-igr-6 embed URL статья в энциклопедии
Python main.py
import math

import pygame

from core.config import ISO_TILE_H, ISO_TILE_W, SCREEN_HEIGHT, SCREEN_WIDTH


def world_to_screen(wx: float, wy: float, cam_x: float, cam_y: float) -> tuple[float, float]:
    sx = (wx - wy) * (ISO_TILE_W / 2) - cam_x + SCREEN_WIDTH / 2
    sy = (wx + wy) * (ISO_TILE_H / 2) - cam_y + SCREEN_HEIGHT / 2 - 80
    return sx, sy


def screen_to_world(sx: float, sy: float, cam_x: float, cam_y: float) -> tuple[float, float]:
    x = sx - SCREEN_WIDTH / 2 + cam_x
    y = sy - SCREEN_HEIGHT / 2 + 80 + cam_y
    wx = (x / (ISO_TILE_W / 2) + y / (ISO_TILE_H / 2)) / 2
    wy = (y / (ISO_TILE_H / 2) - x / (ISO_TILE_W / 2)) / 2
    return wx, wy


class Renderer:
    def __init__(self, screen: pygame.Surface) -> None:
        self.screen = screen

    def draw_entity_circle(
        self,
        wx: float,
        wy: float,
        cam_x: float,
        cam_y: float,
        radius_px: int,
        color: tuple[int, int, int],
    ) -> None:
        sx, sy = world_to_screen(wx, wy, cam_x, cam_y)
        pygame.draw.circle(self.screen, color, (int(sx), int(sy)), radius_px)

    def draw_slash(self, slash, cam_x: float, cam_y: float) -> None:
        sx, sy = world_to_screen(slash.x, slash.y, cam_x, cam_y)
        r = 48
        start = -slash.angle + math.pi / 2
        end = start + math.pi
        rect = pygame.Rect(sx - r, sy - r, r * 2, r * 2)
        pygame.draw.arc(self.screen, (255, 220, 120), rect, start, end, 3)

    def draw_enemy_hp(self, enemy, cam_x: float, cam_y: float) -> None:
        sx, sy = world_to_screen(enemy.x, enemy.y, cam_x, cam_y)
        w, h = 36, 5
        x = int(sx - w // 2)
        y = int(sy - 28)
        pygame.draw.rect(self.screen, (40, 20, 24), (x, y, w, h))
        if enemy.max_hp > 0:
            fill = int(w * max(0, enemy.hp) / enemy.max_hp)
            pygame.draw.rect(self.screen, (220, 60, 60), (x, y, fill, h))

    def draw_ground_item(self, item, cam_x: float, cam_y: float) -> None:
        sx, sy = world_to_screen(item.x, item.y, cam_x, cam_y)
        pygame.draw.circle(self.screen, item.color, (int(sx), int(sy)), 8)

    def draw_projectile(self, proj, cam_x: float, cam_y: float) -> None:
        sx, sy = world_to_screen(proj.x, proj.y, cam_x, cam_y)
        pygame.draw.circle(self.screen, (255, 120, 40), (int(sx), int(sy)), 10)
import math

import pygame

from core.config import ISO_TILE_H, ISO_TILE_W, SCREEN_HEIGHT, SCREEN_WIDTH


def world_to_screen(wx: float, wy: float, cam_x: float, cam_y: float) -> tuple[float, float]:
    sx = (wx - wy) * (ISO_TILE_W / 2) - cam_x + SCREEN_WIDTH / 2
    sy = (wx + wy) * (ISO_TILE_H / 2) - cam_y + SCREEN_HEIGHT / 2 - 80
    return sx, sy


def screen_to_world(sx: float, sy: float, cam_x: float, cam_y: float) -> tuple[float, float]:
    x = sx - SCREEN_WIDTH / 2 + cam_x
    y = sy - SCREEN_HEIGHT / 2 + 80 + cam_y
    wx = (x / (ISO_TILE_W / 2) + y / (ISO_TILE_H / 2)) / 2
    wy = (y / (ISO_TILE_H / 2) - x / (ISO_TILE_W / 2)) / 2
    return wx, wy


class Renderer:
    def __init__(self, screen: pygame.Surface) -> None:
        self.screen = screen

    def draw_entity_circle(
        self,
        wx: float,
        wy: float,
        cam_x: float,
        cam_y: float,
        radius_px: int,
        color: tuple[int, int, int],
    ) -> None:
        sx, sy = world_to_screen(wx, wy, cam_x, cam_y)
        pygame.draw.circle(self.screen, color, (int(sx), int(sy)), radius_px)

    def draw_slash(self, slash, cam_x: float, cam_y: float) -> None:
        sx, sy = world_to_screen(slash.x, slash.y, cam_x, cam_y)
        r = 48
        start = -slash.angle + math.pi / 2
        end = start + math.pi
        rect = pygame.Rect(sx - r, sy - r, r * 2, r * 2)
        pygame.draw.arc(self.screen, (255, 220, 120), rect, start, end, 3)

    def draw_enemy_hp(self, enemy, cam_x: float, cam_y: float) -> None:
        sx, sy = world_to_screen(enemy.x, enemy.y, cam_x, cam_y)
        w, h = 36, 5
        x = int(sx - w // 2)
        y = int(sy - 28)
        pygame.draw.rect(self.screen, (40, 20, 24), (x, y, w, h))
        if enemy.max_hp > 0:
            fill = int(w * max(0, enemy.hp) / enemy.max_hp)
            pygame.draw.rect(self.screen, (220, 60, 60), (x, y, fill, h))

    def draw_ground_item(self, item, cam_x: float, cam_y: float) -> None:
        sx, sy = world_to_screen(item.x, item.y, cam_x, cam_y)
        pygame.draw.circle(self.screen, item.color, (int(sx), int(sy)), 8)

    def draw_projectile(self, proj, cam_x: float, cam_y: float) -> None:
        sx, sy = world_to_screen(proj.x, proj.y, cam_x, cam_y)
        pygame.draw.circle(self.screen, (255, 120, 40), (int(sx), int(sy)), 10)