Python
from ursina import *
from ursina.prefabs.first_person_controller import FirstPersonController
import random

app = Ursina()

# --- Текстуры (можно заменить на свои) ---
grass_top = 'textures/grass_top.png'
grass_side = 'textures/grass_side.png'
dirt = 'textures/dirt.png'
stone = 'textures/stone.png'
wood = 'textures/wood.png'
leaves = 'textures/leaves.png'

# --- Список блоков для выбора ---
block_types = [grass_side, dirt, stone, wood, leaves]
current_block = 0

# --- Функция создания блока ---
def create_block(position, texture=grass_side):
    return Entity(
        model='cube',
        texture=texture,
        position=position,
        collider='box',
        origin_y=0.5,
        scale=1
    )

# --- Генерация мира (плоский + холмы) ---
world_size = 20
for x in range(-world_size, world_size):
    for z in range(-world_size, world_size):
        # Простая высота на основе шума
        y = int((random.random() + random.random()) * 2)
        for h in range(y + 1):
            tex = grass_side if h == y else dirt
            create_block((x, h, z), tex)

# --- Деревья ---
for _ in range(15):
    tx = random.randint(-world_size + 2, world_size - 2)
    tz = random.randint(-world_size + 2, world_size - 2)
    # Ствол
    for i in range(4):
        create_block((tx, i + 1, tz), wood)
    # Крона
    for dx in range(-2, 3):
        for dz in range(-2, 3):
            for dy in range(0, 3):
                if random.random() > 0.2:
                    create_block((tx + dx, 5 + dy, tz + dz), leaves)

# --- Игрок ---
player = FirstPersonController()
player.cursor.color = color.white
player.cursor.scale = 10

# --- Подсказка ---
Text(
    text='WASD — движение | ЛКМ — сломать | ПКМ — поставить | 1-5 — блок | ESC — выход',
    origin=(0, 0),
    y=0.45,
    scale=0.8,
    color=color.yellow
)

# --- Логика ломания/постановки блоков ---
class Voxel(Button):
    def __init__(self, position=(0,0,0), texture=grass_side):
        super().__init__(
            parent=scene,
            model='cube',
            texture=texture,
            position=position,
            collider='box',
            origin_y=0.5,
            scale=1,
            color=color.white
        )

    def input(self, key):
        global current_block
        if self.hovered:
            if key == 'left mouse down':
                destroy(self)                    # ломаем блок
            if key == 'right mouse down':
                # ставим блок рядом
                Voxel(position=self.position + mouse.normal,
                      texture=block_types[current_block])

# --- Заменяем статичные блоки на интерактивные ---
for e in scene.entities:
    if hasattr(e, 'model') and e.model and e.model.name == 'cube' and e != player:
        pos = e.position
        tex = e.texture
        destroy(e)
        Voxel(position=pos, texture=tex)

# --- Выбор блока клавишами 1-5 ---
def input(key):
    global current_block
    if key == '1': current_block = 0
    if key == '2': current_block = 1
    if key == '3': current_block = 2
    if key == '4': current_block = 3
    if key == '5': current_block = 4

# --- Небо ---
Sky(color=color.rgb(135, 206, 235))

app.run()

майн.

Sign in to react