我正在使用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) # 控制主循环的最大帧率
*实在是找不到解决办法了,球帮助!