首页 > 解决方案 > How to put a health bar over the sprite in pygame

问题描述

By the title, I'm hoping that my the player would have a health bar attached to their head. If they move, the health bar also moves. Say sprite is my player. Hey sprite! He has a health bar on top of his head and yeah thats it. To be honest, I don't really know where to start, so help would be appreciated. Thanks!

P.S. A big thanks to Rabbid76 for his help! Also to Ann Zen! Code:

import pygame
import os
import random
import math
import winsound
# winsound.PlaySound("explosion.wav", winsound.SND_ALIAS)

os.environ['SDL_VIDEO_WINDOW_POS'] = "%d,%d" % (0, 30)
wn = pygame.display.set_mode((1920, 1020))
clock = pygame.time.Clock()
icon = pygame.image.load('Icon.png')
pygame.image.load('Sprite0.png')
pygame.image.load('Sprite0.png')
pygame.display.set_icon(icon)
pygame.display.set_caption('DeMass.io')
vel = 5

class Player(pygame.sprite.Sprite):
    def __init__(self, x, y):
        pygame.sprite.Sprite.__init__(self)
        z = random.randint(0, 101)
        if z <= 51:
            self.original_image = pygame.image.load('Sprite0.png')
        else:
            self.original_image = pygame.image.load('Sprite3.png')
        if z == 41:
            self.original_image = pygame.image.load('Sprite5.png')
        self.image = self.original_image
        self.rect = self.image.get_rect(center=(x, y))
        self.direction = pygame.math.Vector2((0, -1))
        self.velocity = 5
        self.position = pygame.math.Vector2(x, y)
        self.x = pygame.math.Vector2(x)
        self.y = pygame.math.Vector2(y)
        self.health = 10
        self.visible = True


    def point_at(self, x, y):
        self.direction = pygame.math.Vector2(x, y) - self.rect.center
        if self.direction.length() > 0:
            self.direction = self.direction.normalize()
        angle = self.direction.angle_to((0, -1))
        self.image = pygame.transform.rotate(self.original_image, angle)
        self.rect = self.image.get_rect(center=self.rect.center)

    def move(self, x, y):
        self.position -= self.direction * y * self.velocity
        self.position += pygame.math.Vector2(-self.direction.y, self.direction.x) * x * self.velocity
        self.rect.center = round(self.position.x), round(self.position.y)


    def reflect(self, NV):
        self.direction = self.direction.reflect(pygame.math.Vector2(NV))

    def update(self):
        self.position += self.direction * self.velocity
        self.rect.center = round(self.position.x), round(self.position.y)

    def hit(self, player):
        if self.health > 0:
            self.health -= 1
        else:
            self.visible = False
        distance = math.sqrt(math.pow(player.x - player.x(), 2) + math.pow(player.y - player.y(), 2))
        if distance < 20:
            return True

        else:
            return False



    def move(self, x, y, clamp_rect):
        self.position -= self.direction * y * self.velocity
        self.position += pygame.math.Vector2(-self.direction.y, self.direction.x) * x * self.velocity
        self.rect.center = round(self.position.x), round(self.position.y)

        if self.rect.left < clamp_rect.left:
            self.rect.left = clamp_rect.left
            self.position.x = self.rect.centerx
        if self.rect.right > clamp_rect.right:
            self.rect.right = clamp_rect.right
            self.position.x = self.rect.centerx
        if self.rect.top < clamp_rect.top:
            self.rect.top = clamp_rect.top
            self.position.y = self.rect.centery
        if self.rect.bottom > clamp_rect.bottom:
            self.rect.bottom = clamp_rect.bottom
            self.position.y = self.rect.centery

    class Projectile(object):
        def __init__(self, x, y, radius, color, facing):
            self.x = x
            self.y = y
            self.radius = radius
            self.color = color
            self.facing = facing
            self.vel = 8 * facing

        def draw(self, win):
            pygame.draw.circle(win, self.color, (self.x, self.y), self.radius)






player = Player(200, 200)
all_sprites = pygame.sprite.Group(player)


run = True
while run:
    clock.tick(60)
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            run = False
        elif event.type == pygame.MOUSEMOTION:
            player.point_at(*event.pos)

    pygame.draw.rect(wn, (0, 0, 0), (50, 50, 10000, 100000))



    keys = pygame.key.get_pressed()
    if keys[pygame.K_w] or keys[pygame.K_UP]:
        player.move(0, -1, wn.get_rect())


    wn.fill((255, 255, 255))
    all_sprites.draw(wn)
    pygame.display.update()

标签: pythonpygame

解决方案


