已完成功能
- 放置与挖掘:玩家能够放置和挖掘方块,构建和改变游戏世界。
- 简单生物:游戏中已引入了一些简单的生物,为玩家提供互动和挑战。自行增加其它生物逻辑
- 第一人称视角:玩家可通过第一人称视角来探索游戏世界,增强沉浸感。
- 随机地形生成:使用算法Perlin Noise生成随机地形
- 光影效果:虽然当前的光影效果可能不够理想,但已初步实现,为后续优化提供了基础。
待完成功能
- 背包系统:玩家需要一个背包来存储和管理收集到的物品。
- 工作台:工作台是玩家制作和合成新物品的关键工具。
- 天气系统:引入天气变化,如晴天、雨天、雪天等,为游戏世界增添更多动态元素。
- 昼夜循环:实现昼夜循环,让游戏世界随时间变化而呈现出不同的风貌。
代码部分
from ursina import *
from ursina.prefabs.first_person_controller import FirstPersonController
from perlin_noise import PerlinNoise
from ursina.shaders import lit_with_shadows_shader
app=Ursina()
Entity.default_shader = lit_with_shadows_shader
sth=[]
xzblock=""
ok1=-1
class bag_fullnormal_block(Entity):
def __init__(self,position=(0,0,0),texture1="grass"):
super().__init__(parent = scene,model="cube",position=position+(0,-0.2,0),texture1=texture1,texture=texture1,collider='box')
self.gravity=True
def update(self):
self.animate('rotation_y', self.rotation_y+360, duration=2, curve=curve.in_out_expo)
self.animate('rotation_z', self.rotation_z+360, duration=2, curve=curve.in_out_expo)
self.animate('rotation_x', self.rotation_x+360, duration=2, curve=curve.in_out_expo)
self.scale=(0.2,0.2,0.2)
if self.intersects(player).hit:
sth.append(self.texture1)
destroy(self)
elif self.gravity:
hit_info = raycast(origin=self.position, direction=(0, -1, 0), distance=0.5, ignore=[camera,self], debug=False)
if not hit_info.hit:
self.y=self.y-1*time.dt
else:
pass
class block(Button):
def __init__(self,position=(0,0,0),texture="white_cube",highlight_color=color.green,texture1="grass"):
super().__init__(parent = scene,position=position,model="cube",texture=texture,color=color.color(0,0,random.uniform(0.9,1)),highlight_color=highlight_color,texture1=texture1)
def input(self,key):
global xzblock,sth,ok1
if self.hovered:
if key == "left mouse down":
bag_fullnormal_block(position=self.position,texture1=self.texture1)
#sth.append(self.texture1)
destroy(self)
if key == "right mouse down":
if not xzblock=="":
if not ok1==-1:
sth.pop(ok1)
ok1=-1
b3=block(position=self.position+mouse.normal,texture=xzblock,highlight_color=color.light_gray,texture1=xzblock)
xzblock=""
class physblock(Button):
def __init__(self,position=(0,0,0),highlight_color=color.green,scale=(1,1,1),phys_once=False,gravity=True):
super().__init__(parent = scene,position=position,model="cube",texture=texture,color=color.green,highlight_color=highlight_color,scale=scale,phys_once=phys_once,gravity=gravity)
self.traverse_target = scene
self.height = self.scale_y
self.ignore_list = [self, ]
def update(self):
if self.gravity:
self.hit_info = raycast(origin=self.position, direction=(0, -1, 0), distance=0.5, ignore=[camera,self], debug=False)
if not self.hit_info.hit:
self.y=self.y-1*time.dt
else:
pass
def input(self,key):
if self.hovered:
if key == "left mouse down":
destroy(self)
class biology(Entity):
def __init__(self,position=(0,0,0),highlight_color=color.green,scale=(1,1,1),phys_once=False,gravity=True):
super().__init__(parent = scene,position=position,model="cube",texture=texture,color=color.green,highlight_color=highlight_color,scale=scale,phys_once=phys_once,gravity=gravity)
self.traverse_target = scene
self.height = self.scale_y
self.ignore_list = [self, ]
def update(self):
self.flag=False
if self.gravity:
self.hit_info = boxcast(origin=self.position, direction=(0, -1, 0), distance=0.5, ignore=[camera,self,player], thickness=(1,1), debug=False)
if not self.hit_info.hit:
self.y=self.y-1*time.dt
self.speed=1
self.flag=True
else:
self.speed=1
dist = distance_xz(player.position, self.position)
self.doing=2
if self.doing == 2:
self.look_at_2d(player.position, 'y')
if dist > 1:
self.hit_info1 = raycast(origin=self.position, direction=(0, 0, 1), distance=0.5, ignore=[camera,self,player], debug=False)
if self.hit_info1.hit:
if not self.flag:
self.y=self.y+2
else:
self.position += self.forward * time.dt * self.speed
def input(self,key):
if self.hovered:
if key == "left mouse down":
destroy(self)
n1=PerlinNoise(octaves=3,seed=2023)
scale=24
for x in range(25):
for z in range(25):
b1=block(position=(x-13,0,z-13),texture="grass")
b1.y=floor(n1([x/scale,z/scale])*8)
older = 0
for i in range(-2,int(b1.y)):
older = older + 1
if not older<3:
b4=block(position=(b1.x,int(i),b1.z),texture="dirt",highlight_color=color.light_gray,texture1="dirt")
else:
b4=block(position=(b1.x,int(i),b1.z),texture="stone",highlight_color=color.light_gray,texture1="stone")
biology(position=(4,10,4))
text = Text(text=xzblock, world_scale=100,parent=camera.ui,origin=(-.50, .5), position=(0, -2 * .1))
def input(key):
global xzblock,sth,ok1
if key=='t':
mouse.locked = False
if key=='l':
mouse.locked = True
try:
if key == "z":
xzblock=sth[1-1]
text.text=xzblock
ok1=0
if key == "x":
xzblock=sth[2-1]
text.text=xzblock
ok1=1
if key == "c":
xzblock=sth[3-1]
text.text=xzblock
ok1=2
if key == "v":
xzblock=sth[4-1]
text.text=xzblock
ok1=3
if key == "b":
xzblock=sth[5-1]
text.text=xzblock
ok1=4
if key == "n":
xzblock=sth[6-1]
text.text=xzblock
ok1=5
if key == "m":
xzblock=sth[7-1]
ok1=6
text.text=xzblock
except Exception as e:
print(e)
def update():
global text,xzblock
text.text=xzblock
player = FirstPersonController(model="cube",collider='box')
sun = DirectionalLight(x=17,y=50,z=17)
sun.look_at(Vec3(17,0,17))
sky=Sky()
app.run()
注意事项
- 依赖库安装:请确保已安装ursina游戏引擎和perlin_noise库,它们是游戏开发所必需的。