Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Basic Mixin support #1

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .gitnore → .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
__pycache__/
mods/
mods/
*.pyc
29 changes: 21 additions & 8 deletions episode-11-Fire-Loader/camera.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,19 @@
import math
import os

import matrix

WALKING_SPEED = 7
SPRINTING_SPEED = 21

class Camera:
mods = []
mods_imported = []

if os.path.isdir("mods"):
mods = [os.path.join("mods", f[1], "camera.py").replace(".py", "") for f in [[os.listdir(os.path.join("mods", d)), d] for d in os.listdir("mods") if os.path.isdir(os.path.join("mods", d))] if "camera.py" in f[0]]
mods_imported = [__import__(m.replace("\\", "."), fromlist=[""]) for m in mods]

class CameraBaseImpl:
def __init__(self, shader, width, height):
self.width = width
self.height = height
Expand All @@ -28,17 +37,12 @@ def __init__(self, shader, width, height):

self.target_speed = WALKING_SPEED
self.speed = self.target_speed

# set variables to read

self.walking_speed_r = WALKING_SPEED
self.sprinting_speed_r = SPRINTING_SPEED

def update_camera(self, delta_time):
self.speed += (self.target_speed - self.speed) * delta_time * 20
multiplier = self.speed * delta_time

self.position[1] += (1 if self.input[1] else 0) * multiplier
self.position[1] += self.input[1] * multiplier

if self.input[0] or self.input[2]:
angle = self.rotation[0] - math.atan2(self.input[2], self.input[0]) + math.tau / 4
Expand All @@ -64,4 +68,13 @@ def update_matrices(self):
# modelviewprojection matrix

mvp_matrix = self.p_matrix * self.mv_matrix
self.shader.uniform_matrix(self.shader_matrix_location, mvp_matrix)
self.shader.uniform_matrix(self.shader_matrix_location, mvp_matrix)

CameraMixins = []
for module in mods_imported:
if hasattr(module, "CameraMixin"):
CameraMixins.append(module.CameraMixin)
print("Applying mixin to class camera.Camera")

class Camera(*CameraMixins, CameraBaseImpl):
"""Camera class that handles camera transforms"""
23 changes: 21 additions & 2 deletions episode-11-Fire-Loader/chunk.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,22 @@
import pyglet.gl as gl

import subchunk
import os

CHUNK_WIDTH = 16
CHUNK_HEIGHT = 128
CHUNK_LENGTH = 16

class Chunk:
mods = []
mods_imported = []

if os.path.isdir("mods"):
mods = [os.path.join("mods", f[1], "chunk.py").replace(".py", "") for f in [[os.listdir(os.path.join("mods", d)), d] for d in os.listdir("mods") if os.path.isdir(os.path.join("mods", d))] if "chunk.py" in f[0]]
mods_imported = [__import__(m.replace("\\", "."), fromlist=[""]) for m in mods]

print(mods)

class ChunkBaseImpl:
def __init__(self, world, chunk_position):
self.world = world

Expand Down Expand Up @@ -186,4 +196,13 @@ def draw(self):
gl.GL_TRIANGLES,
self.mesh_indices_length,
gl.GL_UNSIGNED_INT,
None)
None)

ChunkMixins = []
for module in mods_imported:
if hasattr(module, "ChunkMixin"):
ChunkMixins.append(module.ChunkMixin)
print("Applying mixin to class chunk.Chunk")

class Chunk(*ChunkMixins, ChunkBaseImpl):
"""Chunk class that handles storage of blocks and render region"""
19 changes: 12 additions & 7 deletions episode-11-Fire-Loader/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,18 +13,14 @@

import pyglet.gl as gl

import matrix
import shader
import camera

import block_type
import texture_manager

import world

import hit

lines = ["--- Welcome to Fire Loader ---", "Developed by drakeerv", "Modified from obiwac", "--- Starting---", ""]
lines = ["--- Welcome to Fire Loader ---", "Developed by drakeerv and Jukitsu", "Modified from obiwac", "--- Starting---", ""]
[print(line) for line in lines]
del lines

Expand All @@ -40,7 +36,7 @@

print("")

class Window(pyglet.window.Window):
class WindowBaseImpl(pyglet.window.Window):
def __init__(self, **args):
super().__init__(**args)

Expand Down Expand Up @@ -219,10 +215,19 @@ def on_key_release(self, key, modifiers):
try: module.keyboard_release(self)
except Exception as e: print(e)

WindowMixins = []
for module in mods_imported:
if hasattr(module, "WindowMixin"):
WindowMixins.append(module.WindowMixin)
print("Applying mixin to class main.Window")

class Window(*WindowMixins, WindowBaseImpl):
"""Window class that handles the game window and event callbacks"""

