当我点击鼠标并慢慢淡出时,我试图让一个实例类(Block)产生,并且我希望能够产生无限数量的淡出块,只要点击鼠标即可足够快。
为此,我想在第一次生成实例时启动fade()函数,并将tick设置为255并将alpha设置为ticks。
然而,当使用while循环时,该函数在不更新显示的情况下自行完成,因为程序被限制为fade()函数中的while循环。
有人可以帮助我为每个实例调用淡入淡出函数255次吗?
import pygame,sys,time,Blockm
from pygame.locals import *
black,white=(0,0,0),(255,255,255)
size=w,h=1400,800
screen=pygame.display.set_mode(size)
pygame.init()
class Block(object):
sprite = None
def __init__(self, x, y):
if not Block.sprite:
Block.sprite = pygame.image.load("Block.png").convert_alpha()
self.rect = Block.sprite.get_rect(top=y, left=x)
self.fade()
def fade(self):
ticks=255
Block.sprite.set_alpha(ticks)
while ticks!=0:
ticks-=1
print(ticks)
while True:
blocks = []
mmraw=pygame.mouse.get_pos()
mmx,mmy=mmraw[0]-(pygame.image.load("Block.png").get_width())/2,mmraw[1]-(pygame.image.load("Block.png").get_width())/2
for event in pygame.event.get():
if event.type== pygame.QUIT:
pygame.quit()
sys.exit()
if event.type == pygame.MOUSEBUTTONDOWN:
print('click')
blocks.append(Block(mmx,mmy))
for block in blocks:
screen.blit(block.sprite, block.rect)
print('trying to blit')
print(Block.sprite.get_offset())
pygame.display.update()
答案 0 :(得分:1)
您可能想要使用threads。这些允许您一次运行多个事物。对于您的代码,请按以下方式进行更改:
from threading import Thread
import pygame, sys, time, Blockm
from pygame.locals import *
black = (0,) * 3
white = (255,) * 3
size = w, h = 1400, 800
screen = pygame.display.set_mode(size)
pygame.init()
class Block(object):
sprite = None
def __init__(self, x, y):
if not Block.sprite:
Block.sprite = pygame.image.load("Block.png").convert_alpha()
self.rect = Block.sprite.get_rect(top=y, left=x)
Thread(target=self.fade) # Made this a Thread so it runs separately.
def fade(self):
for tick in range(255, 0, -1):
Block.sprite.set_alpha(tick)
print(tick)
def game():
while True:
# The contents of that while True loop at the end
def main():
Thread(target=Main)
if __name__ == "__main__":
main()
这也为您的程序添加了一个缺少的入口点。此外,Block.fade
实际上并不会做你想要的,因为你只set_alpha
一次。我用for
循环来修复它。另外,请注意,您现在可以return
打破整个游戏。
答案 1 :(得分:1)
我有一个适合你的解决方案应该达到你想要的目标,但我承认并没有完全按照要求回答问题。
您可能遇到的第一个也是最令人阻碍的问题是,您需要使用pygame.image.load("Block.png").convert()
而不是pygame.image.load("Block").convert_alpha()
,因为.convert_alpha()
不能与.set_alpha(..)
一起使用。
由于screen
未在update
之前刷新,因此您可能无法注意到任何解决方案中的块何时淡入淡出。新的,褪色的街区正在被吸引到更加明亮的地方。那些,没有产生差异(尽管有重叠的块)。我在下面的解决方案代码中添加了一个权宜之计,用蓝色填充屏幕,但我想你会想要一些与众不同的东西。它标有评论。
我建议让每个Block
在你的for block in blocks:
块中的主循环调用期间在本地处理其alpha值。这个版本的代码应该可以提供你想要的结果,虽然它只使用主循环,而不是像你要问的并行循环......
import pygame,sys,time,Blockm
from pygame.locals import *
black,white=(0,0,0),(255,255,255)
size=w,h=1400,800
screen=pygame.display.set_mode(size)
pygame.init()
class Block(object):
sprite = None
def __init__(self, x, y):
if not Block.sprite:
Block.sprite = pygame.image.load("Block.png").convert()
# ^ MODIFIED: .convert_alpha() won't recognize the effects of .set_alpha(), so use regular .convert() instead.
self.rect = Block.sprite.get_rect(top=y, left=x)
self.ticks = 255 # NEW: Set a local tick count.
# REMOVED `self.fade()`: This runs on main now.
def fade(self):
## REPURPOSED METHOD: Runs each frame that the Block is active. Called on main loop.
# MODIFIED BLOCK: Update local tick count before setting the class's sprite alpha.
self.ticks -= 1
Block.sprite.set_alpha(self.ticks) # MOVED, MODIFIED: uses local tick count for alpha.
print(self.ticks) # UPDATED: Using local ticks.
blocks = [] # MOVED: Make a list for the Blocks, but don't clear it on frame.
while True:
mmraw=pygame.mouse.get_pos()
mmx,mmy=mmraw[0]-(pygame.image.load("Block.png").get_width())/2,mmraw[1]-(pygame.image.load("Block.png").get_width())/2
# ^ There may be a tidier way of doing this. Described in solution body...
for event in pygame.event.get():
if event.type== pygame.QUIT:
pygame.quit()
sys.exit()
if event.type == pygame.MOUSEBUTTONDOWN:
print('click')
blocks.append(Block(mmx,mmy))
screen.fill((22,22,222))
# ^ NEW: Fill the screen with some backdrop so that the erasure is obvious!
# If you don't do this, you'll be blitting faded images over brighter ones and there will be no real change!!
for block in blocks:
block.fade() # NEW: Update this block.
if block.ticks < 1: # NEW BLOCK: If the block has become invisible...
blocks.remove(block) # NEW: Expunge this invisible block.
continue # NEW: Immediately move on to the next block.
screen.blit(Block.sprite, block.rect)
print('trying to blit')
print(Block.sprite.get_offset())
pygame.display.update()
它有一个小问题,即消失的块会触发闪烁&#39;在其他剩余的块中(或者至少是blocks
中的下一个块),我不知道为什么或如何。
在我看的时候,我发现了一些你可能想要考虑的事情:
...在class Block:
中:
- 使用sprite = pygame.image.load("Block.png").convert()
代替sprite = None
。这样,您可以使用mmx,mmy = mmraw[0] - Block.sprite.get_rect.centerx, mmraw[1] - Block.sprite.get_rect().centery
之类的内容,而不是暂时加载图像,只是为了知道它的大小。由于所有Block
都使用相同的图形,因此它不应该有所不同,这样,如果在运行时更改Block.sprite
,则不必重新获取偏移量!< / p>
- 将Block
精灵的副本分配给每个实例,而不是使用类的Surface。这会占用更多的处理能力,但只是暂时用作return
而不是class Block(object):
...
def fade(self):
sprite = Block.sprite.copy()
sprite.set_alpha(self.ticks)
self.ticks -= 1
return sprite
...
while True: # main loop
...
for block in blocks:
screen.blit(block.fade(), block.rect) # Although there are more Pythonic ways of writing this.
。例如:
screen.blit(sprite, self.rect)
或者,您可以在Block.fade()
中使用fade
而不是使用主要内容,并完全放弃退货。由于alpha是在本地设置的,因此每次Block
运行时都不会重置,sprite
未绑定{{1}}可以保持新鲜!
无论如何,我希望这可以解决你的问题,即使它没有(完全)回答你的问题!