-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathworld.py
More file actions
138 lines (98 loc) · 5.26 KB
/
world.py
File metadata and controls
138 lines (98 loc) · 5.26 KB
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
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
import random
import math
import chunk
import block_type
import texture_manager
import models.plant
import models.cactus
class World:
def __init__(self):
# create list of block types
self.texture_manager = texture_manager.Texture_manager(16, 16, 256)
self.block_types = [None] # "None" is the block type for air
self.block_types.append(block_type.Block_type(self.texture_manager, "cobblestone", {"all": "cobblestone"}))
self.block_types.append(block_type.Block_type(self.texture_manager, "grass", {"top": "grass", "bottom": "dirt", "sides": "grass_side"}))
self.block_types.append(block_type.Block_type(self.texture_manager, "grass_block", {"all": "grass"}))
self.block_types.append(block_type.Block_type(self.texture_manager, "dirt", {"all": "dirt"}))
self.block_types.append(block_type.Block_type(self.texture_manager, "stone", {"all": "stone"}))
self.block_types.append(block_type.Block_type(self.texture_manager, "sand", {"all": "sand"}))
self.block_types.append(block_type.Block_type(self.texture_manager, "planks", {"all": "planks"}))
self.block_types.append(block_type.Block_type(self.texture_manager, "log", {"top": "log_top", "bottom": "log_top", "sides": "log_side"}))
self.block_types.append(block_type.Block_type(self.texture_manager, "daisy", {"all": "daisy"}, models.plant))
self.block_types.append(block_type.Block_type(self.texture_manager, "rose", {"all": "rose"}, models.plant))
self.block_types.append(block_type.Block_type(self.texture_manager, "cactus", {"top": "cactus_top", "bottom": "cactus_bottom", "sides": "cactus_side"}, models.cactus))
self.block_types.append(block_type.Block_type(self.texture_manager, "dead_bush", {"all": "dead_bush"}, models.plant))
self.texture_manager.generate_mipmaps()
# create chunks with very crude terrain generation
self.chunks = {}
for x in range(2):
for z in range(2):
chunk_position = (x - 1, -1, z - 1)
current_chunk = chunk.Chunk(self, chunk_position)
for i in range(chunk.CHUNK_WIDTH):
for j in range(chunk.CHUNK_HEIGHT):
for k in range(chunk.CHUNK_LENGTH):
if j == 15: current_chunk.blocks[i][j][k] = random.choices([0, 9, 10], [20, 2, 1])[0]
elif j == 14: current_chunk.blocks[i][j][k] = 2
elif j > 10: current_chunk.blocks[i][j][k] = 4
else: current_chunk.blocks[i][j][k] = 5
self.chunks[chunk_position] = current_chunk
# update each chunk's mesh
for chunk_position in self.chunks:
self.chunks[chunk_position].update_subchunk_meshes()
self.chunks[chunk_position].update_mesh()
# create functions to make things a bit easier
def get_chunk_position(self, position):
x, y, z = position
return (
math.floor(x / chunk.CHUNK_WIDTH),
math.floor(y / chunk.CHUNK_HEIGHT),
math.floor(z / chunk.CHUNK_LENGTH))
def get_local_position(self, position):
x, y, z = position
return (
int(x % chunk.CHUNK_WIDTH),
int(y % chunk.CHUNK_HEIGHT),
int(z % chunk.CHUNK_LENGTH))
def get_block_number(self, position):
x, y, z = position
chunk_position = self.get_chunk_position(position)
if not chunk_position in self.chunks:
return 0
lx, ly, lz = self.get_local_position(position)
block_number = self.chunks[chunk_position].blocks[lx][ly][lz]
return block_number
def is_opaque_block(self, position):
# get block type and check if it's opaque or not
# air counts as a transparent block, so test for that too
block_type = self.block_types[self.get_block_number(position)]
if not block_type:
return False
return not block_type.transparent
def set_block(self, position, number): # set number to 0 (air) to remove block
x, y, z = position
chunk_position = self.get_chunk_position(position)
if not chunk_position in self.chunks: # if no chunks exist at this position, create a new one
if number == 0:
return # no point in creating a whole new chunk if we're not gonna be adding anything
self.chunks[chunk_position] = chunk.Chunk(self, chunk_position)
if self.get_block_number(position) == number: # no point updating mesh if the block is the same
return
lx, ly, lz = self.get_local_position(position)
self.chunks[chunk_position].blocks[lx][ly][lz] = number
self.chunks[chunk_position].update_at_position((x, y, z))
self.chunks[chunk_position].update_mesh()
cx, cy, cz = chunk_position
def try_update_chunk_at_position(chunk_position, position):
if chunk_position in self.chunks:
self.chunks[chunk_position].update_at_position(position)
self.chunks[chunk_position].update_mesh()
if lx == chunk.CHUNK_WIDTH - 1: try_update_chunk_at_position((cx + 1, cy, cz), (x + 1, y, z))
if lx == 0: try_update_chunk_at_position((cx - 1, cy, cz), (x - 1, y, z))
if ly == chunk.CHUNK_HEIGHT - 1: try_update_chunk_at_position((cx, cy + 1, cz), (x, y + 1, z))
if ly == 0: try_update_chunk_at_position((cx, cy - 1, cz), (x, y - 1, z))
if lz == chunk.CHUNK_LENGTH - 1: try_update_chunk_at_position((cx, cy, cz + 1), (x, y, z + 1))
if lz == 0: try_update_chunk_at_position((cx, cy, cz - 1), (x, y, z - 1))
def draw(self): # draw all the chunks in the world
for chunk_position in self.chunks:
self.chunks[chunk_position].draw()