You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

我的世界克隆版中无法破坏地形生成方块的问题求助

我的世界克隆版中无法破坏地形生成方块的问题求助

Hey,我看了你的代码,马上就找到问题根源啦!你现在右键点击方块没反应,本质是每帧都在重复生成同一区域的方块——刚把方块删掉,下一帧update就自动补回来了,所以看起来好像啥都没发生。另外还有几个小细节得调整,我给你一步步拆解:

问题核心分析

  • 重复生成方块:你的generate_terrain函数在update里每帧都会执行,完全不检查目标位置有没有已经存在的方块,导致同一个坐标会被反复创建新的Voxel实例。右键删掉一个,下一帧立刻又生成一个新的在原地,自然看不到变化。
  • 多余的self in chunks判断:这个不是主因,但其实没必要做这个检查——只要你点击的是当前这个方块实例,直接销毁并从列表移除就行,多此一举的判断反而可能引入潜在问题。

修复后的完整代码

我给你调整了代码,主要加了一个坐标集合来记录已生成的方块,避免重复创建;同时优化了破坏方块的逻辑,确保删掉后不会自动恢复:

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 = []
generated_positions = set()  # 新增:记录已生成方块的坐标
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':
                new_pos = self.position + mouse.normal
                # 放置方块前先检查坐标是否已存在
                if new_pos not in generated_positions:
                    voxel = Voxel(position=new_pos)
                    chunks.append(voxel)
                    generated_positions.add(new_pos)
            elif key == 'right mouse down':
                # 移除坐标记录,直接销毁方块并从chunks删除
                generated_positions.remove(self.position)
                chunks.remove(self)
                destroy(self)

def generate_terrain(player):
    """Generate terrain blocks around the player."""
    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)
        pos = (x, y, z)
        
        # 只有坐标未生成过才创建方块
        if pos not in generated_positions:
            voxel = Voxel(position=pos)
            chunks.append(voxel)
            generated_positions.add(pos)

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:
            generated_positions.remove((chunk.x, chunk.y, chunk.z))  # 同步移除坐标记录
            destroy(chunk)
            chunks.remove(chunk)
    
    # Generate new terrain
    generate_terrain(player)

Minecraft.run()

关键修改说明

  1. 新增generated_positions集合:用来存储所有已生成方块的坐标,生成前先做检查,彻底避免重复创建同一位置的方块。
  2. 优化放置方块逻辑:左键放方块时也检查坐标,防止出现重叠方块的情况。
  3. 简化右键破坏逻辑:去掉多余的self in chunks判断,直接移除坐标记录、从列表删除实例并销毁方块。
  4. 同步更新超出范围的方块记录:移除超出渲染距离的方块时,同时把对应的坐标从集合中删除,避免下次回到该区域时重复生成。

这样修改后,你右键点击地形生成的方块就能正常破坏了,而且不会自动恢复,放置方块也不会出现重叠问题啦!

备注:内容来源于stack exchange,提问作者Glitched

火山引擎 最新活动