class Game:
def __init__(self):
self.config = gl.Config(major_version = 3, depth_size = 16)
self.window = Window(config = self.config, width = 800, height = 600, caption = "Minecraft clone (Fire Loader)", resizable = True, vsync = False)
self.window = Window(config = self.config, width = 852, height = 480, caption = "Minecraft clone (Fire Loader)", resizable = True, vsync = False)

def run(self):
pyglet.app.run()
Expand Down
9 changes: 8 additions & 1 deletion episode-11-Fire-Loader/matrix.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import ctypes
import math


def copy_matrix(matrix):
return copy.deepcopy(matrix) # we need to use deepcopy since we're dealing with 2D arrays

Expand Down Expand Up @@ -42,15 +43,18 @@ def __mul__(self, matrix):
def __imul__(self, matrix):
self.data = multiply_matrices(self.data, matrix.data)

def scale(self, x, y, z):

def scale(self, scale_x, scale_y, scale_z):
for i in range(4): self.data[0][i] *= scale_x
for i in range(4): self.data[1][i] *= scale_y
for i in range(4): self.data[2][i] *= scale_z


def translate(self, x, y, z):
for i in range(4):
self.data[3][i] = self.data[3][i] + (self.data[0][i] * x + self.data[1][i] * y + self.data[2][i] * z)


def rotate(self, angle, x, y, z):
magnitude = math.sqrt(x * x + y * y + z * z)

Expand Down Expand Up @@ -114,6 +118,7 @@ def frustum(self, left, right, bottom, top, near, far):

self.data = multiply_matrices(self.data, frustum_matrix)


def perspective(self, fovy, aspect, near, far):
frustum_y = math.tan(math.radians(fovy) / 2)
frustum_x = frustum_y * aspect
Expand All @@ -137,3 +142,5 @@ def orthographic(self, left, right, bottom, top, near, far):
orthographic_matrix[3][2] = -(near + far) / deltaz

self.data = multiply_matrices(self.data, orthographic_matrix)


Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
8 changes: 4 additions & 4 deletions episode-11-Fire-Loader/save.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ def load_chunk(self, chunk_position):
chunk_path = self.chunk_position_to_path(chunk_position)

try:
chunk_blocks = nbt.load(chunk_path).root["Level"]["Blocks"]
chunk_blocks = nbt.load(chunk_path)["Level"]["Blocks"]

except FileNotFoundError:
return
Expand Down Expand Up @@ -54,8 +54,8 @@ def save_chunk(self, chunk_position):
except FileNotFoundError:
chunk_data = nbt.File({"": nbt.Compound({"Level": nbt.Compound()})})

chunk_data.root["Level"]["xPos"] = x
chunk_data.root["Level"]["zPos"] = z
chunk_data["Level"]["xPos"] = x
chunk_data["Level"]["zPos"] = z

# fill the chunk file with the blocks from our chunk

Expand All @@ -71,7 +71,7 @@ def save_chunk(self, chunk_position):

# save the chunk file

chunk_data.root["Level"]["Blocks"] = chunk_blocks
chunk_data["Level"]["Blocks"] = chunk_blocks
chunk_data.save(chunk_path, gzipped = True)

def load(self):
Expand Down
91 changes: 54 additions & 37 deletions episode-11-Fire-Loader/subchunk.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,16 @@
SUBCHUNK_HEIGHT = 4
SUBCHUNK_LENGTH = 4

class Subchunk:
import os

mods = []
mods_imported = []

if os.path.isdir("mods"):
mods = [os.path.join("mods", f[1], "subchunk.py").replace(".py", "") for f in [[os.listdir(os.path.join("mods", d)), d] for d in os.listdir("mods") if os.path.isdir(os.path.join("mods", d))] if "subchunk.py" in f[0]]
mods_imported = [__import__(m.replace("\\", "."), fromlist=[""]) for m in mods]

class SubchunkBaseImpl:
def __init__(self, parent, subchunk_position):
self.parent = parent
self.world = self.parent.world
Expand Down Expand Up @@ -33,6 +42,31 @@ def __init__(self, parent, subchunk_position):
self.subchunk_width_r = SUBCHUNK_WIDTH
self.subchunk_height_r = SUBCHUNK_HEIGHT
self.subchunk_length_r = SUBCHUNK_LENGTH

def add_face(self, face, pos, block_type):
x, y, z = pos
vertex_positions = block_type.vertex_positions[face].copy()

for i in range(4):
vertex_positions[i * 3 + 0] += x
vertex_positions[i * 3 + 1] += y
vertex_positions[i * 3 + 2] += z

self.mesh_vertex_positions.extend(vertex_positions)

indices = [0, 1, 2, 0, 2, 3]
for i in range(6):
indices[i] += self.mesh_index_counter

self.mesh_indices.extend(indices)
self.mesh_index_counter += 4

self.mesh_tex_coords.extend(block_type.tex_coords[face])
self.mesh_shading_values.extend(block_type.shading_values[face])

def can_render_face(self, glass, block_number, position):
return not (self.world.is_opaque_block(position)
or (glass and self.world.get_block_number(position) == block_number))

