我正在pygame中创建游戏,我想实时降低玩家的HP。为此,我知道我不能使用time.sleep()
,因为它冻结了整个游戏。我曾尝试在threading.Thread
上使用pygame.MOUSEBUTTONDOWN
对播放器造成一定程度的损害,但没有奏效。请记住,这是我第一次使用线程。
我的代码:
#-*- coding-utf8 -*-
import pygame
import threading
import time
import os
os.environ['SDL_VIDEO_CENTERED'] = '1'
pygame.init()
SIZE = (1200, 600)
screen = pygame.display.set_mode(SIZE)
clock = pygame.time.Clock()
class Player:
def __init__(self):
self.HP = 100
self.HP_BAR = pygame.Rect(10, 10, self.HP * 3, 10)
self.X = 100
self.Y = 100
self.WIDTH = 50
self.HEIGHT = 100
self.COLOR = (255,255,0)
self.PLAYER = pygame.Rect(self.X, self.Y, self.WIDTH, self.HEIGHT)
def move(self):
pressed = pygame.key.get_pressed()
if pressed[pygame.K_w]: self.Y -= 1
if pressed[pygame.K_s]: self.Y += 1
if pressed[pygame.K_a]: self.X -= 1
if pressed[pygame.K_d]: self.X += 1
self.PLAYER = pygame.Rect(self.X, self.Y, self.WIDTH, self.HEIGHT)
def draw(self):
# clear screen
screen.fill((0,0,0))
# draw HP bar
self.HP_BAR = pygame.Rect(10, 10, self.HP * 3, 10)
pygame.draw.rect(screen, (50,0,0), self.HP_BAR)
# draw player
pygame.draw.rect(screen, self.COLOR, self.PLAYER)
pygame.display.flip()
def remove_HP(self, value):
for x in range(value):
self.HP -= 1
self.draw()
# time.sleep(0.1)
p1 = Player()
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT or (event.type == pygame.KEYDOWN and event.key == pygame.K_ESCAPE):
exit()
if event.type == pygame.MOUSEBUTTONDOWN and event.button == 1:
td2 = threading.Thread(target = p1.remove_HP(20), name = "td2")
td2.daemon = True
td2.start()
p1.move()
p1.draw()
clock.tick(60)
我使用线程错误吗?我想同时执行p1.remove_HP()
和p1.move()
,但是程序要做的是:
用户在按下[A]
时单击1º:p1.move()
2º:p1停止移动
3º:p1.remove_HP()
4º:p1再次移动
对不起,如果它很愚蠢,但我确实在尝试和学习。预先感谢!
答案 0 :(得分:1)
您根本不需要线程。不要让您的生活变得不必要的复杂。
您只需要对游戏的运行方式有不同的看法。它循环运行;在您的情况下,它以60 fps的速度运行。
因此,如果您想随时间做任何事情,可以有不同的选择:
1)制作一个变量,每帧增加一次,当它达到60时,您知道已经过去了1秒(这很简单,但是不可靠,因为您依赖于恒定的帧频)
2)使用事件。在pygame中,您可以创建可以手动或定期触发的自定义事件,并在主循环中处理它们,例如pygame的内置事件(适用于简单的用例,但可以创建的事件数量有限)
3)创建一个变量并在其中存储时间戳。时间戳记可以是系统时间,也可以是其他时间,例如游戏开始以来的滴答声数量(例如,使用pygame的pygame.time.get_ticks
。然后,每帧将其与当前系统时间或滴答声进行比较,以计算多少时间)通过
我稍微更新了您的代码。注意我如何将不同的关注点分离到代码的不同部分:
我只是每帧降低一点马力(这基本上是我上面列出的选项1的一种形式);这是解决问题的好方法。
#-*- coding-utf8 -*-
import pygame
import threading
import time
import os
os.environ['SDL_VIDEO_CENTERED'] = '1'
pygame.init()
SIZE = (1200, 600)
screen = pygame.display.set_mode(SIZE)
clock = pygame.time.Clock()
class GUI(pygame.sprite.Sprite):
def __init__(self):
super().__init__()
self.image = pygame.Surface((1200, 600))
self.image.set_colorkey((12,34,56))
self.image.fill((12,34,56))
self.rect = self.image.get_rect()
self.player = None
def update(self):
self.image.fill((12,34,56))
if self.player:
pygame.draw.rect(self.image, (50, 0, 0), pygame.Rect(10, 10, self.player.hp * 3, 10))
class Player(pygame.sprite.Sprite):
def __init__(self):
super().__init__()
self.image = pygame.Surface((50, 100))
self.image.fill((255,255,0))
self.rect = self.image.get_rect(topleft=(100, 100))
self.hp = 100
def update(self):
pressed = pygame.key.get_pressed()
if pressed[pygame.K_w]: self.rect.move_ip( 0, -1)
if pressed[pygame.K_s]: self.rect.move_ip( 0, 1)
if pressed[pygame.K_a]: self.rect.move_ip(-1, 0)
if pressed[pygame.K_d]: self.rect.move_ip( 1, 0)
self.hp -= 0.05
p1 = Player()
gui = GUI()
gui.player = p1
sprites = pygame.sprite.Group(p1, gui)
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT or (event.type == pygame.KEYDOWN and event.key == pygame.K_ESCAPE):
exit()
screen.fill((0,0,0))
sprites.update()
sprites.draw(screen)
pygame.display.flip()
clock.tick(60)