请参阅 How to draw a bar in How can I display a smooth loading bar in pygame? . 创建一个绘制健康条的函数:

def draw_health_bar(surf, pos, size, borderC, backC, healthC, progress):
    pygame.draw.rect(surf, backC, (*pos, *size))
    pygame.draw.rect(surf, borderC, (*pos, *size), 1)
    innerPos  = (pos[0]+1, pos[1]+1)
    innerSize = ((size[0]-2) * progress, size[1]-2)
    rect = (round(innerPos[0]), round(innerPos[1]), round(innerSize[0]), round(innerSize[1]))
    pygame.draw.rect(surf, healthC, rect)

draw_health向类添加一个方法Player并使用该函数draw_health_bar

class Player(pygame.sprite.Sprite):
    # [...]

    def draw_health(self, surf):
        health_rect = pygame.Rect(0, 0, self.original_image.get_width(), 7)
        health_rect.midbottom = self.rect.centerx, self.rect.top
        max_health = 10
        draw_health_bar(surf, health_rect.topleft, health_rect.size, 
                (0, 0, 0), (255, 0, 0), (0, 255, 0), self.health/max_health)    

在主应用程序循环中调用该方法:

while run:
    # [...]

    wn.fill((255, 255, 255))
    all_sprites.draw(wn)
    player.draw_health(wn)    # <---
    pygame.display.update()

另请参阅雪碧


最小的例子:

repl.it/@Rabbid76/PyGame-HealthBar

import pygame
import math

def draw_health_bar(surf, pos, size, borderC, backC, healthC, progress):
    pygame.draw.rect(surf, backC, (*pos, *size))
    pygame.draw.rect(surf, borderC, (*pos, *size), 1)
    innerPos  = (pos[0]+1, pos[1]+1)
    innerSize = ((size[0]-2) * progress, size[1]-2)
    rect = (round(innerPos[0]), round(innerPos[1]), round(innerSize[0]), round(innerSize[1]))
    pygame.draw.rect(surf, healthC, rect)
    
class Player(pygame.sprite.Sprite):
    def __init__(self, x, y):
        pygame.sprite.Sprite.__init__(self)
        self.original_image = pygame.image.load('CarBlue64.png')
        self.original_image = pygame.transform.rotate(self.original_image, 90)
        self.image = self.original_image
        self.rect = self.image.get_rect(center=(x, y))
        self.direction = pygame.math.Vector2((0, -1))
        self.velocity = 5
        self.position = pygame.math.Vector2(x, y)
        self.health = 10

    def point_at(self, x, y):
        self.direction = pygame.math.Vector2(x, y) - self.rect.center
        if self.direction.length() > 0:
            self.direction = self.direction.normalize()
        angle = self.direction.angle_to((0, -1))
        self.image = pygame.transform.rotate(self.original_image, angle)
        self.rect = self.image.get_rect(center=self.rect.center)

    def move(self, x, y, clamp_rect):
        self.position -= self.direction * y * self.velocity
        self.position += pygame.math.Vector2(-self.direction.y, self.direction.x) * x * self.velocity
        self.rect.center = round(self.position.x), round(self.position.y)

        test_rect = self.rect.clamp(clamp_rect)
        if test_rect.x != self.rect.x:
            self.rect.x = test_rect.x
            self.position.x = self.rect.centerx
            self.health = max(0, self.health - 1)
        if test_rect.y != self.rect.y:
            self.rect.y = test_rect.y
            self.position.y = self.rect.centery
            self.health = max(0, self.health - 1)

    def draw_health(self, surf):
        health_rect = pygame.Rect(0, 0, self.original_image.get_width(), 7)
        health_rect.midbottom = self.rect.centerx, self.rect.top
        max_health = 10
        draw_health_bar(surf, health_rect.topleft, health_rect.size, 
                (0, 0, 0), (255, 0, 0), (0, 255, 0), self.health/max_health)    

window = pygame.display.set_mode((250, 250))
clock = pygame.time.Clock()

player = Player(200, 200)
all_sprites = pygame.sprite.Group(player)

run = True
while run:
    clock.tick(60)
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            run = False
        elif event.type == pygame.MOUSEMOTION:
            player.point_at(*event.pos)

    keys = pygame.key.get_pressed()
    mouse_buttons = pygame.mouse.get_pressed()
    if any(keys) or any(mouse_buttons):
        player.move(0, -1, window.get_rect())

    window.fill((127, 127, 127))
    pygame.draw.rect(window, (255, 0, 0), window.get_rect(), 3)
    all_sprites.draw(window)
    player.draw_health(window)
    pygame.display.update()

pygame.quit()
exit()

推荐阅读