def update_mesh(self):
self.mesh_vertex_positions = []
Expand All @@ -42,26 +76,6 @@ def update_mesh(self):
self.mesh_index_counter = 0
self.mesh_indices = []

def add_face(face):
vertex_positions = block_type.vertex_positions[face].copy()

for i in range(4):
vertex_positions[i * 3 + 0] += x
vertex_positions[i * 3 + 1] += y
vertex_positions[i * 3 + 2] += z

self.mesh_vertex_positions.extend(vertex_positions)

indices = [0, 1, 2, 0, 2, 3]
for i in range(6):
indices[i] += self.mesh_index_counter

self.mesh_indices.extend(indices)
self.mesh_index_counter += 4

self.mesh_tex_coords.extend(block_type.tex_coords[face])
self.mesh_shading_values.extend(block_type.shading_values[face])

for local_x in range(SUBCHUNK_WIDTH):
for local_y in range(SUBCHUNK_HEIGHT):
for local_z in range(SUBCHUNK_LENGTH):
Expand All @@ -74,32 +88,35 @@ def add_face(face):
if block_number:
block_type = self.world.block_types[block_number]

x, y, z = (
x, y, z = pos = (
self.position[0] + local_x,
self.position[1] + local_y,
self.position[2] + local_z)

def can_render_face(position):
if not self.world.is_opaque_block(position):
if block_type.glass and self.world.get_block_number(position) == block_number:
return False

return True

return False


# if block is cube, we want it to check neighbouring blocks so that we don't uselessly render faces
# if block isn't a cube, we just want to render all faces, regardless of neighbouring blocks
# since the vast majority of blocks are probably anyway going to be cubes, this won't impact performance all that much; the amount of useless faces drawn is going to be minimal

if block_type.is_cube:
if can_render_face((x + 1, y, z)): add_face(0)
if can_render_face((x - 1, y, z)): add_face(1)
if can_render_face((x, y + 1, z)): add_face(2)
if can_render_face((x, y - 1, z)): add_face(3)
if can_render_face((x, y, z + 1)): add_face(4)
if can_render_face((x, y, z - 1)): add_face(5)
if self.can_render_face(block_type.glass, block_number, (x + 1, y, z)): self.add_face(0, pos, block_type)
if self.can_render_face(block_type.glass, block_number, (x - 1, y, z)): self.add_face(1, pos, block_type)
if self.can_render_face(block_type.glass, block_number, (x, y + 1, z)): self.add_face(2, pos, block_type)
if self.can_render_face(block_type.glass, block_number, (x, y - 1, z)): self.add_face(3, pos, block_type)
if self.can_render_face(block_type.glass, block_number, (x, y, z + 1)): self.add_face(4, pos, block_type)
if self.can_render_face(block_type.glass, block_number, (x, y, z - 1)): self.add_face(5, pos, block_type)

else:
for i in range(len(block_type.vertex_positions)):
add_face(i)
self.add_face(i, pos, block_type)


SubchunkMixins = []
for module in mods_imported:
if hasattr(module, "SubchunkMixin"):
SubchunkMixins.append(module.SubchunkMixin)
print("Applying mixin to class subchunk.Subchunk")

class Subchunk(*SubchunkMixins, SubchunkBaseImpl):
"""Subchunk class that handles subregions of a chunk"""
22 changes: 19 additions & 3 deletions episode-11-Fire-Loader/texture_manager.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,16 @@
import ctypes
import os
import pyglet

import pyglet.gl as gl

class Texture_manager:
mods = []
mods_imported = []

if os.path.isdir("mods"):
mods = [os.path.join("mods", f[1], "texture_manager.py").replace(".py", "") for f in [[os.listdir(os.path.join("mods", d)), d] for d in os.listdir("mods") if os.path.isdir(os.path.join("mods", d))] if "texture_manager.py" in f[0]]
mods_imported = [__import__(m.replace("\\", "."), fromlist=[""]) for m in mods]

class TextureManagerBaseImpl:
def __init__(self, texture_width, texture_height, max_textures):
self.texture_width = texture_width
self.texture_height = texture_height
Expand Down Expand Up @@ -39,4 +46,13 @@ def add_texture(self, texture):
0, 0, self.textures.index(texture),
self.texture_width, self.texture_height, 1,
gl.GL_RGBA, gl.GL_UNSIGNED_BYTE,
texture_image.get_data("RGBA", texture_image.width * 4))
texture_image.get_data("RGBA", texture_image.width * 4))

TextureManagerMixins = []
for module in mods_imported:
if hasattr(module, "TextureManagerMixin"):
TextureManagerMixins.append(module.TextureManagerMixin)
print("Applying mixin to class texture_manager.TextureManager")

class TextureManager(*TextureManagerMixins, TextureManagerBaseImpl):
"""Texture Manager class"""
Loading