如何在 pygame 中的精灵上放置健康栏 [英] How to put a health bar over the sprite in pygame

查看:50
本文介绍了如何在 pygame 中的精灵上放置健康栏的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

根据标题,我希望我的玩家头上有一个健康条.如果他们移动,健康栏也会移动.说精灵是我的播放器.嘿精灵!他的头顶上有一个健康棒,是的,就是这样.说实话,我真的不知道从哪里开始,所以帮助将不胜感激.谢谢!

附言非常感谢 Rabbid76 的帮助!也给安禅!代码:

导入pygame导入操作系统随机导入导入数学导入 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))时钟 = 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类玩家(pygame.sprite.Sprite):def __init__(self, x, y):pygame.sprite.Sprite.__init__(self)z = random.randint(0, 101)如果 z <= 51:self.original_image = pygame.image.load('Sprite0.png')别的:self.original_image = pygame.image.load('Sprite3.png')如果 z == 41:self.original_image = pygame.image.load('Sprite5.png')self.image = self.original_imageself.rect = self.image.get_rect(center=(x, y))self.direction = pygame.math.Vector2((0, -1))self.velocity = 5self.position = pygame.math.Vector2(x, y)self.x = pygame.math.Vector2(x)self.y = pygame.math.Vector2(y)自我健康 = 10self.visible = 真def point_at(self, x, y):self.direction = pygame.math.Vector2(x, y) - self.rect.center如果 self.direction.length() >0:self.direction = self.direction.normalize()角度 = self.direction.angle_to((0, -1))self.image = pygame.transform.rotate(self.original_image, 角度)self.rect = self.image.get_rect(center=self.rect.center)定义移动(自我,x,y):self.position -= self.direction * y * self.velocityself.position += pygame.math.Vector2(-self.direction.y, self.direction.x) * x * self.velocityself.rect.center = round(self.position.x), round(self.position.y)定义反射(自我,NV):self.direction = self.direction.reflect(pygame.math.Vector2(NV))定义更新(自我):self.position += self.direction * self.velocityself.rect.center = round(self.position.x), round(self.position.y)def hit(self, player):如果 self.health >0:self.health -= 1别的:self.visible = 假距离 = math.sqrt(math.pow(player.x - player.x(), 2) + math.pow(player.y - player.y(), 2))如果距离<20:返回真别的:返回错误定义移动(自我,x,y,clamp_rect):self.position -= self.direction * y * self.velocityself.position += pygame.math.Vector2(-self.direction.y, self.direction.x) * x * self.velocityself.rect.center = round(self.position.x), round(self.position.y)如果 self.rect.left <夹具_rect.left:self.rect.left =clamp_rect.leftself.position.x = self.rect.centerx如果 self.rect.right >夹具_rect.right:self.rect.right =clamp_rect.rightself.position.x = self.rect.centerx如果 self.rect.top <夹具_rect.top:self.rect.top =clamp_rect.topself.position.y = self.rect.centery如果 self.rect.bottom >夹具_rect.底部:self.rect.bottom =clamp_rect.bottomself.position.y = self.rect.centery类射弹(对象):def __init__(self, x, y, 半径, 颜色, 面向):自我.x = x自我.y = yself.radius = 半径self.color = 颜色self.looking = 面对self.vel = 8 * 面对def draw(self, win):pygame.draw.circle(win, self.color, (self.x, self.y), self.radius)玩家 = 玩家(200, 200)all_sprites = pygame.sprite.Group(玩家)运行 = 真运行时:时钟滴答(60)对于 pygame.event.get() 中的事件:如果 event.type == pygame.QUIT:运行 = 错误elif event.type == pygame.MOUSEMOTION:player.point_at(*event.pos)pygame.draw.rect(wn,​​ (0, 0, 0), (50, 50, 10000, 100000))键 = pygame.key.get_pressed()如果keys[pygame.K_w] 或keys[pygame.K_UP]:player.move(0, -1, wn.get_rect())wn.fill((255, 255, 255))all_sprites.draw(wn)pygame.display.update()

解决方案

参见

导入pygame导入数学def draw_health_bar(surf, pos, size, borderC, backC, healthC, progress):pygame.draw.rect(冲浪,backC,(*pos,*size))pygame.draw.rect(冲浪,borderC,(*pos,*size),1)innerPos = (pos[0]+1, pos[1]+1)内部大小 = ((大小[0]-2) * 进度,大小[1]-2)rect = (round(innerPos[0]), round(innerPos[1]), round(innerSize[0]), round(innerSize[1]))pygame.draw.rect(冲浪,healthC,rect)类玩家(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_imageself.rect = self.image.get_rect(center=(x, y))self.direction = pygame.math.Vector2((0, -1))self.velocity = 5self.position = pygame.math.Vector2(x, y)自我健康 = 10def point_at(self, x, y):self.direction = pygame.math.Vector2(x, y) - self.rect.center如果 self.direction.length() >0:self.direction = self.direction.normalize()角度 = self.direction.angle_to((0, -1))self.image = pygame.transform.rotate(self.original_image, 角度)self.rect = self.image.get_rect(center=self.rect.center)定义移动(自我,x,y,clamp_rect):self.position -= self.direction * y * self.velocityself.position += pygame.math.Vector2(-self.direction.y, self.direction.x) * x * self.velocityself.rect.center = round(self.position.x), round(self.position.y)test_rect = self.rect.clamp(clamp_rect)如果 test_rect.x != self.rect.x:self.rect.x = test_rect.xself.position.x = self.rect.centerxself.health = max(0, self.health - 1)如果 test_rect.y != self.rect.y:self.rect.y = test_rect.yself.position.y = self.rect.centeryself.health = max(0, self.health - 1)def draw_health(自我,冲浪):health_rect = pygame.Rect(0, 0, self.original_image.get_width(), 7)health_rect.midbottom = self.rect.centerx, self.rect.top最大健康 = 10draw_health_bar(冲浪,health_rect.topleft,health_rect.size,(0, 0, 0), (255, 0, 0), (0, 255, 0), self.health/max_health)窗口 = pygame.display.set_mode((250, 250))时钟 = pygame.time.Clock()玩家 = 玩家(200, 200)all_sprites = pygame.sprite.Group(玩家)运行 = 真运行时:时钟滴答(60)对于 pygame.event.get() 中的事件:如果 event.type == pygame.QUIT:运行 = 错误elif event.type == pygame.MOUSEMOTION:player.point_at(*event.pos)键 = pygame.key.get_pressed()mouse_buttons = pygame.mouse.get_pressed()如果有(键)或任何(鼠标按钮):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(窗口)player.draw_health(窗口)pygame.display.update()pygame.quit()出口()

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()

解决方案

See haw to draw a bar in How can I display a smooth loading bar in pygame?. Create a function that draws a health bar:

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)

Add a method draw_health to the class Player and use the function 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)    

Call the method in the main application loop:

while run:
    # [...]

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

See also Sprite.


Minimal example:

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()

这篇关于如何在 pygame 中的精灵上放置健康栏的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