pygame做一个星空穿越:提供一序列名称可以产生动态效果

先看效果

在这里插入图片描述

直接上代码

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

张三
李四
王五
赵六
钱七
孙八
周九
吴十
郑十一
王十二
赵十三
李十四
张十五
刘十六
陈十七
杨十八
黄十九
吴二十
周二十一
郑二十二

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值