【问题标题】:Stopping a loop in my hp bar在我的 hp bar 中停止循环
【发布时间】:2013-10-08 19:16:19
【问题描述】:

我正在制作游戏,但我在为这个游戏制作的 Hp 栏类遇到问题,使用以下代码:

import pygame, sys

class hpbar():
    def __init__(self, hpchunk, screen, posx, posy):
        # hpchunk can either be 125 or 250
        self.hpchunk = hpchunk
        self.screen = screen
        self.posx = posx
        self.posy = posy
        self.unit_h = 18
        self.unit_w = 250
        self.image = pygame.image.load('hpbar.png')
        self.total_hp = [self.posx + 3, self.posy + 3, self.unit_w, self.unit_h]  # +3 is there due to the thickness of the actual HP bar 
        self.val_per_chunk = self.unit_w / self.hpchunk                     # units of a single chunk e.g. 250 / 125 = 2
        self.startPos = 253
        screen.blit(self.image, [self.posx, self.posy])
        pygame.draw.rect(screen, [0, 255, 0], self.total_hp, 0)

    def loss(self, loss_val):
        self.loss_val = loss_val
        total_chunk = self.loss_val * self.val_per_chunk                    
        chunkPosx = self.posx + self.startPos                               # e.g. if hpchunk = 125, then the hp will be in chunks of two
        healthbar = [0, 255, 0]
        chunkRangeEnd = self.unit_w - total_chunk                           
        total_chunk = 0                                                     # first iterative value
        stop_val = chunkPosx - total_chunk
        for lossx in range(self.unit_w, chunkRangeEnd, -self.val_per_chunk):
            pygame.draw.rect(self.screen, healthbar, self.total_hp, 0)      # hp bar 
            chunkPosx = chunkPosx - self.val_per_chunk                      # x position of chunk 
            total_chunk = total_chunk + self.val_per_chunk                  # total size of chunk
            if chunkPosx <= self.posx + 141:                                # yellow zone
                healthbar = [255, 255, 0]
            if chunkPosx <= self.posx + 48:                                 # red zone
                if self.val_per_chunk == 25:
                    healthbar = [255, 255, 255]
                else:
                    healthbar = [255, 0, 0]
            pygame.draw.rect(self.screen, [255, 0, 255], [chunkPosx, self.posy + 3, total_chunk, self.unit_h], 0)
            pygame.time.delay(200)
            pygame.display.flip()

    # chunkPosx = 253 + 150 = 403
    # total_chunk = 5 * 2 = 10
    # chunkRangeEnd = 250 - 20 = 230

    # chunkPosx iteration
    # x = x - 2
    # 403 = 403 - 2
    # 401 = 403 - 2     1st
    # 399 = 401 - 2     2nd
    # 397 = 399 - 2     3rd
    # 395 = 397 - 2     4th
    # 393 = 395 - 2     5th

    # total_chunk iteration
    # x = x + 2
    # 0 = 0 + 2
    # 2 = 0 + 2     1st 
    # 4 = 2 + 2     2nd
    # 6 = 4 + 2     3rd
    # 8 = 6 + 2     4th
    #10 = 8 + 2     5th 

pygame.init()
screen = pygame.display.set_mode([720, 480])
screen.fill((255, 255, 255))
pygame.display.flip()

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

    # test, using hp bar instance
    newbar = hpbar(125, screen, 150, 150)
    newbar.loss(5)
    pygame.display.flip()

我这样写我的模块是为了让它可以在游戏的不同区域重复使用,另外需要注意的是,一个图像和一系列矩形用于显示 hp。

每当我给我的损失方法一个值时,它会不断迭代从起始位置丢失的相同数量的块;这让我很难堆叠在前一个之后调用第二个甚至第三个损失方法时扣除的值,无论如何我可以阻止这个吗? 另一方面,这些块可以随着时间的推移对损失/增益进行动画处理,所有这些都显示在我的 hp bar 图像上;我尝试在代码的不同区域使用 break 语句,但它们不会生成预期的输出,而是限制了整体块值丢失

如果你能帮助我,那将不胜感激。 如果我没有正确解释这一点,谢谢和道歉。

【问题讨论】:

  • 作为您当前方法的替代方案,我建议仅根据实体的当前和最大健康状况之间的比率对条形进行编程。您可以使用比例来做到这一点。您当前使用条形“块”的实现似乎过于复杂。

标签: python python-2.7 pygame


【解决方案1】:

我不清楚什么不起作用。

我认为您正在绘制一个显示 cur hp X% 的 HP 条。这些块是否会随着时间的推移为损失设置动画?如果是这样,在那里延迟暂停,将阻止程序的其余部分在完成之前进行更新。还是在bar中显示块?

你可以这样做的一种方法是这样的:

class HpBar():
    def __init__(self, max_hp=56, cur_hp=20):
        self.max_hp = 56
        self.cur_hp = 20
        self.animating = False
        self.animate_delay = 200

    def damage(self, dmg):
        # damage and start animation
        self.cur_hp -= dmg
        self.started_ticks = pygame.time.get_ticks()        
        self.animating = True

    @property
    def ratio(self):
        # get ratio in the range [0., 1.] from original range [0, max_hp]
        return self.cur_hp * (1. / self.max_hp)

    def draw(self):
        # draw background max and current

        # start the same
        hp_box_max = Rect(...)
        hp_box_cur = Rect(hp_box_max)
        hp_box_animate = Rect(hp_box_max)
        hp_box_cur.width = self.ratio * hp_box_max.width

        # always show hp cur/max
        draw(hp_box_max)
        draw(hp_box_cur)

        # animation over?
        now = pygame.time.get_ticks()
        elapsed = now - self.started_ticks
        if now - elapsed > self.animate_duration:
            self.animating = False

        # only show extra effect if animating
        if self.animating:
            hp_box_animate.left = hp_box_cur.right
            hp_box_animate.right = hp_box_cur.right

            # now animate based on time elapsed
            chunks = elapsed / self.animate_delay

            # if elapsed is 200, chunks = 1
            # elapsed 400, chunks = 2 , etc...
            hp_box_animate.width = chunks * chunk_width    
            draw(hp_box_animate)

draw() 正在重新计算 3 个矩形(如果动画结束,则为 2 个)。如果您愿意,cur_hp 可以升级为@property,它将自动渲染和缓存更新的表面。我使用类似的方法来缓存文本的渲染,并且只有在数据导致设置了脏布尔值时才重新渲染。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-01-11
    • 2015-05-09
    • 2019-01-25
    • 2017-08-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多