Untitled

Anonymous
plain_text
02/12/2026 11:45 AM
7.5 KB
13
Indexable
# Minecraft-like Prototype (Educational, Simplified)
# This is NOT a full Minecraft clone. It is a small voxel sandbox demo
# showing terrain, biomes, water, simple mobs, and respawn logic.
# Requires: pip install ursina

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

app = Ursina()
window.title = 'MiniCraft Prototype'
window.borderless = False
window.exit_button.visible = False

# -------------------------
# Block Textures
# -------------------------
textures = {
    'grass': 'white_cube',
    'dirt': 'white_cube',
    'stone': 'white_cube',
    'sand': 'white_cube',
    'water': 'white_cube',
    'wood': 'white_cube',
    'leaf': 'white_cube'
}

colors_map = {
    'grass': color.green,
    'dirt': color.rgb(120,72,0),
    'stone': color.gray,
    'sand': color.yellow,
    'water': color.azure,
    'wood': color.rgb(100,60,20),
    'leaf': color.lime
}

# -------------------------
# Block Class
# -------------------------
class Block(Button):
    def __init__(self, position=(0,0,0), block_type='grass'):
        super().__init__(
            parent=scene,
            position=position,
            model='cube',
            origin_y=0.5,
            texture=textures[block_type],
            color=colors_map[block_type],
            scale=1
        )
        self.block_type = block_type

    def input(self, key):
        if self.hovered:
            if key == 'left mouse down':
                destroy(self)
            if key == 'right mouse down':
                new_pos = self.position + mouse.normal
                bt = inventory.current
                Block(position=new_pos, block_type=bt)

# -------------------------
# Simple Mob
# -------------------------
class Mob(Entity):
    def __init__(self, position):
        super().__init__(
            model='cube',
            color=color.red,
            scale=0.9,
            position=position
        )
        self.speed = random.uniform(0.5, 1.5)

    def update(self):
        self.x += random.uniform(-1,1) * time.dt * self.speed
        self.z += random.uniform(-1,1) * time.dt * self.speed
        if distance(self.position, player.position) < 1.5:
            player.damage(10)

# -------------------------
# Player with Respawn
# -------------------------
class Player(FirstPersonController):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.health = 100
        self.spawn_point = Vec3(0, 20, 0)

    def damage(self, amount):
        self.health -= amount
        if self.health <= 0:
            self.respawn()

    def respawn(self):
        self.position = self.spawn_point
        self.health = 100

player = Player(y=20)

# -------------------------
# Inventory
# -------------------------
class Inventory:
    def __init__(self):
        self.blocks = ['grass','dirt','stone','sand','wood','leaf','water']
        self.index = 0

    @property
    def current(self):
        return self.blocks[self.index]

    def next(self):
        self.index = (self.index + 1) % len(self.blocks)

inventory = Inventory()

# -------------------------
# Biome + Terrain Generation
# -------------------------
size = 40
water_level = 3


def biome_height(x,z):
    h = int(5 + 4 * noise([x*0.05, z*0.05]))
    return h


def biome_type(x,z):
    n = noise([x*0.02+100, z*0.02+100])
    if n < -0.2:
        return 'desert'
    elif n < 0.2:
        return 'plains'
    else:
        return 'forest'


for x in range(-size, size):
    for z in range(-size, size):
        h = biome_height(x,z)
        b = biome_type(x,z)

        for y in range(h):
            if y == h-1:
                if b == 'desert':
                    bt = 'sand'
                else:
                    bt = 'grass'
            elif y > h-4:
                bt = 'dirt'
            else:
                bt = 'stone'
            Block(position=(x,y,z), block_type=bt)

        if h <= water_level:
            for y in range(h, water_level+1):
                Block(position=(x,y,z), block_type='water')

        if b == 'forest' and random.random() < 0.05:
            th = random.randint(3,5)
            for ty in range(th):
                Block(position=(x,h+ty,z), block_type='wood')
            for lx in range(-2,3):
                for lz in range(-2,3):
                    for ly in range(2):
                        if random.random() < 0.7:
                            Block(position=(x+lx,h+th+ly,z+lz), block_type='leaf')

# -------------------------
# Lakes & Rivers
# -------------------------
for _ in range(6):
    cx = random.randint(-size,size)
    cz = random.randint(-size,size)
    r = random.randint(3,6)
    for x in range(cx-r, cx+r):
        for z in range(cz-r, cz+r):
            if (x-cx)**2 + (z-cz)**2 < r*r:
                Block(position=(x,water_level,z), block_type='water')

for _ in range(3):
    x = random.randint(-size,size)
    for z in range(-size,size):
        Block(position=(x,water_level,z), block_type='water')

# -------------------------
# Spawn Mobs
# -------------------------
mobs = []
for _ in range(12):
    m = Mob(position=(random.randint(-20,20),10,random.randint(-20,20)))
    mobs.append(m)

# -------------------------
# UI
# -------------------------
block_text = Text(text='Block: grass', position=(-0.85,0.45))
health_text = Text(text='Health: 100', position=(-0.85,0.40))


def update():
    if held_keys['tab']:
        inventory.next()
        block_text.text = f'Block: {inventory.current}'
    health_text.text = f'Health: {player.health}'

app.run()
Editor is loading...
Leave a Comment