使用Ursina引擎开发Minecraft时纹理加载失败及'int'对象不可调用错误
Ursina引擎Minecraft类游戏问题修复:纹理加载失败与'int'不可调用错误
1. 修复「'int' object is not callable」错误
错误根源在mesh_terrain.py第17行的e.texture.width():Ursina引擎中,Texture对象的width是属性而非可调用方法,直接访问即可,不需要加括号。原代码把整数类型的width当作函数调用,触发类型错误。
修改这一行:
# 错误写法 e.texture_scale*=64/e.texture.width() # 正确写法 e.texture_scale *= 64 / e.texture.width
2. 修复实体纹理无法加载问题
针对纹理不显示的问题,从以下几点排查修复:
- 确保纹理路径正确:将
texture_atlas_3.png放在Ursina项目的assets文件夹下(默认资源目录),如果文件在子目录,要写完整相对路径(比如textures/texture_atlas_3.png)。 - 修正UV坐标计算:原代码中直接给UV加固定值不符合纹理 atlas 的坐标逻辑,需要按 atlas 的格子比例计算。假设你的 atlas 是64x64像素,每个格子是8x8像素(对应64/8=8个格子),那么每个格子的UV单位是
1/8=0.125,正确的UV偏移应该按比例计算。 - 确保Mesh正确生成:修改完vertices和uvs后,必须调用
model.generate()更新Mesh,原代码中genTerrain方法最后已包含这一步,保持即可。
修改后的完整代码
mesh_terrain.py
from random import randrange from ursina import * class MeshTerrain: def __init__(this): this.block = load_model('block.obj') this.textureAtlas = 'texture_atlas_3.png' this.subsets = [] this.numSubsets = 1 this.subWidth = 32 this.grid_size = 8 # 纹理 atlas 的格子数量,根据实际情况调整 for i in range(this.numSubsets): e = Entity(model=Mesh(), texture=this.textureAtlas) # 修复width调用方式 e.texture_scale *= 64 / e.texture.width this.subsets.append(e) def genBlock(this, x, y, z): model = this.subsets[0].model model.vertices.extend([Vec3(x, y, z) + v for v in this.block.vertices]) # 修正UV坐标计算,适配纹理 atlas uu = 8 / this.grid_size # 草方块在atlas中的横向位置(从0开始计数的话调整数值) uv = 7 / this.grid_size # 草方块在atlas中的纵向位置 # 按格子比例缩放原始UV model.uvs.extend([Vec2(uu, uv) + u * (1/this.grid_size) for u in this.block.uvs]) def genTerrain(this): x = 0 z = 0 d = int(this.subWidth * 0.5) for k in range(-d, d): for j in range(-d, d): y = randrange(-1, 1) this.genBlock(x + k, y, z + j) this.subsets[0].model.generate()
main.py
from ursina import * from ursina.prefabs.first_person_controller import FirstPersonController from mesh_terrain import MeshTerrain app = Ursina() window.color = color.rgb(200, 0, 255) subject = FirstPersonController() subject.gravity = 0.0 terrain = MeshTerrain() def update(): pass # updateTerrain() terrain.genTerrain() app.run()
内容的提问来源于stack exchange,提问作者Selwyn Bredesen
相关产品推荐
相关产品推荐

