我的世界克隆版中无法破坏地形生成方块的问题求助
我的世界克隆版中无法破坏地形生成方块的问题求助
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()
关键修改说明
- 新增
generated_positions集合:用来存储所有已生成方块的坐标,生成前先做检查,彻底避免重复创建同一位置的方块。 - 优化放置方块逻辑:左键放方块时也检查坐标,防止出现重叠方块的情况。
- 简化右键破坏逻辑:去掉多余的
self in chunks判断,直接移除坐标记录、从列表删除实例并销毁方块。 - 同步更新超出范围的方块记录:移除超出渲染距离的方块时,同时把对应的坐标从集合中删除,避免下次回到该区域时重复生成。
这样修改后,你右键点击地形生成的方块就能正常破坏了,而且不会自动恢复,放置方块也不会出现重叠问题啦!
备注:内容来源于stack exchange,提问作者Glitched




