黑客帝国的屏幕效果如图1所示。
图1 黑客帝国屏幕效果
实现以上功能,实际上就是在Pygame中创建两个Surface,其中一个Surface是纯黑屏背景,用来覆盖之前的屏幕,达到数字逐渐消失的效果;另一个Surface用来显示数字,达到数字下移的效果。
1 创建显示数字的Surface
使用如下代码创建一个全屏的Surface,该Surface用来显示数字,并且具有数字下移的效果。
screen = pygame.display.set_mode((0,0), pygame.FULLSCREEN)
其中,pygame.FULLSCREEN表示该Surface为全屏。
2 创建纯黑屏背景Surface
使用pygame.Surface()方法,创建纯黑屏背景Surface,代码如下所示。
screenwidth = screen.get_width()
screenheight = screen.get_height()
surface = pygame.Surface((screenwidth, screenheight), pygame.SRCALPHA)
该Surface的大小与“1 创建显示数字的Surface”中创建的Surface大小相同,因此pygame.Surface()方法的第一个参数指定的Surface大小即为screen的宽度和高度;第二个参数pygame.SRCALPHA表示Surface的像素格式有alpha值,即有透明度。因为要做出数字的淡出效果,因此背景Surface需要有透明度。
3 设置Surface的透明度
通过以下代码设置Surface的透明度。
surface.fill((0, 0, 0, 10))
其中,前三个0表示Surface的背景颜色是(0,0,0),即黑色,最后一位数字表示透明度。
相关链接1 透明度的范围是0-255,0表示完全透明,255表示完全不透明。
Surface的透明度的值越大,说明每层的Surface越“厚”,数字被完全覆盖所需要的层数就越少。换句话说,透明度的值越大,每一列显示的数字就越少,因为覆盖的Surface变变少了。
4 创建显示内容的
在屏幕中显示的内容只有“0”和“1”,通过列表推导式创建要显示的内容。
font = pygame.font.SysFont('宋体', 25)
texts = [font.render(i, True, (0, 255, 0)) for i in ['0','1']]
其中,render()方法的作用是创建一个新的Surface来显示“0”和“1”。此时,创建的两个Surface以列表的形式保存在texts中。
相关链接2 font.render()的使用方法,请参考Pygame显示文字_棉猴的博客-CSDN博客
5 用surface覆盖screen
之后,在while True循环中,使用带有透明度surface覆盖screen。
pygame.time.delay(50)
screen.blit(surface, (0, 0))
因为显示的“0”和“1”需要有淡出效果,所以,需要通过pygame.time.delay加入延时,50表示每隔50毫秒,在screen上覆盖一次surface。
6 显示多行多列内容
在while True循环中,使用for循环显示多行多列的“0”和“1”。
for i in range(len(lst)):
text = random.choice(texts)
screen.blit(text, (i * 20, lst[i] * 20))
lst[i] += 1
if random.random() < 0.05:
lst[i] = 0
其中,lst的定义为
lst = list(range(99))
在以上代码中,i表示显示的行数,lst[i]表示显示的列数。通过random.choice()在texts中随机选择显示的内容;之后通过blit()方法将该内容显示在screen中,显示数字的位置由i和lst[i]确定;在显示了某个行数字后,需要对lst[i]进行加1处理,这样才会有数字下移的效果;因为并每列数字都要显示到最后一行才从第1行重新显示,而是随机显示到某行之后就会重新从第1行显示,所以在代码的最后加入一个随机的概率,让lst[i]的值为0,即某一列从第1行开始重新显示。
代码的最后,调用pygame.display.flip()方法,将Surface中的内容显示到屏幕上。
pygame.display.flip()
7 完整代码
import pygame
import random
pygame.init()
font = pygame.font.SysFont('宋体', 25)
screen = pygame.display.set_mode((0,0), pygame.FULLSCREEN)
screenwidth = screen.get_width()
screenheight = screen.get_height()
surface = pygame.Surface((screenwidth, screenheight), pygame.SRCALPHA)
surface.fill((0, 0, 0, 10))
texts = [font.render(i, True, (0, 255, 0)) for i in ['0','1']]
lst = list(range(99))
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT :
exit()
if event.type == pygame.KEYUP:#按Esc退出全屏
if event.key == pygame.K_ESCAPE:
pygame.display.set_mode((400, 400))
if event.key == pygame.K_f:#按f键恢复全屏
pygame.display.set_mode((0,0), pygame.FULLSCREEN)
pygame.time.delay(50)
screen.blit(surface, (0, 0))
for i in range(len(lst)):
text = random.choice(texts)
screen.blit(text, (i * 20, lst[i] * 20))
lst[i] += 1
if random.random() < 0.05:
lst[i] = 0
pygame.display.flip()