-
Notifications
You must be signed in to change notification settings - Fork 65
Open
Description
EDIT: Just realized this was in a later part, whoops (Different method I suppose?)
I'm on fire today and wanted a better system to generate chunks than to constantly press "g", and that was to generate chunks similar to how Minecraft handles it's chunk generation.
By telling the system to generate only when the player has moved a distance.
Note, that this system is not perfected and I would like the swirl engine take into account the players direction (i.e. north, south, east, etc) and swirl from that starting position, I just haven't figured out a way to implement it (and the player move detection really needs to be improved).
(Note: My files are named differently and vise versa for my variables)
main.py
from ursina import *
from ursina.prefabs.first_person_controller import FirstPersonController
from terrain import MeshTerrain
from swirl_chunks import SwirlEngine
mc = Ursina()
window.color = color.rgb(75, 175, 255)
sky = Sky()
sky.color = window.color
window.borderless = False
window.exit_button.visible = False
camera.fov = 90
scene.fog_density = 0.03
scene.fog_color = color.rgb(50, 125, 200)
mouse.locked = True
player = FirstPersonController()
player.gravity = 0
player.cursor.visible = False
g_terrain = MeshTerrain()
g_terrain.gen_terrain() # Give the player a starting platform than to just fall into the void
plr_old_x = player.X
plr_old_z = player.Z
def update():
global plr_old_x, plr_old_z # Really preferred to not use a global statement but I wasn't sure how else to implement it
dist_x = floor(plr_old_x - player.x)
dist_z = floor(plr_old_z - player.z)
# print(f"x: {dist_x}")
# print(f"z: {dist_z}")
if dist_x < -1 or dist_x > 0 or dist_z < -1 or dist_z > 0:
plr_old_x = player.X
plr_old_z = player.Z
g_terrain.gen_terrain()
else:
plr_old_x = player.X
plr_old_z = player.Z
block_found = False
step = 2
height = 1
x = str(floor(player.x + 0.5))
y = floor(player.y + 0.5)
z = str(floor(player.z + 0.5))
for i in range(-step, step):
if g_terrain.terrain_dict.get("x" + x + "-y" + str(y + i) + "-z" + z):
if g_terrain.terrain_dict.get("x" + x + "-y" + str(y + i) + "-z" + z)[0]:
# print(f"[INFO] Terrain recorded at {x}, {y}, {z}")
target = y + i + height
block_found = True
break
if block_found:
player.y = lerp(player.y, target, 6 * time.dt)
else:
player.y -= 9.8 * time.dt
mc.run()
swirl_chunks.py
from ursina import Vec2
class SwirlEngine:
def __init__(self, sub_width):
self.sub_width = sub_width
self.run = 1
self.iteration = 0
self.iter_limit = 4
self.count = 0
self.pos = Vec2(0, 0)
self.current_dir = 0
self.dir = [Vec2(0, 1), Vec2(1, 0), Vec2(0, -1), Vec2(-1, 0)]
def change_dir(self):
if self.current_dir < 3:
self.current_dir += 1
else:
self.current_dir = 0
self.iteration += 1
if self.current_dir < 2:
self.run = (self.iteration * 2) - 1
else:
self.run = (self.iteration * 2)
def move(self):
if self.iteration < self.iter_limit:
if self.count < self.run:
self.pos.x += self.dir[self.current_dir].x * self.sub_width
self.pos.y += self.dir[self.current_dir].y * self.sub_width
self.count += 1
else:
self.count = 0
self.change_dir()
self.move()
terrain.py
from ursina import Entity, load_model, Mesh, Vec3, Vec2, floor, Vec4
from ursina.shaders import lit_with_shadows_shader
from perlin import Perlin
from swirl_chunks import SwirlEngine
class MeshTerrain:
def __init__(self):
self.block = load_model("block.obj")
self.atlas = "atlas.png"
self.subsets = []
self.subset_limit = 512
self.sub_width = 16 # Must be even
self.swirl_engine = SwirlEngine(self.sub_width)
self.current_subset = 0
self.terrain_dict = {}
self.p_noise = Perlin()
for i in range(0, self.subset_limit):
ent = Entity(model=Mesh(), texture=self.atlas)
ent.texture_scale *= 64 / ent.texture.width
self.subsets.append(ent)
def gen_block(self, x, y, z):
from random import random
uu = 8
uv = 7
model = self.subsets[self.current_subset].model
model.vertices.extend([Vec3(x, y, z) + v for v in self.block.vertices])
# Biome temp hardcoded until I figure how to implement a proper heatmap
if y > 2:
self.terrain_dict["x" + str(floor(x)) + "-y" + str(floor(y)) + "-z" + str(floor(z))] = [True, "Cool"] # [Terrain? True | Yes, False | No, Biome Temperature? Warm? Cold? Hot?]
uu = 8
uv = 6
else:
self.terrain_dict["x" + str(floor(x)) + "-y" + str(floor(y)) + "-z" + str(floor(z))] = [True, "Warm"]
color = random() - 0.5
model.colors.extend((Vec4(1-color, 1-color, 1-color, 1),) * len(self.block.vertices))
model.uvs.extend([Vec2(uu, uv) + u for u in self.block.uvs])
def gen_terrain(self):
x = floor(self.swirl_engine.pos.x)
z = floor(self.swirl_engine.pos.y)
dist = int(self.sub_width * 0.5)
for _x in range(-dist, dist):
for _z in range(-dist, dist):
n_x, n_z = x + _x, z + _z
# y = self.p_noise.get_height(n_x, n_z)
y = floor(self.p_noise.get_height(n_x, n_z))
if not self.terrain_dict.get("x" + str(n_x) + "-y" + str(y) + "-z" + str(n_z)):
self.gen_block(n_x, y, n_z)
self.subsets[self.current_subset].model.generate()
if self.current_subset < self.subset_limit - 1:
self.current_subset += 1
else:
self.current_subset = 0
if self.swirl_engine.iteration == self.swirl_engine.iter_limit:
self.swirl_engine.iteration = 0
else:
self.swirl_engine.move()
Metadata
Metadata
Assignees
Labels
No labels