Ответы

Увеличение кадров и увеличение плавности pygame

Всем привет, написал простенькую игру по типу маинкрафт на базе py game

столкнулся с проблемой оптимизации кадров, всю инфу переискал ничего годного не нашел,

кому не сложно оптимизируйте мой код и проверьте на ошибки если можно)

вот код:

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
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()
По дате
По рейтингу
Аватар пользователя
Ученик
2мес

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()