Увеличение кадров и увеличение плавности pygame
Всем привет, написал простенькую игру по типу маинкрафт на базе py game
столкнулся с проблемой оптимизации кадров, всю инфу переискал ничего годного не нашел,
кому не сложно оптимизируйте мой код и проверьте на ошибки если можно)
вот код:
import numba
import ursina
from ursina import *
import random
import pygame
import pygame as pg
import numpy as np
app = Ursina()
pygame.init()
pygame.mixer.music.load("miyagi.mp3") # Замените "background.mp3" на путь к вашему файлу
pygame.mixer.music.play(-1) # -1 означает бесконечное повторение
@numba.njit(cache=True)
def linear_interpolation(X0: int, X1: int, p: float) -> float:
return x0 + (x1-x0)*p # example linear interpolation method - math calculationsp
# Текстуры
grass_block_texture = load_texture('i-_3_.png')
stone_texture = load_texture('stone.png')
dirt_texture = load_texture('wood.png')
wood_texture = load_texture('dirt.png')
leaves_texture = load_texture('leaves.png')
sand_texture = load_texture('sand.png')
water_texture = load_texture('')
sky_texture = load_texture('')
block_pick = 1 # Для выбора блока
sky_texture = load_texture("sky.png")# Укажите путь к вашей текстуре неба
wall_texture = load_texture("wall.png") # Укажите путь к вашей текстуре стены
# Класс блока
# преобразуем Surface в numpy массивы для работы
fps = 200
clock = pygame.time.Clock()
class Block(Button):
def __init__(self, position=(0, 0, 0), texture=grass_block_texture):
super().__init__(
parent=scene,
position=position,
model='cube',
origin_y=0.5,
texture=texture,
color=color.white,
highlight_color=color.lime)
def input(self, key):
if self.hovered:
if key == 'left mouse down':
if block_pick == 1:
Block(position=self.position + mouse.normal, texture=grass_block_texture)
if block_pick == 2:
Block(position=self.position + mouse.normal, texture=stone_texture)
if block_pick == 3:
Block(position=self.position + mouse.normal, texture=dirt_texture)
if block_pick == 4:
Block(position=self.position + mouse.normal, texture=wood_texture)
if block_pick == 5:
Block(position=self.position + mouse.normal, texture=sand_texture)
if key == 'right mouse down':
destroy(self)
# Класс игрока
class Player(Entity):
def __init__(self):
super().__init__(
parent=camera.ui,
model='cube',
origin_y=-0.5,
collider='box',
scale=2,
position=(0, 0, 0),
rotation=(0, 0, 0))
self.speed = 5
self.jump_height = 2
self.gravity = 1
self.y_velocity = 0
self.grounded = False
def update(self):
self.direction = Vec3(
camera.right * (held_keys['d'] - held_keys['a'])
+ camera.forward * (held_keys['w'] - held_keys['s'])
).normalized()
if held_keys['space'] and self.grounded:
self.y_velocity = self.jump_height
self.grounded = False
if not self.grounded:
self.y_velocity -= self.gravity * time.dt
self.position += self.direction * self.speed * time.dt
self.position += Vec3(0, self.y_velocity, 0) * time.dt
if self.position.y < 1:
self.position = Vec3(self.position.x, 1, self.position.z)
self.y_velocity = 0
self.grounded = True
camera.position = self.position
camera.z = self.position.z - 3
camera.y = self.position.y + 1.5
pygame.time.delay(3000)
def generate_terrain():
global water
terrain_width = 32
terrain_height = 8
for x in range(-terrain_width // 2, terrain_width // 2):
for z in range(-terrain_width // 2, terrain_width // 2):
y = int(math.sin(x / 5) * math.cos(z / 5) * terrain_height) + 1
Block(position=(x, y, z), texture=grass_block_texture)
for i in range(1, random.randint(1, 3)):
Block(position=(x, y - i, z), texture=dirt_texture)
Block(position=(x, y - 3, z), texture=stone_texture)
if y <= 2:
water = Entity(model='cube', scale=(terrain_width, 1, terrain_width), position=(0, 0, 0),
color=color.rgba(0, 0, 255, 0.5), texture=water_texture)
def generate_trees():
for i in range(10):
x = random.randint(-15, 15)
z = random.randint(-15, 15)
y = int(math.sin(x / 5) * math.cos(z / 5) * 8) + 2
height = random.randint(4, 7)
for j in range(height):
Block(position=(x, y + j, z), texture=wood_texture)
leaves_size = random.randint(3, 5)
leaf = Block(position=(x, y + height, z), texture=leaves_texture)
leaf.scale = leaves_size
def input(key):
global block_pick
if key == '1':
block_pick = 1
if key == '2':
block_pick = 2
if key == '3':
block_pick = 3
if key == '4':
block_pick = 4
if key == '5':
block_pick = 5
print('Выбран блок:', block_pick)
generate_terrain()
generate_trees()
well = Entity(model='cube', scale=(3, 3, 3), position=(5, 1.5, 5), texture=wood_texture)
clock.tick(200)
player = Player()
app.run()import ursina
from ursina import *
import random
import math
app = Ursina()
# Оптимизация 1: Предзагрузка всех текстур один раз
textures = {
1: load_texture('i-_3_.png'), # grass
2: load_texture('stone.png'), # stone
3: load_texture('wood.png'), # dirt (исправлено название)
4: load_texture('dirt.png'), # wood (исправлено название)
5: load_texture('sand.png'), # sand
6: load_texture('leaves.png'), # leaves
}
# Оптимизация 2: Кэш для блоков и система чанков
class Chunk:
def init(self, position):
self.position = position
self.blocks = []
def add_block(self, position, texture_id):
block = Block(position=position, texture_id=texture_id)
self.blocks.append(block)
return block
chunks = {}
active_chunks = set()
def get_chunk_position(world_pos):
return (int(world_pos[0] // 16), int(world_pos[2] // 16))
# Оптимизация 3: Упрощенный класс блока с кэшированием
class Block(Button):
def init(self, position=(0, 0, 0), texture_id=1):
super().__init__(
parent=scene,
position=position,
model='cube',
origin_y=0.5,
texture=textures[texture_id],
color=color.white,
highlight_color=color.lime,
collider='box'
)
self.texture_id = texture_id
def input(self, key):
if self.hovered:
if key == 'left mouse down':
chunk_pos = get_chunk_position(self.position + mouse.normal)
if chunk_pos not in chunks:
chunks[chunk_pos] = Chunk(chunk_pos)
chunks[chunk_pos].add_block(self.position + mouse.normal, block_pick)
if key == 'right mouse down':
destroy(self)
# Удаляем из кэша чанка
chunk_pos = get_chunk_position(self.position)
if chunk_pos in chunks and self in chunks[chunk_pos].blocks:
chunks[chunk_pos].blocks.remove(self)
# Оптимизация 4: Улучшенный класс игрока с более эффективной физикой
class Player(Entity):
def init(self):
super().__init__(
parent=camera.ui,
model='cube',
origin_y=-0.5,
collider='box',
scale=(0.8, 1.8, 0.8),
position=(0, 10, 0)
)
self.speed = 8
self.jump_height = 4
self.gravity = 25
self.y_velocity = 0
self.grounded = False
self.sensitivity = 100
camera.parent = self
camera.position = (0, 1.6, 0)
camera.rotation = (0, 0, 0)
mouse.locked = True
def update(self):
# Более эффективное управление
move_direction = Vec3(0, 0, 0)
if held_keys['w']: move_direction += camera.forward
if held_keys['s']: move_direction += camera.back
if held_keys['a']: move_direction += camera.left
if held_keys['d']: move_direction += camera.right
move_direction.y = 0
if move_direction.length() > 0:
move_direction = move_direction.normalized()
self.position += move_direction self.speed time.dt
# Оптимизированная физика прыжка и гравитации
if held_keys['space'] and self.grounded:
self.y_velocity = self.jump_height
self.grounded = False
if not self.grounded:
self.y_velocity -= self.gravity * time.dt
self.y += self.y_velocity * time.dt
# Проверка земли
ray = raycast(self.position, Vec3(0, -1, 0), distance=1.1, ignore=[self])
if ray.hit:
self.grounded = True
self.y_velocity = 0
self.y = ray.world_point.y + 1
else:
self.grounded = False
def input(self, key):
if key == 'escape':
mouse.locked = not mouse.locked
# Оптимизация 5: Эффективная генерация террейна с LOD
def generate_terrain():
terrain_size = 24
height_variation = 6
for x in range(-terrain_size, terrain_size):
for z in range(-terrain_size, terrain_size):
# Упрощенная генерация высоты
height = int((math.sin(x 0.3) + math.cos(z 0.3)) * height_variation) + 3
chunk_pos = get_chunk_position((x, height, z))
if chunk_pos not in chunks:
chunks[chunk_pos] = Chunk(chunk_pos)
# Создаем колонну блоков
chunks[chunk_pos].add_block((x, height, z), 1) # Трава
for y_offset in range(1, 4):
chunks[chunk_pos].add_block((x, height - y_offset, z), 3) # Земля
chunks[chunk_pos].add_block((x, height - 4, z), 2) # Камень
# Оптимизация 6: Улучшенная генерация деревьев
def generate_trees():
for _ in range(8): # Уменьшено количество деревьев
x = random.randint(-12, 12)
z = random.randint(-12, 12)
base_height = int((math.sin(x 0.3) + math.cos(z 0.3)) * 6) + 4
# Генерация ствола
trunk_height = random.randint(3, 5)
for y_offset in range(trunk_height):
chunk_pos = get_chunk_position((x, base_height + y_offset, z))
if chunk_pos not in chunks:
chunks[chunk_pos] = Chunk(chunk_pos)
chunks[chunk_pos].add_block((x, base_height + y_offset, z), 4)
# Генерация листвы
leaf_radius = 2
for lx in range(-leaf_radius, leaf_radius + 1):
for lz in range(-leaf_radius, leaf_radius + 1):
for ly in range(2):
if abs(lx) + abs(lz) + abs(ly) <= leaf_radius + 1:
chunk_pos = get_chunk_position((x + lx, base_height + trunk_height + ly, z + lz))
if chunk_pos not in chunks:
chunks[chunk_pos] = Chunk(chunk_pos)
chunks[chunk_pos].add_block((x + lx, base_height + trunk_height + ly, z + lz), 6)
# Управление выбором блоков
block_pick = 1
def input(key):
global block_pick
if key in '12345':
block_pick = int(key)
print(f'Выбран блок: {block_pick}')
# Оптимизация 7: Удаление неиспользуемого кода и зависимостей
# Убраны: pygame, numba, numpy - они не используются в основном коде
# Запуск игры
generate_terrain()
generate_trees()
player = Player()
# Включение FPS счетчика для мониторинга производительности
window.fps_counter.enabled = True
app.run()