当我运行代码时,玩家周围距离玩家 5m 以内的区域最初能够放置块,这是在放置块下处理的,但是,当我移动并尝试在 5m 半径之外放置块时,块不会放置即使我刚刚复制并粘贴了代码,也将其放在“删除任何不附近的实体上的碰撞器”下,并将其放入一个每当玩家移动时运行的函数中,这应该可以工作。
import math
from ursina import *
from ursina.prefabs.first_person_controller import FirstPersonController
from perlin_noise import PerlinNoise
import random
from distance_calc import distance_calc
noise = PerlinNoise(octaves=5, seed=random.randint(-1000000000000, 10000000000))
optimal_distance = 5
#set up app
app = Ursina()
# VARAIBLES
selected_block = "grass"
water = load_texture("assets/water.jpg"),
# TEXTURES
block_textures = {
'grass': load_texture("assets/grass.jpg"),
'dirt': load_texture("assets/dirt.jpg"),
'stone': load_texture("assets/stone.jpg"),
'bedrock': load_texture("assets/bedrock.jpg"),
'faux_bedrock': load_texture("assets/bedrock.jpg"),
'cobblestone': load_texture("assets/cobblestone.jpg")
}
# CREATE PLAYER
player = FirstPersonController(
mouse_sensitivity=Vec2(100, 100),
scale=0.85,
position=(0, 25, 0)
)
class Block(Entity):
def input(self, key):
if key == "w" or key == "a" or key == "s" or key == "d":
# UPDATING THE COLLIDERS WHEN PLAYER MOVES
self.distance_from_player = distance_calc(player.x, player.y, player.z, self.x, self.y, self.z)
if self.distance_from_player < optimal_distance:
self.collider = "box"
else:
self.collider = None
# UPDATING THE VIEWING WHEN PLAYER MOVES
if self.distance_from_player < 10:
self.visible = True
else:
self.visible = False
def __init__(self, position, block_type):
super().__init__(
position=position,
model="cube",
scale=1,
origin_y=-0.5,
texture=block_textures.get(block_type),
)
self.block_type = block_type
# OTIMIZATION
# REMOVING COLLIDERS ON ANY ENTITIES THAT ARE NOT NEAR
self.distance_from_player = distance_calc(player.x, player.y, player.z, self.x, self.y, self.z)
if self.distance_from_player < optimal_distance:
self.collider ="box"
else:
self.collider = None
# SETTING VIEWING DISTANCE TO 10 SO ANY ENTITIES FURTHER ARE NOT SHOWN
if self.distance_from_player < 10:
self.visible = True
else:
self.visible = False
mini_block = Entity(
parent=camera,
model="cube",
scale=0.2,
origin_y=-0.5,
texture=block_textures.get(selected_block),
collider="box",
position = (0.3, -0.25, 0.45),
)
# GROUND
ground = Entity(
model = 'plane',
scale = (100, 1, 100),
texture = "water",
texture_scale = (100, 100),
collider = "box",
block_type = "water",
position=(0,-5, 0),
)
#PLACING BLOCK
def input(key):
global selected_block
#place block
if key == "right mouse down":
hit_info = raycast(camera.world_position, camera.forward, distance=10)
if hit_info.hit:
block = Block(hit_info.entity.position + hit_info.normal, selected_block)
#place block
if key == "left mouse down" and mouse.hovered_entity:
if not mouse.hovered_entity.block_type == "bedrock":
if not mouse.hovered_entity.block_type == "water":
destroy(mouse.hovered_entity)
#BLOCK CHOOSER
if key=="1":
selected_block = "grass"
if key=="2":
selected_block = "stone"
if key=="3":
selected_block = "faux_bedrock"
if key=="4":
selected_block = "cobblestone"
# TERRAIN
min_height = -2
for x in range (-25, 25):
for z in range(-25, 25):
height = noise([x*0.02, z*0.02])
height = math.floor(height * 7.5)
for y in range(height, min_height -1, -1):
if y == min_height:
block = Block((x,y + min_height, z), "bedrock")
elif y == height:
block = Block((x,y + min_height, z), "grass")
elif height - y > 2:
block = Block((x,y + min_height, z), "stone")
else:
block = Block((x,y + min_height, z), "dirt")
def update():
mini_block.texture = block_textures.get(selected_block)
# RUN APP
app.run()
这里有一个关于如何优化 Minecraft 克隆的视频(以 ursina 为例)https://www.youtube.com/watch?v=SABBMIVxMkA
已经有很多基于此的 Minecraft 克隆,例如 https://github.com/hypercubed-music/ursina_minecraft_clone;
https://github.com/a2cy/CubePixel;#这两个仅适用于C++转换器
https://bitbucket.org/experimentfailed/testcraft_ursina/;#但是我的效果不太好,所以我必须将 C++ 和 Cython 转换为 Python,然后它就可以工作了。
https://github.com/SirDank/dank.tool #《世界剥削游戏》也是以此为基础的
我目前正在开发一个,但它距离完成还很远,还有三个错误需要修复,我需要一个更好的采矿/建筑系统:
https://github.com/Raphi-2Code/Voxel-Engine-Ursina
还有ursina的开发者Petter Amland(pokepetter)也做了一个这样的小游戏,它是闭源的,但是他的X博客上有截图。
我希望这是一套很好的代码,可以产生新的想法。
祝你的项目顺利👍