Как заставить игрока / врага менять цвет при попадании? - PullRequest
1 голос
/ 01 ноября 2019

Когда игрок или враг поражен, я хочу, чтобы их спрайт изменился на красный. по сути, я хочу прозрачный красный эффект над спрайтом. Pygame предлагает способ сделать это? (Я использую несколько изображений, так как персонажи анимированы, поэтому создание красного спрайта и просто перетягивание вместо обычного не сработает)

1 Ответ

0 голосов
/ 03 ноября 2019

Pygame - это низкий уровень, поэтому вам нужно написать собственную функцию для этого. Я немного поиграл и нашел хороший способ.
Здесь я предполагаю, что для покрасневших изображений установлена ​​прозрачность с pixel alphas (т.е. каждый пиксель имеет свое собственное альфа-значение). Это позволит мне контролировать, где происходит покраснение, и, например, предотвратить покраснение прозрачного фона.
Чтобы использовать пиксельные альфа-символы при загрузке изображений, используйте .convert_alpha().

Шагиследующие:

  1. Сделайте красный оттенок. Создайте поверхность с альфа-пикселями, залейте ее красным цветом со значением прозрачности, равным для каждого пикселя. Выберите альфа-значение, которое, по вашему мнению, лучше всего подходит для вашего случая (чем прозрачнее, тем светлее будет эффект покраснения).
  2. Объедините альфа-канал красного оттенка с альфа-каналом изображения, которое нужно покраснеть. Держите самое низкое (самое прозрачное) значение для каждого пикселя. Вы можете сделать это довольно эффективно с помощью модуля surfarray и numpy .
  3. Поверхность красного оттенка на поверхности вашего Sprite. Это покраснет его.
  4. Переместите покрасневшую поверхность Sprite на дисплей.

Это код:

import sys
import numpy as np
import pygame

pygame.init()
screen = pygame.display.set_mode((800, 800))
pygame.display.set_caption("Test")

def reddening(surf):
    """surf: pygame.Surface to be reddened. The function returns a new surface."""
    #making a red shade with transparency
    redshade = pygame.Surface(surf.get_rect().size).convert_alpha()
    redshade.fill((255, 0, 0, 100)) #red with alpha

    #merging the alpha chanel of base image on the redshade, keeping minimum values (most transparent) in each pixel
    alpha_basemask = pygame.surfarray.array_alpha(surf)
    alpha_redmask = pygame.surfarray.pixels_alpha(redshade)
    np.minimum(alpha_basemask, alpha_redmask, out=alpha_redmask)

    #deleting the alpha_redmask reference to unlock redshade (or it cannot be blit)
    del alpha_redmask

    #reddening a copy of the original image
    redsurf = surf.copy()
    redsurf.blit(redshade, (0, 0))

    return redsurf

#loading a base image with transparency
surf_base = pygame.image.load('testcolim_walpha.png').convert_alpha()
red_surf = reddening(surf_base)

screen.blit(red_surf, (100, 200))

pygame.display.update()

while True:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            sys.exit()

Чтобы показать эффект, этооригинал 'testimage.png' (прямоугольник с окружающим альфа-каналом для создания эллипса):

original image

И это покрасневшее изображение с кодом выше:

reddened image

Как использовать его в анимации

Здесь нет анимации, она статична. Но идея та же самая. Используйте функцию покраснения, чтобы покрасить каждое изображение Sprite во время каждого кадра анимации.
Чтобы сделать вашу игру быстрее, вы можете покрасить все изображения один раз, сохранить их и переключиться с исходных не покрасневших на покрасневшие в соответствии сваша игровая логика (значение хитпоинта или что-то еще).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...