m0_61802713 2024-11-16 11:07 采纳率: 0%
浏览 8

pygame渲染效率无法提升

我正在使用python制作一个2D的Minecraft同人,但是在负责渲染的地方效率很低,在全屏渲染方块的情况下仅20fps(我电脑性能并不低)。以下是负责渲染的代码片段:

import pygame

from .world_generators import *

def teleport_camera(x, y):
    global camera_x, camera_y, block_size
    camera_x = x * block_size
    camera_y = y * block_size
    print(camera_x, camera_y)

def start_render(block_images, font):
    global camera_x, camera_y, camera_width, camera_height, start_x, start_y, start_width, start_height
    running = True
    teleport_camera(800, 250)
    clock = pygame.time.Clock()  # 创建时钟对象
    fps = 120# 设置目标帧率为 60 FPS
    total_fps = 0
    frame_count = 0  # 帧计数
    last_time = pygame.time.get_ticks()  # 记录起始时间


    while running:
        # 处理事件
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                running = False

            # 获取鼠标点击事件
            if event.type == pygame.MOUSEBUTTONDOWN:
                mouse_x, mouse_y = pygame.mouse.get_pos()  # 获取鼠标位置

                # 计算方块网格坐标
                x = (mouse_x + camera_x) // block_size
                y = (mouse_y + camera_y) // block_size

                if event.button == 1:  # 左键
                #    if 0 <= x < viewport_width and 0 <= y < viewport_height:
                        set_block(loading_map_grid, x, y, "air")  # 将该方块设置为空(破坏方块)

                elif event.button == 3:  # 右键
                #    if 0 <= x < viewport_width and 0 <= y < viewport_height:
                        place_block(loading_map_grid, x, y, "grass_block")  # 在该方块放置一个草方块(示例)

        # 获取按键状态
        keys = pygame.key.get_pressed()
        if keys[pygame.K_w]:  # 按下 W 键
            camera_y -= camera_speed  # 向上移动
        if keys[pygame.K_s]:  # 按下 S 键
            camera_y += camera_speed  # 向下移动
        if keys[pygame.K_a]:  # 按下 A 键
            camera_x -= camera_speed  # 向左移动
        if keys[pygame.K_d]:  # 按下 D 键
            camera_x += camera_speed  # 向右移动
        if keys[pygame.K_UP]:
            print(camera_x, camera_y)

        # 填充背景色
        screen.fill(sky_blue)

        # 获取鼠标位置用于高亮效果
        mouse_x, mouse_y = pygame.mouse.get_pos()
        highlight_x = (mouse_x + camera_x) // block_size
        highlight_y = (mouse_y + camera_y) // block_size

        window_width, window_height = screen.get_size()  # 获取当前窗口大小

        # 获取可视区域的起始和结束坐标
        start_x = camera_x // block_size
        end_x = (camera_x + window_width) // block_size + 1  # 加1以确保覆盖边界
        start_y = camera_y // block_size
        end_y = (camera_y + window_height) // block_size + 1  # 加1以确保覆盖边界

        if get_block(loading_map_grid, start_x, 0): #同下当玩家移动时用于生成新的世界
            pass
        else:
            print(f"generate world at {start_x}")
            generate_world(start_x)

        if get_block(loading_map_grid, end_x-1, 0):
            pass
        else:
            print(f"generate world at {end_x}")
            generate_world(end_x-1)

        # 绘制方块
        for y in range(start_y, end_y):  # 遍历可视高度范围
            for x in range(start_x, end_x):  # 遍历可视宽度范围
                block_id = loading_map_grid.get((x, y))  # 获取对应位置的方块 ID
                if block_id in block_images:  # 检查方块 ID 是否在贴图字典中
                    screen.blit(block_images[block_id], ((x * block_size) - camera_x, (y * block_size) - camera_y))  # 绘制方块
                if get_block(loading_map_grid, x, 0):
                    pass
                else:
                    print(f"generate world at {x}")
                    generate_world(x)

                    # 检查是否高亮
                if x == highlight_x and y == highlight_y:
                        # 画一个高亮的边框(简单的方法,使用矩形)
                        pygame.draw.rect(screen, (0, 0, 0), ((x * block_size) - camera_x, (y * block_size) - camera_y, block_size, block_size), 1)  # 边框

        # 计算并显示 FPS
        frame_count += 1  # 增加帧计数
        if pygame.time.get_ticks() - last_time >= 1000:  # 每过1秒更新 FPS
            total_fps = frame_count  # 更新总帧率
            frame_count = 0  # 重置帧计数
            last_time = pygame.time.get_ticks()  # 重置时间

        # 渲染并绘制 FPS 文本
        screen.blit(font.render(f"{str(total_fps)}FPS", True, (255, 255, 255)),
                    font.render(str(total_fps), True, (255, 255, 255)).get_rect(
                        center=(window_width - 100, window_height - 30)))

        # 更新屏幕
        pygame.display.flip()

        # 限制帧率
        clock.tick(fps)  # 控制主循环的最大帧率

*实在是找不到解决办法了,球帮助!

  • 写回答

1条回答 默认 最新

  • 关注

    以下回复参考:皆我百晓生券券喵儿等免费微信小程序作答:

    渲染效率的问题可能有很多原因,以下是一些可能帮助你提高渲染效率的建议:

    1. 优化渲染循环:你的渲染循环中多次调用了一些函数,如 get_block()generate_world()。这些函数调用在每次循环中都执行,可能导致性能下降。尝试将这些操作移到循环外部或仅在必要时执行。
    2. 使用更高效的数据结构:考虑使用更高效的数据结构来存储地图数据。例如,你可以考虑使用二维数组或网格来存储方块信息,这样可以更高效地访问和更新数据。
    3. 批量渲染:在渲染循环中,你可以尝试批量渲染方块,而不是逐个渲染。这样可以减少绘制的次数并提高性能。
    4. 避免不必要的绘图操作:在你的代码中,有些部分可能会执行不必要的绘图操作。例如,在每次循环中都绘制FPS文本可能会导致性能下降。你可以考虑只在FPS发生变化时重新绘制FPS文本。
    5. 优化贴图处理:确保你的贴图加载得当且没有内存泄漏。避免在循环中频繁加载和卸载贴图,这可能会导致性能问题。
    6. 使用硬件加速:确保你的pygame窗口启用了硬件加速。你可以通过设置窗口的flag来实现这一点。这可以充分利用GPU的性能来提高渲染效率。
    7. 分析性能瓶颈:使用性能分析工具(如Python的cProfile模块)来分析你的代码,找出性能瓶颈并优化相关部分。
    8. 优化算法:对于复杂的算法和计算任务,可以考虑使用更高效的算法来实现相同的功能,以减少计算时间并提高性能。
    9. 使用多线程或多进程:如果某些任务(如世界生成或物理计算)是独立的并且不需要频繁地与主线程交互,可以考虑使用多线程或多进程来提高性能。请注意,在多线程或多进程环境中需要妥善处理线程安全和资源访问同步的问题。

    尝试应用上述建议中的一项或多项优化措施,并观察是否有助于提高你的渲染效率。此外,还要注意硬件性能和限制也可能是一个因素,确保你的电脑能够支持你所追求的渲染效果和目标帧率。

    评论

报告相同问题?

问题事件

  • 创建了问题 11月16日