先看效果
直接上代码
import pygame
import random
import sys
import time
# 初始化Pygame
pygame.init()
# 设置屏幕尺寸
WIDTH, HEIGHT = 800, 600
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("Space Flight")
# 定义星星类
class Star:
def __init__(self):
self.x = random.uniform(-WIDTH / 2, WIDTH / 2)
self.y = random.uniform(-HEIGHT / 2, HEIGHT / 2)
self.z = random.randint(100, 300) / 100 # 模拟星星的深度,z值越小,星星越靠近观察者
self.size = random.randint(100, 300) / 100 # 星星的大小
def move(self):
self.z -= 0.015 # 模拟星星的移动,z值减小表示星星向观察者移动
if self.z <= 0:
self.x = random.uniform(-WIDTH / 2, WIDTH / 2)
self.y = random.uniform(-HEIGHT / 2, HEIGHT / 2)
self.z = 3 # 当星星移动至屏幕之外时,重新生成星星位置
def draw(self):
# 计算星星在屏幕上的位置
screen_x = WIDTH / 2 + self.x * (1 / self.z)
screen_y = HEIGHT / 2 + self.y * (1 / self.z)
size = self.size * (1 / self.z)
# 检查位置参数是否有效
if 0 <= screen_x <= WIDTH and 0 <= screen_y <= HEIGHT:
# 星星越靠近观察者,就越大
pygame.draw.circle(screen, (255, 255, 255), (int(screen_x), int(screen_y)), int(size))
# 定义跳动的文本类
class JumpingText:
def __init__(self, text, font_size, color):
self.text = text
self.font = pygame.font.SysFont("华文楷体", font_size, True) # 使用华文楷体并加粗
self.color = color
self.x = random.uniform(-WIDTH / 4, WIDTH / 4)
self.y = random.uniform(-HEIGHT / 4, HEIGHT / 4)
self.z = 3.1 # 文本的深度
self.size = random.randint(30, 45) # 文本的初始大小
self.max_size = self.size # 文本的最大大小与初始大小相同
self.dx = random.uniform(-0.05, 0.05) # 水平移动速度
self.dy = random.uniform(-0.05, 0.05) # 垂直移动速度
self.speed = 0.03125 # 文本的移动速度降为原来的一半
print("zero: begin:", self.text)
def getText(self) :
return self.text
def move(self):
if self.z <= 0:
return # 只绘制一遍
self.x += self.dx * self.speed # 更新文本的水平位置
self.y += self.dy * self.speed # 更新文本的垂直位置
self.z -= 0.0125 # 文本的深度减小,向观察者移动
# if self.z <= 0:
# print("zero: end:", self.text)
# self.x = random.uniform(-WIDTH / 4, WIDTH / 4)
# self.y = random.uniform(-HEIGHT / 4, HEIGHT / 4)
# self.z = 3 # 当文本移动至屏幕之外时,重新生成文本位置
def draw(self):
if self.z <= 0:
return # 只绘制一遍
# 计算文本在屏幕上的位置
screen_x = WIDTH / 2 + self.x * (1 / self.z)
screen_y = HEIGHT / 2 + self.y * (1 / self.z)
size = self.size * (1 / self.z)
# 检查位置参数是否有效
if 0 <= screen_x <= WIDTH and 0 <= screen_y <= HEIGHT:
# 绘制文本
font_surface = self.font.render(self.text, True, self.color)
scaled_surface = pygame.transform.scale(font_surface, (int(size), int(size)))
screen.blit(scaled_surface, (screen_x - size / 2, screen_y - size / 2))
# 从文件中读取所有人名
def read_names_from_file(file_name):
with open(file_name, 'r', encoding='utf-8') as file:
names = [line.strip() for line in file]
return names
def optimize_cache(cache, all_names, cache_size, isAdd):
# 如果cache已满,删除第一个元素
if len(cache) > cache_size:
print("pop :", len(cache), cache[0].getText())
cache.pop(0)
# 随机选择要添加的元素
if (len(cache) < cache_size) and isAdd:
remaining_names = [name for name in all_names if name not in cache]
selected_name = random.choice(remaining_names)
font_size = random.randint(30, 45)
color = (255, 255, 255)
print("init :", selected_name)
cache.append(JumpingText(selected_name, font_size, color))
def printTime() :
timestamp = time.time()
print("当前时间戳:", timestamp)
# 主程序
def main():
file_name = 'showName.txt' # 假设人名文件名为 showName.txt
all_names = read_names_from_file(file_name)
cache_size = 5
cache_size_init = 3
span_frame = 60
cache = []
# 填充初始缓存
for _ in range(cache_size_init):
name = random.choice(all_names)
font_size = random.randint(30, 45)
color = (255, 255, 255)
cache.append(JumpingText(name, font_size, color))
# 创建星星列表
stars = [Star() for _ in range(100)]
clock = pygame.time.Clock()
frame_count = 0
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
# 清屏
screen.fill((0, 0, 0))
# 移动并绘制星星
for star in stars:
star.move()
star.draw()
# 更新并绘制文本
for text in cache:
text.move()
text.draw()
for text in cache:
if text.z <=0 and frame_count % span_frame == 0:
# 选择新的文本
remaining_names = [name for name in all_names if name not in cache]
selected_name = random.choice(remaining_names)
font_size = random.randint(30, 45)
color = (255, 255, 255)
print("add :", selected_name)
# 将新的文本添加到缓存中
cache.append(JumpingText(selected_name, font_size, color))
frame_count += 1
break
# 更新屏幕
pygame.display.flip()
# 控制帧率
clock.tick(120)
optimize_cache(cache, all_names, cache_size, frame_count % span_frame == 0)
frame_count += 1
if __name__ == "__main__":
main()
逐步讲解代码
这段代码是一个简单的Pygame程序,实现了一个太空飞行的场景,其中包括星星的移动和绘制,以及跳动的文本(人名)的随机添加和移动。
让我逐行解释代码:
import pygame
import random
import sys
import time
这些是导入所需的模块,包括pygame、random、sys和time。
pygame.init()
这里初始化了Pygame,这是使用Pygame的必要步骤。
WIDTH, HEIGHT = 800, 600
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("Space Flight")
设置了窗口的尺寸和标题,并创建了窗口对象。
class Star:
def __init__(self):
self.x = random.uniform(-WIDTH / 2, WIDTH / 2)
self.y = random.uniform(-HEIGHT / 2, HEIGHT / 2)
self.z = random.randint(100, 300) / 100
self.size = random.randint(100, 300) / 100
def move(self):
self.z -= 0.015
if self.z <= 0:
self.x = random.uniform(-WIDTH / 2, WIDTH / 2)
self.y = random.uniform(-HEIGHT / 2, HEIGHT / 2)
self.z = 3
def draw(self):
screen_x = WIDTH / 2 + self.x * (1 / self.z)
screen_y = HEIGHT / 2 + self.y * (1 / self.z)
size = self.size * (1 / self.z)
if 0 <= screen_x <= WIDTH and 0 <= screen_y <= HEIGHT:
pygame.draw.circle(screen, (255, 255, 255), (int(screen_x), int(screen_y)), int(size))
这是Star类,用于表示并绘制星星。每个星星具有随机的位置(x,y),以及随机的深度(z)和大小(size)。move()方法用于模拟星星的移动,draw()方法用于绘制星星。
class JumpingText:
def __init__(self, text, font_size, color):
self.text = text
self.font = pygame.font.SysFont("华文楷体", font_size, True)
self.color = color
self.x = random.uniform(-WIDTH / 4, WIDTH / 4)
self.y = random.uniform(-HEIGHT / 4, HEIGHT / 4)
self.z = 3.1
self.size = random.randint(30, 45)
self.max_size = self.size
self.dx = random.uniform(-0.05, 0.05)
self.dy = random.uniform(-0.05, 0.05)
self.speed = 0.03125
def move(self):
if self.z <= 0:
return
self.x += self.dx * self.speed
self.y += self.dy * self.speed
self.z -= 0.0125
def draw(self):
if self.z <= 0:
return
screen_x = WIDTH / 2 + self.x * (1 / self.z)
screen_y = HEIGHT / 2 + self.y * (1 / self.z)
size = self.size * (1 / self.z)
if 0 <= screen_x <= WIDTH and 0 <= screen_y <= HEIGHT:
font_surface = self.font.render(self.text, True, self.color)
scaled_surface = pygame.transform.scale(font_surface, (int(size), int(size)))
screen.blit(scaled_surface, (screen_x - size / 2, screen_y - size / 2))
这是JumpingText类,用于表示并绘制跳动的文本。每个文本对象具有文本内容、字体大小、颜色和位置(x,y),以及深度(z)。move()方法用于模拟文本的移动,draw()方法用于绘制文本。
def read_names_from_file(file_name):
with open(file_name, 'r', encoding='utf-8') as file:
names = [line.strip() for line in file]
return names
这个函数用于从文件中读取所有人名,并返回一个包含所有人名的列表。
def optimize_cache(cache, all_names, cache_size, isAdd):
if len(cache) > cache_size:
cache.pop(0)
if (len(cache) < cache_size) and isAdd:
remaining_names = [name for name in all_names if name not in cache]
selected_name = random.choice(remaining_names)
font_size = random.randint(30, 45)
color = (255, 255, 255)
cache.append(JumpingText(selected_name, font_size, color))
这个函数用于优化文本缓存,保持缓存的大小不超过指定的大小,并在需要时添加新的文本对象。
def printTime() :
timestamp = time.time()
print("当前时间戳:", timestamp)
这个函数用于打印当前时间戳。
def main():
file_name = 'showName.txt'
all_names = read_names_from_file(file_name)
cache_size = 5
cache_size_init = 3
span_frame = 60
cache = []
for _ in range(cache_size_init):
name = random.choice(all_names)
font_size = random.randint(30, 45)
color = (255, 255, 255)
cache.append(JumpingText(name, font_size, color))
stars = [Star() for _ in range(100)]
clock = pygame.time.Clock()
frame_count = 0
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
screen.fill((0, 0, 0))
for star in stars:
star.move()
star.draw()
for text in cache:
text.move()
text.draw()
for text in cache:
if text.z <=0 and frame_count % span_frame == 0:
remaining_names = [name for name in all_names if name not in cache]
selected_name = random.choice(remaining_names)
font_size = random.randint(30, 45)
color = (255, 255, 255)
cache.append(JumpingText(selected_name, font_size, color))
frame_count += 1
break
pygame.display.flip()
clock.tick(120)
optimize_cache(cache, all_names, cache_size, frame_count % span_frame == 0)
frame_count += 1
if
__name__ == "__main__":
main()
这是主程序,包括从文件中读取人名,初始化文本缓存和星星列表,以及主循环中的事件处理、绘制和帧率控制等。在主循环中,通过调用JumpingText类和Star类的方法来移动和绘制文本和星星,同时通过optimize_cache函数来优化文本缓存。
showName.txt
张三
李四
王五
赵六
钱七
孙八
周九
吴十
郑十一
王十二
赵十三
李十四
张十五
刘十六
陈十七
杨十八
黄十九
吴二十
周二十一
郑二十二