-
Notifications
You must be signed in to change notification settings - Fork 0
/
Chunk.py
119 lines (110 loc) · 4.63 KB
/
Chunk.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
from Block import Block
from perlin_noise import PerlinNoise
from ursina import *
#Class that builds a chunk
class Chunk():
def __init__(self, chunkSize, startX, startZ, noise, terrainSize):
self.chunkSize = chunkSize
self.startX = startX
self.startZ = startZ
self.blocks = []
self.blocksPos = []
self.currChunk = False
self.noise = noise
self.terrainSize = terrainSize
#Function that builds a chunk of blocks. The functions determines y position of block based on perlin noise value. x and z positions are determined by for loop increment
def buildChunk(self):
for x in range(self.startX, self.startX + self.chunkSize):
for z in range(self.startZ, self.startZ + self.chunkSize):
frequency = 2.5
noise = self.noise([frequency * x/self.terrainSize - 0.5, frequency * z/self.terrainSize - 0.5])
y = round(noise, 1) * 10
self.blocksPos.append([x,y,z])
self.optimizeChunk()
#Function that optimizes the chunk mesh so the performance of the app improves
def optimizeChunk(self):
for blockPos in self.blocksPos:
x = blockPos[0]
y = blockPos[1]
z = blockPos[2]
mesh = self.buildMesh(x,y,z)
color = self.blockType(y)
block = Block((x,y,z),mesh, color)
self.blocks.append(block)
#Function that deletes all blocks in the chunk
def deleteChunk(self):
for block in self.blocks:
destroy(block)
#Function that checks whether player is in this chunk or not
def checkChunkPosition(self, playerX, playerZ):
if(playerX >= self.startX and playerZ >= self.startZ and playerX < self.startX + self.chunkSize and playerZ < self.startZ + self.chunkSize):
return True
return False
#Function that determines what type of block a block is based on y-value
def blockType(self, y):
blockColor = color.rgb(255,255,255)
#ocean
if y < -2:
blockColor = color.rgb(0, 107, 255)
#sand
elif y >= -2 and y < 0:
blockColor = color.rgb(255, 227, 170)
#grass
elif y >= 0 and y < 3:
blockColor = color.rgb(38,148,71)
#mountain
else:
blockColor = color.rgb(124,124,124)
return blockColor
#Function that builds the mesh of the block as well optimizes the block by deleting uneccessary faces of the block.
def buildMesh(self, x, y, z):
#default mesh with only bottom face removed
ourMesh = Mesh(
vertices=[[0,0,0],#0
[1,0,0],#1
[1,0,1],#2
[0,0,1],#3
[0,1,0],#4
[1,1,0],#5
[1,1,1],#6
[0,1,1]#7
],
triangles=[
[0,1,5,4],
[1,2,6,5],
[2,3,7,6],
[3,0,4,7],
[4,5,6,7]
],
normals = [[-1,-1,-1],#0
[1,-1,-1],#1
[1,-1,1],#2
[-1,-1,1],#3
[-1,1,-1],#4
[1,1,-1],#5
[1,1,1],#6
[-1,1,1]#7
],
uvs=[[0,0],[1,0],[1,1],[0,1], [0,0],[1,0],[1,1],[0,1]],
)
#if there is a block to the left of currBlock, remove left face
if [x-1, y, z] in self.blocksPos:
ourMesh.triangles.remove([3,0,4,7])
#if there is a block to the right of currBlock, remove right face
if [x + 1, y, z] in self.blocksPos:
ourMesh.triangles.remove([1,2,6,5])
#if there is a block in front of currBlock, remove front face
if [x, y, z - 1] in self.blocksPos:
ourMesh.triangles.remove([0,1,5,4])
#if there is a block in front of currBlock and above, remove Front face
if [x, y + 1, z - 1] in self.blocksPos:
ourMesh.triangles.remove([0,1,5,4])
#if there is a block behind currBlock, remove back face
if [x, y, z + 1] in self.blocksPos:
ourMesh.triangles.remove([2,3,7,6])
#if there is a block behind currBlock and above it, remove back face
if [x, y + 1, z + 1] in self.blocksPos:
ourMesh.triangles.remove([2,3,7,6])
#generate newMesh based on modifications
ourMesh.generate()
return ourMesh