Glitched
Glitched

Reputation: 1

I can't break terrain generated block in my mincraft clone

When i attempt to break block generated by the terrain generation code nothing happens, no traceback errors nothing happens when i right click on block generated by the terrain generation function. the block are created form the voxel class and appended to the chunks list which is the iterated over by the generate_terrain function. here's the code:
ㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤ

from ursina import *
from numpy import floor
from perlin_noise import PerlinNoise
from ursina.prefabs.first_person_controller import FirstPersonController

RENDER_DISTANCE = 5  # How far to render terrain from player
AMPLITUDE = 8
FREQUENCY = 24
SEED = 42
chunks = []
noise = PerlinNoise(octaves=3, seed=SEED)

Minecraft = Ursina(
            title='Minecraft',
            borderless=False,
            vsync=False,
            show_ursina_splash= True)

player = FirstPersonController()

def input(key):
    if key == 'escape':
        quit()

class Voxel(Button):
    def __init__(self, position=(0,0,0)):
        super().__init__(
            parent=scene,
            position=position,
            model='cube',
            origin_y=0.5,
            texture='white_cube',
            color=color.white,
            highlight_color=color.lime
        )
    
    def input(self, key):
        if self.hovered:
            if key == 'left mouse down':
                Voxel(position=self.position + mouse.normal)
            elif key == 'right mouse down':
                if self in chunks:
                    chunks.remove(self)
                destroy(self)

def generate_terrain(player):
    """Generate terrain blocks around the player."""
    global amp, freq
    for i in range(RENDER_DISTANCE * RENDER_DISTANCE):
        x = floor((i / RENDER_DISTANCE) + player.x - 0.5 * RENDER_DISTANCE)
        z = floor((i % RENDER_DISTANCE) + player.z - 0.5 * RENDER_DISTANCE)
        y = floor(noise([x / FREQUENCY, z / FREQUENCY]) * AMPLITUDE)

        # Create a terrain block using the Voxel class
        voxel = Voxel(position=(x, y, z))
        chunks.append(voxel)

def update():
    # Delete chunks outside render distance
    for chunk in chunks[:]:  # Use slice copy to avoid modification during iteration
        distance = abs(chunk.x - player.x) + abs(chunk.z - player.z)
        if distance > RENDER_DISTANCE * 2:
            destroy(chunk)
            chunks.remove(chunk)
    
    # Generate new terrain
    generate_terrain(player)

Minecraft.run()

Upvotes: 0

Views: 34

Answers (1)

Kxffie
Kxffie

Reputation: 31

I could be wrong on this, and I'm not in a position to test my solution, but I believe the references you have arent being handled correctly. When you are appending new terrain blocks to chunks the Voxel.input() method is not identifying blocks correctly.

class Voxel(Button):
    def __init__(self, position=(0, 0, 0)):
        super().__init__(
            parent=scene,
            position=position,
            model='cube',
            origin_y=0.5,
            texture='white_cube',
            color=color.white,
            highlight_color=color.lime
        )
        chunks[position] = self  # Track this voxel in chunks
    
    def input(self, key):
        if self.hovered:
            if key == 'left mouse down':
                new_position = self.position + mouse.normal
                if new_position not in chunks:  # Avoid duplicating blocks by doing this
                    Voxel(position=new_position)
            elif key == 'right mouse down':
                if self.position in chunks:
                    del chunks[self.position]  # remove from tracking
                destroy(self)

def generate_terrain(player):
    """Generate terrain blocks around the player."""
    global chunks
    for i in range(RENDER_DISTANCE * RENDER_DISTANCE):
        x = floor((i / RENDER_DISTANCE) + player.x - 0.5 * RENDER_DISTANCE)
        z = floor((i % RENDER_DISTANCE) + player.z - 0.5 * RENDER_DISTANCE)
        y = floor(noise([x / FREQUENCY, z / FREQUENCY]) * AMPLITUDE)

        position = (x, y, z)
        if position not in chunks:  # Again, avoid trying to make duplicates
            Voxel(position=position)
    ```

If you are still having issues, here is the discord

https://discord.gg/Rh7Xfd98BU

Upvotes: 0

Related Questions