From 957fb53696cbb66891ecd2f65bef80cad322e275 Mon Sep 17 00:00:00 2001 From: Kyle Wadas Date: Tue, 25 Feb 2025 19:42:49 -0700 Subject: [PATCH 01/46] Basic Refactoring of Main, Model, And Window --- LICENSE => OLD/LICENSE | 0 README.md => OLD/README.md | 0 OLD/main_old.py | 902 +++++++++++++++++++++++++++++ texture.png => OLD/texture.png | Bin __pycache__/model.cpython-312.pyc | Bin 0 -> 18055 bytes __pycache__/window.cpython-312.pyc | Bin 0 -> 19418 bytes main.py | 855 +-------------------------- model.py | 413 +++++++++++++ window.py | 452 +++++++++++++++ 9 files changed, 1769 insertions(+), 853 deletions(-) rename LICENSE => OLD/LICENSE (100%) rename README.md => OLD/README.md (100%) create mode 100644 OLD/main_old.py rename texture.png => OLD/texture.png (100%) create mode 100644 __pycache__/model.cpython-312.pyc create mode 100644 __pycache__/window.cpython-312.pyc create mode 100644 model.py create mode 100644 window.py diff --git a/LICENSE b/OLD/LICENSE similarity index 100% rename from LICENSE rename to OLD/LICENSE diff --git a/README.md b/OLD/README.md similarity index 100% rename from README.md rename to OLD/README.md diff --git a/OLD/main_old.py b/OLD/main_old.py new file mode 100644 index 00000000..61afe41c --- /dev/null +++ b/OLD/main_old.py @@ -0,0 +1,902 @@ +from __future__ import division + +import sys +import math +import random +import time + +from collections import deque +from pyglet import image +from pyglet.gl import * +from pyglet.graphics import TextureGroup +from pyglet.window import key, mouse + +TICKS_PER_SEC = 60 + +# Size of sectors used to ease block loading. +SECTOR_SIZE = 16 + +WALKING_SPEED = 5 +FLYING_SPEED = 15 + +GRAVITY = 20.0 +MAX_JUMP_HEIGHT = 1.0 # About the height of a block. +# To derive the formula for calculating jump speed, first solve +# v_t = v_0 + a * t +# for the time at which you achieve maximum height, where a is the acceleration +# due to gravity and v_t = 0. This gives: +# t = - v_0 / a +# Use t and the desired MAX_JUMP_HEIGHT to solve for v_0 (jump speed) in +# s = s_0 + v_0 * t + (a * t^2) / 2 +JUMP_SPEED = math.sqrt(2 * GRAVITY * MAX_JUMP_HEIGHT) +TERMINAL_VELOCITY = 50 + +PLAYER_HEIGHT = 2 + +if sys.version_info[0] >= 3: + xrange = range + +def cube_vertices(x, y, z, n): + """ Return the vertices of the cube at position x, y, z with size 2*n. + + """ + return [ + x-n,y+n,z-n, x-n,y+n,z+n, x+n,y+n,z+n, x+n,y+n,z-n, # top + x-n,y-n,z-n, x+n,y-n,z-n, x+n,y-n,z+n, x-n,y-n,z+n, # bottom + x-n,y-n,z-n, x-n,y-n,z+n, x-n,y+n,z+n, x-n,y+n,z-n, # left + x+n,y-n,z+n, x+n,y-n,z-n, x+n,y+n,z-n, x+n,y+n,z+n, # right + x-n,y-n,z+n, x+n,y-n,z+n, x+n,y+n,z+n, x-n,y+n,z+n, # front + x+n,y-n,z-n, x-n,y-n,z-n, x-n,y+n,z-n, x+n,y+n,z-n, # back + ] + + +def tex_coord(x, y, n=4): + """ Return the bounding vertices of the texture square. + + """ + m = 1.0 / n + dx = x * m + dy = y * m + return dx, dy, dx + m, dy, dx + m, dy + m, dx, dy + m + + +def tex_coords(top, bottom, side): + """ Return a list of the texture squares for the top, bottom and side. + + """ + top = tex_coord(*top) + bottom = tex_coord(*bottom) + side = tex_coord(*side) + result = [] + result.extend(top) + result.extend(bottom) + result.extend(side * 4) + return result + + +TEXTURE_PATH = 'OLD/texture.png' + +GRASS = tex_coords((1, 0), (0, 1), (0, 0)) +SAND = tex_coords((1, 1), (1, 1), (1, 1)) +BRICK = tex_coords((2, 0), (2, 0), (2, 0)) +STONE = tex_coords((2, 1), (2, 1), (2, 1)) + +FACES = [ + ( 0, 1, 0), + ( 0,-1, 0), + (-1, 0, 0), + ( 1, 0, 0), + ( 0, 0, 1), + ( 0, 0,-1), +] + + +def normalize(position): + """ Accepts `position` of arbitrary precision and returns the block + containing that position. + + Parameters + ---------- + position : tuple of len 3 + + Returns + ------- + block_position : tuple of ints of len 3 + + """ + x, y, z = position + x, y, z = (int(round(x)), int(round(y)), int(round(z))) + return (x, y, z) + + +def sectorize(position): + """ Returns a tuple representing the sector for the given `position`. + + Parameters + ---------- + position : tuple of len 3 + + Returns + ------- + sector : tuple of len 3 + + """ + x, y, z = normalize(position) + x, y, z = x // SECTOR_SIZE, y // SECTOR_SIZE, z // SECTOR_SIZE + return (x, 0, z) + + +class Model(object): + + def __init__(self): + + # A Batch is a collection of vertex lists for batched rendering. + self.batch = pyglet.graphics.Batch() + + # A TextureGroup manages an OpenGL texture. + self.group = TextureGroup(image.load(TEXTURE_PATH).get_texture()) + + # A mapping from position to the texture of the block at that position. + # This defines all the blocks that are currently in the world. + self.world = {} + + # Same mapping as `world` but only contains blocks that are shown. + self.shown = {} + + # Mapping from position to a pyglet `VertextList` for all shown blocks. + self._shown = {} + + # Mapping from sector to a list of positions inside that sector. + self.sectors = {} + + # Simple function queue implementation. The queue is populated with + # _show_block() and _hide_block() calls + self.queue = deque() + + self._initialize() + + def _initialize(self): + """ Initialize the world by placing all the blocks. + + """ + n = 80 # 1/2 width and height of world + s = 1 # step size + y = 0 # initial y height + for x in xrange(-n, n + 1, s): + for z in xrange(-n, n + 1, s): + # create a layer stone an grass everywhere. + self.add_block((x, y - 2, z), GRASS, immediate=False) + self.add_block((x, y - 3, z), STONE, immediate=False) + if x in (-n, n) or z in (-n, n): + # create outer walls. + for dy in xrange(-2, 3): + self.add_block((x, y + dy, z), STONE, immediate=False) + + # generate the hills randomly + o = n - 10 + for _ in xrange(120): + a = random.randint(-o, o) # x position of the hill + b = random.randint(-o, o) # z position of the hill + c = -1 # base of the hill + h = random.randint(1, 6) # height of the hill + s = random.randint(4, 8) # 2 * s is the side length of the hill + d = 1 # how quickly to taper off the hills + t = random.choice([GRASS, SAND, BRICK]) + for y in xrange(c, c + h): + for x in xrange(a - s, a + s + 1): + for z in xrange(b - s, b + s + 1): + if (x - a) ** 2 + (z - b) ** 2 > (s + 1) ** 2: + continue + if (x - 0) ** 2 + (z - 0) ** 2 < 5 ** 2: + continue + self.add_block((x, y, z), t, immediate=False) + s -= d # decrement side length so hills taper off + + def hit_test(self, position, vector, max_distance=8): + """ Line of sight search from current position. If a block is + intersected it is returned, along with the block previously in the line + of sight. If no block is found, return None, None. + + Parameters + ---------- + position : tuple of len 3 + The (x, y, z) position to check visibility from. + vector : tuple of len 3 + The line of sight vector. + max_distance : int + How many blocks away to search for a hit. + + """ + m = 8 + x, y, z = position + dx, dy, dz = vector + previous = None + for _ in xrange(max_distance * m): + key = normalize((x, y, z)) + if key != previous and key in self.world: + return key, previous + previous = key + x, y, z = x + dx / m, y + dy / m, z + dz / m + return None, None + + def exposed(self, position): + """ Returns False is given `position` is surrounded on all 6 sides by + blocks, True otherwise. + + """ + x, y, z = position + for dx, dy, dz in FACES: + if (x + dx, y + dy, z + dz) not in self.world: + return True + return False + + def add_block(self, position, texture, immediate=True): + """ Add a block with the given `texture` and `position` to the world. + + Parameters + ---------- + position : tuple of len 3 + The (x, y, z) position of the block to add. + texture : list of len 3 + The coordinates of the texture squares. Use `tex_coords()` to + generate. + immediate : bool + Whether or not to draw the block immediately. + + """ + if position in self.world: + self.remove_block(position, immediate) + self.world[position] = texture + self.sectors.setdefault(sectorize(position), []).append(position) + if immediate: + if self.exposed(position): + self.show_block(position) + self.check_neighbors(position) + + def remove_block(self, position, immediate=True): + """ Remove the block at the given `position`. + + Parameters + ---------- + position : tuple of len 3 + The (x, y, z) position of the block to remove. + immediate : bool + Whether or not to immediately remove block from canvas. + + """ + del self.world[position] + self.sectors[sectorize(position)].remove(position) + if immediate: + if position in self.shown: + self.hide_block(position) + self.check_neighbors(position) + + def check_neighbors(self, position): + """ Check all blocks surrounding `position` and ensure their visual + state is current. This means hiding blocks that are not exposed and + ensuring that all exposed blocks are shown. Usually used after a block + is added or removed. + + """ + x, y, z = position + for dx, dy, dz in FACES: + key = (x + dx, y + dy, z + dz) + if key not in self.world: + continue + if self.exposed(key): + if key not in self.shown: + self.show_block(key) + else: + if key in self.shown: + self.hide_block(key) + + def show_block(self, position, immediate=True): + """ Show the block at the given `position`. This method assumes the + block has already been added with add_block() + + Parameters + ---------- + position : tuple of len 3 + The (x, y, z) position of the block to show. + immediate : bool + Whether or not to show the block immediately. + + """ + texture = self.world[position] + self.shown[position] = texture + if immediate: + self._show_block(position, texture) + else: + self._enqueue(self._show_block, position, texture) + + def _show_block(self, position, texture): + """ Private implementation of the `show_block()` method. + + Parameters + ---------- + position : tuple of len 3 + The (x, y, z) position of the block to show. + texture : list of len 3 + The coordinates of the texture squares. Use `tex_coords()` to + generate. + + """ + x, y, z = position + vertex_data = cube_vertices(x, y, z, 0.5) + texture_data = list(texture) + # create vertex list + # FIXME Maybe `add_indexed()` should be used instead + self._shown[position] = self.batch.add(24, GL_QUADS, self.group, + ('v3f/static', vertex_data), + ('t2f/static', texture_data)) + + def hide_block(self, position, immediate=True): + """ Hide the block at the given `position`. Hiding does not remove the + block from the world. + + Parameters + ---------- + position : tuple of len 3 + The (x, y, z) position of the block to hide. + immediate : bool + Whether or not to immediately remove the block from the canvas. + + """ + self.shown.pop(position) + if immediate: + self._hide_block(position) + else: + self._enqueue(self._hide_block, position) + + def _hide_block(self, position): + """ Private implementation of the 'hide_block()` method. + + """ + self._shown.pop(position).delete() + + def show_sector(self, sector): + """ Ensure all blocks in the given sector that should be shown are + drawn to the canvas. + + """ + for position in self.sectors.get(sector, []): + if position not in self.shown and self.exposed(position): + self.show_block(position, False) + + def hide_sector(self, sector): + """ Ensure all blocks in the given sector that should be hidden are + removed from the canvas. + + """ + for position in self.sectors.get(sector, []): + if position in self.shown: + self.hide_block(position, False) + + def change_sectors(self, before, after): + """ Move from sector `before` to sector `after`. A sector is a + contiguous x, y sub-region of world. Sectors are used to speed up + world rendering. + + """ + before_set = set() + after_set = set() + pad = 4 + for dx in xrange(-pad, pad + 1): + for dy in [0]: # xrange(-pad, pad + 1): + for dz in xrange(-pad, pad + 1): + if dx ** 2 + dy ** 2 + dz ** 2 > (pad + 1) ** 2: + continue + if before: + x, y, z = before + before_set.add((x + dx, y + dy, z + dz)) + if after: + x, y, z = after + after_set.add((x + dx, y + dy, z + dz)) + show = after_set - before_set + hide = before_set - after_set + for sector in show: + self.show_sector(sector) + for sector in hide: + self.hide_sector(sector) + + def _enqueue(self, func, *args): + """ Add `func` to the internal queue. + + """ + self.queue.append((func, args)) + + def _dequeue(self): + """ Pop the top function from the internal queue and call it. + + """ + func, args = self.queue.popleft() + func(*args) + + def process_queue(self): + """ Process the entire queue while taking periodic breaks. This allows + the game loop to run smoothly. The queue contains calls to + _show_block() and _hide_block() so this method should be called if + add_block() or remove_block() was called with immediate=False + + """ + start = time.perf_counter() + while self.queue and time.perf_counter() - start < 1.0 / TICKS_PER_SEC: + self._dequeue() + + def process_entire_queue(self): + """ Process the entire queue with no breaks. + + """ + while self.queue: + self._dequeue() + + +class Window(pyglet.window.Window): + + def __init__(self, *args, **kwargs): + super(Window, self).__init__(*args, **kwargs) + + # Whether or not the window exclusively captures the mouse. + self.exclusive = False + + # When flying gravity has no effect and speed is increased. + self.flying = False + + # Strafing is moving lateral to the direction you are facing, + # e.g. moving to the left or right while continuing to face forward. + # + # First element is -1 when moving forward, 1 when moving back, and 0 + # otherwise. The second element is -1 when moving left, 1 when moving + # right, and 0 otherwise. + self.strafe = [0, 0] + + # Current (x, y, z) position in the world, specified with floats. Note + # that, perhaps unlike in math class, the y-axis is the vertical axis. + self.position = (0, 0, 0) + + # First element is rotation of the player in the x-z plane (ground + # plane) measured from the z-axis down. The second is the rotation + # angle from the ground plane up. Rotation is in degrees. + # + # The vertical plane rotation ranges from -90 (looking straight down) to + # 90 (looking straight up). The horizontal rotation range is unbounded. + self.rotation = (0, 0) + + # Which sector the player is currently in. + self.sector = None + + # The crosshairs at the center of the screen. + self.reticle = None + + # Velocity in the y (upward) direction. + self.dy = 0 + + # A list of blocks the player can place. Hit num keys to cycle. + self.inventory = [BRICK, GRASS, SAND] + + # The current block the user can place. Hit num keys to cycle. + self.block = self.inventory[0] + + # Convenience list of num keys. + self.num_keys = [ + key._1, key._2, key._3, key._4, key._5, + key._6, key._7, key._8, key._9, key._0] + + # Instance of the model that handles the world. + self.model = Model() + + # The label that is displayed in the top left of the canvas. + self.label = pyglet.text.Label('', font_name='Arial', font_size=18, + x=10, y=self.height - 10, anchor_x='left', anchor_y='top', + color=(0, 0, 0, 255)) + + # This call schedules the `update()` method to be called + # TICKS_PER_SEC. This is the main game event loop. + pyglet.clock.schedule_interval(self.update, 1.0 / TICKS_PER_SEC) + + def set_exclusive_mouse(self, exclusive): + """ If `exclusive` is True, the game will capture the mouse, if False + the game will ignore the mouse. + + """ + super(Window, self).set_exclusive_mouse(exclusive) + self.exclusive = exclusive + + def get_sight_vector(self): + """ Returns the current line of sight vector indicating the direction + the player is looking. + + """ + x, y = self.rotation + # y ranges from -90 to 90, or -pi/2 to pi/2, so m ranges from 0 to 1 and + # is 1 when looking ahead parallel to the ground and 0 when looking + # straight up or down. + m = math.cos(math.radians(y)) + # dy ranges from -1 to 1 and is -1 when looking straight down and 1 when + # looking straight up. + dy = math.sin(math.radians(y)) + dx = math.cos(math.radians(x - 90)) * m + dz = math.sin(math.radians(x - 90)) * m + return (dx, dy, dz) + + def get_motion_vector(self): + """ Returns the current motion vector indicating the velocity of the + player. + + Returns + ------- + vector : tuple of len 3 + Tuple containing the velocity in x, y, and z respectively. + + """ + if any(self.strafe): + x, y = self.rotation + strafe = math.degrees(math.atan2(*self.strafe)) + y_angle = math.radians(y) + x_angle = math.radians(x + strafe) + if self.flying: + m = math.cos(y_angle) + dy = math.sin(y_angle) + if self.strafe[1]: + # Moving left or right. + dy = 0.0 + m = 1 + if self.strafe[0] > 0: + # Moving backwards. + dy *= -1 + # When you are flying up or down, you have less left and right + # motion. + dx = math.cos(x_angle) * m + dz = math.sin(x_angle) * m + else: + dy = 0.0 + dx = math.cos(x_angle) + dz = math.sin(x_angle) + else: + dy = 0.0 + dx = 0.0 + dz = 0.0 + return (dx, dy, dz) + + def update(self, dt): + """ This method is scheduled to be called repeatedly by the pyglet + clock. + + Parameters + ---------- + dt : float + The change in time since the last call. + + """ + self.model.process_queue() + sector = sectorize(self.position) + if sector != self.sector: + self.model.change_sectors(self.sector, sector) + if self.sector is None: + self.model.process_entire_queue() + self.sector = sector + m = 8 + dt = min(dt, 0.2) + for _ in xrange(m): + self._update(dt / m) + + def _update(self, dt): + """ Private implementation of the `update()` method. This is where most + of the motion logic lives, along with gravity and collision detection. + + Parameters + ---------- + dt : float + The change in time since the last call. + + """ + # walking + speed = FLYING_SPEED if self.flying else WALKING_SPEED + d = dt * speed # distance covered this tick. + dx, dy, dz = self.get_motion_vector() + # New position in space, before accounting for gravity. + dx, dy, dz = dx * d, dy * d, dz * d + # gravity + if not self.flying: + # Update your vertical speed: if you are falling, speed up until you + # hit terminal velocity; if you are jumping, slow down until you + # start falling. + self.dy -= dt * GRAVITY + self.dy = max(self.dy, -TERMINAL_VELOCITY) + dy += self.dy * dt + # collisions + x, y, z = self.position + x, y, z = self.collide((x + dx, y + dy, z + dz), PLAYER_HEIGHT) + self.position = (x, y, z) + + def collide(self, position, height): + """ Checks to see if the player at the given `position` and `height` + is colliding with any blocks in the world. + + Parameters + ---------- + position : tuple of len 3 + The (x, y, z) position to check for collisions at. + height : int or float + The height of the player. + + Returns + ------- + position : tuple of len 3 + The new position of the player taking into account collisions. + + """ + # How much overlap with a dimension of a surrounding block you need to + # have to count as a collision. If 0, touching terrain at all counts as + # a collision. If .49, you sink into the ground, as if walking through + # tall grass. If >= .5, you'll fall through the ground. + pad = 0.25 + p = list(position) + np = normalize(position) + for face in FACES: # check all surrounding blocks + for i in xrange(3): # check each dimension independently + if not face[i]: + continue + # How much overlap you have with this dimension. + d = (p[i] - np[i]) * face[i] + if d < pad: + continue + for dy in xrange(height): # check each height + op = list(np) + op[1] -= dy + op[i] += face[i] + if tuple(op) not in self.model.world: + continue + p[i] -= (d - pad) * face[i] + if face == (0, -1, 0) or face == (0, 1, 0): + # You are colliding with the ground or ceiling, so stop + # falling / rising. + self.dy = 0 + break + return tuple(p) + + def on_mouse_press(self, x, y, button, modifiers): + """ Called when a mouse button is pressed. See pyglet docs for button + amd modifier mappings. + + Parameters + ---------- + x, y : int + The coordinates of the mouse click. Always center of the screen if + the mouse is captured. + button : int + Number representing mouse button that was clicked. 1 = left button, + 4 = right button. + modifiers : int + Number representing any modifying keys that were pressed when the + mouse button was clicked. + + """ + if self.exclusive: + vector = self.get_sight_vector() + block, previous = self.model.hit_test(self.position, vector) + if (button == mouse.RIGHT) or \ + ((button == mouse.LEFT) and (modifiers & key.MOD_CTRL)): + # ON OSX, control + left click = right click. + if previous: + self.model.add_block(previous, self.block) + elif button == pyglet.window.mouse.LEFT and block: + texture = self.model.world[block] + if texture != STONE: + self.model.remove_block(block) + else: + self.set_exclusive_mouse(True) + + def on_mouse_motion(self, x, y, dx, dy): + """ Called when the player moves the mouse. + + Parameters + ---------- + x, y : int + The coordinates of the mouse click. Always center of the screen if + the mouse is captured. + dx, dy : float + The movement of the mouse. + + """ + if self.exclusive: + m = 0.15 + x, y = self.rotation + x, y = x + dx * m, y + dy * m + y = max(-90, min(90, y)) + self.rotation = (x, y) + + def on_key_press(self, symbol, modifiers): + """ Called when the player presses a key. See pyglet docs for key + mappings. + + Parameters + ---------- + symbol : int + Number representing the key that was pressed. + modifiers : int + Number representing any modifying keys that were pressed. + + """ + if symbol == key.W: + self.strafe[0] -= 1 + elif symbol == key.S: + self.strafe[0] += 1 + elif symbol == key.A: + self.strafe[1] -= 1 + elif symbol == key.D: + self.strafe[1] += 1 + elif symbol == key.SPACE: + if self.dy == 0: + self.dy = JUMP_SPEED + elif symbol == key.ESCAPE: + self.set_exclusive_mouse(False) + elif symbol == key.TAB: + self.flying = not self.flying + elif symbol in self.num_keys: + index = (symbol - self.num_keys[0]) % len(self.inventory) + self.block = self.inventory[index] + + def on_key_release(self, symbol, modifiers): + """ Called when the player releases a key. See pyglet docs for key + mappings. + + Parameters + ---------- + symbol : int + Number representing the key that was pressed. + modifiers : int + Number representing any modifying keys that were pressed. + + """ + if symbol == key.W: + self.strafe[0] += 1 + elif symbol == key.S: + self.strafe[0] -= 1 + elif symbol == key.A: + self.strafe[1] += 1 + elif symbol == key.D: + self.strafe[1] -= 1 + + def on_resize(self, width, height): + """ Called when the window is resized to a new `width` and `height`. + + """ + # label + self.label.y = height - 10 + # reticle + if self.reticle: + self.reticle.delete() + x, y = self.width // 2, self.height // 2 + n = 10 + self.reticle = pyglet.graphics.vertex_list(4, + ('v2i', (x - n, y, x + n, y, x, y - n, x, y + n)) + ) + + def set_2d(self): + """ Configure OpenGL to draw in 2d. + + """ + width, height = self.get_size() + glDisable(GL_DEPTH_TEST) + viewport = self.get_viewport_size() + glViewport(0, 0, max(1, viewport[0]), max(1, viewport[1])) + glMatrixMode(GL_PROJECTION) + glLoadIdentity() + glOrtho(0, max(1, width), 0, max(1, height), -1, 1) + glMatrixMode(GL_MODELVIEW) + glLoadIdentity() + + def set_3d(self): + """ Configure OpenGL to draw in 3d. + + """ + width, height = self.get_size() + glEnable(GL_DEPTH_TEST) + viewport = self.get_viewport_size() + glViewport(0, 0, max(1, viewport[0]), max(1, viewport[1])) + glMatrixMode(GL_PROJECTION) + glLoadIdentity() + gluPerspective(65.0, width / float(height), 0.1, 60.0) + glMatrixMode(GL_MODELVIEW) + glLoadIdentity() + x, y = self.rotation + glRotatef(x, 0, 1, 0) + glRotatef(-y, math.cos(math.radians(x)), 0, math.sin(math.radians(x))) + x, y, z = self.position + glTranslatef(-x, -y, -z) + + def on_draw(self): + """ Called by pyglet to draw the canvas. + + """ + self.clear() + self.set_3d() + glColor3d(1, 1, 1) + self.model.batch.draw() + self.draw_focused_block() + self.set_2d() + self.draw_label() + self.draw_reticle() + + def draw_focused_block(self): + """ Draw black edges around the block that is currently under the + crosshairs. + + """ + vector = self.get_sight_vector() + block = self.model.hit_test(self.position, vector)[0] + if block: + x, y, z = block + vertex_data = cube_vertices(x, y, z, 0.51) + glColor3d(0, 0, 0) + glPolygonMode(GL_FRONT_AND_BACK, GL_LINE) + pyglet.graphics.draw(24, GL_QUADS, ('v3f/static', vertex_data)) + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL) + + def draw_label(self): + """ Draw the label in the top left of the screen. + + """ + x, y, z = self.position + self.label.text = '%02d (%.2f, %.2f, %.2f) %d / %d' % ( + pyglet.clock.get_fps(), x, y, z, + len(self.model._shown), len(self.model.world)) + self.label.draw() + + def draw_reticle(self): + """ Draw the crosshairs in the center of the screen. + + """ + glColor3d(0, 0, 0) + self.reticle.draw(GL_LINES) + + +def setup_fog(): + """ Configure the OpenGL fog properties. + + """ + # Enable fog. Fog "blends a fog color with each rasterized pixel fragment's + # post-texturing color." + glEnable(GL_FOG) + # Set the fog color. + glFogfv(GL_FOG_COLOR, (GLfloat * 4)(0.5, 0.69, 1.0, 1)) + # Say we have no preference between rendering speed and quality. + glHint(GL_FOG_HINT, GL_DONT_CARE) + # Specify the equation used to compute the blending factor. + glFogi(GL_FOG_MODE, GL_LINEAR) + # How close and far away fog starts and ends. The closer the start and end, + # the denser the fog in the fog range. + glFogf(GL_FOG_START, 20.0) + glFogf(GL_FOG_END, 60.0) + + +def setup(): + """ Basic OpenGL configuration. + + """ + # Set the color of "clear", i.e. the sky, in rgba. + glClearColor(0.5, 0.69, 1.0, 1) + # Enable culling (not rendering) of back-facing facets -- facets that aren't + # visible to you. + glEnable(GL_CULL_FACE) + # Set the texture minification/magnification function to GL_NEAREST (nearest + # in Manhattan distance) to the specified texture coordinates. GL_NEAREST + # "is generally faster than GL_LINEAR, but it can produce textured images + # with sharper edges because the transition between texture elements is not + # as smooth." + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST) + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST) + setup_fog() + + +def main(): + window = Window(width=800, height=600, caption='Pyglet', resizable=True) + # Hide the mouse cursor and prevent the mouse from leaving the window. + window.set_exclusive_mouse(True) + setup() + pyglet.app.run() + + +if __name__ == '__main__': + main() diff --git a/texture.png b/OLD/texture.png similarity index 100% rename from texture.png rename to OLD/texture.png diff --git a/__pycache__/model.cpython-312.pyc b/__pycache__/model.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..38c38291ba49b05831037db336f0e5be855b30df GIT binary patch literal 18055 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 literal 0 HcmV?d00001 diff --git a/main.py b/main.py index 6332d97a..ad5b12c4 100644 --- a/main.py +++ b/main.py @@ -1,857 +1,9 @@ -from __future__ import division - -import sys -import math -import random -import time - -from collections import deque +from window import Window from pyglet import image from pyglet.gl import * from pyglet.graphics import TextureGroup from pyglet.window import key, mouse -TICKS_PER_SEC = 60 - -# Size of sectors used to ease block loading. -SECTOR_SIZE = 16 - -WALKING_SPEED = 5 -FLYING_SPEED = 15 - -GRAVITY = 20.0 -MAX_JUMP_HEIGHT = 1.0 # About the height of a block. -# To derive the formula for calculating jump speed, first solve -# v_t = v_0 + a * t -# for the time at which you achieve maximum height, where a is the acceleration -# due to gravity and v_t = 0. This gives: -# t = - v_0 / a -# Use t and the desired MAX_JUMP_HEIGHT to solve for v_0 (jump speed) in -# s = s_0 + v_0 * t + (a * t^2) / 2 -JUMP_SPEED = math.sqrt(2 * GRAVITY * MAX_JUMP_HEIGHT) -TERMINAL_VELOCITY = 50 - -PLAYER_HEIGHT = 2 - -if sys.version_info[0] >= 3: - xrange = range - -def cube_vertices(x, y, z, n): - """ Return the vertices of the cube at position x, y, z with size 2*n. - - """ - return [ - x-n,y+n,z-n, x-n,y+n,z+n, x+n,y+n,z+n, x+n,y+n,z-n, # top - x-n,y-n,z-n, x+n,y-n,z-n, x+n,y-n,z+n, x-n,y-n,z+n, # bottom - x-n,y-n,z-n, x-n,y-n,z+n, x-n,y+n,z+n, x-n,y+n,z-n, # left - x+n,y-n,z+n, x+n,y-n,z-n, x+n,y+n,z-n, x+n,y+n,z+n, # right - x-n,y-n,z+n, x+n,y-n,z+n, x+n,y+n,z+n, x-n,y+n,z+n, # front - x+n,y-n,z-n, x-n,y-n,z-n, x-n,y+n,z-n, x+n,y+n,z-n, # back - ] - - -def tex_coord(x, y, n=4): - """ Return the bounding vertices of the texture square. - - """ - m = 1.0 / n - dx = x * m - dy = y * m - return dx, dy, dx + m, dy, dx + m, dy + m, dx, dy + m - - -def tex_coords(top, bottom, side): - """ Return a list of the texture squares for the top, bottom and side. - - """ - top = tex_coord(*top) - bottom = tex_coord(*bottom) - side = tex_coord(*side) - result = [] - result.extend(top) - result.extend(bottom) - result.extend(side * 4) - return result - - -TEXTURE_PATH = 'texture.png' - -GRASS = tex_coords((1, 0), (0, 1), (0, 0)) -SAND = tex_coords((1, 1), (1, 1), (1, 1)) -BRICK = tex_coords((2, 0), (2, 0), (2, 0)) -STONE = tex_coords((2, 1), (2, 1), (2, 1)) - -FACES = [ - ( 0, 1, 0), - ( 0,-1, 0), - (-1, 0, 0), - ( 1, 0, 0), - ( 0, 0, 1), - ( 0, 0,-1), -] - - -def normalize(position): - """ Accepts `position` of arbitrary precision and returns the block - containing that position. - - Parameters - ---------- - position : tuple of len 3 - - Returns - ------- - block_position : tuple of ints of len 3 - - """ - x, y, z = position - x, y, z = (int(round(x)), int(round(y)), int(round(z))) - return (x, y, z) - - -def sectorize(position): - """ Returns a tuple representing the sector for the given `position`. - - Parameters - ---------- - position : tuple of len 3 - - Returns - ------- - sector : tuple of len 3 - - """ - x, y, z = normalize(position) - x, y, z = x // SECTOR_SIZE, y // SECTOR_SIZE, z // SECTOR_SIZE - return (x, 0, z) - - -class Model(object): - - def __init__(self): - - # A Batch is a collection of vertex lists for batched rendering. - self.batch = pyglet.graphics.Batch() - - # A TextureGroup manages an OpenGL texture. - self.group = TextureGroup(image.load(TEXTURE_PATH).get_texture()) - - # A mapping from position to the texture of the block at that position. - # This defines all the blocks that are currently in the world. - self.world = {} - - # Same mapping as `world` but only contains blocks that are shown. - self.shown = {} - - # Mapping from position to a pyglet `VertextList` for all shown blocks. - self._shown = {} - - # Mapping from sector to a list of positions inside that sector. - self.sectors = {} - - # Simple function queue implementation. The queue is populated with - # _show_block() and _hide_block() calls - self.queue = deque() - - self._initialize() - - def _initialize(self): - """ Initialize the world by placing all the blocks. - - """ - n = 80 # 1/2 width and height of world - s = 1 # step size - y = 0 # initial y height - for x in xrange(-n, n + 1, s): - for z in xrange(-n, n + 1, s): - # create a layer stone an grass everywhere. - self.add_block((x, y - 2, z), GRASS, immediate=False) - self.add_block((x, y - 3, z), STONE, immediate=False) - if x in (-n, n) or z in (-n, n): - # create outer walls. - for dy in xrange(-2, 3): - self.add_block((x, y + dy, z), STONE, immediate=False) - - # generate the hills randomly - o = n - 10 - for _ in xrange(120): - a = random.randint(-o, o) # x position of the hill - b = random.randint(-o, o) # z position of the hill - c = -1 # base of the hill - h = random.randint(1, 6) # height of the hill - s = random.randint(4, 8) # 2 * s is the side length of the hill - d = 1 # how quickly to taper off the hills - t = random.choice([GRASS, SAND, BRICK]) - for y in xrange(c, c + h): - for x in xrange(a - s, a + s + 1): - for z in xrange(b - s, b + s + 1): - if (x - a) ** 2 + (z - b) ** 2 > (s + 1) ** 2: - continue - if (x - 0) ** 2 + (z - 0) ** 2 < 5 ** 2: - continue - self.add_block((x, y, z), t, immediate=False) - s -= d # decrement side length so hills taper off - - def hit_test(self, position, vector, max_distance=8): - """ Line of sight search from current position. If a block is - intersected it is returned, along with the block previously in the line - of sight. If no block is found, return None, None. - - Parameters - ---------- - position : tuple of len 3 - The (x, y, z) position to check visibility from. - vector : tuple of len 3 - The line of sight vector. - max_distance : int - How many blocks away to search for a hit. - - """ - m = 8 - x, y, z = position - dx, dy, dz = vector - previous = None - for _ in xrange(max_distance * m): - key = normalize((x, y, z)) - if key != previous and key in self.world: - return key, previous - previous = key - x, y, z = x + dx / m, y + dy / m, z + dz / m - return None, None - - def exposed(self, position): - """ Returns False is given `position` is surrounded on all 6 sides by - blocks, True otherwise. - - """ - x, y, z = position - for dx, dy, dz in FACES: - if (x + dx, y + dy, z + dz) not in self.world: - return True - return False - - def add_block(self, position, texture, immediate=True): - """ Add a block with the given `texture` and `position` to the world. - - Parameters - ---------- - position : tuple of len 3 - The (x, y, z) position of the block to add. - texture : list of len 3 - The coordinates of the texture squares. Use `tex_coords()` to - generate. - immediate : bool - Whether or not to draw the block immediately. - - """ - if position in self.world: - self.remove_block(position, immediate) - self.world[position] = texture - self.sectors.setdefault(sectorize(position), []).append(position) - if immediate: - if self.exposed(position): - self.show_block(position) - self.check_neighbors(position) - - def remove_block(self, position, immediate=True): - """ Remove the block at the given `position`. - - Parameters - ---------- - position : tuple of len 3 - The (x, y, z) position of the block to remove. - immediate : bool - Whether or not to immediately remove block from canvas. - - """ - del self.world[position] - self.sectors[sectorize(position)].remove(position) - if immediate: - if position in self.shown: - self.hide_block(position) - self.check_neighbors(position) - - def check_neighbors(self, position): - """ Check all blocks surrounding `position` and ensure their visual - state is current. This means hiding blocks that are not exposed and - ensuring that all exposed blocks are shown. Usually used after a block - is added or removed. - - """ - x, y, z = position - for dx, dy, dz in FACES: - key = (x + dx, y + dy, z + dz) - if key not in self.world: - continue - if self.exposed(key): - if key not in self.shown: - self.show_block(key) - else: - if key in self.shown: - self.hide_block(key) - - def show_block(self, position, immediate=True): - """ Show the block at the given `position`. This method assumes the - block has already been added with add_block() - - Parameters - ---------- - position : tuple of len 3 - The (x, y, z) position of the block to show. - immediate : bool - Whether or not to show the block immediately. - - """ - texture = self.world[position] - self.shown[position] = texture - if immediate: - self._show_block(position, texture) - else: - self._enqueue(self._show_block, position, texture) - - def _show_block(self, position, texture): - """ Private implementation of the `show_block()` method. - - Parameters - ---------- - position : tuple of len 3 - The (x, y, z) position of the block to show. - texture : list of len 3 - The coordinates of the texture squares. Use `tex_coords()` to - generate. - - """ - x, y, z = position - vertex_data = cube_vertices(x, y, z, 0.5) - texture_data = list(texture) - # create vertex list - # FIXME Maybe `add_indexed()` should be used instead - self._shown[position] = self.batch.add(24, GL_QUADS, self.group, - ('v3f/static', vertex_data), - ('t2f/static', texture_data)) - - def hide_block(self, position, immediate=True): - """ Hide the block at the given `position`. Hiding does not remove the - block from the world. - - Parameters - ---------- - position : tuple of len 3 - The (x, y, z) position of the block to hide. - immediate : bool - Whether or not to immediately remove the block from the canvas. - - """ - self.shown.pop(position) - if immediate: - self._hide_block(position) - else: - self._enqueue(self._hide_block, position) - - def _hide_block(self, position): - """ Private implementation of the 'hide_block()` method. - - """ - self._shown.pop(position).delete() - - def show_sector(self, sector): - """ Ensure all blocks in the given sector that should be shown are - drawn to the canvas. - - """ - for position in self.sectors.get(sector, []): - if position not in self.shown and self.exposed(position): - self.show_block(position, False) - - def hide_sector(self, sector): - """ Ensure all blocks in the given sector that should be hidden are - removed from the canvas. - - """ - for position in self.sectors.get(sector, []): - if position in self.shown: - self.hide_block(position, False) - - def change_sectors(self, before, after): - """ Move from sector `before` to sector `after`. A sector is a - contiguous x, y sub-region of world. Sectors are used to speed up - world rendering. - - """ - before_set = set() - after_set = set() - pad = 4 - for dx in xrange(-pad, pad + 1): - for dy in [0]: # xrange(-pad, pad + 1): - for dz in xrange(-pad, pad + 1): - if dx ** 2 + dy ** 2 + dz ** 2 > (pad + 1) ** 2: - continue - if before: - x, y, z = before - before_set.add((x + dx, y + dy, z + dz)) - if after: - x, y, z = after - after_set.add((x + dx, y + dy, z + dz)) - show = after_set - before_set - hide = before_set - after_set - for sector in show: - self.show_sector(sector) - for sector in hide: - self.hide_sector(sector) - - def _enqueue(self, func, *args): - """ Add `func` to the internal queue. - - """ - self.queue.append((func, args)) - - def _dequeue(self): - """ Pop the top function from the internal queue and call it. - - """ - func, args = self.queue.popleft() - func(*args) - - def process_queue(self): - """ Process the entire queue while taking periodic breaks. This allows - the game loop to run smoothly. The queue contains calls to - _show_block() and _hide_block() so this method should be called if - add_block() or remove_block() was called with immediate=False - - """ - start = time.perf_counter() - while self.queue and time.perf_counter() - start < 1.0 / TICKS_PER_SEC: - self._dequeue() - - def process_entire_queue(self): - """ Process the entire queue with no breaks. - - """ - while self.queue: - self._dequeue() - - -class Window(pyglet.window.Window): - - def __init__(self, *args, **kwargs): - super(Window, self).__init__(*args, **kwargs) - - # Whether or not the window exclusively captures the mouse. - self.exclusive = False - - # When flying gravity has no effect and speed is increased. - self.flying = False - - # Strafing is moving lateral to the direction you are facing, - # e.g. moving to the left or right while continuing to face forward. - # - # First element is -1 when moving forward, 1 when moving back, and 0 - # otherwise. The second element is -1 when moving left, 1 when moving - # right, and 0 otherwise. - self.strafe = [0, 0] - - # Current (x, y, z) position in the world, specified with floats. Note - # that, perhaps unlike in math class, the y-axis is the vertical axis. - self.position = (0, 0, 0) - - # First element is rotation of the player in the x-z plane (ground - # plane) measured from the z-axis down. The second is the rotation - # angle from the ground plane up. Rotation is in degrees. - # - # The vertical plane rotation ranges from -90 (looking straight down) to - # 90 (looking straight up). The horizontal rotation range is unbounded. - self.rotation = (0, 0) - - # Which sector the player is currently in. - self.sector = None - - # The crosshairs at the center of the screen. - self.reticle = None - - # Velocity in the y (upward) direction. - self.dy = 0 - - # A list of blocks the player can place. Hit num keys to cycle. - self.inventory = [BRICK, GRASS, SAND] - - # The current block the user can place. Hit num keys to cycle. - self.block = self.inventory[0] - - # Convenience list of num keys. - self.num_keys = [ - key._1, key._2, key._3, key._4, key._5, - key._6, key._7, key._8, key._9, key._0] - - # Instance of the model that handles the world. - self.model = Model() - - # The label that is displayed in the top left of the canvas. - self.label = pyglet.text.Label('', font_name='Arial', font_size=18, - x=10, y=self.height - 10, anchor_x='left', anchor_y='top', - color=(0, 0, 0, 255)) - - # This call schedules the `update()` method to be called - # TICKS_PER_SEC. This is the main game event loop. - pyglet.clock.schedule_interval(self.update, 1.0 / TICKS_PER_SEC) - - def set_exclusive_mouse(self, exclusive): - """ If `exclusive` is True, the game will capture the mouse, if False - the game will ignore the mouse. - - """ - super(Window, self).set_exclusive_mouse(exclusive) - self.exclusive = exclusive - - def get_sight_vector(self): - """ Returns the current line of sight vector indicating the direction - the player is looking. - - """ - x, y = self.rotation - # y ranges from -90 to 90, or -pi/2 to pi/2, so m ranges from 0 to 1 and - # is 1 when looking ahead parallel to the ground and 0 when looking - # straight up or down. - m = math.cos(math.radians(y)) - # dy ranges from -1 to 1 and is -1 when looking straight down and 1 when - # looking straight up. - dy = math.sin(math.radians(y)) - dx = math.cos(math.radians(x - 90)) * m - dz = math.sin(math.radians(x - 90)) * m - return (dx, dy, dz) - - def get_motion_vector(self): - """ Returns the current motion vector indicating the velocity of the - player. - - Returns - ------- - vector : tuple of len 3 - Tuple containing the velocity in x, y, and z respectively. - - """ - if any(self.strafe): - x, y = self.rotation - strafe = math.degrees(math.atan2(*self.strafe)) - y_angle = math.radians(y) - x_angle = math.radians(x + strafe) - if self.flying: - m = math.cos(y_angle) - dy = math.sin(y_angle) - if self.strafe[1]: - # Moving left or right. - dy = 0.0 - m = 1 - if self.strafe[0] > 0: - # Moving backwards. - dy *= -1 - # When you are flying up or down, you have less left and right - # motion. - dx = math.cos(x_angle) * m - dz = math.sin(x_angle) * m - else: - dy = 0.0 - dx = math.cos(x_angle) - dz = math.sin(x_angle) - else: - dy = 0.0 - dx = 0.0 - dz = 0.0 - return (dx, dy, dz) - - def update(self, dt): - """ This method is scheduled to be called repeatedly by the pyglet - clock. - - Parameters - ---------- - dt : float - The change in time since the last call. - - """ - self.model.process_queue() - sector = sectorize(self.position) - if sector != self.sector: - self.model.change_sectors(self.sector, sector) - if self.sector is None: - self.model.process_entire_queue() - self.sector = sector - m = 8 - dt = min(dt, 0.2) - for _ in xrange(m): - self._update(dt / m) - - def _update(self, dt): - """ Private implementation of the `update()` method. This is where most - of the motion logic lives, along with gravity and collision detection. - - Parameters - ---------- - dt : float - The change in time since the last call. - - """ - # walking - speed = FLYING_SPEED if self.flying else WALKING_SPEED - d = dt * speed # distance covered this tick. - dx, dy, dz = self.get_motion_vector() - # New position in space, before accounting for gravity. - dx, dy, dz = dx * d, dy * d, dz * d - # gravity - if not self.flying: - # Update your vertical speed: if you are falling, speed up until you - # hit terminal velocity; if you are jumping, slow down until you - # start falling. - self.dy -= dt * GRAVITY - self.dy = max(self.dy, -TERMINAL_VELOCITY) - dy += self.dy * dt - # collisions - x, y, z = self.position - x, y, z = self.collide((x + dx, y + dy, z + dz), PLAYER_HEIGHT) - self.position = (x, y, z) - - def collide(self, position, height): - """ Checks to see if the player at the given `position` and `height` - is colliding with any blocks in the world. - - Parameters - ---------- - position : tuple of len 3 - The (x, y, z) position to check for collisions at. - height : int or float - The height of the player. - - Returns - ------- - position : tuple of len 3 - The new position of the player taking into account collisions. - - """ - # How much overlap with a dimension of a surrounding block you need to - # have to count as a collision. If 0, touching terrain at all counts as - # a collision. If .49, you sink into the ground, as if walking through - # tall grass. If >= .5, you'll fall through the ground. - pad = 0.25 - p = list(position) - np = normalize(position) - for face in FACES: # check all surrounding blocks - for i in xrange(3): # check each dimension independently - if not face[i]: - continue - # How much overlap you have with this dimension. - d = (p[i] - np[i]) * face[i] - if d < pad: - continue - for dy in xrange(height): # check each height - op = list(np) - op[1] -= dy - op[i] += face[i] - if tuple(op) not in self.model.world: - continue - p[i] -= (d - pad) * face[i] - if face == (0, -1, 0) or face == (0, 1, 0): - # You are colliding with the ground or ceiling, so stop - # falling / rising. - self.dy = 0 - break - return tuple(p) - - def on_mouse_press(self, x, y, button, modifiers): - """ Called when a mouse button is pressed. See pyglet docs for button - amd modifier mappings. - - Parameters - ---------- - x, y : int - The coordinates of the mouse click. Always center of the screen if - the mouse is captured. - button : int - Number representing mouse button that was clicked. 1 = left button, - 4 = right button. - modifiers : int - Number representing any modifying keys that were pressed when the - mouse button was clicked. - - """ - if self.exclusive: - vector = self.get_sight_vector() - block, previous = self.model.hit_test(self.position, vector) - if (button == mouse.RIGHT) or \ - ((button == mouse.LEFT) and (modifiers & key.MOD_CTRL)): - # ON OSX, control + left click = right click. - if previous: - self.model.add_block(previous, self.block) - elif button == pyglet.window.mouse.LEFT and block: - texture = self.model.world[block] - if texture != STONE: - self.model.remove_block(block) - else: - self.set_exclusive_mouse(True) - - def on_mouse_motion(self, x, y, dx, dy): - """ Called when the player moves the mouse. - - Parameters - ---------- - x, y : int - The coordinates of the mouse click. Always center of the screen if - the mouse is captured. - dx, dy : float - The movement of the mouse. - - """ - if self.exclusive: - m = 0.15 - x, y = self.rotation - x, y = x + dx * m, y + dy * m - y = max(-90, min(90, y)) - self.rotation = (x, y) - - def on_key_press(self, symbol, modifiers): - """ Called when the player presses a key. See pyglet docs for key - mappings. - - Parameters - ---------- - symbol : int - Number representing the key that was pressed. - modifiers : int - Number representing any modifying keys that were pressed. - - """ - if symbol == key.W: - self.strafe[0] -= 1 - elif symbol == key.S: - self.strafe[0] += 1 - elif symbol == key.A: - self.strafe[1] -= 1 - elif symbol == key.D: - self.strafe[1] += 1 - elif symbol == key.SPACE: - if self.dy == 0: - self.dy = JUMP_SPEED - elif symbol == key.ESCAPE: - self.set_exclusive_mouse(False) - elif symbol == key.TAB: - self.flying = not self.flying - elif symbol in self.num_keys: - index = (symbol - self.num_keys[0]) % len(self.inventory) - self.block = self.inventory[index] - - def on_key_release(self, symbol, modifiers): - """ Called when the player releases a key. See pyglet docs for key - mappings. - - Parameters - ---------- - symbol : int - Number representing the key that was pressed. - modifiers : int - Number representing any modifying keys that were pressed. - - """ - if symbol == key.W: - self.strafe[0] += 1 - elif symbol == key.S: - self.strafe[0] -= 1 - elif symbol == key.A: - self.strafe[1] += 1 - elif symbol == key.D: - self.strafe[1] -= 1 - - def on_resize(self, width, height): - """ Called when the window is resized to a new `width` and `height`. - - """ - # label - self.label.y = height - 10 - # reticle - if self.reticle: - self.reticle.delete() - x, y = self.width // 2, self.height // 2 - n = 10 - self.reticle = pyglet.graphics.vertex_list(4, - ('v2i', (x - n, y, x + n, y, x, y - n, x, y + n)) - ) - - def set_2d(self): - """ Configure OpenGL to draw in 2d. - - """ - width, height = self.get_size() - glDisable(GL_DEPTH_TEST) - viewport = self.get_viewport_size() - glViewport(0, 0, max(1, viewport[0]), max(1, viewport[1])) - glMatrixMode(GL_PROJECTION) - glLoadIdentity() - glOrtho(0, max(1, width), 0, max(1, height), -1, 1) - glMatrixMode(GL_MODELVIEW) - glLoadIdentity() - - def set_3d(self): - """ Configure OpenGL to draw in 3d. - - """ - width, height = self.get_size() - glEnable(GL_DEPTH_TEST) - viewport = self.get_viewport_size() - glViewport(0, 0, max(1, viewport[0]), max(1, viewport[1])) - glMatrixMode(GL_PROJECTION) - glLoadIdentity() - gluPerspective(65.0, width / float(height), 0.1, 60.0) - glMatrixMode(GL_MODELVIEW) - glLoadIdentity() - x, y = self.rotation - glRotatef(x, 0, 1, 0) - glRotatef(-y, math.cos(math.radians(x)), 0, math.sin(math.radians(x))) - x, y, z = self.position - glTranslatef(-x, -y, -z) - - def on_draw(self): - """ Called by pyglet to draw the canvas. - - """ - self.clear() - self.set_3d() - glColor3d(1, 1, 1) - self.model.batch.draw() - self.draw_focused_block() - self.set_2d() - self.draw_label() - self.draw_reticle() - - def draw_focused_block(self): - """ Draw black edges around the block that is currently under the - crosshairs. - - """ - vector = self.get_sight_vector() - block = self.model.hit_test(self.position, vector)[0] - if block: - x, y, z = block - vertex_data = cube_vertices(x, y, z, 0.51) - glColor3d(0, 0, 0) - glPolygonMode(GL_FRONT_AND_BACK, GL_LINE) - pyglet.graphics.draw(24, GL_QUADS, ('v3f/static', vertex_data)) - glPolygonMode(GL_FRONT_AND_BACK, GL_FILL) - - def draw_label(self): - """ Draw the label in the top left of the screen. - - """ - x, y, z = self.position - self.label.text = '%02d (%.2f, %.2f, %.2f) %d / %d' % ( - pyglet.clock.get_fps(), x, y, z, - len(self.model._shown), len(self.model.world)) - self.label.draw() - - def draw_reticle(self): - """ Draw the crosshairs in the center of the screen. - - """ - glColor3d(0, 0, 0) - self.reticle.draw(GL_LINES) - - def setup_fog(): """ Configure the OpenGL fog properties. @@ -870,7 +22,6 @@ def setup_fog(): glFogf(GL_FOG_START, 20.0) glFogf(GL_FOG_END, 60.0) - def setup(): """ Basic OpenGL configuration. @@ -889,7 +40,6 @@ def setup(): glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST) setup_fog() - def main(): window = Window(width=800, height=600, caption='Pyglet', resizable=True) # Hide the mouse cursor and prevent the mouse from leaving the window. @@ -897,6 +47,5 @@ def main(): setup() pyglet.app.run() - if __name__ == '__main__': - main() + main() \ No newline at end of file diff --git a/model.py b/model.py new file mode 100644 index 00000000..e4ec38b3 --- /dev/null +++ b/model.py @@ -0,0 +1,413 @@ +from __future__ import division + +import sys +import math +import random +import time + +from collections import deque +from pyglet import image +from pyglet.gl import * +from pyglet.graphics import TextureGroup +from pyglet.window import key, mouse + +if sys.version_info[0] >= 3: + xrange = range + +# Size of sectors used to ease block loading. +SECTOR_SIZE = 16 + +TICKS_PER_SEC = 60 + +def cube_vertices(x, y, z, n): + """ Return the vertices of the cube at position x, y, z with size 2*n. + + """ + return [ + x-n,y+n,z-n, x-n,y+n,z+n, x+n,y+n,z+n, x+n,y+n,z-n, # top + x-n,y-n,z-n, x+n,y-n,z-n, x+n,y-n,z+n, x-n,y-n,z+n, # bottom + x-n,y-n,z-n, x-n,y-n,z+n, x-n,y+n,z+n, x-n,y+n,z-n, # left + x+n,y-n,z+n, x+n,y-n,z-n, x+n,y+n,z-n, x+n,y+n,z+n, # right + x-n,y-n,z+n, x+n,y-n,z+n, x+n,y+n,z+n, x-n,y+n,z+n, # front + x+n,y-n,z-n, x-n,y-n,z-n, x-n,y+n,z-n, x+n,y+n,z-n, # back + ] + + +def tex_coord(x, y, n=4): + """ Return the bounding vertices of the texture square. + + """ + m = 1.0 / n + dx = x * m + dy = y * m + return dx, dy, dx + m, dy, dx + m, dy + m, dx, dy + m + + +def tex_coords(top, bottom, side): + """ Return a list of the texture squares for the top, bottom and side. + + """ + top = tex_coord(*top) + bottom = tex_coord(*bottom) + side = tex_coord(*side) + result = [] + result.extend(top) + result.extend(bottom) + result.extend(side * 4) + return result + + +TEXTURE_PATH = 'OLD/texture.png' + +GRASS = tex_coords((1, 0), (0, 1), (0, 0)) +SAND = tex_coords((1, 1), (1, 1), (1, 1)) +BRICK = tex_coords((2, 0), (2, 0), (2, 0)) +STONE = tex_coords((2, 1), (2, 1), (2, 1)) + +FACES = [ + ( 0, 1, 0), + ( 0,-1, 0), + (-1, 0, 0), + ( 1, 0, 0), + ( 0, 0, 1), + ( 0, 0,-1), +] + + +def normalize(position): + """ Accepts `position` of arbitrary precision and returns the block + containing that position. + + Parameters + ---------- + position : tuple of len 3 + + Returns + ------- + block_position : tuple of ints of len 3 + + """ + x, y, z = position + x, y, z = (int(round(x)), int(round(y)), int(round(z))) + return (x, y, z) + + +def sectorize(position): + """ Returns a tuple representing the sector for the given `position`. + + Parameters + ---------- + position : tuple of len 3 + + Returns + ------- + sector : tuple of len 3 + + """ + x, y, z = normalize(position) + x, y, z = x // SECTOR_SIZE, y // SECTOR_SIZE, z // SECTOR_SIZE + return (x, 0, z) + +class Model(object): + + def __init__(self): + + # A Batch is a collection of vertex lists for batched rendering. + self.batch = pyglet.graphics.Batch() + + # A TextureGroup manages an OpenGL texture. + self.group = TextureGroup(image.load(TEXTURE_PATH).get_texture()) + + # A mapping from position to the texture of the block at that position. + # This defines all the blocks that are currently in the world. + self.world = {} + + # Same mapping as `world` but only contains blocks that are shown. + self.shown = {} + + # Mapping from position to a pyglet `VertextList` for all shown blocks. + self._shown = {} + + # Mapping from sector to a list of positions inside that sector. + self.sectors = {} + + # Simple function queue implementation. The queue is populated with + # _show_block() and _hide_block() calls + self.queue = deque() + + self._initialize() + + def _initialize(self): + """ Initialize the world by placing all the blocks. + + """ + n = 80 # 1/2 width and height of world + s = 1 # step size + y = 0 # initial y height + for x in xrange(-n, n + 1, s): + for z in xrange(-n, n + 1, s): + # create a layer stone an grass everywhere. + self.add_block((x, y - 2, z), GRASS, immediate=False) + self.add_block((x, y - 3, z), STONE, immediate=False) + if x in (-n, n) or z in (-n, n): + # create outer walls. + for dy in xrange(-2, 3): + self.add_block((x, y + dy, z), STONE, immediate=False) + + # generate the hills randomly + o = n - 10 + for _ in xrange(120): + a = random.randint(-o, o) # x position of the hill + b = random.randint(-o, o) # z position of the hill + c = -1 # base of the hill + h = random.randint(1, 6) # height of the hill + s = random.randint(4, 8) # 2 * s is the side length of the hill + d = 1 # how quickly to taper off the hills + t = random.choice([GRASS, SAND, BRICK]) + for y in xrange(c, c + h): + for x in xrange(a - s, a + s + 1): + for z in xrange(b - s, b + s + 1): + if (x - a) ** 2 + (z - b) ** 2 > (s + 1) ** 2: + continue + if (x - 0) ** 2 + (z - 0) ** 2 < 5 ** 2: + continue + self.add_block((x, y, z), t, immediate=False) + s -= d # decrement side length so hills taper off + + def hit_test(self, position, vector, max_distance=8): + """ Line of sight search from current position. If a block is + intersected it is returned, along with the block previously in the line + of sight. If no block is found, return None, None. + + Parameters + ---------- + position : tuple of len 3 + The (x, y, z) position to check visibility from. + vector : tuple of len 3 + The line of sight vector. + max_distance : int + How many blocks away to search for a hit. + + """ + m = 8 + x, y, z = position + dx, dy, dz = vector + previous = None + for _ in xrange(max_distance * m): + key = normalize((x, y, z)) + if key != previous and key in self.world: + return key, previous + previous = key + x, y, z = x + dx / m, y + dy / m, z + dz / m + return None, None + + def exposed(self, position): + """ Returns False is given `position` is surrounded on all 6 sides by + blocks, True otherwise. + + """ + x, y, z = position + for dx, dy, dz in FACES: + if (x + dx, y + dy, z + dz) not in self.world: + return True + return False + + def add_block(self, position, texture, immediate=True): + """ Add a block with the given `texture` and `position` to the world. + + Parameters + ---------- + position : tuple of len 3 + The (x, y, z) position of the block to add. + texture : list of len 3 + The coordinates of the texture squares. Use `tex_coords()` to + generate. + immediate : bool + Whether or not to draw the block immediately. + + """ + if position in self.world: + self.remove_block(position, immediate) + self.world[position] = texture + self.sectors.setdefault(sectorize(position), []).append(position) + if immediate: + if self.exposed(position): + self.show_block(position) + self.check_neighbors(position) + + def remove_block(self, position, immediate=True): + """ Remove the block at the given `position`. + + Parameters + ---------- + position : tuple of len 3 + The (x, y, z) position of the block to remove. + immediate : bool + Whether or not to immediately remove block from canvas. + + """ + del self.world[position] + self.sectors[sectorize(position)].remove(position) + if immediate: + if position in self.shown: + self.hide_block(position) + self.check_neighbors(position) + + def check_neighbors(self, position): + """ Check all blocks surrounding `position` and ensure their visual + state is current. This means hiding blocks that are not exposed and + ensuring that all exposed blocks are shown. Usually used after a block + is added or removed. + + """ + x, y, z = position + for dx, dy, dz in FACES: + key = (x + dx, y + dy, z + dz) + if key not in self.world: + continue + if self.exposed(key): + if key not in self.shown: + self.show_block(key) + else: + if key in self.shown: + self.hide_block(key) + + def show_block(self, position, immediate=True): + """ Show the block at the given `position`. This method assumes the + block has already been added with add_block() + + Parameters + ---------- + position : tuple of len 3 + The (x, y, z) position of the block to show. + immediate : bool + Whether or not to show the block immediately. + + """ + texture = self.world[position] + self.shown[position] = texture + if immediate: + self._show_block(position, texture) + else: + self._enqueue(self._show_block, position, texture) + + def _show_block(self, position, texture): + """ Private implementation of the `show_block()` method. + + Parameters + ---------- + position : tuple of len 3 + The (x, y, z) position of the block to show. + texture : list of len 3 + The coordinates of the texture squares. Use `tex_coords()` to + generate. + + """ + x, y, z = position + vertex_data = cube_vertices(x, y, z, 0.5) + texture_data = list(texture) + # create vertex list + # FIXME Maybe `add_indexed()` should be used instead + self._shown[position] = self.batch.add(24, GL_QUADS, self.group, + ('v3f/static', vertex_data), + ('t2f/static', texture_data)) + + def hide_block(self, position, immediate=True): + """ Hide the block at the given `position`. Hiding does not remove the + block from the world. + + Parameters + ---------- + position : tuple of len 3 + The (x, y, z) position of the block to hide. + immediate : bool + Whether or not to immediately remove the block from the canvas. + + """ + self.shown.pop(position) + if immediate: + self._hide_block(position) + else: + self._enqueue(self._hide_block, position) + + def _hide_block(self, position): + """ Private implementation of the 'hide_block()` method. + + """ + self._shown.pop(position).delete() + + def show_sector(self, sector): + """ Ensure all blocks in the given sector that should be shown are + drawn to the canvas. + + """ + for position in self.sectors.get(sector, []): + if position not in self.shown and self.exposed(position): + self.show_block(position, False) + + def hide_sector(self, sector): + """ Ensure all blocks in the given sector that should be hidden are + removed from the canvas. + + """ + for position in self.sectors.get(sector, []): + if position in self.shown: + self.hide_block(position, False) + + def change_sectors(self, before, after): + """ Move from sector `before` to sector `after`. A sector is a + contiguous x, y sub-region of world. Sectors are used to speed up + world rendering. + + """ + before_set = set() + after_set = set() + pad = 4 + for dx in xrange(-pad, pad + 1): + for dy in [0]: # xrange(-pad, pad + 1): + for dz in xrange(-pad, pad + 1): + if dx ** 2 + dy ** 2 + dz ** 2 > (pad + 1) ** 2: + continue + if before: + x, y, z = before + before_set.add((x + dx, y + dy, z + dz)) + if after: + x, y, z = after + after_set.add((x + dx, y + dy, z + dz)) + show = after_set - before_set + hide = before_set - after_set + for sector in show: + self.show_sector(sector) + for sector in hide: + self.hide_sector(sector) + + def _enqueue(self, func, *args): + """ Add `func` to the internal queue. + + """ + self.queue.append((func, args)) + + def _dequeue(self): + """ Pop the top function from the internal queue and call it. + + """ + func, args = self.queue.popleft() + func(*args) + + def process_queue(self): + """ Process the entire queue while taking periodic breaks. This allows + the game loop to run smoothly. The queue contains calls to + _show_block() and _hide_block() so this method should be called if + add_block() or remove_block() was called with immediate=False + + """ + start = time.perf_counter() + while self.queue and time.perf_counter() - start < 1.0 / TICKS_PER_SEC: + self._dequeue() + + def process_entire_queue(self): + """ Process the entire queue with no breaks. + + """ + while self.queue: + self._dequeue() \ No newline at end of file diff --git a/window.py b/window.py new file mode 100644 index 00000000..1943248d --- /dev/null +++ b/window.py @@ -0,0 +1,452 @@ +from __future__ import division + +import sys +import math +import random +import time +import model + +from collections import deque +from pyglet import image +from pyglet.gl import * +from pyglet.graphics import TextureGroup +from pyglet.window import key, mouse + + + +WALKING_SPEED = 5 +FLYING_SPEED = 15 + +GRAVITY = 20.0 +MAX_JUMP_HEIGHT = 1.0 # About the height of a block. +# To derive the formula for calculating jump speed, first solve +# v_t = v_0 + a * t +# for the time at which you achieve maximum height, where a is the acceleration +# due to gravity and v_t = 0. This gives: +# t = - v_0 / a +# Use t and the desired MAX_JUMP_HEIGHT to solve for v_0 (jump speed) in +# s = s_0 + v_0 * t + (a * t^2) / 2 +JUMP_SPEED = math.sqrt(2 * GRAVITY * MAX_JUMP_HEIGHT) +TERMINAL_VELOCITY = 50 + +PLAYER_HEIGHT = 2 + +class Window(pyglet.window.Window): + + def __init__(self, *args, **kwargs): + super(Window, self).__init__(*args, **kwargs) + + # Whether or not the window exclusively captures the mouse. + self.exclusive = False + + # When flying gravity has no effect and speed is increased. + self.flying = False + + # Strafing is moving lateral to the direction you are facing, + # e.g. moving to the left or right while continuing to face forward. + # + # First element is -1 when moving forward, 1 when moving back, and 0 + # otherwise. The second element is -1 when moving left, 1 when moving + # right, and 0 otherwise. + self.strafe = [0, 0] + + # Current (x, y, z) position in the world, specified with floats. Note + # that, perhaps unlike in math class, the y-axis is the vertical axis. + self.position = (0, 0, 0) + + # First element is rotation of the player in the x-z plane (ground + # plane) measured from the z-axis down. The second is the rotation + # angle from the ground plane up. Rotation is in degrees. + # + # The vertical plane rotation ranges from -90 (looking straight down) to + # 90 (looking straight up). The horizontal rotation range is unbounded. + self.rotation = (0, 0) + + # Which sector the player is currently in. + self.sector = None + + # The crosshairs at the center of the screen. + self.reticle = None + + # Velocity in the y (upward) direction. + self.dy = 0 + + # A list of blocks the player can place. Hit num keys to cycle. + self.inventory = [model.BRICK, model.GRASS, model.SAND] + + # The current block the user can place. Hit num keys to cycle. + self.block = self.inventory[0] + + # Convenience list of num keys. + self.num_keys = [ + key._1, key._2, key._3, key._4, key._5, + key._6, key._7, key._8, key._9, key._0] + + # Instance of the model that handles the world. + self.model = model.Model() + + # The label that is displayed in the top left of the canvas. + self.label = pyglet.text.Label('', font_name='Arial', font_size=18, + x=10, y=self.height - 10, anchor_x='left', anchor_y='top', + color=(0, 0, 0, 255)) + + # This call schedules the `update()` method to be called + # TICKS_PER_SEC. This is the main game event loop. + pyglet.clock.schedule_interval(self.update, 1.0 / model.TICKS_PER_SEC) + + def set_exclusive_mouse(self, exclusive): + """ If `exclusive` is True, the game will capture the mouse, if False + the game will ignore the mouse. + + """ + super(Window, self).set_exclusive_mouse(exclusive) + self.exclusive = exclusive + + def get_sight_vector(self): + """ Returns the current line of sight vector indicating the direction + the player is looking. + + """ + x, y = self.rotation + # y ranges from -90 to 90, or -pi/2 to pi/2, so m ranges from 0 to 1 and + # is 1 when looking ahead parallel to the ground and 0 when looking + # straight up or down. + m = math.cos(math.radians(y)) + # dy ranges from -1 to 1 and is -1 when looking straight down and 1 when + # looking straight up. + dy = math.sin(math.radians(y)) + dx = math.cos(math.radians(x - 90)) * m + dz = math.sin(math.radians(x - 90)) * m + return (dx, dy, dz) + + def get_motion_vector(self): + """ Returns the current motion vector indicating the velocity of the + player. + + Returns + ------- + vector : tuple of len 3 + Tuple containing the velocity in x, y, and z respectively. + + """ + if any(self.strafe): + x, y = self.rotation + strafe = math.degrees(math.atan2(*self.strafe)) + y_angle = math.radians(y) + x_angle = math.radians(x + strafe) + if self.flying: + m = math.cos(y_angle) + dy = math.sin(y_angle) + if self.strafe[1]: + # Moving left or right. + dy = 0.0 + m = 1 + if self.strafe[0] > 0: + # Moving backwards. + dy *= -1 + # When you are flying up or down, you have less left and right + # motion. + dx = math.cos(x_angle) * m + dz = math.sin(x_angle) * m + else: + dy = 0.0 + dx = math.cos(x_angle) + dz = math.sin(x_angle) + else: + dy = 0.0 + dx = 0.0 + dz = 0.0 + return (dx, dy, dz) + + def update(self, dt): + """ This method is scheduled to be called repeatedly by the pyglet + clock. + + Parameters + ---------- + dt : float + The change in time since the last call. + + """ + self.model.process_queue() + sector = model.sectorize(self.position) + if sector != self.sector: + self.model.change_sectors(self.sector, sector) + if self.sector is None: + self.model.process_entire_queue() + self.sector = sector + m = 8 + dt = min(dt, 0.2) + for _ in model.xrange(m): + self._update(dt / m) + + def _update(self, dt): + """ Private implementation of the `update()` method. This is where most + of the motion logic lives, along with gravity and collision detection. + + Parameters + ---------- + dt : float + The change in time since the last call. + + """ + # walking + speed = FLYING_SPEED if self.flying else WALKING_SPEED + d = dt * speed # distance covered this tick. + dx, dy, dz = self.get_motion_vector() + # New position in space, before accounting for gravity. + dx, dy, dz = dx * d, dy * d, dz * d + # gravity + if not self.flying: + # Update your vertical speed: if you are falling, speed up until you + # hit terminal velocity; if you are jumping, slow down until you + # start falling. + self.dy -= dt * GRAVITY + self.dy = max(self.dy, -TERMINAL_VELOCITY) + dy += self.dy * dt + # collisions + x, y, z = self.position + x, y, z = self.collide((x + dx, y + dy, z + dz), PLAYER_HEIGHT) + self.position = (x, y, z) + + def collide(self, position, height): + """ Checks to see if the player at the given `position` and `height` + is colliding with any blocks in the world. + + Parameters + ---------- + position : tuple of len 3 + The (x, y, z) position to check for collisions at. + height : int or float + The height of the player. + + Returns + ------- + position : tuple of len 3 + The new position of the player taking into account collisions. + + """ + # How much overlap with a dimension of a surrounding block you need to + # have to count as a collision. If 0, touching terrain at all counts as + # a collision. If .49, you sink into the ground, as if walking through + # tall grass. If >= .5, you'll fall through the ground. + pad = 0.25 + p = list(position) + np = model.normalize(position) + for face in model.FACES: # check all surrounding blocks + for i in model.xrange(3): # check each dimension independently + if not face[i]: + continue + # How much overlap you have with this dimension. + d = (p[i] - np[i]) * face[i] + if d < pad: + continue + for dy in model.xrange(height): # check each height + op = list(np) + op[1] -= dy + op[i] += face[i] + if tuple(op) not in self.model.world: + continue + p[i] -= (d - pad) * face[i] + if face == (0, -1, 0) or face == (0, 1, 0): + # You are colliding with the ground or ceiling, so stop + # falling / rising. + self.dy = 0 + break + return tuple(p) + + def on_mouse_press(self, x, y, button, modifiers): + """ Called when a mouse button is pressed. See pyglet docs for button + amd modifier mappings. + + Parameters + ---------- + x, y : int + The coordinates of the mouse click. Always center of the screen if + the mouse is captured. + button : int + Number representing mouse button that was clicked. 1 = left button, + 4 = right button. + modifiers : int + Number representing any modifying keys that were pressed when the + mouse button was clicked. + + """ + if self.exclusive: + vector = self.get_sight_vector() + block, previous = self.model.hit_test(self.position, vector) + if (button == mouse.RIGHT) or \ + ((button == mouse.LEFT) and (modifiers & key.MOD_CTRL)): + # ON OSX, control + left click = right click. + if previous: + self.model.add_block(previous, self.block) + elif button == pyglet.window.mouse.LEFT and block: + texture = self.model.world[block] + if texture != model.STONE: + self.model.remove_block(block) + else: + self.set_exclusive_mouse(True) + + def on_mouse_motion(self, x, y, dx, dy): + """ Called when the player moves the mouse. + + Parameters + ---------- + x, y : int + The coordinates of the mouse click. Always center of the screen if + the mouse is captured. + dx, dy : float + The movement of the mouse. + + """ + if self.exclusive: + m = 0.15 + x, y = self.rotation + x, y = x + dx * m, y + dy * m + y = max(-90, min(90, y)) + self.rotation = (x, y) + + def on_key_press(self, symbol, modifiers): + """ Called when the player presses a key. See pyglet docs for key + mappings. + + Parameters + ---------- + symbol : int + Number representing the key that was pressed. + modifiers : int + Number representing any modifying keys that were pressed. + + """ + if symbol == key.W: + self.strafe[0] -= 1 + elif symbol == key.S: + self.strafe[0] += 1 + elif symbol == key.A: + self.strafe[1] -= 1 + elif symbol == key.D: + self.strafe[1] += 1 + elif symbol == key.SPACE: + if self.dy == 0: + self.dy = JUMP_SPEED + elif symbol == key.ESCAPE: + self.set_exclusive_mouse(False) + elif symbol == key.TAB: + self.flying = not self.flying + elif symbol in self.num_keys: + index = (symbol - self.num_keys[0]) % len(self.inventory) + self.block = self.inventory[index] + + def on_key_release(self, symbol, modifiers): + """ Called when the player releases a key. See pyglet docs for key + mappings. + + Parameters + ---------- + symbol : int + Number representing the key that was pressed. + modifiers : int + Number representing any modifying keys that were pressed. + + """ + if symbol == key.W: + self.strafe[0] += 1 + elif symbol == key.S: + self.strafe[0] -= 1 + elif symbol == key.A: + self.strafe[1] += 1 + elif symbol == key.D: + self.strafe[1] -= 1 + + def on_resize(self, width, height): + """ Called when the window is resized to a new `width` and `height`. + + """ + # label + self.label.y = height - 10 + # reticle + if self.reticle: + self.reticle.delete() + x, y = self.width // 2, self.height // 2 + n = 10 + self.reticle = pyglet.graphics.vertex_list(4, + ('v2i', (x - n, y, x + n, y, x, y - n, x, y + n)) + ) + + def set_2d(self): + """ Configure OpenGL to draw in 2d. + + """ + width, height = self.get_size() + glDisable(GL_DEPTH_TEST) + viewport = self.get_viewport_size() + glViewport(0, 0, max(1, viewport[0]), max(1, viewport[1])) + glMatrixMode(GL_PROJECTION) + glLoadIdentity() + glOrtho(0, max(1, width), 0, max(1, height), -1, 1) + glMatrixMode(GL_MODELVIEW) + glLoadIdentity() + + def set_3d(self): + """ Configure OpenGL to draw in 3d. + + """ + width, height = self.get_size() + glEnable(GL_DEPTH_TEST) + viewport = self.get_viewport_size() + glViewport(0, 0, max(1, viewport[0]), max(1, viewport[1])) + glMatrixMode(GL_PROJECTION) + glLoadIdentity() + gluPerspective(65.0, width / float(height), 0.1, 60.0) + glMatrixMode(GL_MODELVIEW) + glLoadIdentity() + x, y = self.rotation + glRotatef(x, 0, 1, 0) + glRotatef(-y, math.cos(math.radians(x)), 0, math.sin(math.radians(x))) + x, y, z = self.position + glTranslatef(-x, -y, -z) + + def on_draw(self): + """ Called by pyglet to draw the canvas. + + """ + self.clear() + self.set_3d() + glColor3d(1, 1, 1) + self.model.batch.draw() + self.draw_focused_block() + self.set_2d() + self.draw_label() + self.draw_reticle() + + def draw_focused_block(self): + """ Draw black edges around the block that is currently under the + crosshairs. + + """ + vector = self.get_sight_vector() + block = self.model.hit_test(self.position, vector)[0] + if block: + x, y, z = block + vertex_data = model.cube_vertices(x, y, z, 0.51) + glColor3d(0, 0, 0) + glPolygonMode(GL_FRONT_AND_BACK, GL_LINE) + pyglet.graphics.draw(24, GL_QUADS, ('v3f/static', vertex_data)) + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL) + + def draw_label(self): + """ Draw the label in the top left of the screen. + + """ + x, y, z = self.position + self.label.text = '%02d (%.2f, %.2f, %.2f) %d / %d' % ( + pyglet.clock.get_fps(), x, y, z, + len(self.model._shown), len(self.model.world)) + self.label.draw() + + def draw_reticle(self): + """ Draw the crosshairs in the center of the screen. + + """ + glColor3d(0, 0, 0) + self.reticle.draw(GL_LINES) \ No newline at end of file From 7072a1b14b0365ce8a4c23228ea340b2977a773c Mon Sep 17 00:00:00 2001 From: Kyle Wadas Date: Wed, 26 Feb 2025 18:29:59 -0700 Subject: [PATCH 02/46] Added Block File & Restructured --- __pycache__/block.cpython-312.pyc | Bin 0 -> 1183 bytes __pycache__/model.cpython-312.pyc | Bin 18055 -> 17181 bytes __pycache__/window.cpython-312.pyc | Bin 19418 -> 19453 bytes block.py | 26 ++++++++++++++++++ model.py | 41 +++++------------------------ texture.png | Bin 0 -> 5257 bytes window.py | 11 ++++---- 7 files changed, 38 insertions(+), 40 deletions(-) create mode 100644 __pycache__/block.cpython-312.pyc create mode 100644 block.py create mode 100644 texture.png diff --git a/__pycache__/block.cpython-312.pyc b/__pycache__/block.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..132cea88c3b32f264ec1d70d3674475a901fcfd4 GIT binary patch literal 1183 zcmah|O=uHA6rS0?{A`1?wiT`5f)b3B3Oxi`L`hpKMN@0zsRSg=Y|_+px6W=#6H?eh z!So{Osqq#sQt3r+p7bhs3ABfF@#ZPFYCQGio5_zU6nw)>zW2SiZ)V;%`5p-P5t#Yq zYxgdB}9ZBw1fquVsLSS?`k#imbqsvL0 z^AZ?cPR{#6YD0ob$#ywj)CVi`n@?bYBjBP?P!ZY^i>N3T;DB3F5x0?Cl!|PM1;{;z zS`3SFl=8+mqUG@l-V0a8E3_JUyHTYFk#`#h^yBzv{3%>hCu-6}6DpnWFl#yQ@OuFJ$YvXI zE21}OtJlZirSK4u>+kAi(Lo^C-^q%>;-EiXqz;y2rMu4bkHBz6sReF0vp;|$HFd<9sRu4O zvvtY;I=US#-#nIvJ2-eOUG3momHxfk$I?h$?RTOy0Cht`gY~rmlbw4Qe&|pSW(4qz zYV!?tMV<)!l@322!mYb2{OIs=xB3exmkt5| literal 0 HcmV?d00001 diff --git a/__pycache__/model.cpython-312.pyc b/__pycache__/model.cpython-312.pyc index 38c38291ba49b05831037db336f0e5be855b30df..21051fe215f7d72bf1ce63782d63d9c222eaebb7 100644 GIT binary patch delta 2389 zcmZ`)YfKbZ6rMY?yDa-+fqj91s8n2#w^Aay^4h9UtqP=e+qx_}!vgNIaCbrEAvBuS z8fc-nRxq_ff3#3FYNv^5V``iJY0{*zu_ktuwyFAqKZ^cn(k3RoXO@M9q?61y=bm%! zIro0&+&k}#qVsPf!%up>hM`aU&6~c{#p4DWD>37nN_Me+l}p7lJm-%Ks9kErP+8%R z4`^H(SyuYBmswd-`E>!kOE1fDenTL^l@KtxjEE7~_VwfE)>S9DlKFU-iPyNyy!IsH zvhX^W)yMGqPm#;U8>l9QPoS8}GP@Ywc#`20g*6vBSQW##(vGqAB=HUOm_t^vPWc;W z>(hpX-f%Y-@;f_xc9osOEOnemcaaTkouHc;%qGeviwE*AR~}U71PsRpJTbV-__Kocs}+uOJ#z3A#!grflUo zh8a|n%5_%qmdUDXS5fE1hm4uZ&5G!#T^*GehFYxTfhi3&e_&2g=FkW#h_FF1zzwMS zsNaCHg$w`RREuV0vw|7cJAheBqYu&9~s@6P9 z5^Wm`p`7!OcOG^=4}8t1P}pbJNUC1!>F^0syocxA&HkYGh@>PsDgA>Xa~`zY<4uFQ7PTqbVD=Hlhjkt}X3?VbU;zW{PI; zZ0XgaspDUDU+=%x|D!NrxMOR0${}+jda8#s3!FN>kvvT4vRvq&?7!r^Qaf9FLwQsC zwf0s<&26Jobf=1(&mr%W-M5c+X$6%rv?Jb3!EV4MAg57~R6T+>9K@0?;OTYqZK1HI z!z)NAfD^z4>Vgx&kL7!DT}0@U)SX!9X$y9T@Ln>Iu?>AFUeB0DxpHvza`06#@F9o> zLGWwjL}nhkB3{d^=ZayPq{BiW*ds)0feS#T2?=3dXz_IW!#EQZDob|!srG8J$o8O}1HZ^ScMlk5;=l4CE%i{!+4R4r**+xTdDo+@U! zn2pGR;Z|9S+e8O_Nqd95;Lnd;`Y%);a#0v&7A%ZD@%`F&YsY$T=`!!Cb>ijhA-3jC zYLx4M4}%2Bu@|6~f;~Pa>&g|%3o4M2!U~(8s{0Zn zdv}LggGVD(ix(dj4zdL@n_OqGQ_{L)I1NC+HVUB?Jhqat5;MvmpOrk%g><-wf~2Cf z3Sq&{F0&DWyEj_ZqvYo;7E~xc+Tuobxmh@$5RPyuvkHVRR!~xf>;~#2WaG59z`yAdMnbaLn(2zEh8tY3tWx^3{$Wt z;1beSUXUBp=3rY{MM(jKNeW;F50W3stI%#ywfz>#Ed=Lg3ej~dTDm*DlEQ<1p_QBk z2y!GNFEKmrB)}{wj099bodV_vHZGpC6M+n31fV0T+nnObs zAg%>C17HHM1IQ;d9i&VOk}BBTPN&Q3S+&rA)!PF>zS}Q2@aNPOeo3Kj3JV-UXpUL? qfYIDzwD%ajjJiim`W$1s&sgV}O@ELl&fK_#RK}P-tRvo+vi<{2QYS+I delta 3142 zcmZ`*X>1$E72eq;mp4U9A|;!mP1&*(O192g@EIMp>^in2D{_EZCOtq$zC_tx~su4F*NfAIaaM%?|;#TX|u$2v9U|e;AI_qUetv?+qzR zYLQv&x9^yFGyBb(xBH_jmdyX34FJIT^ZJ$+J4j+;UzA}E4l zh?(P-kcG>}nDv(;m*ki&ZV%bHY>GMJ&X6-+6{;eFDxMFprM8-^umu7u<_m8K0u@zv zs9LdvY7}dzRXV)JoZtpeAYtuxdxB`BUdB;;4TFvT{d4sg3D92b=O%Yw2+4XkwyHC_~hzM@Q? zNyJFT(;2GF>@gBs;Z@FBA}g9180-zgc40m1>{+kYS9Tc5~$C%Tde_TUqU=+&-D1EG<7aKkxWvB`ao}jJ9P{oCpo@;HRM<*@`v1Q1at7YW3oDUF>D)MW#cNy@3zlGD3^Pfbh41CfLhNJSO3%;Zx8tS~5YE_7L) z)6|3#H0Tlx(dE(*-GKddnX0LDOiST_bvmsTI#YBfc-rAkjRWL_?BC3St#)zzT1W24 z6Nfi1uQ;~njy(aBvSRb)j;=bYa>rH;)~myB4KMC|Xz;Gd%?}M**5szVd+DWz2H&d9 zog1be2%M=JJ$1ALriDyV+ouy#LGdZFMMVI36MWDnfb5!5cA$+rU;yt_w(qLg<)E}a zycDlwc={h`Yldd*zaBv1F*g}XPH!b{IVv|d7yB(bG42NEaB;is2B|?&w~Y@SIWzid zc>F|Yh_-f=UhGH`|JZ(i#!h}%{b4xy1ndAt~&M? zx0BVocM+NW(d}jD+CN70^Rk~+JI!ldx#2-|HLN_SVqexa2a)2ZG640XWJbUWIuf+#@*IsMrc~V$QIs${ z>^VdRS;n)~NVh@Is>_k-X(%3ainTQEY*~K|Q~9XUW6*1J^`Ikcrm>d% zp?Ib7mYBtvc2*RF^Vfs?ss3g{>tLqiaoGuwiiEa%8ExP!O6FRPN9U8(-^`GK+v*b)^FMapfA$WK;rCD z3w)hP@%@(jqRijz5F2at@2oJx384vy`#-G2*ix%UtRcna)}M=Qz0g6IAlY^E@l)Zk z*9MM`(*wAo!?>c28=7DXd-_S5eY(d>nv0M2EQlSPJZTz=xh=eb!dVgO92(hHio_h^dnr z{Q>*y!B%pm=s7ee?x%I&!`Coq(YUJHr&T%$|0d~#rc%nsInJCoa&kO;dI-J@Lr3WQ z&>#1K{r2Sp=} z-5>D#$G}2A0MKm{$yf{$BAQI3r~%DA?D@d!qr57%qy8a6ErJgLe=+Djgi(Yu2(KZW zM&O5+7t;<CdFW^ZIaBb#O;Y$k(Dm+4OwUKqfM1NXu-%QDmH3!^Xeg~nIDWAXQ#HsZbbn zJD ztr~d^FzVwtO&Cg@DCPE{kr*HQ}E=N-Yh+^L(|l)Hd%g zsdRu81ULA}S)rbB-sCNz-uYjKj2T<(9sgD|idfNZ@&)A7gF4@!V~k7Imb&L-C6$ho z*F8Rw1?$M~;u<_jsU-lGl%5?pNs88nbGDczlT|gHwAyY%6BX=}Jf!H`js+glSK1{D zyh8VHTNNNqc<&{+OlQ5vL|CMozL16a0{*jbmtOZj0sL{EoO1i@?||VMN zjC?`9=aUOQd9JPCi;>z$o!EER6Q_G3Y|kKFmH!Yc@v@47t_>McrVN=ZKl%*prWKF< zAT+**o)BUhaUOAj;Ss^;Mm!pW15S3$oeP>6}AHJ7SUa?u)~lbaLNoeANo` z6w3zn16e(5>{5+5@pLr75{Y*_1@F^0I>z~iI2KJHnlM=!7*1))mo+1QVnE9oH%X|g z#X67SHS%Itklp%t*W>ihdq1Yz)ehynAr?Pd(YwI;l$J3 z&l(%d%;CT0Hxd|LXBc&FZDVL`30+$u!NloZ=P>78#4O?p;v>WoVg>On0#`F|Bx9X? zmxw};JV*>f9m)5~BJM&i_Kw2`#D6Fn`jweDK<-tBKLr5zk!$#wbKK{g_c_U=i)0U- F{2PW9I)nfK delta 1182 zcmY+DZA@EL7{~9qFMYYCqtMzxfeHmzxVRP=Y>{ncg*K%Hw>Z=#cN&D<8*I64lS>t8 zI?0R}jUS{wDxwZHO&m%Vhu4i6lc8j|EsI&IGmyLaX-kYIE`IUbjGog;HqVFOeg4n$ zKhJr&Ie*U}eFj;tTCF^V$Fq|cMh5fNO8PF9Z`?h}D8{5oG$Bf&Bvvsed66&1oMJgm z7bAmGlC+A}Vr*2lBumB8q)oJ8Z4%2QvsfvjObznD zwIcs0(!!EVQ;`w2#^Tv@CtBbM*8YHQBN}^8vemxKecR5>3HQGve2yBd-qe|`@B`~b z7Wj)@Lr(1*&V!nhX-QUeuKQrLr%&f12ZI9xIy(^DAJWb7)QfT|lU65mZdgel83kl~ z41&fhs6n%srf4*z<@vKTihmNZawx0ymVd_}0eI&eI;nl;Jj|kHjjL+la89Uw6J6KN z)pj8IIT{MQ%QTHtTaHRF5Zqk_g6A^*VGe4m9|Cjzl%YRoP^0%`gmIMQ43+o*M@>0X zhSdu7t2A!-&bBV(hwIx8bE+Q~A>e)7fPXeMb_?>}nrgRaJ~5kEcefVYt!EmRw=Zq~ z*7=jW_l*Ouho|AH_fY%S+=k0NFU$(-E}`HO7CH*9)@kF0-Sv??KRP@5qrGXvQ85$C z$JQOq1xNEj_-99(_H-jYv`4!s++l5nMfo{twlIS8>2074)UeitlUZ%@d za7H(eC_QNhYZ)54EB- zxE6AwPqjOtH0?P~s^rn=hQYDt)8i>MM>6{e_7Yr#$w*_x_c+X!9g3%<^tew_hsFn$ zp;27^$Nin0ojsz34V|I@LQ^ky@0CVt(X88V#m-2u&>Wo_bWD# dwa2m;e=-Q6U#N#~QTz?ca)YvB!rOhL{{n>6H{<{S diff --git a/block.py b/block.py new file mode 100644 index 00000000..b0f3a2df --- /dev/null +++ b/block.py @@ -0,0 +1,26 @@ +def tex_coord(x, y, n=4): + """ Return the bounding vertices of the texture square. + + """ + m = 1.0 / n + dx = x * m + dy = y * m + return dx, dy, dx + m, dy, dx + m, dy + m, dx, dy + m + +def tex_coords(top, bottom, side): + """ Return a list of the texture squares for the top, bottom and side. + + """ + top = tex_coord(*top) + bottom = tex_coord(*bottom) + side = tex_coord(*side) + result = [] + result.extend(top) + result.extend(bottom) + result.extend(side * 4) + return result + +GRASS = tex_coords((1, 0), (0, 1), (0, 0)) +SAND = tex_coords((1, 1), (1, 1), (1, 1)) +BRICK = tex_coords((2, 0), (2, 0), (2, 0)) +STONE = tex_coords((2, 1), (2, 1), (2, 1)) \ No newline at end of file diff --git a/model.py b/model.py index e4ec38b3..b861d20b 100644 --- a/model.py +++ b/model.py @@ -4,6 +4,7 @@ import math import random import time +import block from collections import deque from pyglet import image @@ -32,37 +33,7 @@ def cube_vertices(x, y, z, n): x+n,y-n,z-n, x-n,y-n,z-n, x-n,y+n,z-n, x+n,y+n,z-n, # back ] - -def tex_coord(x, y, n=4): - """ Return the bounding vertices of the texture square. - - """ - m = 1.0 / n - dx = x * m - dy = y * m - return dx, dy, dx + m, dy, dx + m, dy + m, dx, dy + m - - -def tex_coords(top, bottom, side): - """ Return a list of the texture squares for the top, bottom and side. - - """ - top = tex_coord(*top) - bottom = tex_coord(*bottom) - side = tex_coord(*side) - result = [] - result.extend(top) - result.extend(bottom) - result.extend(side * 4) - return result - - -TEXTURE_PATH = 'OLD/texture.png' - -GRASS = tex_coords((1, 0), (0, 1), (0, 0)) -SAND = tex_coords((1, 1), (1, 1), (1, 1)) -BRICK = tex_coords((2, 0), (2, 0), (2, 0)) -STONE = tex_coords((2, 1), (2, 1), (2, 1)) +TEXTURE_PATH = 'texture.png' FACES = [ ( 0, 1, 0), @@ -147,12 +118,12 @@ def _initialize(self): for x in xrange(-n, n + 1, s): for z in xrange(-n, n + 1, s): # create a layer stone an grass everywhere. - self.add_block((x, y - 2, z), GRASS, immediate=False) - self.add_block((x, y - 3, z), STONE, immediate=False) + self.add_block((x, y - 2, z), block.GRASS, immediate=False) + self.add_block((x, y - 3, z), block.STONE, immediate=False) if x in (-n, n) or z in (-n, n): # create outer walls. for dy in xrange(-2, 3): - self.add_block((x, y + dy, z), STONE, immediate=False) + self.add_block((x, y + dy, z), block.STONE, immediate=False) # generate the hills randomly o = n - 10 @@ -163,7 +134,7 @@ def _initialize(self): h = random.randint(1, 6) # height of the hill s = random.randint(4, 8) # 2 * s is the side length of the hill d = 1 # how quickly to taper off the hills - t = random.choice([GRASS, SAND, BRICK]) + t = random.choice([block.GRASS, block.SAND, block.BRICK]) for y in xrange(c, c + h): for x in xrange(a - s, a + s + 1): for z in xrange(b - s, b + s + 1): diff --git a/texture.png b/texture.png new file mode 100644 index 0000000000000000000000000000000000000000..9d05a7e2db1eecfe427228730ba1a9d7f5e38515 GIT binary patch literal 5257 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 tZXY)`ICb#Xax+y7?`HqVj7PH^u;uCX Date: Wed, 26 Feb 2025 18:50:52 -0700 Subject: [PATCH 03/46] Added Player Class --- __pycache__/block.cpython-312.pyc | Bin 1183 -> 1223 bytes __pycache__/mmath.cpython-312.pyc | Bin 0 -> 701 bytes __pycache__/model.cpython-312.pyc | Bin 17181 -> 15603 bytes __pycache__/player.cpython-312.pyc | Bin 0 -> 1715 bytes __pycache__/window.cpython-312.pyc | Bin 19453 -> 19684 bytes block.py | 1 + mmath.py | 16 ++++++++++ model.py | 45 ++--------------------------- player.py | 38 ++++++++++++++++++++++++ window.py | 15 ++++++---- 10 files changed, 68 insertions(+), 47 deletions(-) create mode 100644 __pycache__/mmath.cpython-312.pyc create mode 100644 __pycache__/player.cpython-312.pyc create mode 100644 mmath.py create mode 100644 player.py diff --git a/__pycache__/block.cpython-312.pyc b/__pycache__/block.cpython-312.pyc index 132cea88c3b32f264ec1d70d3674475a901fcfd4..0c1765ea8bef829f685e991825b777dab1e9f0fe 100644 GIT binary patch delta 154 zcmbQwd7P8?G%qg~0}z}(us{9tL|#e8vWexEKpq zj3WgI;bN>C=T$Kau@&(EH5G{fiCe7hL5{(}lMPt(xMYBQMj$TsoSea8IC(jX0sxCP B7{vep diff --git a/__pycache__/mmath.cpython-312.pyc b/__pycache__/mmath.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a561e469f446dec5c265c42d426441767dc32d83 GIT binary patch literal 701 zcmZuvF=!M)6rI^UNpgA|ib1iOD+CubjR-MF@UTdw9Hx^MGnt*st?th3&CWsg*o74= z4r~GuB50?D5(`0l3(GVqWw8^i1J|YU@5BiT_hA0tH}C!b`OF@)T1^C)`~GdK#0dSW zi3MHj<0eXQRp$vNtvq~+`!ExbCcOdMc9QnWsTsVcRPkp*}802{W@2$-zV_po>cLWyRSQC@m`354tNKr{^Lof9G2Z5=US8D yPG@rauyJt;J@NLh5ZF{{ zBWb8HQu@D?2OHBDt<}Uh555@t;ESmbk{BB^@xe5P2OmsBOZwu2=M0G8B=gO=%{gbj z|D5^wI(@nj_|fn861aN4e=zx0<7%Ls{{5s#YVM3j_D}+{q8<+mYkYD6OaS8?9zgnLb)(gBo|Sl3K#46YJKq_set^7`_eceOi+vE62&8j6t7&W z_?C!VrWDBKlSJ{~rE-N5086Dn`iK%-B1)lJbzj8p2$91JLafMi(!WGnZf;3ql1~CN zdY>AEkF_4+w|r$0wAoi)AmoZ*?AJv@;tzelM?}k!$)t=a%ahHqOiG*1tCnxLw|nHw zx#V!a+#BN?-gs13(?*Vgk5xm;m*Lhs0Irf}Fl&IZ8w`TABP47zHv0f)8P$w45DIgmf%CxWqwOg=Gm)Y z0U^)ls^fIoyjwjizJyU$0aG)%chuwsEtkH;8qnm`RYOrHQnQ+2f2ie5&CIA-g^luP zq&Av>7#7Arm!ZxZvrJ_zpy|kL4P2}k1KRlIND1ZU^~jpAh?VTzJNdS2vN)J6@6@#N zZ}~AW+!NVuh3&+6q`P_F040B5n}EHoe-3tC2DnO|loEf@%D|0*oAc`hHNUzG%sX|9 zLgXAcncc}KN?4rX3oHo`^Vn>a`-ahiY_SoZiiYVJe=k}|zctsQUkgtA?KmHbSJ&?E zk-;ecp8=V##zXWc^V9f!p}r3MmY7l$%iZ@{a%i-(XPCW+Rq6ros8B{y**JfoGse09a0#8P!l@ z!hgkd*a@I^`^2*R!I4txF&`aC(y%=U;-qS9^JFuIWZ~)Xp`#~h&|EpH(GbQlhG6rF zR5G0xwj^LDJ6rw`T8^Wo6d*@T-+?*vL8_WO$|0-0$*N+{h5%c-6b=uyDk#7R*%#$Te%x2S;lwyP1byjWV&J(``F^A;>+BJ2;VDIxkPsC}L8ERbIk^G>Rj!68>4o3yVk4fh)~yg4~-T6O42#ah0 delta 3118 zcmZuz`)?b^5#GJyo1&-}MLnGpB|j+ZVac*%%Sxk%6 z>`_O+!N%r@^Cuh|St2D-SHQ)_)<|j89dJj>0%aIU+^lcyM@>T&flARHs1h9kkLX-M zfoicN;GIUI>jyYcBbI`uR&)c_ap)Wp%T|zBF4b@IG#G>e4GGR)k+I=NJoaY(ZFMKSDa*-qYsaU%QIS&*tA>yNch&OF0MmWhovU zV;$?9&QI~<$d8j>2m|4;G^eS;#GInanykbo1Z7GHkx5x2A(9a0h!mDp&bMs)LAo8=40ZP@k>YRQcNMyP()5jq!A8q41Q`qz%qJVhuq%l=avVSKb7fD_^PUf&h}`Y)wZHZcdXK;Y#LF2B67x^)T?HRmkl z(p|dq>a*aIROv3G|6ujf0wNZwo#Mh!!{bPIrJTB1w}EXZ904|h4SSJf)g1*XWrY~c z?+%+#g7=$3e*;Iti*ih&NvO)xGn$}EArhVuric<1!t;bku|oQG2qQ~S3b{lVWR)c> z&38yxiKtRolSDz*U}mo_B(Y5hMHDE5MOm9E6bUV&1zDL_BMI2c^bv?+-(Ef%a5yEz zlzoT7R1K|)wmtL0s1lRf7}Ds)ng$XbG(q+{Rm0tBfLW317) zL_HSHotr2ujE1fSMOoECv9Kic(i866peH`BEDF(3ERhRM6+(-lgaGdI^eF^*nvu1R zTvgL8uONwL2;wW*`C1n)K={iol zMlR+C$*e6;DS3%5umPy00Mv8gA(eE!4FU@;X_BfXOLHkt6;ytoZrcEW-f{rBO4E3! zqV9$@jniG}(2l46h9k|T2UoeBN^jcsu-v;*vKhZ$bL2s}e;1kUr_%!uE9y7KHt}ZH z#>j(;L+PO%cg5<=&85xbw_84G-D|P`s2y678s__?^Js?d>ipwht_5{ zn>HtJcYQeZVe9SC9p9b!PY-R)La&P77yJxNS)K9w1NFve^%otCHd}$VudqX2 zg;Owk$hTl*On6)ICz*G=<9s*WnJpnwR9TRMtQ(U~s&c53CQ4JG`G`gYs<4FS=A@WN z-Z0AQoBIkEWYwf=(Do&A3RbDKIZ%cfw`2gMq&vrINECDSf0a?{Z*d}Z%v|l6&xJtR zL7jEX$YMSk5foc|(b1S6+I05aOn{KA$hj##$^A^^z<0T`S74eY7I}k?s0R|JFazMX z7ny!Kr;1rKE;KbX&`^?|oF7(N!I%VnVp1XM=b5*fe#TkYq1uh!md4Zj3^8Je1be^2 z4visMmNTc$D2q9I{*_s6+2)QOhRG}sq-AaAUJQ8-MTllbf#1T7m0`G^LSujRz-Mv7GteiCbI)n{r(q8M-(gd}SEE3x1C-g!Jrzbb5$Wnm0TBqVI3bbFckD^>D`>06a68uzJQY&cJR90)Q z-#yuE_CC3QYt41LCykynFJqsva>nNyraKG@g8*4)Scyd74+lOLRYKbYX)%6x=GCr# zI(&x0cPLa*@Ka!A+ek+OK-Qv6&cb%$GsgNFn|=r?NDZXU13cz2#(zf7e2yHSBIl>b g1!%n2ccG!mjXk?9rP%YO5HsP1^b7w)^v#a-e-AJR-v9sr diff --git a/__pycache__/player.cpython-312.pyc b/__pycache__/player.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5cf8aca35a16fa031370e0f5d6d3c61b57b81261 GIT binary patch literal 1715 zcmah}%}?W25P#2(jR{GBpe|ijZ6ByzZB{H>w1=vzRV7M4sMJPC?I}uS8T&agI5s>x zfFnocz#&vUzzKQ_H&)xj_AltAxAwyBp^>|lD(wlW2LzQW?Wyx@V$xGb^1PXOZ)Sco zD4X{KLYkCV-<2a%$x zmSg#<+8Rv|%=Hbt$({sk2lbS~B?w68YM*2fc+$&XfkCTrTMBU%EN!_x)K)?%`3QZz2wr)gM~i8-KgPZR)=&8&rG6`72DO(;AfHNlo`sN=^NW$V1{c*X_7|n>yq{dV&}B6#%}oJxhXF(ki80 zAihiVI)xVS`>((b;*HIeUwrW_OuQ@t}SkUD(0Y|sw zZjpxO1W9{5qHSpb$JU=90MJO?@&}r8#$SSRNhp`$cFEgJb80k_8V${_N5hWG8k%jj zXlaxU!?{T5cPWy#TxJ`QoFI&HgUBM>i12oVg9x`G!Ptf`fUgDaS5uC#8i{K(@c1R? z$Onk!;!FTj^{MBlx3h1^!?t$_YzLjciSmUG?iHu@hB~-2-_d%n-P+4`gwBWiLT_TS zqr4cOJj!)9PG7(Ce7tmlq~Z5F3onY3hxZTecjvp>$#}Q)yg1ug?2Q)p>)(FUeQ@&5 z@uS}4)X~y@``OsrAa#~{Hzto}jyAr(eX!b{?yj87ADhQ_Pqe2qPd9$N{djeMy0fvj za6SUD&vR&OiWLA`xrEsmtnj|UJLACrr>ap_RU59+w7Hy9)s3cRCp(PS#AZ0-l2q|_N#W7WCfqTI&iH#0iC*BbBA0TT@bklMg$K`c zBPkv-8;6}F{(p16QXVBJKVWy^2!E=)cY&RY7~?8+hsh0gJ2n7gVLcjQ{`u literal 0 HcmV?d00001 diff --git a/__pycache__/window.cpython-312.pyc b/__pycache__/window.cpython-312.pyc index aed9f15459f1585c85402d8a42c0af92b0d97f2c..f4e7cb04fb4dc8bc9c4c1c5b5563a889df27be24 100644 GIT binary patch delta 3439 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 G-Tw#hRr6v1 diff --git a/block.py b/block.py index b0f3a2df..37fcd08b 100644 --- a/block.py +++ b/block.py @@ -21,6 +21,7 @@ def tex_coords(top, bottom, side): return result GRASS = tex_coords((1, 0), (0, 1), (0, 0)) +DIRT = tex_coords((0, 1), (0, 1), (0, 1)) SAND = tex_coords((1, 1), (1, 1), (1, 1)) BRICK = tex_coords((2, 0), (2, 0), (2, 0)) STONE = tex_coords((2, 1), (2, 1), (2, 1)) \ No newline at end of file diff --git a/mmath.py b/mmath.py new file mode 100644 index 00000000..f8f9b057 --- /dev/null +++ b/mmath.py @@ -0,0 +1,16 @@ +def normalize(position): + """ Accepts `position` of arbitrary precision and returns the block + containing that position. + + Parameters + ---------- + position : tuple of len 3 + + Returns + ------- + block_position : tuple of ints of len 3 + + """ + x, y, z = position + x, y, z = (int(round(x)), int(round(y)), int(round(z))) + return (x, y, z) \ No newline at end of file diff --git a/model.py b/model.py index b861d20b..9ff3bc00 100644 --- a/model.py +++ b/model.py @@ -5,6 +5,7 @@ import random import time import block +import mmath from collections import deque from pyglet import image @@ -45,22 +46,7 @@ def cube_vertices(x, y, z, n): ] -def normalize(position): - """ Accepts `position` of arbitrary precision and returns the block - containing that position. - Parameters - ---------- - position : tuple of len 3 - - Returns - ------- - block_position : tuple of ints of len 3 - - """ - x, y, z = position - x, y, z = (int(round(x)), int(round(y)), int(round(z))) - return (x, y, z) def sectorize(position): @@ -75,7 +61,7 @@ def sectorize(position): sector : tuple of len 3 """ - x, y, z = normalize(position) + x, y, z = mmath.normalize(position) x, y, z = x // SECTOR_SIZE, y // SECTOR_SIZE, z // SECTOR_SIZE return (x, 0, z) @@ -145,32 +131,7 @@ def _initialize(self): self.add_block((x, y, z), t, immediate=False) s -= d # decrement side length so hills taper off - def hit_test(self, position, vector, max_distance=8): - """ Line of sight search from current position. If a block is - intersected it is returned, along with the block previously in the line - of sight. If no block is found, return None, None. - - Parameters - ---------- - position : tuple of len 3 - The (x, y, z) position to check visibility from. - vector : tuple of len 3 - The line of sight vector. - max_distance : int - How many blocks away to search for a hit. - - """ - m = 8 - x, y, z = position - dx, dy, dz = vector - previous = None - for _ in xrange(max_distance * m): - key = normalize((x, y, z)) - if key != previous and key in self.world: - return key, previous - previous = key - x, y, z = x + dx / m, y + dy / m, z + dz / m - return None, None + def exposed(self, position): """ Returns False is given `position` is surrounded on all 6 sides by diff --git a/player.py b/player.py new file mode 100644 index 00000000..780b795f --- /dev/null +++ b/player.py @@ -0,0 +1,38 @@ +from __future__ import division + +import sys +import mmath + +if sys.version_info[0] >= 3: + xrange = range + +class Player(): + def __init__(self, *args, **kwargs): + return + + def hit_test(self, position, world, vector, max_distance=8): + """ Line of sight search from current position. If a block is + intersected it is returned, along with the block previously in the line + of sight. If no block is found, return None, None. + + Parameters + ---------- + position : tuple of len 3 + The (x, y, z) position to check visibility from. + vector : tuple of len 3 + The line of sight vector. + max_distance : int + How many blocks away to search for a hit. + + """ + m = 8 + x, y, z = position + dx, dy, dz = vector + previous = None + for _ in xrange(max_distance * m): + key = mmath.normalize((x, y, z)) + if key != previous and key in world: + return key, previous + previous = key + x, y, z = x + dx / m, y + dy / m, z + dz / m + return None, None \ No newline at end of file diff --git a/window.py b/window.py index a03a49f7..62347740 100644 --- a/window.py +++ b/window.py @@ -6,6 +6,8 @@ import time import model import block +import mmath +import player from collections import deque from pyglet import image @@ -36,7 +38,10 @@ class Window(pyglet.window.Window): def __init__(self, *args, **kwargs): super(Window, self).__init__(*args, **kwargs) - + + + self.player = player.Player() + # Whether or not the window exclusively captures the mouse. self.exclusive = False @@ -73,7 +78,7 @@ def __init__(self, *args, **kwargs): self.dy = 0 # A list of blocks the player can place. Hit num keys to cycle. - self.inventory = [block.BRICK, block.GRASS, block.SAND] + self.inventory = [block.BRICK, block.GRASS, block.SAND, block.DIRT] # The current block the user can place. Hit num keys to cycle. self.block = self.inventory[0] @@ -233,7 +238,7 @@ def collide(self, position, height): # tall grass. If >= .5, you'll fall through the ground. pad = 0.25 p = list(position) - np = model.normalize(position) + np = mmath.normalize(position) for face in model.FACES: # check all surrounding blocks for i in model.xrange(3): # check each dimension independently if not face[i]: @@ -275,7 +280,7 @@ def on_mouse_press(self, x, y, button, modifiers): """ if self.exclusive: vector = self.get_sight_vector() - selectedBlock, previous = self.model.hit_test(self.position, vector) + selectedBlock, previous = self.player.hit_test(self.position, vector) if (button == mouse.RIGHT) or \ ((button == mouse.LEFT) and (modifiers & key.MOD_CTRL)): # ON OSX, control + left click = right click. @@ -426,7 +431,7 @@ def draw_focused_block(self): """ vector = self.get_sight_vector() - block = self.model.hit_test(self.position, vector)[0] + block = self.player.hit_test(self.position, self.model.world, vector)[0] if block: x, y, z = block vertex_data = model.cube_vertices(x, y, z, 0.51) From c3e3b10086ce6bd22c5a2f09673329519f4ad95c Mon Sep 17 00:00:00 2001 From: Kyle Wadas Date: Wed, 26 Feb 2025 19:29:37 -0700 Subject: [PATCH 04/46] Refactored For Math Library & Furthered Player Class Separation From Original Format --- __pycache__/mmath.cpython-312.pyc | Bin 701 -> 700 bytes __pycache__/model.cpython-312.pyc | Bin 15603 -> 15528 bytes __pycache__/player.cpython-312.pyc | Bin 1715 -> 1773 bytes __pycache__/window.cpython-312.pyc | Bin 19684 -> 19685 bytes inventory.py | 5 +++++ main.py | 14 ++++++++------ mmath.py | 1 - model.py | 8 +------- player.py | 2 ++ window.py | 19 ++++++------------- 10 files changed, 22 insertions(+), 27 deletions(-) create mode 100644 inventory.py diff --git a/__pycache__/mmath.cpython-312.pyc b/__pycache__/mmath.cpython-312.pyc index a561e469f446dec5c265c42d426441767dc32d83..71761680067e8f3d466e94dce8fa86516a7d936a 100644 GIT binary patch delta 45 zcmdnXx`&nbG%qg~0}vRV+MixGk@p(o(}_I|SKke< delta 45 zcmdnPx|fyrG%qg~0}!wu-k;tuk@p(ovx!e0PCmj|%_ue5fvJRppHZ}k8z>I|QWp(^ diff --git a/__pycache__/model.cpython-312.pyc b/__pycache__/model.cpython-312.pyc index cb6a97ad86b0a83d102aef1df691a75170b8ef76..e1a9a8be2cce4a32623a21a6d59b51ac1c4d0b78 100644 GIT binary patch delta 2122 zcmZ8iT}&KR6rMY?EV~QC0?V?{h5kXh?DDh83Z#X#sUU5Lwzj22yJ}b1nZlNVp=Wk$ z*_cpCjW$h#&3!S^K4^XLCnhGF^v(9gm>AQfZzfZkkW@{0skUm2J`~Tn!_RIf@a>s% z&pqF{=jYC!3tud#KdGuu!e{F4ovGM$wV8c?J(65hjLKP0%EKg0(p-jj)|c`Lxx%RW zMi!FWsGe0*DwA~iTnjlUe>ABX6ZOYP1S3@%Tg+!RizrHB(3^0 zmI`VrY8qwfh@{nAmNdT}s`*-R+@+cpsMuN*OJ#~+amc&Gx>edzL*PfSTnM}IfjSgyucc>lCS(gbgz>$HKlY8XKyk2Y zNoIBYw%W=L@fGzQRGqF_cCiM&R^Jlzpyk@r_4V~N%Iexh1PJmSftjWr5^E7`W;vXK z-Oq0XdRvJQx)2I=M@>yPdeYgsY%V)tAp7gZM}fmK3-Eh8oB6TE-v%RS7xjQ}xPvy9 zAH$Zli*OkAC=@ITh|WY0)NwNuW=s5P=oE&%8hR=x$eCRY`mA|DPfr?VW(H!U@>zOL z)6Y)ijhr~X?VgyQ*XJ}CekVI9%@0@5t(;WZTxEa2J z^#6wavPSfRaD&7N1Uf_r(^+jZrqihSQYksJV52S(=OQoT2!(owtn@seb7N-)`R?uP zmluzdr63(6iFn{Of;SPO-V%cHq{0a@qO8J61Y4QW7c4JINbfwNX@KG^1f3u<(|Tqm zJ*Q`B;S@nQQ>d4z_vpWEv?W9S!n`sFyNt&f8V#lB#9M=@|s8tWuQg%`ra~JCu z-K|XNIj8ud4JfG_-DSI-u?L#0?XdZ&?l!lVp=y-Ja7j*UFOoXZ#G;m&Ve^M^2{4Muy>i+`Lg#yTZy%KyIt7{D=J!Hq0OGH!1iSd%!5FVi1{Xz3&{q|%63~=GJAt^<=o4kT z&B=4PTg3HD!2fxYv!<3e^n>s*no{a48ks*7#@GXC*F(v7UsCT&RrjT8{QFgEeIPZh lNTCN($ExD~Sqbp3l8I1#4GaFYd)&oZJ~;fhM86^>{{vid+OPls delta 2159 zcmZ8iTWl0n7@jjbyWLB7d)e-8w-=zcX*(_5#oCer6{NJq#v+%tK?cma>`dFGvpe<7 zETxTxfIJ{E3OO&Bs8Msd^4j)qlpPd5`w6SCgA^{*|J?uvfuva zod5jy|DO+*|6C5<3KZ;R>QzdWDyS~qoAW6?A^^J53o8w(Pl>30 zC8`F_2}(?@RvPDoPBr*GQQ~R{j+#Vaub|eP6VzI*`D2$OPH9;d<+@9EwuNNTb}eYj zwmWAOOsy!BD=v2fFf|sxm4Z@z3`i=jf$XADcE{UPAB7XxJiMT>VvFxA>8nA`T7)_P zQv%ooi-v))eWsSN44PfhXe;ao*iHWgi4-G&vmyzz%fVJM&OQsi%C zq|}efxT;&IZ(Js}FPqD0YBp_Y6oY^3{(}b(ZgJ`q^2XS``h~_VNY(?`#B^-p*4444 z@PG#mq6v0293|=EjqtcgBJ5gkoOMTk+abf9?4|sD3-VQZWsB-5`ZUTF)fLkV1iFZe zhS@}{nVe@@Y#JO}jolafQJ7s#wVZKMOC8sZ%mUqvM}AYYRBbk0&@CPf+ml{g)bc8w zVZS%E4?k3HS6SLAt3Wk62+t}bN_WE1O3gk))$~MKRUP?^O*Fp>?vUGUODtA+uhbgK4-_;E<#*yx3!7KxHj%W zAZ5-QOOEfhH>KrYENBHymey%SM<{g6qwzx_ zop3E0i*_KjE*mP!cmcqy$N)xk&EzuoKTPQvfsDM}vpRy-&>Vp6fx6HvO%}_cFtLS7 z4N3DTtIlzMooXL@v$qqhyVg5Iw(??i&1sgCRi0lATd7cNkJHo?8>MV1OZ2sSY6u)n zFkiBhz1-L3)XSAG`^aM`lTrj;Dd-Y4E8qW|XeW(KO6~pFBRX~AN2Lbewnlt zSNoqL;KzSYys@hf^&A0M3xqUV$Y*RRP3O#V9FPeUxe_Wxxm2CQ?CXJckaTWiZhcm~EEn8>AB!3Z{p4juuRO-Okq14pa9(o?$l@e{c zO)E{UhpA@o4t0?Uc4No@Aw%0fjdI)Z0ZpPdNRxoG>;ASuGR+3IL+;tp?TOQmBS!*( zXB~$PJ&b^Z!s+h}QapcHOXc9xGq~j?%=NsE+lvSxga`s3!5fi67=@qt9Kbo@t`v7S z-`&c*I}YsUoOmy{+Wu5(wt%BBm7>@akoslQmU3xpo{qqtUO?D|fFDUakTG-}J~>$< zZ&C@5+t_AA0y9vpvS~6QGCt@rZ-}dWUm{TF|wf^c`TuP=`&d^*b&?$dAItUj_g7LV)ca fZgl-5bg(1CL$Rh1iQL;XBaxQ#<9`YG&ja>9{k7;` diff --git a/__pycache__/player.cpython-312.pyc b/__pycache__/player.cpython-312.pyc index 5cf8aca35a16fa031370e0f5d6d3c61b57b81261..0adbd16a7b33d55175a437077563008af92d48df 100644 GIT binary patch delta 395 zcmdnY`<9pYG%qg~0}$Lfu|Iw1L|#e8oQdj+A}I_h%sDK%tWm7FY*B2C45>_6d=q^n zomsMD7#NC}QaPeHnHby|QdnCUQrK2Afec_^h~lbb(qw-LVrnwp;z-FX%Ph{!&-2q{ zy2YHGT6v2#H@~zvb>ggZj69n&8AX^GxhL1L_)8bD05ufz0|^CGP{cR+1&bUb|73R7 z1)Ksvc|T3YBB99}Shbu%s*99C1jzA4Aju*=5WxW>xPgpf9w5=e@QI0$mH!KyB&!re zAxMoT_heZ%@p=&;^A>MGWqM9(iC%eTUP^vB*f~Y4APJtb)FO}%;xqHo@^7&gCFZ54 z76}7oAl9H-{fomUH$SB`C)KV<2dIP*h>MMZ#0O?ZM#j4g@{bv~ZZq&aXHa>-%yykw S_#(6L1jotK*(6v%jt2l=omK(> delta 308 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 diff --git a/inventory.py b/inventory.py new file mode 100644 index 00000000..95915673 --- /dev/null +++ b/inventory.py @@ -0,0 +1,5 @@ +class Inventory: + def __init__(self, *args, **kwargs): + return + + \ No newline at end of file diff --git a/main.py b/main.py index ad5b12c4..20fd82e9 100644 --- a/main.py +++ b/main.py @@ -1,8 +1,10 @@ -from window import Window +# from window import Window +# from pyglet import image +# from pyglet.gl import * # noqa: F403 +# from pyglet.graphics import TextureGroup +import window from pyglet import image -from pyglet.gl import * -from pyglet.graphics import TextureGroup -from pyglet.window import key, mouse +from pyglet.gl import * # noqa: F403 def setup_fog(): """ Configure the OpenGL fog properties. @@ -41,9 +43,9 @@ def setup(): setup_fog() def main(): - window = Window(width=800, height=600, caption='Pyglet', resizable=True) + userWindow = window.Window(width=800, height=600, caption='Pyglet', resizable=True) # Hide the mouse cursor and prevent the mouse from leaving the window. - window.set_exclusive_mouse(True) + userWindow.set_exclusive_mouse(True) setup() pyglet.app.run() diff --git a/mmath.py b/mmath.py index f8f9b057..dfc10d8a 100644 --- a/mmath.py +++ b/mmath.py @@ -9,7 +9,6 @@ def normalize(position): Returns ------- block_position : tuple of ints of len 3 - """ x, y, z = position x, y, z = (int(round(x)), int(round(y)), int(round(z))) diff --git a/model.py b/model.py index 9ff3bc00..4db47829 100644 --- a/model.py +++ b/model.py @@ -1,7 +1,6 @@ from __future__ import division import sys -import math import random import time import block @@ -11,7 +10,6 @@ from pyglet import image from pyglet.gl import * from pyglet.graphics import TextureGroup -from pyglet.window import key, mouse if sys.version_info[0] >= 3: xrange = range @@ -45,10 +43,6 @@ def cube_vertices(x, y, z, n): ( 0, 0,-1), ] - - - - def sectorize(position): """ Returns a tuple representing the sector for the given `position`. @@ -68,7 +62,7 @@ def sectorize(position): class Model(object): def __init__(self): - + # A Batch is a collection of vertex lists for batched rendering. self.batch = pyglet.graphics.Batch() diff --git a/player.py b/player.py index 780b795f..14449f6f 100644 --- a/player.py +++ b/player.py @@ -3,6 +3,8 @@ import sys import mmath +from pyglet.window import key, mouse + if sys.version_info[0] >= 3: xrange = range diff --git a/window.py b/window.py index 62347740..2f5fc9fd 100644 --- a/window.py +++ b/window.py @@ -1,18 +1,11 @@ from __future__ import division -import sys import math -import random -import time import model -import block -import mmath import player -from collections import deque -from pyglet import image +#from collections import deque from pyglet.gl import * -from pyglet.graphics import TextureGroup from pyglet.window import key, mouse @@ -78,7 +71,7 @@ def __init__(self, *args, **kwargs): self.dy = 0 # A list of blocks the player can place. Hit num keys to cycle. - self.inventory = [block.BRICK, block.GRASS, block.SAND, block.DIRT] + self.inventory = [model.block.BRICK, model.block.GRASS, model.block.SAND, model.block.DIRT] # The current block the user can place. Hit num keys to cycle. self.block = self.inventory[0] @@ -238,7 +231,7 @@ def collide(self, position, height): # tall grass. If >= .5, you'll fall through the ground. pad = 0.25 p = list(position) - np = mmath.normalize(position) + np = model.mmath.normalize(position) for face in model.FACES: # check all surrounding blocks for i in model.xrange(3): # check each dimension independently if not face[i]: @@ -280,15 +273,15 @@ def on_mouse_press(self, x, y, button, modifiers): """ if self.exclusive: vector = self.get_sight_vector() - selectedBlock, previous = self.player.hit_test(self.position, vector) + selectedBlock, previous = self.player.hit_test(self.position, self.model.world, vector) if (button == mouse.RIGHT) or \ ((button == mouse.LEFT) and (modifiers & key.MOD_CTRL)): # ON OSX, control + left click = right click. if previous: self.model.add_block(previous, self.block) - elif button == pyglet.window.mouse.LEFT and block: + elif button == pyglet.window.mouse.LEFT and selectedBlock: texture = self.model.world[selectedBlock] - if texture != block.STONE: + if texture != model.block.STONE: self.model.remove_block(selectedBlock) else: self.set_exclusive_mouse(True) From eebababc1d0d3f6450172c9961e28caee47b24b1 Mon Sep 17 00:00:00 2001 From: Kyle Wadas Date: Wed, 26 Feb 2025 23:17:41 -0700 Subject: [PATCH 05/46] Further Refactoring For Player --- __pycache__/block.cpython-312.pyc | Bin 1223 -> 1225 bytes __pycache__/inventory.cpython-312.pyc | Bin 0 -> 735 bytes __pycache__/mmath.cpython-312.pyc | Bin 700 -> 702 bytes __pycache__/model.cpython-312.pyc | Bin 15528 -> 17087 bytes __pycache__/player.cpython-312.pyc | Bin 1773 -> 2316 bytes __pycache__/window.cpython-312.pyc | Bin 19685 -> 18025 bytes inventory.py | 8 +- main.py | 2 +- model.py | 69 ++++++++++++++--- player.py | 22 ++++++ window.py | 104 +++++--------------------- 11 files changed, 103 insertions(+), 102 deletions(-) create mode 100644 __pycache__/inventory.cpython-312.pyc diff --git a/__pycache__/block.cpython-312.pyc b/__pycache__/block.cpython-312.pyc index 0c1765ea8bef829f685e991825b777dab1e9f0fe..72643d25e12537859545558fb2115c8633ef09d3 100644 GIT binary patch delta 37 rcmX@kd6JXsG%qg~0}uq<-N=>4$fK8R6%$aDpOuE`8B&;97*d#5GeJ~D zF;+5avb+Rw{E{I;5Rwtf`78uvOlL@Ch+<4(h+;}%Y+;CEu4K|=zQyU8SC*Prl3!Gr z3{wo!1G1VQh(B)v64MzPGOV;GJxvf!j%k~OnyZmhibCjVol1)PtLx@>J;SZ?0t*XJ;*UQ_!djB zqo2zy78lQ;kXvjS`6Wq-MZmCNDNfBvyTy`NlwN#`ExQ~<7c&D*QBY9$Wt40c6Ht_& zm6}{q91~Dkl98XM0O$K==A|YVC8m|cWWqvIub}c4M|^x{US>&re3cM9l=Wa@ppYsy z1QHDlcf@6;S5K^7;=0^>q4yTi?NS@1_Jr<_+8K30%%g*)hx>u3#CB` literal 0 HcmV?d00001 diff --git a/__pycache__/mmath.cpython-312.pyc b/__pycache__/mmath.cpython-312.pyc index 71761680067e8f3d466e94dce8fa86516a7d936a..7e1c8367f2a82087bb8d6a5a24fc23720ab14ab7 100644 GIT binary patch delta 35 pcmdnPx{sCXG%qg~0}uq<-N^NZkw-7tDkh*PKPxr4q<9k39sskV3m^ah delta 34 ocmdnTx`&nPG%qg~0}vRV+Q{{WkxM7pD#kfKB{MI5G85At0HRh2_W%F@ diff --git a/__pycache__/model.cpython-312.pyc b/__pycache__/model.cpython-312.pyc index e1a9a8be2cce4a32623a21a6d59b51ac1c4d0b78..63dafefbe74515e2b6b4cd351e7e5a3df2d0ff7c 100644 GIT binary patch delta 3030 zcmZuzT~Hg>6~1?+mBdN{8%aorA1`rSEHGeWofsyBHfh)P#;KYZs6qNWQz6 zpAnUtaXZS`Z6UWA#5kSU?L+W*oHV0{zO<7zeQ771PMowebcdPtwSBS)edtTub9Pw) zp57UKd+t5wo^$TG=bodL*-yVu%Rl$~B?4oZ{$})G$6|Se{%W!Dp{)4skfD%3UMGtG z4pGY0s>co#BV;H%E5s^3dG>+B*P1*&+{e;4)TFKzm!0*_;-0b(saOqCjr?;dNpJHu zue>j)IPcIQml9M&__`GrsP@3j4YM-E12ahpa@~7WQYv8*oDIZ6{3CB&!%0fW5*Z~5 z{Ta=YxM?0i7dA;Q9|-Y-`-1%T(Xud!J8cQwTcZ5@kGtvuyX^U6P>JJ4fIs&}`CC3O z|AFuD!4v`giIKIw7wpefs6YsK)G0@A)Y8qfarF z9R(>3FHwfUb_2mq6_3<>BwRonrq)eOmNnK4%Z4y;`bVVBD9&-9hr2-@W!_V zS;d{#0JI%}jTgI{0<;-bvPl5LrKl6CuEvBdM>WiI`)2Zk0f<$wL%goN&AaX9_+a}UI#rx*&r{yl7K&|{nWE5nhYplAved34^G}b4HjE(2Z=_T$qrg zBPpE3nUr;xIGc{nLC)KJ9cXK0C0id<$IUv*!+Un;y3qZS4si5E_jlNHDdPBk2!@z- zDK4Z~e(dg3JaK8D|?PO{A_XN$e1AJROr3KuAMjj73TP1e)0 zrmAvkMApYtIWv)%RT=-&{z!+Mm{jCzV`^%2Our`CFE^#h$@IiTN=Z$Q%F`)*48&$- zv)XBLYLcI?p2>mABr2Cj(#(?9Qt3%ePUx*AJ(gbiIPB475F43DC-f2*tqp)Xn^NiR z&b3MCZ<))V9CJQz;PiDWW81s<4ZGQHfU ze$Hu8j9i=(xDt;6@pnr@yQuthJj5( z)Tc5Ns@ZqU8X5C$l?B6PotWW%gJuk2GGjPL5=qsdDb|Pj&LKxgXEZMm_N~CzEUAXu zx*Rn(=l@n3%1-O%{3zVG765=s+e9h?dB>V>*FxlOZ=SCCD}Nk+CtmpWSN?D0h1FnW z>5auV)=8)=n(tl<)f7(itLr4_k1o*FFwEYaUJF)#5pDW&uz59D`}a`Q!p+5j!kNO& z<(|di2Lme&4+ozH59B~P5M0pSeFcQpqVj{P`>pH5w>!FUX05ueaQ%K{;mm3f_VS*> z<;C;7$DRy4XjldXFY}(YaBbl-pIvc&EIpE*hTB&o@@g=&kl@{gOAi9egDcLJOOM=7 zYula%+juwnHuq&XwleUGt6#Rf*0SLu)%6ACeedc^dkfC@-G2>MKd%P+&v(O7o;l!j z8wbd)(88s=Gx-Ys@577!R*ddd0Iaus=}27&>-$`}6-T?vl{L@Stor6OOVM#8{vmf4u(DDG_)aK5NU1x?7s+pP2c_p D*1x#@ delta 1732 zcmZ8hTTC2P7@jk`v%Ab*D9r9smgQE9Fw0epXo2EV3XP!>=t|mdpd;)ITj;{lGXpIZ zB55$vG{!Wi28}VsOQNPpO*4soBpBWrKVp1P8(I*Y9&-(wfI|!X*zy0t3Ip2TI z*?xz7y%Ks942m3l*&nvEiPk%zqh$9^<7Z7-P7Qoc(h)Vd!KI@-cZO3#8=P9IRoru7 zILD=ruJH1a2Y-C(5?eCe69aj5b|Gsrca8gm?2%oRhnPPJfGs(Of8lcs5y$Bm!t8M% z772s77;ZZ##+eU%UlE}Sq&7AwX2=b;Bi1!Ys(XW^J*uP%@b6VUuvi~xUeHQZA84W~ zF^|7XUMZKumhgIB)p8kJl=BH7;D(+gz`Dg59Q)B1XFDBXRvPd{S2?A)TaGhIoE+A1 zq$X^H9Q9tY-dq{m?u|tp6>|48W?4<(0*j)bqt}L4kzX@8umN!lKd@(#CE|qol?BNxH^MGZ3}Kt&#~?@fyG8T5}t0 zHu|X55{CK*22->V{IZX>!5@tw1QBo-6xU$!>UBEAl!~tCFsSR?-y$bf-STdd%@;PO zeu>qZ-&UM(bz&7OK(+b&vZhSu@|i0%fhJMc3{{(%TFMy|r(}7i78kVzm8Mv%>bb`K zu9nx(t{Y2Kqc1{~?gprXkCuTzdrh_KK7ST_*j0;_3f*WEm@V=0tm-tr2!?N52X=~3)tw@aaf9q0vwNdURzK4fLO93XtdEn6 zY^}aF`YsrNxX?4ieOLb>KV)~Yx8PUw%lT^s@+_aCEnHpFmNeOYpc`(4rU9NI=z@9o z_zvHE3_O-=N>wf2nX}5+c>n1XeI8R}fI~A*v-QR#nKpMC@AB<-ch_Qm(ef(?Xv|>d zB>?>pb(7{sLL$vrlI8#`58NHi&}9Dqh3a_8o$1Y+-#0H4***@gtY#GGw24Jdi<7cE zx|T8Wl*Y`d)=x+T!|7E7n|&mnQd4S=xL$e%W&1TCg@>RM3?s5&x!|zT9`t4r41{F> zxs<}|(An-kIG(M}TB4f|J2wf7cHa&*WAJ$ZTo1e7T^+&w-w4@HLz^>=F7|8p&!re^ zd4aH;He=A6Y_}&tddi_$m(9_+$7oJPs!WFDpcozitw?aA52-$V6% zgaCqsU|%VGawtL{{B)ed2Dj&~6sq>RSVRBG3AfO+7Z8N-UZ_NfKZy!LypW73a-}6I z%FGg8S4E+CI)M5WohCt|w-8PuQ~+51Og@)`$-&-K|$;y5EX(V=y|strNcSD=l6S`&-c9VPhr(+{wN40 zz$gFr!%S6QG@qpM#WP+Hon&LI1QMO(VjNl~sY~f&`jjDNpdd~sti>r$yD8Q}Ll7ix z86@2XP09eo_~LVAmPKa4Z+{Qr1xQpLL}ZOeqES(Yib2&(29Q`(jOJ5}8cWot)KtSt zT>cr|R(QhU_>j>3?<9(NHkysF>|unYL#5Z^u?&a?O(`~wC5~(C$Zj+#W@w`oAO}8u zq=vnqM)o|@h#9!vB)fw(vc1|l1Ye6P-1CP=LXn_&CmIOcRQaLsc21Ex;q*bhXbMD@VLsR9w@Uan|&lJs;Ta1^pv)FM9_zmFE^Bap=S1l1&p4;PdLIWCGa zxoawu&1K~-WU`e&J6RLvb2G`f(ziI5mNJVnxzRG2QZ3Ev+R`2(>n+a{b~wgw!_`zq zT1dvP$yd-pE?@Q%!Y)Hm)K_qS1Je%hJJ7NNtv|q9Wpvw&t<2b-`pe9Tm!8i|M@6tM P4gE6oQ;t1AsF(f+ebLKr delta 367 zcmeAXddtgqnwOW00SNA#*q^?WWg?#hW6nf%6+z}4mR!~-)?BtIHb#b2rYydRIf~*O zQJhQ+?hGlcEet7atC>LB7#O0sCN3!v1F`sl_%jQTn9fkipvmaBl40^mCV4L1WUCnG z{FKbR^vPeC?74Y>3W`~QL<7U-#mrpHjNFsgv1KyyO_pGnW8|M~&c1+C04VFH$yg*b z`2o9DG|1Q@We@>!Xc0)Vhz~??zzA+2qZnjv3&STSMpphWY?7=}5QQK$n%uXz;^Wgw zOG=AUE&Hu$=lbfGXnv-f*qytpK2*kz4K;i>4 zBO~Ko2KmPfT(=o`o-?RCU}n3{EPRn!c!J|aX0aKHmzbq*@Cr4!eP@wnl={Q~B*1O~ E0Kafe8~^|S diff --git a/__pycache__/window.cpython-312.pyc b/__pycache__/window.cpython-312.pyc index b852c0cceb452fbaa5d10d4a877fc80a4f685ec1..30434d08e7d9b62381e38ac6fc371b72bfe1ee6f 100644 GIT binary patch delta 3301 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 diff --git a/inventory.py b/inventory.py index 95915673..f09e53b2 100644 --- a/inventory.py +++ b/inventory.py @@ -1,5 +1,7 @@ +import block + class Inventory: def __init__(self, *args, **kwargs): - return - - \ No newline at end of file + self.hotbar = [block.BRICK, block.GRASS, block.SAND, block.DIRT] + + self.block = self.hotbar[0] \ No newline at end of file diff --git a/main.py b/main.py index 20fd82e9..407c414c 100644 --- a/main.py +++ b/main.py @@ -26,7 +26,7 @@ def setup_fog(): def setup(): """ Basic OpenGL configuration. - +w """ # Set the color of "clear", i.e. the sky, in rgba. glClearColor(0.5, 0.69, 1.0, 1) diff --git a/model.py b/model.py index 4db47829..5d45dd2c 100644 --- a/model.py +++ b/model.py @@ -34,14 +34,7 @@ def cube_vertices(x, y, z, n): TEXTURE_PATH = 'texture.png' -FACES = [ - ( 0, 1, 0), - ( 0,-1, 0), - (-1, 0, 0), - ( 1, 0, 0), - ( 0, 0, 1), - ( 0, 0,-1), -] + def sectorize(position): """ Returns a tuple representing the sector for the given `position`. @@ -62,7 +55,14 @@ def sectorize(position): class Model(object): def __init__(self): - + self.FACES = [ + ( 0, 1, 0), + ( 0,-1, 0), + (-1, 0, 0), + ( 1, 0, 0), + ( 0, 0, 1), + ( 0, 0,-1), + ] # A Batch is a collection of vertex lists for batched rendering. self.batch = pyglet.graphics.Batch() @@ -133,7 +133,7 @@ def exposed(self, position): """ x, y, z = position - for dx, dy, dz in FACES: + for dx, dy, dz in self.FACES: if (x + dx, y + dy, z + dz) not in self.world: return True return False @@ -187,7 +187,7 @@ def check_neighbors(self, position): """ x, y, z = position - for dx, dy, dz in FACES: + for dx, dy, dz in self.FACES: key = (x + dx, y + dy, z + dz) if key not in self.world: continue @@ -306,6 +306,53 @@ def change_sectors(self, before, after): self.show_sector(sector) for sector in hide: self.hide_sector(sector) + + def collide(self, position, height): + """ Checks to see if the player at the given `position` and `height` + is colliding with any blocks in the world. + + Parameters + ---------- + position : tuple of len 3 + The (x, y, z) position to check for collisions at. + height : int or float + The height of the player. + + Returns + ------- + position : tuple of len 3 + The new position of the player taking into account collisions. + + """ + # How much overlap with a dimension of a surrounding block you need to + # have to count as a collision. If 0, touching terrain at all counts as + # a collision. If .49, you sink into the ground, as if walking through + # tall grass. If >= .5, you'll fall through the ground. + pad = 0.25 + p = list(position) + np = mmath.normalize(position) + for face in self.FACES: # check all surrounding blocks + for i in xrange(3): # check each dimension independently + if not face[i]: + continue + # How much overlap you have with this dimension. + d = (p[i] - np[i]) * face[i] + if d < pad: + continue + for dy in xrange(height): # check each height + op = list(np) + op[1] -= dy + op[i] += face[i] + if tuple(op) not in self.world: + continue + p[i] -= (d - pad) * face[i] + if face == (0, -1, 0) or face == (0, 1, 0): + # You are colliding with the ground or ceiling, so stop + # falling / rising. + print(face) + self.dy = 0 + break + return tuple(p) def _enqueue(self, func, *args): """ Add `func` to the internal queue. diff --git a/player.py b/player.py index 14449f6f..8e368e28 100644 --- a/player.py +++ b/player.py @@ -2,14 +2,36 @@ import sys import mmath +import math +import inventory from pyglet.window import key, mouse if sys.version_info[0] >= 3: xrange = range + + class Player(): def __init__(self, *args, **kwargs): + self.WALKING_SPEED = 5 + self.FLYING_SPEED = 15 + + self.GRAVITY = 20.0 + self.MAX_JUMP_HEIGHT = 1.0 # About the height of a block. + # To derive the formula for calculating jump speed, first solve + # v_t = v_0 + a * t + # for the time at which you achieve maximum height, where a is the acceleration + # due to gravity and v_t = 0. This gives: + # t = - v_0 / a + # Use t and the desired MAX_JUMP_HEIGHT to solve for v_0 (jump speed) in + # s = s_0 + v_0 * t + (a * t^2) / 2 + self.JUMP_SPEED = math.sqrt(2 * self.GRAVITY * self.MAX_JUMP_HEIGHT) + self.TERMINAL_VELOCITY = 50 + + self.PLAYER_HEIGHT = 2 + + self.inventory = inventory.Inventory() return def hit_test(self, position, world, vector, max_distance=8): diff --git a/window.py b/window.py index 2f5fc9fd..52e80c78 100644 --- a/window.py +++ b/window.py @@ -5,28 +5,10 @@ import player #from collections import deque -from pyglet.gl import * +from pyglet.gl import * # noqa: F403 from pyglet.window import key, mouse - -WALKING_SPEED = 5 -FLYING_SPEED = 15 - -GRAVITY = 20.0 -MAX_JUMP_HEIGHT = 1.0 # About the height of a block. -# To derive the formula for calculating jump speed, first solve -# v_t = v_0 + a * t -# for the time at which you achieve maximum height, where a is the acceleration -# due to gravity and v_t = 0. This gives: -# t = - v_0 / a -# Use t and the desired MAX_JUMP_HEIGHT to solve for v_0 (jump speed) in -# s = s_0 + v_0 * t + (a * t^2) / 2 -JUMP_SPEED = math.sqrt(2 * GRAVITY * MAX_JUMP_HEIGHT) -TERMINAL_VELOCITY = 50 - -PLAYER_HEIGHT = 2 - class Window(pyglet.window.Window): def __init__(self, *args, **kwargs): @@ -70,12 +52,6 @@ def __init__(self, *args, **kwargs): # Velocity in the y (upward) direction. self.dy = 0 - # A list of blocks the player can place. Hit num keys to cycle. - self.inventory = [model.block.BRICK, model.block.GRASS, model.block.SAND, model.block.DIRT] - - # The current block the user can place. Hit num keys to cycle. - self.block = self.inventory[0] - # Convenience list of num keys. self.num_keys = [ key._1, key._2, key._3, key._4, key._5, @@ -85,13 +61,13 @@ def __init__(self, *args, **kwargs): self.model = model.Model() # The label that is displayed in the top left of the canvas. - self.label = pyglet.text.Label('', font_name='Arial', font_size=18, + self.label = pyglet.text.Label('', font_name='Arial', font_size=18, # noqa: F405 x=10, y=self.height - 10, anchor_x='left', anchor_y='top', color=(0, 0, 0, 255)) # This call schedules the `update()` method to be called # TICKS_PER_SEC. This is the main game event loop. - pyglet.clock.schedule_interval(self.update, 1.0 / model.TICKS_PER_SEC) + pyglet.clock.schedule_interval(self.update, 1.0 / model.TICKS_PER_SEC) # noqa: F405 def set_exclusive_mouse(self, exclusive): """ If `exclusive` is True, the game will capture the mouse, if False @@ -190,7 +166,7 @@ def _update(self, dt): """ # walking - speed = FLYING_SPEED if self.flying else WALKING_SPEED + speed = self.player.FLYING_SPEED if self.flying else self.player.WALKING_SPEED d = dt * speed # distance covered this tick. dx, dy, dz = self.get_motion_vector() # New position in space, before accounting for gravity. @@ -200,60 +176,14 @@ def _update(self, dt): # Update your vertical speed: if you are falling, speed up until you # hit terminal velocity; if you are jumping, slow down until you # start falling. - self.dy -= dt * GRAVITY - self.dy = max(self.dy, -TERMINAL_VELOCITY) + self.dy -= dt * self.player.GRAVITY + self.dy = max(self.dy, -self.player.TERMINAL_VELOCITY) dy += self.dy * dt # collisions x, y, z = self.position - x, y, z = self.collide((x + dx, y + dy, z + dz), PLAYER_HEIGHT) + x, y, z = self.model.collide((x + dx, y + dy, z + dz), self.player.PLAYER_HEIGHT) self.position = (x, y, z) - def collide(self, position, height): - """ Checks to see if the player at the given `position` and `height` - is colliding with any blocks in the world. - - Parameters - ---------- - position : tuple of len 3 - The (x, y, z) position to check for collisions at. - height : int or float - The height of the player. - - Returns - ------- - position : tuple of len 3 - The new position of the player taking into account collisions. - - """ - # How much overlap with a dimension of a surrounding block you need to - # have to count as a collision. If 0, touching terrain at all counts as - # a collision. If .49, you sink into the ground, as if walking through - # tall grass. If >= .5, you'll fall through the ground. - pad = 0.25 - p = list(position) - np = model.mmath.normalize(position) - for face in model.FACES: # check all surrounding blocks - for i in model.xrange(3): # check each dimension independently - if not face[i]: - continue - # How much overlap you have with this dimension. - d = (p[i] - np[i]) * face[i] - if d < pad: - continue - for dy in model.xrange(height): # check each height - op = list(np) - op[1] -= dy - op[i] += face[i] - if tuple(op) not in self.model.world: - continue - p[i] -= (d - pad) * face[i] - if face == (0, -1, 0) or face == (0, 1, 0): - # You are colliding with the ground or ceiling, so stop - # falling / rising. - self.dy = 0 - break - return tuple(p) - def on_mouse_press(self, x, y, button, modifiers): """ Called when a mouse button is pressed. See pyglet docs for button amd modifier mappings. @@ -278,8 +208,8 @@ def on_mouse_press(self, x, y, button, modifiers): ((button == mouse.LEFT) and (modifiers & key.MOD_CTRL)): # ON OSX, control + left click = right click. if previous: - self.model.add_block(previous, self.block) - elif button == pyglet.window.mouse.LEFT and selectedBlock: + self.model.add_block(previous, self.player.inventory.block) + elif button == pyglet.window.mouse.LEFT and selectedBlock: # noqa: F405 texture = self.model.world[selectedBlock] if texture != model.block.STONE: self.model.remove_block(selectedBlock) @@ -327,14 +257,14 @@ def on_key_press(self, symbol, modifiers): self.strafe[1] += 1 elif symbol == key.SPACE: if self.dy == 0: - self.dy = JUMP_SPEED + self.dy = player.JUMP_SPEED elif symbol == key.ESCAPE: self.set_exclusive_mouse(False) elif symbol == key.TAB: self.flying = not self.flying elif symbol in self.num_keys: - index = (symbol - self.num_keys[0]) % len(self.inventory) - self.block = self.inventory[index] + index = (symbol - self.num_keys[0]) % len(self.player.inventory.hotbar) + self.player.inventory.block = self.player.inventory.hotbar[index] def on_key_release(self, symbol, modifiers): """ Called when the player releases a key. See pyglet docs for key @@ -377,9 +307,9 @@ def set_2d(self): """ width, height = self.get_size() - glDisable(GL_DEPTH_TEST) + glDisable(GL_DEPTH_TEST) # noqa: F405 viewport = self.get_viewport_size() - glViewport(0, 0, max(1, viewport[0]), max(1, viewport[1])) + glViewport(0, 0, max(1, viewport[0]), max(1, viewport[1])) # noqa: F405 glMatrixMode(GL_PROJECTION) glLoadIdentity() glOrtho(0, max(1, width), 0, max(1, height), -1, 1) @@ -411,7 +341,7 @@ def on_draw(self): """ self.clear() self.set_3d() - glColor3d(1, 1, 1) + glColor3d(1, 1, 1) # noqa: F405 self.model.batch.draw() self.draw_focused_block() self.set_2d() @@ -430,8 +360,8 @@ def draw_focused_block(self): vertex_data = model.cube_vertices(x, y, z, 0.51) glColor3d(0, 0, 0) glPolygonMode(GL_FRONT_AND_BACK, GL_LINE) - pyglet.graphics.draw(24, GL_QUADS, ('v3f/static', vertex_data)) - glPolygonMode(GL_FRONT_AND_BACK, GL_FILL) + pyglet.graphics.draw(24, GL_QUADS, ('v3f/static', vertex_data)) # noqa: F405 + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL) # noqa: F405 def draw_label(self): """ Draw the label in the top left of the screen. From 372f0afad539ac364bf35c0b7078861c5cb96558 Mon Sep 17 00:00:00 2001 From: Kyle Wadas Date: Thu, 27 Feb 2025 02:16:16 -0700 Subject: [PATCH 06/46] Fixed Issues Regarding Player Movement and View --- __pycache__/block.cpython-312.pyc | Bin 1225 -> 1223 bytes __pycache__/inventory.cpython-312.pyc | Bin 735 -> 733 bytes __pycache__/mmath.cpython-312.pyc | Bin 702 -> 700 bytes __pycache__/model.cpython-312.pyc | Bin 17087 -> 17011 bytes __pycache__/player.cpython-312.pyc | Bin 2316 -> 5282 bytes __pycache__/window.cpython-312.pyc | Bin 18025 -> 16992 bytes model.py | 9 ++- player.py | 99 ++++++++++++++++++++++++-- window.py | 85 ++++++++-------------- 9 files changed, 126 insertions(+), 67 deletions(-) diff --git a/__pycache__/block.cpython-312.pyc b/__pycache__/block.cpython-312.pyc index 72643d25e12537859545558fb2115c8633ef09d3..0c1765ea8bef829f685e991825b777dab1e9f0fe 100644 GIT binary patch delta 35 pcmX@fd7P8$G%qg~0}z}(u#qc|kxM7pD#kfKB{MI5a|@#@GXS-T3RD09 delta 37 rcmX@kd6JXsG%qg~0}uq<-N=>4$fK8R6%$aDpOuT&a#oWiiJxj*(%04KP59See-0NHTsM!lPBtnD4k$r zV3^L3!dS~v0%Soz4by5UyOyCDb?X}M^t)-vdonIz{a4eHiK;r=S>mG zkK){dQXlz&DnBp-HGk2V%x-mqF=g`uD?UcXtj+JO-!m~5ZoY4q&B$1@+1o*!kyVFP b;#17#bVqkaK`&NDnGUzF3?RBl80ZuL31Eo# delta 759 zcmZ8eO-vI}5T3XDcH3^dHI+8CKVTJO1S-NoZP92NYK;j26Y!wHXwpRjB}%qSB)60eB7usmK;aEo0{bz|g&A#C zFs0>f)bDoL3UYXvm&qjwz$CSy?krZ_KWqgHefyLv?ud%UG=r{6tCEnxe0CI|C>N#k zBGZ_sgS3U(dKb4aZW+^DJ_d`y);~U<4pvdqxVS-w2DScwgMUVZ}-xh_AumixT+cFIUUMF?tJ2`F#3%T)2smZCCRAK7c zWZvvU8uPF?dc}degaIEvl1cO~n+tcXuZp#@yfkMH3h;^m{pKh-ej_tV#k2AC%t_M2 z-)GYO5np^Qza2@`bNu=)g!TA3X+$x5dVf0{`xGDi93J8{J3<2dbavrbQ-xSx-PrIq zj`r8-hUZH-wi644;yWSi{3#<@GtJ*-8|04jY%EB~lJnx+4~di=exXFjL+AI!C{c!$ YL%X+~MD8*PO(-O}R`>=^jB^l2l1aj&rom%!w)8nNSv0afgBNsHtJr6?L@N2lN^e z(G(>haG1J@z+IO>-=x4@1}LZCfZCOEa&FxA-wS_e3I6Qqm%k)kbsc4p@vPu&90t)eTgB?oih8 zS5H^@pwWi5JG!%uJO1+FUcx^3vGgRow z#SCr}3LVZmJ`U`GXDC{`!R!Y;yz(NUU0@1k@d(*QaimIsN4J&cp8Fru)!#VhW z!I5Ui;7hYgj8&!hjK-=WkE1he3@ZsXx`;9CLDt%318g|P^6WKPiO#W->LYuI6e+2R zScPpP3aq5T2#ZB+5hq2VpXFsG8E2OzZHCom#ER}b7MCP|QaJ^>244mzYvc}6Lzs#){59OthP8W8|#+#2N7l2|+)?ls7fPMSHk!F7$mxAOJGj-- zv34?lvUsYEiBya z%g+{jir3ap-HY8jzRo}FeYo&d-~HKKPj=zf;BEuh-u0uVF8n;W8D*fd3OVV7-t)l? zvqtV#Yow;de&CZEXkSS-0KXQqD&rX@O{W=xECy!TXi`S7e!y!G-5;?rse#DI?2erxufovv>S&DwW(bp;K`O3Bhx)fRYP-v({W z3^QdQADJbW(Y{i}Xs}QxIh=)bbbozOK#y{$TRW3=}hS9JjF`LB!S?5a#43QF;xeFlcOuGfgD$E8cuzlIo1KG6G@)O{aTu+`F z`Fh^&m-i-56TfP->P5rW`swyF-XuK2Va0UD13xbSyF2ZTG4CSIx%wSDX=JOaflgM= zTLIEaCI=uQMFE{5l_e0iBti;IaMVOypM@5cr&2W=tys1NDw(KFSIqx#7HTA@Q3b9C zczx~n0P<%uLnV;D3aK%G9AG(kn5x0o9dfkd@H2|>vfcSF6waqJkV4{vz{k&#ihL*C zEr@X}imLA9A^UtucVk|V_@ruJw9Z5oRc8RuIiCTtHTX&F=j zNM#@|0bP|GO)GA!39|S#;H`F6koEuZpQ!m^B{$I1Hso*2YM)%cb^UJ*-H`CDy_tXW z)`jd~c3~?RTAR*K|KZ3N$01o0zMQ*1_o(;GM(}L*;#Patnw*!5r+%koM{J_FbnnbY z`#^T2Yy#|7Tj$znezfrZM%&RGMa+GW|DX`x2=*DN<=WZ&*}}qa&uxbe=7!3hq1+&u z-eBg>6$c-;9^GzhFZAX|b3;#E2xhdj*PBbh<2kz4pux)1+riFf`Oi`y(A<_CDp#wf zmfTQ*&ZZxEx((DF=O}y>q67a_f;V~+9zctU^MEZlWjj3(muPlT??p>&a`~&fdKv9U{&J$b7Ly zc=o}3n4msvk(7#$LC@G!nAp(+^C{RF+JJd28;=4^t_j`01Wz_dLEt|OF-3P8&k_6r zQ8v68C%xxM)dSV{o;S>;ox_)bB%5133)L<|QPkhj;qQ>|Tjc*1HGGSj{)vukGpC`}!Ff=F!`{~x68qh|mB delta 619 zcmZ8d&ubGw6n-~2bv=*nzVQf5#g zU21;IC=sihC*d*7S)zV{yQUGQqg|Ll2rK$Cwz zZT@gy``>O>Fd9J&4H7|vMq~gDE3zXxAPu{31uS#cy3KwpLSl3WW}`3R+Z%(fld;{0 zz|{#oOM`;mr7zD1R%WMhx0TsVv6*I0=c)0jg_2sWwqFmgt*?os9f!SCzqM9LTmQ5= zIqvV7{vp#Z?Ad2ukd7cCib=ALO64e5acNC>PUTf0qN>&ieCf+#=L*~bkw;3OfN;!Li-wfIJ&?XCq9}*M3IN;K4jbf; zL|hjBM~dUp&c_{QQ)1~i?&%XHF^8IrKT6WA-d6HZ@4B~7np@&wj+&U)r+9T?2{Y*k z;W_-Og69v(_nFF$J0!#9VN-ALfnUYs-GGQ1`he-EymWa1saQsM55lCyya7H1Gc7G5 z3}8<n~Zb9IJ?`{#srnXY`-)%7w*gskmg=VUK;j@*s&GcjFu4Iws7e)2sUa>_x9m KDq}#H)cymmPkv4S diff --git a/__pycache__/window.cpython-312.pyc b/__pycache__/window.cpython-312.pyc index 30434d08e7d9b62381e38ac6fc371b72bfe1ee6f..f082cb5d15cc9084b3cd010b33521206f7bd3f76 100644 GIT binary patch delta 4322 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 diff --git a/model.py b/model.py index 5d45dd2c..7cf4575d 100644 --- a/model.py +++ b/model.py @@ -8,7 +8,7 @@ from collections import deque from pyglet import image -from pyglet.gl import * +from pyglet.gl import * # noqa: F403 from pyglet.graphics import TextureGroup if sys.version_info[0] >= 3: @@ -64,7 +64,7 @@ def __init__(self): ( 0, 0,-1), ] # A Batch is a collection of vertex lists for batched rendering. - self.batch = pyglet.graphics.Batch() + self.batch = pyglet.graphics.Batch() # noqa: F405 # A TextureGroup manages an OpenGL texture. self.group = TextureGroup(image.load(TEXTURE_PATH).get_texture()) @@ -307,7 +307,7 @@ def change_sectors(self, before, after): for sector in hide: self.hide_sector(sector) - def collide(self, position, height): + def collide(self, window, position, height): """ Checks to see if the player at the given `position` and `height` is colliding with any blocks in the world. @@ -349,8 +349,7 @@ def collide(self, position, height): if face == (0, -1, 0) or face == (0, 1, 0): # You are colliding with the ground or ceiling, so stop # falling / rising. - print(face) - self.dy = 0 + window.dy = 0 break return tuple(p) diff --git a/player.py b/player.py index 8e368e28..2e73f0a5 100644 --- a/player.py +++ b/player.py @@ -13,7 +13,7 @@ class Player(): - def __init__(self, *args, **kwargs): + def __init__(self, model, *args, **kwargs): self.WALKING_SPEED = 5 self.FLYING_SPEED = 15 @@ -32,9 +32,29 @@ def __init__(self, *args, **kwargs): self.PLAYER_HEIGHT = 2 self.inventory = inventory.Inventory() - return + self.model = model + + # When flying gravity has no effect and speed is increased. + self.flying = False + + # Current (x, y, z) position in the world, specified with floats. Note + # that, perhaps unlike in math class, the y-axis is the vertical axis. + self.position = (0, 0, 0) + + # First element is -1 when moving forward, 1 when moving back, and 0 + # otherwise. The second element is -1 when moving left, 1 when moving + # right, and 0 otherwise. + self.strafe = [0, 0] + + # First element is rotation of the player in the x-z plane (ground + # plane) measured from the z-axis down. The second is the rotation + # angle from the ground plane up. Rotation is in degrees. + # + # The vertical plane rotation ranges from -90 (looking straight down) to + # 90 (looking straight up). The horizontal rotation range is unbounded. + self.rotation = (0, 0) - def hit_test(self, position, world, vector, max_distance=8): + def hit_test(self, world, vector, max_distance=8): """ Line of sight search from current position. If a block is intersected it is returned, along with the block previously in the line of sight. If no block is found, return None, None. @@ -50,7 +70,8 @@ def hit_test(self, position, world, vector, max_distance=8): """ m = 8 - x, y, z = position + x, y, z = self.position + print(vector) dx, dy, dz = vector previous = None for _ in xrange(max_distance * m): @@ -59,4 +80,72 @@ def hit_test(self, position, world, vector, max_distance=8): return key, previous previous = key x, y, z = x + dx / m, y + dy / m, z + dz / m - return None, None \ No newline at end of file + return None, None + + def updatePosition(self, window, dt): + """ Private implementation of the `update()` method. This is where most + of the motion logic lives, along with gravity and collision detection. + + Parameters + ---------- + dt : float + The change in time since the last call. + + """ + # walking + speed = self.FLYING_SPEED if self.flying else self.WALKING_SPEED + d = dt * speed # distance covered this tick. + dx, dy, dz = self.get_motion_vector() + # New position in space, before accounting for gravity. + dx, dy, dz = dx * d, dy * d, dz * d + # gravity + if not self.flying: + # Update your vertical speed: if you are falling, speed up until you + # hit terminal velocity; if you are jumping, slow down until you + # start falling. + window.dy -= dt * self.GRAVITY + window.dy = max(window.dy, -self.TERMINAL_VELOCITY) + dy += window.dy * dt + # collisions + x, y, z = self.position + x, y, z = window.model.collide(window, (x + dx, y + dy, z + dz), self.PLAYER_HEIGHT) + self.position = (x, y, z) + + def get_motion_vector(self): + """ Returns the current motion vector indicating the velocity of the + player. + + Returns + ------- + vector : tuple of len 3 + Tuple containing the velocity in x, y, and z respectively. + + """ + if any(self.strafe): + x, y = self.rotation + strafe = math.degrees(math.atan2(*self.strafe)) + y_angle = math.radians(y) + x_angle = math.radians(x + strafe) + if self.flying: + m = math.cos(y_angle) + dy = math.sin(y_angle) + if self.strafe[1]: + # Moving left or right. + dy = 0.0 + m = 1 + if self.strafe[0] > 0: + # Moving backwards. + dy *= -1 + # When you are flying up or down, you have less left and right + # motion. + dx = math.cos(x_angle) * m + dz = math.sin(x_angle) * m + else: + dy = 0.0 + dx = math.cos(x_angle) + dz = math.sin(x_angle) + else: + dy = 0.0 + dx = 0.0 + dz = 0.0 + return (dx, dy, dz) \ No newline at end of file diff --git a/window.py b/window.py index 52e80c78..aeb80a16 100644 --- a/window.py +++ b/window.py @@ -14,8 +14,11 @@ class Window(pyglet.window.Window): def __init__(self, *args, **kwargs): super(Window, self).__init__(*args, **kwargs) + # Instance of the model that handles the world. + self.model = model.Model() + + self.player = player.Player(model) - self.player = player.Player() # Whether or not the window exclusively captures the mouse. self.exclusive = False @@ -29,11 +32,11 @@ def __init__(self, *args, **kwargs): # First element is -1 when moving forward, 1 when moving back, and 0 # otherwise. The second element is -1 when moving left, 1 when moving # right, and 0 otherwise. - self.strafe = [0, 0] + #self.strafe = [0, 0] # Current (x, y, z) position in the world, specified with floats. Note # that, perhaps unlike in math class, the y-axis is the vertical axis. - self.position = (0, 0, 0) + #self.position = (0, 0, 0) # First element is rotation of the player in the x-z plane (ground # plane) measured from the z-axis down. The second is the rotation @@ -41,7 +44,7 @@ def __init__(self, *args, **kwargs): # # The vertical plane rotation ranges from -90 (looking straight down) to # 90 (looking straight up). The horizontal rotation range is unbounded. - self.rotation = (0, 0) + #self.rotation = (0, 0) # Which sector the player is currently in. self.sector = None @@ -57,9 +60,6 @@ def __init__(self, *args, **kwargs): key._1, key._2, key._3, key._4, key._5, key._6, key._7, key._8, key._9, key._0] - # Instance of the model that handles the world. - self.model = model.Model() - # The label that is displayed in the top left of the canvas. self.label = pyglet.text.Label('', font_name='Arial', font_size=18, # noqa: F405 x=10, y=self.height - 10, anchor_x='left', anchor_y='top', @@ -82,7 +82,7 @@ def get_sight_vector(self): the player is looking. """ - x, y = self.rotation + x, y = self.player.rotation # y ranges from -90 to 90, or -pi/2 to pi/2, so m ranges from 0 to 1 and # is 1 when looking ahead parallel to the ground and 0 when looking # straight up or down. @@ -105,7 +105,7 @@ def get_motion_vector(self): """ if any(self.strafe): - x, y = self.rotation + x, y = self.player.rotation strafe = math.degrees(math.atan2(*self.strafe)) y_angle = math.radians(y) x_angle = math.radians(x + strafe) @@ -144,7 +144,7 @@ def update(self, dt): """ self.model.process_queue() - sector = model.sectorize(self.position) + sector = model.sectorize(self.player.position) if sector != self.sector: self.model.change_sectors(self.sector, sector) if self.sector is None: @@ -153,36 +153,7 @@ def update(self, dt): m = 8 dt = min(dt, 0.2) for _ in model.xrange(m): - self._update(dt / m) - - def _update(self, dt): - """ Private implementation of the `update()` method. This is where most - of the motion logic lives, along with gravity and collision detection. - - Parameters - ---------- - dt : float - The change in time since the last call. - - """ - # walking - speed = self.player.FLYING_SPEED if self.flying else self.player.WALKING_SPEED - d = dt * speed # distance covered this tick. - dx, dy, dz = self.get_motion_vector() - # New position in space, before accounting for gravity. - dx, dy, dz = dx * d, dy * d, dz * d - # gravity - if not self.flying: - # Update your vertical speed: if you are falling, speed up until you - # hit terminal velocity; if you are jumping, slow down until you - # start falling. - self.dy -= dt * self.player.GRAVITY - self.dy = max(self.dy, -self.player.TERMINAL_VELOCITY) - dy += self.dy * dt - # collisions - x, y, z = self.position - x, y, z = self.model.collide((x + dx, y + dy, z + dz), self.player.PLAYER_HEIGHT) - self.position = (x, y, z) + self.player.updatePosition(self, dt / m) def on_mouse_press(self, x, y, button, modifiers): """ Called when a mouse button is pressed. See pyglet docs for button @@ -203,7 +174,7 @@ def on_mouse_press(self, x, y, button, modifiers): """ if self.exclusive: vector = self.get_sight_vector() - selectedBlock, previous = self.player.hit_test(self.position, self.model.world, vector) + selectedBlock, previous = self.player.hit_test(self.model.world, vector) if (button == mouse.RIGHT) or \ ((button == mouse.LEFT) and (modifiers & key.MOD_CTRL)): # ON OSX, control + left click = right click. @@ -230,10 +201,10 @@ def on_mouse_motion(self, x, y, dx, dy): """ if self.exclusive: m = 0.15 - x, y = self.rotation + x, y = self.player.rotation x, y = x + dx * m, y + dy * m y = max(-90, min(90, y)) - self.rotation = (x, y) + self.player.rotation = (x, y) def on_key_press(self, symbol, modifiers): """ Called when the player presses a key. See pyglet docs for key @@ -248,20 +219,20 @@ def on_key_press(self, symbol, modifiers): """ if symbol == key.W: - self.strafe[0] -= 1 + self.player.strafe[0] -= 1 elif symbol == key.S: - self.strafe[0] += 1 + self.player.strafe[0] += 1 elif symbol == key.A: - self.strafe[1] -= 1 + self.player.strafe[1] -= 1 elif symbol == key.D: - self.strafe[1] += 1 + self.player.strafe[1] += 1 elif symbol == key.SPACE: if self.dy == 0: - self.dy = player.JUMP_SPEED + self.dy = self.player.JUMP_SPEED elif symbol == key.ESCAPE: self.set_exclusive_mouse(False) elif symbol == key.TAB: - self.flying = not self.flying + self.player.flying = not self.player.flying elif symbol in self.num_keys: index = (symbol - self.num_keys[0]) % len(self.player.inventory.hotbar) self.player.inventory.block = self.player.inventory.hotbar[index] @@ -279,13 +250,13 @@ def on_key_release(self, symbol, modifiers): """ if symbol == key.W: - self.strafe[0] += 1 + self.player.strafe[0] += 1 elif symbol == key.S: - self.strafe[0] -= 1 + self.player.strafe[0] -= 1 elif symbol == key.A: - self.strafe[1] += 1 + self.player.strafe[1] += 1 elif symbol == key.D: - self.strafe[1] -= 1 + self.player.strafe[1] -= 1 def on_resize(self, width, height): """ Called when the window is resized to a new `width` and `height`. @@ -329,10 +300,10 @@ def set_3d(self): gluPerspective(65.0, width / float(height), 0.1, 60.0) glMatrixMode(GL_MODELVIEW) glLoadIdentity() - x, y = self.rotation + x, y = self.player.rotation glRotatef(x, 0, 1, 0) glRotatef(-y, math.cos(math.radians(x)), 0, math.sin(math.radians(x))) - x, y, z = self.position + x, y, z = self.player.position glTranslatef(-x, -y, -z) def on_draw(self): @@ -354,7 +325,7 @@ def draw_focused_block(self): """ vector = self.get_sight_vector() - block = self.player.hit_test(self.position, self.model.world, vector)[0] + block = self.player.hit_test(self.model.world, vector)[0] if block: x, y, z = block vertex_data = model.cube_vertices(x, y, z, 0.51) @@ -367,7 +338,7 @@ def draw_label(self): """ Draw the label in the top left of the screen. """ - x, y, z = self.position + x, y, z = self.player.position self.label.text = '%02d (%.2f, %.2f, %.2f) %d / %d' % ( pyglet.clock.get_fps(), x, y, z, len(self.model._shown), len(self.model.world)) From 8037dfe4d702d82eea344c5ad63f0f1e83d35f4b Mon Sep 17 00:00:00 2001 From: Kyle Wadas Date: Thu, 27 Feb 2025 19:38:04 -0700 Subject: [PATCH 07/46] Moved All Movement Input to Player --- __pycache__/model.cpython-312.pyc | Bin 17011 -> 16948 bytes __pycache__/player.cpython-312.pyc | Bin 5282 -> 11994 bytes __pycache__/window.cpython-312.pyc | Bin 16992 -> 8474 bytes model.py | 23 ++-- player.py | 202 ++++++++++++++++++++++----- window.py | 214 ++--------------------------- 6 files changed, 193 insertions(+), 246 deletions(-) diff --git a/__pycache__/model.cpython-312.pyc b/__pycache__/model.cpython-312.pyc index ef7f299dcb45c57c0e3be9444a29679bd17385fc..9e6ab4c813b981b33957725bfa88cd6a501cc7ff 100644 GIT binary patch delta 1435 zcmZ9MT}&KR6oBuY{bku*ewJNeclp_dLTBkN3t1vAEq~P(|7sP9vY;a{!(V}I@6Hye zkYFT{CO)(|8rny#i9f_NW@>yf8WR(Zeeyw#WA(+F@MeRW_|nvKW`S7m!#C%gd(S!d zoO|#5xxsI4aQ`iz&%v7^cfNMPyWW<{YBULHAF@pZ;TLZ>7(@#y2NQzU88_VTaYr3WNn_OG zVj({^*WEvNal7Wy)R}#`F?gXbnh~*H`KOeRUhXXv|eWsx=(kSJC&tV-}*` zhYsnK${O2yUtCkRC$d#G7sCK`PA2oyas>o^pZfc7GJhVi&h7*w#_zs+b{>S^DpR}~ zssd+u3f2Q>coMz~gm~823A`)?rf~HZTjgW8@il49wr1C1I&>>xI!^YVcyvg}I4`?J z3O^!B@DZpOL0d5;by*C;i`DIsS5eJBfmmmEJuDEphmvx~ff$7v^(l%ZT!bU{rtoyDvoPKsw{R^8vgC>lPn{inQ6c)VWb*Fmpe z3wW*beV{i+d4or4ewLzJDTYa+s3J>H5OT?0IOvPj@Ie@f9gBQ|_WbJz?2Z3_y}22? zDkZI8*6vD`{7i1CSd8gbw8irUt)R*F2ljZeDZ#%n-f!BLnwv1HX~X(W_o*k9XNLP9 z84^d(CRz~(CkHDnWBh01hn6*o$Kkp734Rx@#_xq`kyxYBl79X?&QT zu$`fJB1EVn(7VObXGpFkgbCKEQ3BJU7tYOV#Slo{bIiDt{ zL3pjJ)76PLA%CC27hQ*Jx2tN6ovsD$OVIoXg4zHRnRY%2Z)U#d37G5d;KFA4d_FcL4(m>9#8IqF`FF22lVn)qU}G`=kQF5*mlneqQW1&qco>961SzkTO_ z`951`zppd*U0HStxNbRbEm-RK0O>qOy%pvvol>ehVQ5}66YtpBR0 z)O@;g+ipavK4#W>l*Np@P8$o3FhST976g@j$X11{X-?2Z80u|+-qyqL@<^3m$XfPQ zdiB9hh97Dhy|w%2ZHz^0(F^xoLHphjO0I$0oPfdI6*UHr0CRce1IJZi@d&y^MDY~d zbi_PSH00tw6p4pn#}N#NQG$m91t&YjQ??#YkBv`(MZQ^o6eYz~#5G}8wELVT%Nx!I z9>LdO+>swzSQu`5x>*$d^ju&GP`#6ZF0@@abh4mo`Oa)^DW~V=^0^i5jPafKdC|jB zyD6-)vslPAaZOsYKy9-R9`k+U-G{WB}#Mmg5meux7v-@{70o$axS~LcCm0t%bv>@<}dIL5;=>Su4?D!mh(EVhx@_q zkxG2h*>&xTzRWe=kEbFvC5nq5!VOO%R%$A_%&BT60oz^rIu~6tra7bCCs<%IPpaG z^mO{z6j$h$M-cz?CK)@+elp&Pt%)oS!S*rs8$8$kFi1vxi9*FOVzxzE(DX{CX3muECz5GgwiUH`y})q{_DM(C#q?Z>7%INT&qg*OWgthFktN zAw{5ql&j|p`8>8SS6C`?dQiL>I?~CQ*#JMCHwhj>j8J(%g>#GO#6xf+-Nw$t*Xd{d W4mYcN5S_5HhSKpr1p4P*bod)2O+zpM diff --git a/__pycache__/player.cpython-312.pyc b/__pycache__/player.cpython-312.pyc index c088441db8a99338ecc420f358acb4c4aee56d0e..35cb1c5860acfb823c3f0d3883f656fe029db96f 100644 GIT binary patch literal 11994 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 delta 1940 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 vJho9ve^?glTf!(yY|&bex;>p!UfaFCu(Cso(y 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 h>VKv-eeUUY)0{|UCDQpNxP diff --git a/model.py b/model.py index 7cf4575d..54d2339f 100644 --- a/model.py +++ b/model.py @@ -34,7 +34,14 @@ def cube_vertices(x, y, z, n): TEXTURE_PATH = 'texture.png' - +FACES = [ + ( 0, 1, 0), + ( 0,-1, 0), + (-1, 0, 0), + ( 1, 0, 0), + ( 0, 0, 1), + ( 0, 0,-1), + ] def sectorize(position): """ Returns a tuple representing the sector for the given `position`. @@ -55,14 +62,6 @@ def sectorize(position): class Model(object): def __init__(self): - self.FACES = [ - ( 0, 1, 0), - ( 0,-1, 0), - (-1, 0, 0), - ( 1, 0, 0), - ( 0, 0, 1), - ( 0, 0,-1), - ] # A Batch is a collection of vertex lists for batched rendering. self.batch = pyglet.graphics.Batch() # noqa: F405 @@ -133,7 +132,7 @@ def exposed(self, position): """ x, y, z = position - for dx, dy, dz in self.FACES: + for dx, dy, dz in FACES: if (x + dx, y + dy, z + dz) not in self.world: return True return False @@ -187,7 +186,7 @@ def check_neighbors(self, position): """ x, y, z = position - for dx, dy, dz in self.FACES: + for dx, dy, dz in FACES: key = (x + dx, y + dy, z + dz) if key not in self.world: continue @@ -331,7 +330,7 @@ def collide(self, window, position, height): pad = 0.25 p = list(position) np = mmath.normalize(position) - for face in self.FACES: # check all surrounding blocks + for face in FACES: # check all surrounding blocks for i in xrange(3): # check each dimension independently if not face[i]: continue diff --git a/player.py b/player.py index 2e73f0a5..74131184 100644 --- a/player.py +++ b/player.py @@ -4,7 +4,9 @@ import mmath import math import inventory +import block +from pyglet.gl import * # noqa: F403 from pyglet.window import key, mouse if sys.version_info[0] >= 3: @@ -13,7 +15,7 @@ class Player(): - def __init__(self, model, *args, **kwargs): + def __init__(self, model, window, *args, **kwargs): self.WALKING_SPEED = 5 self.FLYING_SPEED = 15 @@ -33,6 +35,8 @@ def __init__(self, model, *args, **kwargs): self.inventory = inventory.Inventory() self.model = model + self.window = window + self.window.push_handlers(self) # When flying gravity has no effect and speed is increased. self.flying = False @@ -53,8 +57,19 @@ def __init__(self, model, *args, **kwargs): # The vertical plane rotation ranges from -90 (looking straight down) to # 90 (looking straight up). The horizontal rotation range is unbounded. self.rotation = (0, 0) + + # Whether or not the window exclusively captures the mouse. + self.exclusive = True + + # Velocity in the y (upward) direction. + self.dy = 0 + + # Convenience list of num keys. + self.num_keys = [ + key._1, key._2, key._3, key._4, key._5, + key._6, key._7, key._8, key._9, key._0] - def hit_test(self, world, vector, max_distance=8): + def hit_test(self, vector, max_distance=8): """ Line of sight search from current position. If a block is intersected it is returned, along with the block previously in the line of sight. If no block is found, return None, None. @@ -71,45 +86,32 @@ def hit_test(self, world, vector, max_distance=8): """ m = 8 x, y, z = self.position - print(vector) dx, dy, dz = vector previous = None for _ in xrange(max_distance * m): key = mmath.normalize((x, y, z)) - if key != previous and key in world: + if key != previous and key in self.model.world: return key, previous previous = key x, y, z = x + dx / m, y + dy / m, z + dz / m return None, None - def updatePosition(self, window, dt): - """ Private implementation of the `update()` method. This is where most - of the motion logic lives, along with gravity and collision detection. - - Parameters - ---------- - dt : float - The change in time since the last call. + def get_sight_vector(self): + """ Returns the current line of sight vector indicating the direction + the player is looking. """ - # walking - speed = self.FLYING_SPEED if self.flying else self.WALKING_SPEED - d = dt * speed # distance covered this tick. - dx, dy, dz = self.get_motion_vector() - # New position in space, before accounting for gravity. - dx, dy, dz = dx * d, dy * d, dz * d - # gravity - if not self.flying: - # Update your vertical speed: if you are falling, speed up until you - # hit terminal velocity; if you are jumping, slow down until you - # start falling. - window.dy -= dt * self.GRAVITY - window.dy = max(window.dy, -self.TERMINAL_VELOCITY) - dy += window.dy * dt - # collisions - x, y, z = self.position - x, y, z = window.model.collide(window, (x + dx, y + dy, z + dz), self.PLAYER_HEIGHT) - self.position = (x, y, z) + x, y = self.rotation + # y ranges from -90 to 90, or -pi/2 to pi/2, so m ranges from 0 to 1 and + # is 1 when looking ahead parallel to the ground and 0 when looking + # straight up or down. + m = math.cos(math.radians(y)) + # dy ranges from -1 to 1 and is -1 when looking straight down and 1 when + # looking straight up. + dy = math.sin(math.radians(y)) + dx = math.cos(math.radians(x - 90)) * m + dz = math.sin(math.radians(x - 90)) * m + return (dx, dy, dz) def get_motion_vector(self): """ Returns the current motion vector indicating the velocity of the @@ -121,6 +123,7 @@ def get_motion_vector(self): Tuple containing the velocity in x, y, and z respectively. """ + print(self.strafe) if any(self.strafe): x, y = self.rotation strafe = math.degrees(math.atan2(*self.strafe)) @@ -148,4 +151,141 @@ def get_motion_vector(self): dy = 0.0 dx = 0.0 dz = 0.0 - return (dx, dy, dz) \ No newline at end of file + return (dx, dy, dz) + + + + def on_mouse_press(self, x, y, button, modifiers): + """ Called when a mouse button is pressed. See pyglet docs for button + amd modifier mappings. + + Parameters + ---------- + x, y : int + The coordinates of the mouse click. Always center of the screen if + the mouse is captured. + button : int + Number representing mouse button that was clicked. 1 = left button, + 4 = right button. + modifiers : int + Number representing any modifying keys that were pressed when the + mouse button was clicked. + + """ + if self.exclusive: + vector = self.get_sight_vector() + selectedBlock, previous = self.hit_test(vector) + if (button == mouse.RIGHT) or \ + ((button == mouse.LEFT) and (modifiers & key.MOD_CTRL)): + # ON OSX, control + left click = right click. + if previous: + self.model.add_block(previous, self.inventory.block) + elif button == pyglet.window.mouse.LEFT and selectedBlock: # noqa: F405 + texture = self.model.world[selectedBlock] + if texture != block.STONE: + self.model.remove_block(selectedBlock) + else: + self.window.set_exclusive_mouse(True) + + + def on_mouse_motion(self, x, y, dx, dy): + """ Called when the player moves the mouse. + + Parameters + ---------- + x, y : int + The coordinates of the mouse click. Always center of the screen if + the mouse is captured. + dx, dy : float + The movement of the mouse. + + """ + if self.exclusive: + m = 0.15 + x, y = self.rotation + x, y = x + dx * m, y + dy * m + y = max(-90, min(90, y)) + self.rotation = (x, y) + + def update(self, dt): + """ Private implementation of the `update()` method. This is where most + of the motion logic lives, along with gravity and collision detection. + + Parameters + ---------- + dt : float + The change in time since the last call. + + """ + + + # walking + speed = self.FLYING_SPEED if self.flying else self.WALKING_SPEED + d = dt * speed # distance covered this tick. + dx, dy, dz = self.get_motion_vector() + # New position in space, before accounting for gravity. + dx, dy, dz = dx * d, dy * d, dz * d + # gravity + if not self.flying: + # Update your vertical speed: if you are falling, speed up until you + # hit terminal velocity; if you are jumping, slow down until you + # start falling. + self.dy -= dt * self.GRAVITY + self.dy = max(self.dy, -self.TERMINAL_VELOCITY) + dy += self.dy * dt + # collisions + x, y, z = self.position + x, y, z = self.model.collide(self.window, (x + dx, y + dy, z + dz), self.PLAYER_HEIGHT) + self.position = (x, y, z) + + def on_key_press(self, symbol, modifiers): + """ Called when the player presses a key. See pyglet docs for key + mappings. + + Parameters + ---------- + symbol : int + Number representing the key that was pressed. + modifiers : int + Number representing any modifying keys that were pressed. + + """ + if symbol == key.W: + self.strafe[0] -= 1 + elif symbol == key.S: + self.strafe[0] += 1 + elif symbol == key.A: + self.strafe[1] -= 1 + elif symbol == key.D: + self.strafe[1] += 1 + elif symbol == key.SPACE: + if self.dy == 0: + self.dy = self.JUMP_SPEED + elif symbol == key.ESCAPE: + self.window.set_exclusive_mouse(False) + elif symbol == key.TAB: + self.player.flying = not self.player.flying + elif symbol in self.num_keys: + index = (symbol - self.num_keys[0]) % len(self.inventory.hotbar) + self.inventory.block = self.inventory.hotbar[index] + + def on_key_release(self, symbol, modifiers): + """ Called when the player releases a key. See pyglet docs for key + mappings. + + Parameters + ---------- + symbol : int + Number representing the key that was pressed. + modifiers : int + Number representing any modifying keys that were pressed. + + """ + if symbol == key.W: + self.strafe[0] += 1 + elif symbol == key.S: + self.strafe[0] -= 1 + elif symbol == key.A: + self.strafe[1] += 1 + elif symbol == key.D: + self.strafe[1] -= 1 \ No newline at end of file diff --git a/window.py b/window.py index aeb80a16..3dd1172c 100644 --- a/window.py +++ b/window.py @@ -6,7 +6,6 @@ #from collections import deque from pyglet.gl import * # noqa: F403 -from pyglet.window import key, mouse class Window(pyglet.window.Window): @@ -17,34 +16,8 @@ def __init__(self, *args, **kwargs): # Instance of the model that handles the world. self.model = model.Model() - self.player = player.Player(model) - - - # Whether or not the window exclusively captures the mouse. - self.exclusive = False - - # When flying gravity has no effect and speed is increased. - self.flying = False - - # Strafing is moving lateral to the direction you are facing, - # e.g. moving to the left or right while continuing to face forward. - # - # First element is -1 when moving forward, 1 when moving back, and 0 - # otherwise. The second element is -1 when moving left, 1 when moving - # right, and 0 otherwise. - #self.strafe = [0, 0] - - # Current (x, y, z) position in the world, specified with floats. Note - # that, perhaps unlike in math class, the y-axis is the vertical axis. - #self.position = (0, 0, 0) - - # First element is rotation of the player in the x-z plane (ground - # plane) measured from the z-axis down. The second is the rotation - # angle from the ground plane up. Rotation is in degrees. - # - # The vertical plane rotation ranges from -90 (looking straight down) to - # 90 (looking straight up). The horizontal rotation range is unbounded. - #self.rotation = (0, 0) + # Instance of the player that interacts with the world. + self.player = player.Player(self.model, self) # Which sector the player is currently in. self.sector = None @@ -52,13 +25,7 @@ def __init__(self, *args, **kwargs): # The crosshairs at the center of the screen. self.reticle = None - # Velocity in the y (upward) direction. - self.dy = 0 - - # Convenience list of num keys. - self.num_keys = [ - key._1, key._2, key._3, key._4, key._5, - key._6, key._7, key._8, key._9, key._0] + # The label that is displayed in the top left of the canvas. self.label = pyglet.text.Label('', font_name='Arial', font_size=18, # noqa: F405 @@ -69,70 +36,6 @@ def __init__(self, *args, **kwargs): # TICKS_PER_SEC. This is the main game event loop. pyglet.clock.schedule_interval(self.update, 1.0 / model.TICKS_PER_SEC) # noqa: F405 - def set_exclusive_mouse(self, exclusive): - """ If `exclusive` is True, the game will capture the mouse, if False - the game will ignore the mouse. - - """ - super(Window, self).set_exclusive_mouse(exclusive) - self.exclusive = exclusive - - def get_sight_vector(self): - """ Returns the current line of sight vector indicating the direction - the player is looking. - - """ - x, y = self.player.rotation - # y ranges from -90 to 90, or -pi/2 to pi/2, so m ranges from 0 to 1 and - # is 1 when looking ahead parallel to the ground and 0 when looking - # straight up or down. - m = math.cos(math.radians(y)) - # dy ranges from -1 to 1 and is -1 when looking straight down and 1 when - # looking straight up. - dy = math.sin(math.radians(y)) - dx = math.cos(math.radians(x - 90)) * m - dz = math.sin(math.radians(x - 90)) * m - return (dx, dy, dz) - - def get_motion_vector(self): - """ Returns the current motion vector indicating the velocity of the - player. - - Returns - ------- - vector : tuple of len 3 - Tuple containing the velocity in x, y, and z respectively. - - """ - if any(self.strafe): - x, y = self.player.rotation - strafe = math.degrees(math.atan2(*self.strafe)) - y_angle = math.radians(y) - x_angle = math.radians(x + strafe) - if self.flying: - m = math.cos(y_angle) - dy = math.sin(y_angle) - if self.strafe[1]: - # Moving left or right. - dy = 0.0 - m = 1 - if self.strafe[0] > 0: - # Moving backwards. - dy *= -1 - # When you are flying up or down, you have less left and right - # motion. - dx = math.cos(x_angle) * m - dz = math.sin(x_angle) * m - else: - dy = 0.0 - dx = math.cos(x_angle) - dz = math.sin(x_angle) - else: - dy = 0.0 - dx = 0.0 - dz = 0.0 - return (dx, dy, dz) - def update(self, dt): """ This method is scheduled to be called repeatedly by the pyglet clock. @@ -153,110 +56,15 @@ def update(self, dt): m = 8 dt = min(dt, 0.2) for _ in model.xrange(m): - self.player.updatePosition(self, dt / m) - - def on_mouse_press(self, x, y, button, modifiers): - """ Called when a mouse button is pressed. See pyglet docs for button - amd modifier mappings. + self.player.update(dt / m) - Parameters - ---------- - x, y : int - The coordinates of the mouse click. Always center of the screen if - the mouse is captured. - button : int - Number representing mouse button that was clicked. 1 = left button, - 4 = right button. - modifiers : int - Number representing any modifying keys that were pressed when the - mouse button was clicked. - - """ - if self.exclusive: - vector = self.get_sight_vector() - selectedBlock, previous = self.player.hit_test(self.model.world, vector) - if (button == mouse.RIGHT) or \ - ((button == mouse.LEFT) and (modifiers & key.MOD_CTRL)): - # ON OSX, control + left click = right click. - if previous: - self.model.add_block(previous, self.player.inventory.block) - elif button == pyglet.window.mouse.LEFT and selectedBlock: # noqa: F405 - texture = self.model.world[selectedBlock] - if texture != model.block.STONE: - self.model.remove_block(selectedBlock) - else: - self.set_exclusive_mouse(True) - - def on_mouse_motion(self, x, y, dx, dy): - """ Called when the player moves the mouse. - - Parameters - ---------- - x, y : int - The coordinates of the mouse click. Always center of the screen if - the mouse is captured. - dx, dy : float - The movement of the mouse. - - """ - if self.exclusive: - m = 0.15 - x, y = self.player.rotation - x, y = x + dx * m, y + dy * m - y = max(-90, min(90, y)) - self.player.rotation = (x, y) - - def on_key_press(self, symbol, modifiers): - """ Called when the player presses a key. See pyglet docs for key - mappings. - - Parameters - ---------- - symbol : int - Number representing the key that was pressed. - modifiers : int - Number representing any modifying keys that were pressed. - - """ - if symbol == key.W: - self.player.strafe[0] -= 1 - elif symbol == key.S: - self.player.strafe[0] += 1 - elif symbol == key.A: - self.player.strafe[1] -= 1 - elif symbol == key.D: - self.player.strafe[1] += 1 - elif symbol == key.SPACE: - if self.dy == 0: - self.dy = self.player.JUMP_SPEED - elif symbol == key.ESCAPE: - self.set_exclusive_mouse(False) - elif symbol == key.TAB: - self.player.flying = not self.player.flying - elif symbol in self.num_keys: - index = (symbol - self.num_keys[0]) % len(self.player.inventory.hotbar) - self.player.inventory.block = self.player.inventory.hotbar[index] - - def on_key_release(self, symbol, modifiers): - """ Called when the player releases a key. See pyglet docs for key - mappings. - - Parameters - ---------- - symbol : int - Number representing the key that was pressed. - modifiers : int - Number representing any modifying keys that were pressed. + def set_exclusive_mouse(self, exclusive): + """ If `exclusive` is True, the game will capture the mouse, if False + the game will ignore the mouse. """ - if symbol == key.W: - self.player.strafe[0] += 1 - elif symbol == key.S: - self.player.strafe[0] -= 1 - elif symbol == key.A: - self.player.strafe[1] += 1 - elif symbol == key.D: - self.player.strafe[1] -= 1 + super(Window, self).set_exclusive_mouse(exclusive) + self.exclusive = exclusive def on_resize(self, width, height): """ Called when the window is resized to a new `width` and `height`. @@ -324,8 +132,8 @@ def draw_focused_block(self): crosshairs. """ - vector = self.get_sight_vector() - block = self.player.hit_test(self.model.world, vector)[0] + vector = self.player.get_sight_vector() + block = self.player.hit_test(vector)[0] if block: x, y, z = block vertex_data = model.cube_vertices(x, y, z, 0.51) From f102beb5de50516faf677689103875d728e32575 Mon Sep 17 00:00:00 2001 From: Kyle Wadas Date: Tue, 4 Mar 2025 19:07:44 -0700 Subject: [PATCH 08/46] Fixed Player Collision --- .gitignore | 1 + mmath.py | 10 +++++++++- model.py | 4 ++-- player.py | 8 +++++--- 4 files changed, 17 insertions(+), 6 deletions(-) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..0d20b648 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +*.pyc diff --git a/mmath.py b/mmath.py index dfc10d8a..277dac44 100644 --- a/mmath.py +++ b/mmath.py @@ -12,4 +12,12 @@ def normalize(position): """ x, y, z = position x, y, z = (int(round(x)), int(round(y)), int(round(z))) - return (x, y, z) \ No newline at end of file + return (x, y, z) + +def clamp(number, min, max): + if number < min: + return min + elif number > max: + return max + else: + return number \ No newline at end of file diff --git a/model.py b/model.py index 54d2339f..9b5653f0 100644 --- a/model.py +++ b/model.py @@ -306,7 +306,7 @@ def change_sectors(self, before, after): for sector in hide: self.hide_sector(sector) - def collide(self, window, position, height): + def collide(self, player, position, height): """ Checks to see if the player at the given `position` and `height` is colliding with any blocks in the world. @@ -348,7 +348,7 @@ def collide(self, window, position, height): if face == (0, -1, 0) or face == (0, 1, 0): # You are colliding with the ground or ceiling, so stop # falling / rising. - window.dy = 0 + player.dy = 0 break return tuple(p) diff --git a/player.py b/player.py index 74131184..5e95d629 100644 --- a/player.py +++ b/player.py @@ -19,6 +19,8 @@ def __init__(self, model, window, *args, **kwargs): self.WALKING_SPEED = 5 self.FLYING_SPEED = 15 + self.CurrentSpeed = 0 + self.GRAVITY = 20.0 self.MAX_JUMP_HEIGHT = 1.0 # About the height of a block. # To derive the formula for calculating jump speed, first solve @@ -123,7 +125,7 @@ def get_motion_vector(self): Tuple containing the velocity in x, y, and z respectively. """ - print(self.strafe) + #print(self.strafe) if any(self.strafe): x, y = self.rotation strafe = math.degrees(math.atan2(*self.strafe)) @@ -235,7 +237,7 @@ def update(self, dt): dy += self.dy * dt # collisions x, y, z = self.position - x, y, z = self.model.collide(self.window, (x + dx, y + dy, z + dz), self.PLAYER_HEIGHT) + x, y, z = self.model.collide(self, (x + dx, y + dy, z + dz), self.PLAYER_HEIGHT) self.position = (x, y, z) def on_key_press(self, symbol, modifiers): @@ -264,7 +266,7 @@ def on_key_press(self, symbol, modifiers): elif symbol == key.ESCAPE: self.window.set_exclusive_mouse(False) elif symbol == key.TAB: - self.player.flying = not self.player.flying + self.flying = not self.flying elif symbol in self.num_keys: index = (symbol - self.num_keys[0]) % len(self.inventory.hotbar) self.inventory.block = self.inventory.hotbar[index] From d11bdb7f08f182dcf9b7d7997e5554fc0e60160f Mon Sep 17 00:00:00 2001 From: Kyle Wadas Date: Thu, 6 Mar 2025 16:35:05 -0700 Subject: [PATCH 09/46] Added Player Velocity Variable --- main.py | 23 +++++++++++------------ model.py | 6 +++--- player.py | 18 ++++++++---------- 3 files changed, 22 insertions(+), 25 deletions(-) diff --git a/main.py b/main.py index 407c414c..303ebf87 100644 --- a/main.py +++ b/main.py @@ -3,7 +3,6 @@ # from pyglet.gl import * # noqa: F403 # from pyglet.graphics import TextureGroup import window -from pyglet import image from pyglet.gl import * # noqa: F403 def setup_fog(): @@ -12,34 +11,34 @@ def setup_fog(): """ # Enable fog. Fog "blends a fog color with each rasterized pixel fragment's # post-texturing color." - glEnable(GL_FOG) + glEnable(GL_FOG) # noqa: F405 # Set the fog color. - glFogfv(GL_FOG_COLOR, (GLfloat * 4)(0.5, 0.69, 1.0, 1)) + glFogfv(GL_FOG_COLOR, (GLfloat * 4)(0.5, 0.69, 1.0, 1)) # noqa: F405 # Say we have no preference between rendering speed and quality. - glHint(GL_FOG_HINT, GL_DONT_CARE) + glHint(GL_FOG_HINT, GL_DONT_CARE) # noqa: F405 # Specify the equation used to compute the blending factor. - glFogi(GL_FOG_MODE, GL_LINEAR) + glFogi(GL_FOG_MODE, GL_LINEAR) # noqa: F405 # How close and far away fog starts and ends. The closer the start and end, # the denser the fog in the fog range. - glFogf(GL_FOG_START, 20.0) - glFogf(GL_FOG_END, 60.0) + glFogf(GL_FOG_START, 20.0) # noqa: F405 + glFogf(GL_FOG_END, 60.0) # noqa: F405 def setup(): """ Basic OpenGL configuration. w """ # Set the color of "clear", i.e. the sky, in rgba. - glClearColor(0.5, 0.69, 1.0, 1) + glClearColor(0.5, 0.69, 1.0, 1) # noqa: F405 # Enable culling (not rendering) of back-facing facets -- facets that aren't # visible to you. - glEnable(GL_CULL_FACE) + glEnable(GL_CULL_FACE) # noqa: F405 # Set the texture minification/magnification function to GL_NEAREST (nearest # in Manhattan distance) to the specified texture coordinates. GL_NEAREST # "is generally faster than GL_LINEAR, but it can produce textured images # with sharper edges because the transition between texture elements is not # as smooth." - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST) - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST) + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST) # noqa: F405 + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST) # noqa: F405 setup_fog() def main(): @@ -47,7 +46,7 @@ def main(): # Hide the mouse cursor and prevent the mouse from leaving the window. userWindow.set_exclusive_mouse(True) setup() - pyglet.app.run() + pyglet.app.run() # noqa: F405 if __name__ == '__main__': main() \ No newline at end of file diff --git a/model.py b/model.py index 9b5653f0..0721bdb3 100644 --- a/model.py +++ b/model.py @@ -306,7 +306,7 @@ def change_sectors(self, before, after): for sector in hide: self.hide_sector(sector) - def collide(self, player, position, height): + def collide(self, player, position): """ Checks to see if the player at the given `position` and `height` is colliding with any blocks in the world. @@ -338,7 +338,7 @@ def collide(self, player, position, height): d = (p[i] - np[i]) * face[i] if d < pad: continue - for dy in xrange(height): # check each height + for dy in xrange(player.PLAYER_HEIGHT): # check each height op = list(np) op[1] -= dy op[i] += face[i] @@ -348,7 +348,7 @@ def collide(self, player, position, height): if face == (0, -1, 0) or face == (0, 1, 0): # You are colliding with the ground or ceiling, so stop # falling / rising. - player.dy = 0 + player.velocity[1] = 0 break return tuple(p) diff --git a/player.py b/player.py index 5e95d629..ddad02ae 100644 --- a/player.py +++ b/player.py @@ -63,8 +63,8 @@ def __init__(self, model, window, *args, **kwargs): # Whether or not the window exclusively captures the mouse. self.exclusive = True - # Velocity in the y (upward) direction. - self.dy = 0 + # Velocity + self.velocity = [0, 0, 0] # Convenience list of num keys. self.num_keys = [ @@ -219,8 +219,6 @@ def update(self, dt): The change in time since the last call. """ - - # walking speed = self.FLYING_SPEED if self.flying else self.WALKING_SPEED d = dt * speed # distance covered this tick. @@ -232,12 +230,12 @@ def update(self, dt): # Update your vertical speed: if you are falling, speed up until you # hit terminal velocity; if you are jumping, slow down until you # start falling. - self.dy -= dt * self.GRAVITY - self.dy = max(self.dy, -self.TERMINAL_VELOCITY) - dy += self.dy * dt + self.velocity[1] -= dt * self.GRAVITY + self.velocity[1] = max(self.velocity[1], -self.TERMINAL_VELOCITY) + dy += self.velocity[1] * dt # collisions x, y, z = self.position - x, y, z = self.model.collide(self, (x + dx, y + dy, z + dz), self.PLAYER_HEIGHT) + x, y, z = self.model.collide(self, (x + dx, y + dy, z + dz)) self.position = (x, y, z) def on_key_press(self, symbol, modifiers): @@ -261,8 +259,8 @@ def on_key_press(self, symbol, modifiers): elif symbol == key.D: self.strafe[1] += 1 elif symbol == key.SPACE: - if self.dy == 0: - self.dy = self.JUMP_SPEED + if self.velocity[1] == 0: + self.velocity[1] = self.JUMP_SPEED elif symbol == key.ESCAPE: self.window.set_exclusive_mouse(False) elif symbol == key.TAB: From 11910738438739c49e050ddd1099fb0135efca82 Mon Sep 17 00:00:00 2001 From: Elijah Kelting Date: Thu, 6 Mar 2025 16:57:02 -0700 Subject: [PATCH 10/46] start of statemachine --- states.py | 34 ++++++++++++++++++++++++++++++++++ window.py | 3 ++- 2 files changed, 36 insertions(+), 1 deletion(-) create mode 100644 states.py diff --git a/states.py b/states.py new file mode 100644 index 00000000..badfd215 --- /dev/null +++ b/states.py @@ -0,0 +1,34 @@ +# states.py +from enum import Enum, auto + +class GameState(Enum): + MAIN_MENU = auto() + PLAYING = auto() + PAUSED = auto() + INVENTORY = auto() + GAME_OVER = auto() + +class StateMachine: + def __init__(self, initial_state): + self.state = initial_state + self.states = {} + + def add_state(self, state, enter_callback=None, update_callback=None, exit_callback=None): + self.states[state] = { + 'enter': enter_callback, + 'update': update_callback, + 'exit': exit_callback + } + + def change_state(self, new_state): + if self.state in self.states and self.states[self.state]['exit']: + self.states[self.state]['exit']() + + self.state = new_state + + if self.state in self.states and self.states[self.state]['enter']: + self.states[self.state]['enter']() + + def update(self, dt): + if self.state in self.states and self.states[self.state]['update']: + self.states[self.state]['update'](dt) \ No newline at end of file diff --git a/window.py b/window.py index 3dd1172c..47e41ce3 100644 --- a/window.py +++ b/window.py @@ -13,6 +13,8 @@ class Window(pyglet.window.Window): def __init__(self, *args, **kwargs): super(Window, self).__init__(*args, **kwargs) + # Instance of the StateMachine + # Instance of the model that handles the world. self.model = model.Model() @@ -61,7 +63,6 @@ def update(self, dt): def set_exclusive_mouse(self, exclusive): """ If `exclusive` is True, the game will capture the mouse, if False the game will ignore the mouse. - """ super(Window, self).set_exclusive_mouse(exclusive) self.exclusive = exclusive From 74c9cc87fe6dbefd3cdc898caa35cefd52dcc16a Mon Sep 17 00:00:00 2001 From: Elijah Kelting Date: Thu, 6 Mar 2025 17:03:43 -0700 Subject: [PATCH 11/46] Create .gitignore --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..1cf77f78 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +# Virtual Environment +.venv \ No newline at end of file From 1cacbca250009d10985c1a97325f6c4456203fbe Mon Sep 17 00:00:00 2001 From: Elijah Kelting Date: Thu, 6 Mar 2025 17:54:13 -0700 Subject: [PATCH 12/46] added states to proper files. --- .gitignore | 3 ++- main.py | 2 +- player.py | 14 +++++++++---- states.py | 1 - window.py | 58 ++++++++++++++++++++++++++++++++++++++++++++++++------ 5 files changed, 65 insertions(+), 13 deletions(-) diff --git a/.gitignore b/.gitignore index 1cf77f78..d64d1d3d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ # Virtual Environment -.venv \ No newline at end of file +.venv +__pycache__/ \ No newline at end of file diff --git a/main.py b/main.py index 407c414c..20fd82e9 100644 --- a/main.py +++ b/main.py @@ -26,7 +26,7 @@ def setup_fog(): def setup(): """ Basic OpenGL configuration. -w + """ # Set the color of "clear", i.e. the sky, in rgba. glClearColor(0.5, 0.69, 1.0, 1) diff --git a/player.py b/player.py index 74131184..2d6ce161 100644 --- a/player.py +++ b/player.py @@ -5,6 +5,7 @@ import math import inventory import block +from states import GameState, StateMachine from pyglet.gl import * # noqa: F403 from pyglet.window import key, mouse @@ -15,7 +16,7 @@ class Player(): - def __init__(self, model, window, *args, **kwargs): + def __init__(self, model, window, stateMachine, *args, **kwargs): self.WALKING_SPEED = 5 self.FLYING_SPEED = 15 @@ -217,8 +218,6 @@ def update(self, dt): The change in time since the last call. """ - - # walking speed = self.FLYING_SPEED if self.flying else self.WALKING_SPEED d = dt * speed # distance covered this tick. @@ -268,7 +267,14 @@ def on_key_press(self, symbol, modifiers): elif symbol in self.num_keys: index = (symbol - self.num_keys[0]) % len(self.inventory.hotbar) self.inventory.block = self.inventory.hotbar[index] - + + if self.state_machine.state == GameState.PLAYING: + if symbol == pyglet.window.key.ESCAPE: + self.state_machine.change_state(GameState.PAUSED) + elif self.state_machine.state == GameState.PAUSED: + if symbol == pyglet.window.key.ESCAPE: + self.state_machine.change_state(GameState.PLAYING) + def on_key_release(self, symbol, modifiers): """ Called when the player releases a key. See pyglet docs for key mappings. diff --git a/states.py b/states.py index badfd215..291e8ae3 100644 --- a/states.py +++ b/states.py @@ -1,4 +1,3 @@ -# states.py from enum import Enum, auto class GameState(Enum): diff --git a/window.py b/window.py index 47e41ce3..82c74623 100644 --- a/window.py +++ b/window.py @@ -3,6 +3,7 @@ import math import model import player +from states import GameState, StateMachine #from collections import deque from pyglet.gl import * # noqa: F403 @@ -13,13 +14,30 @@ class Window(pyglet.window.Window): def __init__(self, *args, **kwargs): super(Window, self).__init__(*args, **kwargs) - # Instance of the StateMachine - + # Initialize the state machine + self.state_machine = StateMachine(GameState.MAIN_MENU) + + # Add states with their respective callbacks + self.state_machine.add_state( + GameState.MAIN_MENU, + enter_callback=self.enter_main_menu, + update_callback=self.update_main_menu + ) + self.state_machine.add_state( + GameState.PLAYING, + enter_callback=self.enter_playing, + update_callback=self.update_playing + ) + self.state_machine.add_state( + GameState.PAUSED, + enter_callback=self.enter_paused, + update_callback=self.update_paused + ) # Instance of the model that handles the world. self.model = model.Model() # Instance of the player that interacts with the world. - self.player = player.Player(self.model, self) + self.player = player.Player(self.model, self, self.state_machine) # Which sector the player is currently in. self.sector = None @@ -27,8 +45,6 @@ def __init__(self, *args, **kwargs): # The crosshairs at the center of the screen. self.reticle = None - - # The label that is displayed in the top left of the canvas. self.label = pyglet.text.Label('', font_name='Arial', font_size=18, # noqa: F405 x=10, y=self.height - 10, anchor_x='left', anchor_y='top', @@ -48,6 +64,8 @@ def update(self, dt): The change in time since the last call. """ + self.state_machine.update(dt) # Update the current state + # Existing game logic self.model.process_queue() sector = model.sectorize(self.player.position) if sector != self.sector: @@ -158,4 +176,32 @@ def draw_reticle(self): """ glColor3d(0, 0, 0) - self.reticle.draw(GL_LINES) \ No newline at end of file + self.reticle.draw(GL_LINES) + + def enter_main_menu(self): + print("Entering Main Menu") + # Add logic to display the main menu (e.g., render buttons, text) + + + def update_main_menu(self, dt): + # Handle input for the main menu (e.g., start game, quit) + #if some_condition_to_start_game: + self.state_machine.change_state(GameState.PLAYING) + + def enter_playing(self): + print("Entering Playing State") + # Add logic to initialize the game world, player, etc. + + def update_playing(self, dt): + # Handle game logic (e.g., player movement, block placement) + #if some_condition_to_pause_game: + self.state_machine.change_state(GameState.PAUSED) + + def enter_paused(self): + print("Entering Paused State") + # Add logic to display the pause menu + + def update_paused(self, dt): + # Handle input for the pause menu (e.g., resume, quit) + #if some_condition_to_resume_game: + self.state_machine.change_state(GameState.PLAYING) \ No newline at end of file From 73b7decb5d248c25a82920bd8674dfa57470222e Mon Sep 17 00:00:00 2001 From: Elijah Kelting Date: Thu, 6 Mar 2025 19:04:55 -0700 Subject: [PATCH 13/46] states setup. Can switch back and forth. --- .gitignore | 2 +- player.py | 20 ++++++++++---------- window.py | 13 +++++++------ 3 files changed, 18 insertions(+), 17 deletions(-) diff --git a/.gitignore b/.gitignore index fffb6a2c..4c1c36b5 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,4 @@ # Virtual Environment .venv -__pycache__/ +/pycache/ *.pyc \ No newline at end of file diff --git a/player.py b/player.py index 00e4bd8f..75feac18 100644 --- a/player.py +++ b/player.py @@ -5,7 +5,7 @@ import math import inventory import block -from states import GameState, StateMachine +from states import GameState from pyglet.gl import * # noqa: F403 from pyglet.window import key, mouse @@ -13,10 +13,8 @@ if sys.version_info[0] >= 3: xrange = range - - class Player(): - def __init__(self, model, window, stateMachine, *args, **kwargs): + def __init__(self, model, window, statemachine, *args, **kwargs): self.WALKING_SPEED = 5 self.FLYING_SPEED = 15 @@ -40,6 +38,7 @@ def __init__(self, model, window, stateMachine, *args, **kwargs): self.model = model self.window = window self.window.push_handlers(self) + self.state_machine = statemachine # When flying gravity has no effect and speed is increased. self.flying = False @@ -262,20 +261,22 @@ def on_key_press(self, symbol, modifiers): elif symbol == key.SPACE: if self.velocity[1] == 0: self.velocity[1] = self.JUMP_SPEED - elif symbol == key.ESCAPE: - self.window.set_exclusive_mouse(False) elif symbol == key.TAB: self.flying = not self.flying elif symbol in self.num_keys: index = (symbol - self.num_keys[0]) % len(self.inventory.hotbar) self.inventory.block = self.inventory.hotbar[index] - + if self.state_machine.state == GameState.PLAYING: - if symbol == pyglet.window.key.ESCAPE: + if symbol == key.ESCAPE: + self.window.set_exclusive_mouse(False) self.state_machine.change_state(GameState.PAUSED) + return pyglet.event.EVENT_HANDLED elif self.state_machine.state == GameState.PAUSED: - if symbol == pyglet.window.key.ESCAPE: + if symbol == key.ESCAPE: + self.window.set_exclusive_mouse(True) self.state_machine.change_state(GameState.PLAYING) + return pyglet.event.EVENT_HANDLED def on_key_release(self, symbol, modifiers): """ Called when the player releases a key. See pyglet docs for key @@ -287,7 +288,6 @@ def on_key_release(self, symbol, modifiers): Number representing the key that was pressed. modifiers : int Number representing any modifying keys that were pressed. - """ if symbol == key.W: self.strafe[0] += 1 diff --git a/window.py b/window.py index 82c74623..527b16e6 100644 --- a/window.py +++ b/window.py @@ -15,7 +15,7 @@ def __init__(self, *args, **kwargs): super(Window, self).__init__(*args, **kwargs) # Initialize the state machine - self.state_machine = StateMachine(GameState.MAIN_MENU) + self.state_machine = StateMachine(GameState.PLAYING) # Add states with their respective callbacks self.state_machine.add_state( @@ -185,8 +185,7 @@ def enter_main_menu(self): def update_main_menu(self, dt): # Handle input for the main menu (e.g., start game, quit) - #if some_condition_to_start_game: - self.state_machine.change_state(GameState.PLAYING) + pass def enter_playing(self): print("Entering Playing State") @@ -195,13 +194,15 @@ def enter_playing(self): def update_playing(self, dt): # Handle game logic (e.g., player movement, block placement) #if some_condition_to_pause_game: - self.state_machine.change_state(GameState.PAUSED) - + pass + def enter_paused(self): print("Entering Paused State") # Add logic to display the pause menu + pass def update_paused(self, dt): # Handle input for the pause menu (e.g., resume, quit) #if some_condition_to_resume_game: - self.state_machine.change_state(GameState.PLAYING) \ No newline at end of file + pass + \ No newline at end of file From f9e374bae7977776f710d26ea1d426790ea3c049 Mon Sep 17 00:00:00 2001 From: StephenieDugan Date: Thu, 6 Mar 2025 20:31:55 -0700 Subject: [PATCH 14/46] Lamp and Portal blocks added --- Textures.png | Bin 0 -> 11620 bytes __pycache__/block.cpython-312.pyc | Bin 1223 -> 1358 bytes __pycache__/inventory.cpython-312.pyc | Bin 733 -> 851 bytes __pycache__/mmath.cpython-312.pyc | Bin 700 -> 903 bytes __pycache__/model.cpython-312.pyc | Bin 16948 -> 16867 bytes __pycache__/player.cpython-312.pyc | Bin 11994 -> 11904 bytes __pycache__/window.cpython-312.pyc | Bin 8474 -> 8498 bytes block.py | 4 +++- inventory.py | 4 ++-- model.py | 2 +- 10 files changed, 6 insertions(+), 4 deletions(-) create mode 100644 Textures.png diff --git a/Textures.png b/Textures.png new file mode 100644 index 0000000000000000000000000000000000000000..0cfd165ab2997491ba7609af116dd6b643b2114f GIT binary patch literal 11620 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 F{67i{JfZ*q literal 0 HcmV?d00001 diff --git a/__pycache__/block.cpython-312.pyc b/__pycache__/block.cpython-312.pyc index 0c1765ea8bef829f685e991825b777dab1e9f0fe..c8359db074266e18bc1d4ba40734af5227c49e8c 100644 GIT binary patch delta 260 zcmX@kd5(+kG%qg~0}y;nKb7vyJdsa=V;+zge9DM_Bu?6@Cg*f^Yv4E8Ef(ULP@r%PIH$SB`C)KV<0mx+p;^N}T87vW# YJ6HsTIE5#;&2U@bc9~PVkqxW~0F(bf?f?J) delta 116 zcmX@db)1v$G%qg~0}z}(us{7X(?mWAjxr!`IztNAM7;u*N={AgiKnhf=_FglIOnHi z=B393RF-7q=P3jfJ(iBa9$H`yvCv^ce> zI3~CxwICxkFEcg9B|o_|H#M)MI3^?`vnVApHL)lr&?v^WBD1(8GcVmaKP7eYVMZ%P zhspmK<%G_No|ic(b0s|HdU)c+@WcyZNt5N79C(F+mab$d5&=?0LX&ftlg}}#N*N?u#W?4uWag#E1XPw}D-xS*z%0)Kk^unb C&N$`( diff --git a/__pycache__/mmath.cpython-312.pyc b/__pycache__/mmath.cpython-312.pyc index 71761680067e8f3d466e94dce8fa86516a7d936a..4230997d2e27f7582e0208f89436ff0b09fa1dec 100644 GIT binary patch delta 338 zcmdnP+Rn~*nwOW00SK%%9Zwfyn#d<1CIIA3XGmdaVTfW#VFZ$ll}wt<8_fL&#<=7sm*%GCl@!N>WMmelM5ZPd#RM9~xK?Bqmt^LpJLjjQ zP8MJ)tWRbJSpx-3KpMpVtOO*cGt@BDFlGbAikNB`gF!r|Y!@((3B(I#&}8&m$)L%6 zi!HA-Hz~E~7ISW99*{_^CKfRH+iN)MA*(xTqIJKxaCb%TEAR{#|Gd0E~Ke;qF zHLs*NCL|-XC?zsAu_z|cD8{uSv$!NPFWosmC3W*k7A6)>o{-dvlG38o;?0{mWVsmy zCSMd*6~88^+TnOdRC-3>45tN*3mg}+E-1VvsySIwB#CKW?&M|>6?q1EosYZ>Vp<=V z8HCh6h%xZ;OtMViC_aOEy7c4+A|jI?iDXD$6IGqSct=tmX3Pr1g{3PB7gk=A zG@M)@D$0CK)^u{8Xo@U@oEgw4DWea341z)v0w=OfWc(z^Ag1axv!GZEqnI1e z*9{CGxEO?`JJ~xJI}AG#?@P%~?hw~uW{_6cyj^@Pr&tq24Ii4Cdc|C@n)iy?+>9=h zdG#fjuSu9puGZCLW{@^VFB(>R3zl51lV)9`lb*XDY>K#tE z#Uv*%-H}pQpu9k2LGg;fh2__z^e2lMw+Ayw8+>GD5SIdaLs$bCA_9^#tS<7acCg&w zmz?1VX5AK(>TtWkBXFHZ<|2>GjIgUbDnQlZ(vLC4K}Jb${%b7A!d8%zSeaThS;Qil z@x$Z_3uT`BB9a|0py+X&7CCvNg(=fKy~%GaN_iNhH9zt*h{*%Z6y2O>xrBpJZnChG FA^_Rtv#tOD delta 702 zcmZ`%&2JJx9Gzho*aa3?V4*BvK}twNKSCAzk!YYQN#g|$H8H7)O0m|YkhU~v;sHOB zE(ascTuAC+n|PqNn)T+%n0U|=-55D=(D(;*8TG6)<)n#odG9yx_kJ^ZGvA-WH_xE( zNf2y+tVHbH+Q-+z6IPxmEv#IwuC7VXJz-T&itrA6OI1*=ywowVkc9 z*5x90coCg=6LDQkV8HRqP|5YBP`lV(RH2$XFsqxoG>(B)ScWL&yTk2oU;rgjyzq@B zDH#YMM+BP!88UIF%Mh0ek88u zI`H6XC*9dR%p9c;=k-Vi1GAKe=&`gqN{PYHX2S_YPpi0R*@IXlqXr@!ewYer5q}Pb zu8|NLz_0;tsA*N8l2&f_GXN6E1>=1-PXxFKH~X=qTmW-UpuZq1~a;`LB`Z z$I;!`hK=CR!<>2sv4R~gp_8c*P9Hf>=cm!l$#I6D)|@Ouc`?VqoL5P+9ExgBb8a7Pd@%IjY80pSs;C9@KStn&c&BA^JA6dyA3*L)#37`bg65 zV0)qKN+@j46>KjJnO`Qa!zYw{&*A>!2zMRf_Vv$>F@qtSU;iTxsHnX?C$g6MdS$g* zN5``z_#0iAi~IXNayc(AD_7{J$e|k;cmx@h=Q7s)DGcnQj9$*|I0z10L@*dHuSMox fac3h92WG9jrD4V%CzO6h7tJuNi-_}30Tem{Dw(Gh-u4VtN%uF}wM#n#$m<=bPI7{Dibd+}7_lDaX ze>6cylxRE&3?o6lL5LA-V(^0rd@|8UBobZT7x};kiF`n2{D5CP=XLFXaFhP-`JHp_ zz2}{K&aJlR*dE7E4u@61(fiF06MtTD>}2c?q*$LzGR+I)MzYXQZSbzsXOPVEaNbf4 z_nDE+Lq#=7&Mr&AM-U_nt|==qGqUm`Q>%;8qz5`hf1`dX>E;>w*^AbB5t(C!!Bo>) zancV-mmAKC_FZLYa~3_Na%8R&Gf0LBT3b=lSdmqhm<^e`#05C{5631dD7|2-}D6 znvmY5L~s#?j9oBqT*K<&BV)i}ADre~&Z;9*vMj*` zQRS(9ayBg|Hsw;&2XKLs7~PlV(k?m46R&kA;xlPQO=l+tbCL{yn4;cFCJ4ubC4XSS zc&n^t$*0fW+dhB3(cEZcb+FYMaMD?t>75+UNMQ%>fJ4>@Yk>3CR@MzStO4^jv@7S~ zf%Q4VZxvzaut`>-GIHN8xN3Mbf7a#^U#+Kb>1H%TDyL``o|MwbtfCo|bT(|^9b~2~ z@s|kt2pR}t1Oo^Pm1D3lcsGb^+L;VpYfgots88Wnlm=zdfWPHaq9B|WR0f|o1NKWR zE}t?UhMNr@YXYr@*uC=Kdu&g0=hia zu+`;2k2cpcaK!a`*<+@^U2fgvhfu}3$4z4ug;oCi`xOoBs8us0v$H&i0rS-)StNOa z%d(=Gl4>&B&9{;{K(K{?5+1fbnYAElHOuUHGCPrxHOovvcxp1O=&I+^q9Z1>+ui9p zgj&Upi8?0y;}Pu6{1LaAv1tBy)mKJa2#tI@K^*$LO%c5)%9D~bzBiLg?dM)JX(nCP z%u}-%g35j5-U}alJ4YVBVa>dET2*sdt^7bvO23`P;^i;U1`b8e$SGBp2J}q_NoP^z z8FiY=3cWgdyaX7tvnIm6gx;EaX1xeZaNl2*-&lK#ZP|>T!(k)WgQm1Rhth6K4);F&d)sgdv(L?sJ(DE z^lEXve@9DO(o4lFB`}|3~dvc8xA&k zJaz#eu;Pm@%o^#vpY*|*rdsBM_Zq7rR1k9*q)Okc4|E8wh>uK@A*gfKfTOv*`sr5s zo9J&Ydzy8;GQYcdGaGva_Zu1xyE!$##>Vu1(%6W`VjA0|nMQWR2IGZ0_K=4;J~9~F z5ibr+6NkYh*LN5V+4hjC_OBD5&LmEBlq(UVWEA{Icj9V2Lhq)^gqZk ByhQ*2 delta 2226 zcmZuyZ){Ul6o0pUeO=pi?daBZUDtK6e;r$;8`}T}uKNQBb4-SqxUtdoJxjZ;9rrzi zPRJkuQ#1zjCI%8?!WRwxNg$08{Q~=7LNqZTD){u1-!N(vOiYL$Jm&guFPb=xeM7wc z9}!&4amTqCL680KIA8l^Ko&c<)m~_<` z%gCykM#V%lEvrU3kq(+^2;Ex|wjuN*tVI|=hych)G3`Eq01dNk6(JI1^A+#Zb%Q;& z!b=c24lizm-@_Zs@95+Srp=o|;CUm-qr*|DyyKuvbA zshZt)*dI5zoYkz$?c(Vf*phIz+6ASsfdhIIr;ANFt?ayWKSWMA>lt6U#a_obm4!qYvrJ~R?-U-WO%DCT_7`h>SN;vse+472{)=5~!XmZ&Js%%(E2IqCtIYSLs?SjfV06pgcV zGkc?U!^Gp|SB2RlijqmImU&?9%L$3f6njIp%TfwxD~W?z&_T4B73r9Agi11Ix_ALN ze}%W5yvH_se}gl&)csC&ZifY9L7r-74d7nmeDoLqFi?0hbpznn8Hikz@wL-~L*&W& z4sxC4>Z3l5dj{|o29i|cp5MSCb#?iG{~|FY-5NQ*Xz&pa3p-r-UmKn#OLo0{_+(Lh z$>=@=jr90%Q3=6~;78ChYK~=6se~x$xvK&DO3_t=sHi4+L6St3h&pf+felX{TC3Fad?ZgP&zDpWt7<{r7wXQ7>ION1vxuEn@Lf2 zr?na$)BCM0=D)x$_YjuoSY+qh_IjFwSc$vMeYczYZZ-DhhR^LjyZifcKl`I?AFz5T z_^Dw4Pd^6y#lzDK0(L!JKsby*0fI)I-&r&q1dy>NzyM(LrjB;vWU-FdELgm;AfY|% zK}UN}7ie@CLF;RcoiSA72=fT9BAfuY%xRT}XwP?gO&d)cAEwws=X%o3-tBC(_2DuX uf`{Gg9BjgGB*k{6rx5UOX&B&9SwA%Vk(9KJ=2$2+%)E=euONX^Skjd96OF3nBND=Cf% z$;d29iA+r_iU~A|ajnQKF3HSGcg{~q-R#d2%fh&F@>-5wrfKq%9XX|#8H5x!$8qiv F2LO<%Aus>{ delta 99 zcmdnwG|P$WG%qg~0}zPFZ{*Tuk Date: Thu, 6 Mar 2025 21:47:36 -0700 Subject: [PATCH 15/46] some minor changes --- __pycache__/model.cpython-312.pyc | Bin 16867 -> 16928 bytes __pycache__/player.cpython-312.pyc | Bin 11904 -> 11976 bytes player.py | 3 +-- texture.png | Bin 5257 -> 11620 bytes 4 files changed, 1 insertion(+), 2 deletions(-) diff --git a/__pycache__/model.cpython-312.pyc b/__pycache__/model.cpython-312.pyc index 27f29a804b6be14544b300024b1b70b999114c12..dc262de21939441e3b8210e8f11a6be3b9ceebbd 100644 GIT binary patch delta 668 zcmaFd%($S1k@qw&FBbz4yw5n5erqG|7URi=`l4J97#SF*Go&!qGEaVBEXu`F!VFRa z1d|&y#3tM7aMstdmasvD7#Lg_Vs|ny)UuUu!bDP-Rs&4{0ifJUpd5P*TMfG;kYCK$ z!&$=uVb`!i=qjKKVDeS0K-C;I95u|@ObiS~j6DhnQ)?Krz-|Q^Qx7s53XrTS0&3db!d$^r!31(d4QG`&14A-%GLsF6$5q1)mw`I7iWebY0%Su#4HwKj zmKugEzR8U8;`PoT-@vs4-Hq-W6sy=$Sh6*Mp}<gnzga*MU3v>+$7NE0N*QI?vMpPX4zsmWbr01{v;$VseBEh>@$awgw5S7G4>F*q!A z8UIZ-vq<5*u4sBu(e#>>+2lDES)zLSGuY Ia;jq;05D30OaK4? delta 575 zcmYjMJ4+)`6h3D%k4z@xHfF^KuEi<_ToHm8@r@Q+Sh%%_NM?v87BY@v!p-i2mV?bf zq9`IZB57Q*<=TsOTdiUt_y<;OEIl_b{otP0cOKt8*}=zcv~O%X0*u_ub^7L){X6kV zm1zwo`w+k9KL}6+2Ma1aBw`WGmsJV++53^k`ph2%-PfxnfEidg11K22oUg!9O1wdW zxgv96VTf=m=j#}lLaW9?ulhVos`Gh`yG>yVHLC!47<9dD6`{sf7Zx(y81ZXoc!6Fg z3zo2)(3Y~L$b%x1ZvjY!Qp%{zED>%nHA#8S z)7)Te#BkJXFaJ#whNH>IGaOyuqETOl5ENAi4)~p`@a~9Kz8H)u7^cgiwm!|@SX*_y zI8S+B*~FvX0J}SVZFMQ_%RYTbe%7K~=%S(I7yM6d(ov54>2EUA)ZMeM zADOq!txqk`9xs0zzCzqBw~hQ$kjl?vX+)y=iThZ<D2dEtI>5` diff --git a/__pycache__/player.cpython-312.pyc b/__pycache__/player.cpython-312.pyc index 322b569e8472f77fbeb0f3883471c256b62d91c3..45149d8df8945c79f0cd1514b09d575d11d37416 100644 GIT binary patch delta 844 zcmY+?NlX(_7y#gTZ`!hTY$;IEmeLhVm4an6k(S+}(vl!TOjsK1R0N9P6f|Wq7!Q`j z#NvOTF=~nzOt?Ts!_9EhXiS(w0wG>WOpFQXk(2M0lXLho?|=VW{(ok9_}eh|gX8iU z@;sUPKDM{b^&|9K454>OF~;zDACQRId7PX3I2@S{jn9ft<*!j*M#1Q;aoI~w)a86- zWyhG0i6{A9wxFHtBeYREMAwBanfexeFQ?q3bi-eb`@bw_5vNf2>6{Ndy3eQ+GP-Vb z0?qm+-ACW2@Xo~cM7pYVH+IlBaM%}=`hw}MpqS7<$LIzW8{McKe8x7k3vuHDF2>Mi zFo3x{i6<68T~Y$?o%tY@TV!kqd*H0xrr?o|90ozVR#w1lVnC*{JRW&SY*C(F!jcRa zG0kBz`NvejVkavWnbn9FdPq`_v*5fOHNCQm(oeBbG?e?4Qi_RUAROm}rX!JYKJ3gF zYUmjAv&Zu2OgPLRlYO)O%66^;URb=`K1qqPh+&qQQ!PlAp@G0kAZgiGmZfm&&c@LC zkYsjCN;e7oGFemg8{T#AR-t68+u{!!{ZgZUufe}>3dB2KW!Fi{vLoe%gniAm>PjI= zV@=(bG!9AWfJtiuyRYelP3skWmxU2$K)htDN61CmQ_5l5C>~8#k}C92qt$}Zq-A;R z5#QQ(G3tR~hX)1WjiaJukYqY#=d~%Kv8j905n&V#98Ec=w3bE$<5lyJs8rjRR+f^z zlFF2Fr&abNn`5J8y(J-A<5s!kXj*MPWf^saxKr82)}41-A;`%N!VJYsc|;K?QG%1r z9xB9WU=%J_T}3JgReiDhXdwGrWj_y3hYu(ZDGQV(xbE_(jq=(|D=L)RG8YYUYvvlP qx|+}+{B(8cpV6#(N-g0m*E2QE&qcz`LL92AJ5;?gWX>?uY|=mG(c!TG delta 728 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 tZXY)`ICb#Xax+y7?`HqVj7PH^u;uCX Date: Thu, 6 Mar 2025 22:11:41 -0700 Subject: [PATCH 16/46] Added Running & More Flight Movement --- player.py | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/player.py b/player.py index ddad02ae..5dc0428a 100644 --- a/player.py +++ b/player.py @@ -70,6 +70,9 @@ def __init__(self, model, window, *args, **kwargs): self.num_keys = [ key._1, key._2, key._3, key._4, key._5, key._6, key._7, key._8, key._9, key._0] + + # Running + self.running = False def hit_test(self, vector, max_distance=8): """ Line of sight search from current position. If a block is @@ -217,11 +220,10 @@ def update(self, dt): ---------- dt : float The change in time since the last call. - """ # walking speed = self.FLYING_SPEED if self.flying else self.WALKING_SPEED - d = dt * speed # distance covered this tick. + d = dt * speed * 2 if self.running else dt * speed # distance covered this tick. dx, dy, dz = self.get_motion_vector() # New position in space, before accounting for gravity. dx, dy, dz = dx * d, dy * d, dz * d @@ -233,6 +235,8 @@ def update(self, dt): self.velocity[1] -= dt * self.GRAVITY self.velocity[1] = max(self.velocity[1], -self.TERMINAL_VELOCITY) dy += self.velocity[1] * dt + else: + dy += self.velocity[1] * dt # collisions x, y, z = self.position x, y, z = self.model.collide(self, (x + dx, y + dy, z + dz)) @@ -261,6 +265,11 @@ def on_key_press(self, symbol, modifiers): elif symbol == key.SPACE: if self.velocity[1] == 0: self.velocity[1] = self.JUMP_SPEED + elif symbol == key.LSHIFT: + if self.flying: + self.velocity[1] = -self.JUMP_SPEED + elif symbol == key.LCTRL: + self.running = True elif symbol == key.ESCAPE: self.window.set_exclusive_mouse(False) elif symbol == key.TAB: @@ -288,4 +297,12 @@ def on_key_release(self, symbol, modifiers): elif symbol == key.A: self.strafe[1] += 1 elif symbol == key.D: - self.strafe[1] -= 1 \ No newline at end of file + self.strafe[1] -= 1 + elif symbol == key.LCTRL: + self.running = False + elif symbol == key.SPACE: + if self.flying: + self.velocity[1] = 0 + elif symbol == key.LSHIFT: + if self.flying: + self.velocity[1] = 0 \ No newline at end of file From 829a9edd26d12c8f90667005597f9ac3c54c2d1a Mon Sep 17 00:00:00 2001 From: Elijah Kelting Date: Thu, 6 Mar 2025 23:30:12 -0700 Subject: [PATCH 17/46] Pause menu GUI is setup, no interaction with it. --- MainMenu.py | 0 main.py | 3 +- window.py | 99 ++++++++++++++++++++++++++++++++++++++++++++++++++--- 3 files changed, 96 insertions(+), 6 deletions(-) create mode 100644 MainMenu.py diff --git a/MainMenu.py b/MainMenu.py new file mode 100644 index 00000000..e69de29b diff --git a/main.py b/main.py index 63aafd99..c9398fdd 100644 --- a/main.py +++ b/main.py @@ -25,7 +25,6 @@ def setup_fog(): def setup(): """ Basic OpenGL configuration. - """ # Set the color of "clear", i.e. the sky, in rgba. glClearColor(0.5, 0.69, 1.0, 1) # noqa: F405 @@ -42,7 +41,7 @@ def setup(): setup_fog() def main(): - userWindow = window.Window(width=800, height=600, caption='Pyglet', resizable=True) + userWindow = window.Window(width=800, height=600, caption='Py Minecraft', resizable=True) # Hide the mouse cursor and prevent the mouse from leaving the window. userWindow.set_exclusive_mouse(True) setup() diff --git a/window.py b/window.py index 527b16e6..00b49323 100644 --- a/window.py +++ b/window.py @@ -49,7 +49,7 @@ def __init__(self, *args, **kwargs): self.label = pyglet.text.Label('', font_name='Arial', font_size=18, # noqa: F405 x=10, y=self.height - 10, anchor_x='left', anchor_y='top', color=(0, 0, 0, 255)) - + # This call schedules the `update()` method to be called # TICKS_PER_SEC. This is the main game event loop. pyglet.clock.schedule_interval(self.update, 1.0 / model.TICKS_PER_SEC) # noqa: F405 @@ -145,6 +145,9 @@ def on_draw(self): self.set_2d() self.draw_label() self.draw_reticle() + if (self.state_machine.state == GameState.PAUSED): + self.create_pause_menu() + self.pause_menu_batch.draw() def draw_focused_block(self): """ Draw black edges around the block that is currently under the @@ -198,11 +201,99 @@ def update_playing(self, dt): def enter_paused(self): print("Entering Paused State") - # Add logic to display the pause menu - pass + # Create Pause menu + + + def update_paused(self, dt): # Handle input for the pause menu (e.g., resume, quit) #if some_condition_to_resume_game: + + + pass - \ No newline at end of file + + + def create_pause_menu(self): + # Create a container for the pause menu + self.pause_menu_batch = pyglet.graphics.Batch() + + window_size = self.get_size() + + # Create images for the button states + resume_depressed_image = pyglet.image.SolidColorImagePattern((100, 100, 100, 255)).create_image(150, 50) # Gray + resume_pressed_image = pyglet.image.SolidColorImagePattern((150, 150, 150, 255)).create_image(150, 50) # Light gray + quit_depressed_image = pyglet.image.SolidColorImagePattern((100, 100, 100, 255)).create_image(275, 50) # Gray + quit_pressed_image = pyglet.image.SolidColorImagePattern((150, 150, 150, 255)).create_image(275, 50) # Light gray + + # Create a semi-transparent background + self.background = pyglet.shapes.Rectangle( + x=0, + y=0, + width=window_size[0], + height=window_size[1], + color=(0, 0, 0), + batch=self.pause_menu_batch + ) + self.background.opacity = 25 + + # Create "PAUSED" label + self.paused_label = pyglet.text.Label( + "PAUSED", + font_name="Arial", + font_size=36, + x=window_size[0] // 2, + y=window_size[1] // 2 + 100, + anchor_x="center", + anchor_y="center", + batch=self.pause_menu_batch + ) + + # Create "Resume" button + self.resume_button = pyglet.gui.PushButton( + x=window_size[0] // 2 - 75, + y=window_size[1] // 2, + pressed=resume_pressed_image, + depressed=resume_depressed_image, + batch=self.pause_menu_batch + ) + self.resume_button_label = pyglet.text.Label( + "Resume", + font_name="Arial", + font_size=24, + x=self.resume_button.x + (self.resume_button.width // 2), + y=self.resume_button.y + (self.resume_button.height // 2), + anchor_x="center", + anchor_y="center", + batch=self.pause_menu_batch + ) + self.resume_button.on_press = self.resume_button_pressed + + # Create "Quit" button + self.quit_button = pyglet.gui.PushButton( + x=window_size[0] / 2 - 135, + y=window_size[1] / 2 - 100, + pressed=quit_pressed_image.width, + depressed=quit_depressed_image, + batch=self.pause_menu_batch, + ) + self.quit_button_label = pyglet.text.Label( + "Quit to Main Menu", + font_name="Arial", + font_size=24, + x=self.quit_button.x + (self.quit_button.width // 2), + y=self.quit_button.y + (self.quit_button.height // 2), + anchor_x="center", + anchor_y="center", + batch=self.pause_menu_batch + ) + self.quit_button.on_press = self.quit_button_pressed + + def resume_button_pressed(self): + print("Resume button pressed") + self.state_machine.change_state(GameState.PLAYING) + + def quit_button_pressed(self): + print("Quit button pressed") + self.state_machine.change_state(GameState.MAIN_MENU) \ No newline at end of file From 7e9f8a1a9a4aac5ec85fceb61cbdbbbca0651233 Mon Sep 17 00:00:00 2001 From: Elijah Kelting Date: Thu, 6 Mar 2025 23:45:52 -0700 Subject: [PATCH 18/46] player interaction stops on pause --- player.py | 43 +++++++++++++++++++++++-------------------- 1 file changed, 23 insertions(+), 20 deletions(-) diff --git a/player.py b/player.py index 75feac18..2e687982 100644 --- a/player.py +++ b/player.py @@ -103,6 +103,7 @@ def get_sight_vector(self): the player is looking. """ + x, y = self.rotation # y ranges from -90 to 90, or -pi/2 to pi/2, so m ranges from 0 to 1 and # is 1 when looking ahead parallel to the ground and 0 when looking @@ -174,20 +175,21 @@ def on_mouse_press(self, x, y, button, modifiers): mouse button was clicked. """ - if self.exclusive: - vector = self.get_sight_vector() - selectedBlock, previous = self.hit_test(vector) - if (button == mouse.RIGHT) or \ - ((button == mouse.LEFT) and (modifiers & key.MOD_CTRL)): - # ON OSX, control + left click = right click. - if previous: - self.model.add_block(previous, self.inventory.block) - elif button == pyglet.window.mouse.LEFT and selectedBlock: # noqa: F405 - texture = self.model.world[selectedBlock] - if texture != block.STONE: - self.model.remove_block(selectedBlock) - else: - self.window.set_exclusive_mouse(True) + if (self.state_machine.state == GameState.PLAYING): + if self.exclusive: + vector = self.get_sight_vector() + selectedBlock, previous = self.hit_test(vector) + if (button == mouse.RIGHT) or \ + ((button == mouse.LEFT) and (modifiers & key.MOD_CTRL)): + # ON OSX, control + left click = right click. + if previous: + self.model.add_block(previous, self.inventory.block) + elif button == pyglet.window.mouse.LEFT and selectedBlock: # noqa: F405 + texture = self.model.world[selectedBlock] + if texture != block.STONE: + self.model.remove_block(selectedBlock) + else: + self.window.set_exclusive_mouse(True) def on_mouse_motion(self, x, y, dx, dy): @@ -202,12 +204,13 @@ def on_mouse_motion(self, x, y, dx, dy): The movement of the mouse. """ - if self.exclusive: - m = 0.15 - x, y = self.rotation - x, y = x + dx * m, y + dy * m - y = max(-90, min(90, y)) - self.rotation = (x, y) + if (self.state_machine.state == GameState.PLAYING): + if self.exclusive: + m = 0.15 + x, y = self.rotation + x, y = x + dx * m, y + dy * m + y = max(-90, min(90, y)) + self.rotation = (x, y) def update(self, dt): """ Private implementation of the `update()` method. This is where most From 0871c8244ffd3902ea715df554bec2d07af15641 Mon Sep 17 00:00:00 2001 From: Kyle Wadas Date: Fri, 7 Mar 2025 00:00:46 -0700 Subject: [PATCH 19/46] Added More Blocks & Updated Terrain Generation --- Textures.png | Bin 11620 -> 75304 bytes block.py | 20 ++++++++++++-------- model.py | 12 ++++++------ 3 files changed, 18 insertions(+), 14 deletions(-) diff --git a/Textures.png b/Textures.png index 0cfd165ab2997491ba7609af116dd6b643b2114f..ecad4fb7e055f11b343443cbba195907dd045739 100644 GIT binary patch literal 75304 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 P0+)iEifoCD@rVBd4MO3J literal 11620 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 F{67i{JfZ*q diff --git a/block.py b/block.py index 46afd494..c56b5543 100644 --- a/block.py +++ b/block.py @@ -1,4 +1,4 @@ -def tex_coord(x, y, n=4): +def tex_coord(x, y, n=16): """ Return the bounding vertices of the texture square. """ @@ -20,10 +20,14 @@ def tex_coords(top, bottom, side): result.extend(side * 4) return result -GRASS = tex_coords((1, 0), (0, 1), (0, 0)) -DIRT = tex_coords((0, 1), (0, 1), (0, 1)) -SAND = tex_coords((1, 1), (1, 1), (1, 1)) -BRICK = tex_coords((2, 0), (2, 0), (2, 0)) -STONE = tex_coords((2, 1), (2, 1), (2, 1)) -LAMP = tex_coords((3, 1), (3, 1), (3, 1)) -PORTAL = tex_coords((2, 1), (2, 1), (3, 0)) \ No newline at end of file +#Row 1 +GRASS = tex_coords((0, 15), (2, 15), (3, 15)) +STONE = tex_coords((1, 15), (1, 15), (1, 15)) +DIRT = tex_coords((2, 15), (2, 15), (2, 15)) +BRICK = tex_coords((7, 15), (7, 15), (7, 15)) +WOOD_PLANK = tex_coords((4, 15), (4, 15), (4, 15)) +#Row 2 +SAND = tex_coords((2, 14), (2, 14), (2, 14)) +#Row 5 +LAMP = tex_coords((12, 11), (12, 11), (12, 11)) +PORTAL = tex_coords((13, 11), (13, 11), (13, 11)) \ No newline at end of file diff --git a/model.py b/model.py index 62af5759..7b82ee50 100644 --- a/model.py +++ b/model.py @@ -91,7 +91,7 @@ def _initialize(self): """ Initialize the world by placing all the blocks. """ - n = 80 # 1/2 width and height of world + n = 160 # 1/2 width and height of world s = 1 # step size y = 0 # initial y height for x in xrange(-n, n + 1, s): @@ -105,15 +105,15 @@ def _initialize(self): self.add_block((x, y + dy, z), block.STONE, immediate=False) # generate the hills randomly - o = n - 10 + o = n - 5 for _ in xrange(120): a = random.randint(-o, o) # x position of the hill b = random.randint(-o, o) # z position of the hill c = -1 # base of the hill - h = random.randint(1, 6) # height of the hill + h = random.randint(1, 4) # height of the hill s = random.randint(4, 8) # 2 * s is the side length of the hill d = 1 # how quickly to taper off the hills - t = random.choice([block.GRASS, block.SAND, block.BRICK]) + t = block.GRASS # random.choice([block.GRASS, block.SAND, block.BRICK]) for y in xrange(c, c + h): for x in xrange(a - s, a + s + 1): for z in xrange(b - s, b + s + 1): @@ -121,11 +121,11 @@ def _initialize(self): continue if (x - 0) ** 2 + (z - 0) ** 2 < 5 ** 2: continue + if (not self.exposed((x, y, z))): + t = block.DIRT self.add_block((x, y, z), t, immediate=False) s -= d # decrement side length so hills taper off - - def exposed(self, position): """ Returns False is given `position` is surrounded on all 6 sides by blocks, True otherwise. From bf61f8fd3b3f0f76c72df61585448d0cb4dceb8e Mon Sep 17 00:00:00 2001 From: Elijah Kelting Date: Fri, 7 Mar 2025 02:56:30 -0700 Subject: [PATCH 20/46] Pause functionality works, No main menu. --- player.py | 17 +++++++++++++---- window.py | 26 +++++++++++++++----------- 2 files changed, 28 insertions(+), 15 deletions(-) diff --git a/player.py b/player.py index 2e687982..ef54fdda 100644 --- a/player.py +++ b/player.py @@ -5,6 +5,7 @@ import math import inventory import block +from model import Model from states import GameState from pyglet.gl import * # noqa: F403 @@ -14,7 +15,7 @@ xrange = range class Player(): - def __init__(self, model, window, statemachine, *args, **kwargs): + def __init__(self, model: Model, window, statemachine, *args, **kwargs): self.WALKING_SPEED = 5 self.FLYING_SPEED = 15 @@ -37,8 +38,8 @@ def __init__(self, model, window, statemachine, *args, **kwargs): self.inventory = inventory.Inventory() self.model = model self.window = window - self.window.push_handlers(self) self.state_machine = statemachine + self.window.push_handlers(self) # When flying gravity has no effect and speed is increased. self.flying = False @@ -190,8 +191,12 @@ def on_mouse_press(self, x, y, button, modifiers): self.model.remove_block(selectedBlock) else: self.window.set_exclusive_mouse(True) - - + if self.state_machine.state == GameState.PAUSED: + # Pass the mouse press event to the GUI widgets + for widget in self.window.gui_widgets: + widget.on_mouse_press(x, y, button, modifiers) + + def on_mouse_motion(self, x, y, dx, dy): """ Called when the player moves the mouse. @@ -211,6 +216,10 @@ def on_mouse_motion(self, x, y, dx, dy): x, y = x + dx * m, y + dy * m y = max(-90, min(90, y)) self.rotation = (x, y) + if self.state_machine.state == GameState.PAUSED: + # Pass the mouse motion event to the GUI widgets + for widget in self.window.gui_widgets: + widget.on_mouse_motion(x, y, dx, dy) def update(self, dt): """ Private implementation of the `update()` method. This is where most diff --git a/window.py b/window.py index 00b49323..2252451e 100644 --- a/window.py +++ b/window.py @@ -10,7 +10,7 @@ class Window(pyglet.window.Window): - + def __init__(self, *args, **kwargs): super(Window, self).__init__(*args, **kwargs) @@ -33,6 +33,7 @@ def __init__(self, *args, **kwargs): enter_callback=self.enter_paused, update_callback=self.update_paused ) + # Instance of the model that handles the world. self.model = model.Model() @@ -44,6 +45,8 @@ def __init__(self, *args, **kwargs): # The crosshairs at the center of the screen. self.reticle = None + + self.gui_widgets = [] # The label that is displayed in the top left of the canvas. self.label = pyglet.text.Label('', font_name='Arial', font_size=18, # noqa: F405 @@ -146,7 +149,7 @@ def on_draw(self): self.draw_label() self.draw_reticle() if (self.state_machine.state == GameState.PAUSED): - self.create_pause_menu() + self.pause_menu_batch.draw() def draw_focused_block(self): @@ -192,6 +195,7 @@ def update_main_menu(self, dt): def enter_playing(self): print("Entering Playing State") + self.set_exclusive_mouse(True) # Add logic to initialize the game world, player, etc. def update_playing(self, dt): @@ -201,18 +205,14 @@ def update_playing(self, dt): def enter_paused(self): print("Entering Paused State") + self.create_pause_menu() # Create Pause menu - - - def update_paused(self, dt): # Handle input for the pause menu (e.g., resume, quit) #if some_condition_to_resume_game: - + self.pause_menu_batch - - pass def create_pause_menu(self): @@ -258,6 +258,7 @@ def create_pause_menu(self): depressed=resume_depressed_image, batch=self.pause_menu_batch ) + self.resume_button_label = pyglet.text.Label( "Resume", font_name="Arial", @@ -268,13 +269,13 @@ def create_pause_menu(self): anchor_y="center", batch=self.pause_menu_batch ) - self.resume_button.on_press = self.resume_button_pressed + self.resume_button.on_press = self.resume_button_pressed # Set the callback # Create "Quit" button self.quit_button = pyglet.gui.PushButton( x=window_size[0] / 2 - 135, y=window_size[1] / 2 - 100, - pressed=quit_pressed_image.width, + pressed=quit_pressed_image, depressed=quit_depressed_image, batch=self.pause_menu_batch, ) @@ -288,7 +289,10 @@ def create_pause_menu(self): anchor_y="center", batch=self.pause_menu_batch ) - self.quit_button.on_press = self.quit_button_pressed + self.quit_button.on_press = self.quit_button_pressed # Set the callback + + # Add buttons to the GUI widgets list + self.gui_widgets.extend([self.quit_button, self.resume_button]) def resume_button_pressed(self): print("Resume button pressed") From ffc26bf3b5e3d479cff95d1057450fc23d1bf162 Mon Sep 17 00:00:00 2001 From: Elijah Kelting Date: Fri, 7 Mar 2025 15:12:04 -0700 Subject: [PATCH 21/46] main menu is created and implemented --- MainMenu_background.jpg | Bin 0 -> 77711 bytes main.py | 3 +- player.py | 15 ++++- window.py | 126 +++++++++++++++++++++++++++++++++------- 4 files changed, 119 insertions(+), 25 deletions(-) create mode 100644 MainMenu_background.jpg diff --git a/MainMenu_background.jpg b/MainMenu_background.jpg new file mode 100644 index 0000000000000000000000000000000000000000..e123857e2f7656ed5ce26c3086857295b35de549 GIT binary patch literal 77711 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≺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
>T+g3s4l74enipUD7>Eb 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 literal 0 HcmV?d00001 diff --git a/main.py b/main.py index c9398fdd..c607d858 100644 --- a/main.py +++ b/main.py @@ -7,7 +7,6 @@ def setup_fog(): """ Configure the OpenGL fog properties. - """ # Enable fog. Fog "blends a fog color with each rasterized pixel fragment's # post-texturing color." @@ -43,7 +42,7 @@ def setup(): def main(): userWindow = window.Window(width=800, height=600, caption='Py Minecraft', resizable=True) # Hide the mouse cursor and prevent the mouse from leaving the window. - userWindow.set_exclusive_mouse(True) + userWindow.set_exclusive_mouse(False) setup() pyglet.app.run() # noqa: F405 diff --git a/player.py b/player.py index ef54fdda..0df8d783 100644 --- a/player.py +++ b/player.py @@ -192,10 +192,15 @@ def on_mouse_press(self, x, y, button, modifiers): else: self.window.set_exclusive_mouse(True) if self.state_machine.state == GameState.PAUSED: - # Pass the mouse press event to the GUI widgets + # Pass the mouse press event only to widgets in the pause menu batch for widget in self.window.gui_widgets: - widget.on_mouse_press(x, y, button, modifiers) - + if hasattr(widget, '_batch') and widget._batch == self.window.pause_menu_batch: + widget.on_mouse_press(x, y, button, modifiers) + elif self.state_machine.state == GameState.MAIN_MENU: + # Pass the mouse press event only to widgets in the main menu batch + for widget in self.window.gui_widgets: + if hasattr(widget, '_batch') and widget._batch == self.window.main_menu_batch: + widget.on_mouse_press(x, y, button, modifiers) def on_mouse_motion(self, x, y, dx, dy): """ Called when the player moves the mouse. @@ -220,6 +225,10 @@ def on_mouse_motion(self, x, y, dx, dy): # Pass the mouse motion event to the GUI widgets for widget in self.window.gui_widgets: widget.on_mouse_motion(x, y, dx, dy) + if self.state_machine.state == GameState.MAIN_MENU: + # Pass the mouse motion event to the GUI widgets + for widget in self.window.gui_widgets: + widget.on_mouse_motion(x, y, dx, dy) def update(self, dt): """ Private implementation of the `update()` method. This is where most diff --git a/window.py b/window.py index 2252451e..eb9d7cab 100644 --- a/window.py +++ b/window.py @@ -15,7 +15,7 @@ def __init__(self, *args, **kwargs): super(Window, self).__init__(*args, **kwargs) # Initialize the state machine - self.state_machine = StateMachine(GameState.PLAYING) + self.state_machine = StateMachine(GameState.MAIN_MENU) # Add states with their respective callbacks self.state_machine.add_state( @@ -53,6 +53,8 @@ def __init__(self, *args, **kwargs): x=10, y=self.height - 10, anchor_x='left', anchor_y='top', color=(0, 0, 0, 255)) + self.create_main_menu() + # This call schedules the `update()` method to be called # TICKS_PER_SEC. This is the main game event loop. pyglet.clock.schedule_interval(self.update, 1.0 / model.TICKS_PER_SEC) # noqa: F405 @@ -68,6 +70,7 @@ def update(self, dt): """ self.state_machine.update(dt) # Update the current state + # Existing game logic self.model.process_queue() sector = model.sectorize(self.player.position) @@ -148,8 +151,13 @@ def on_draw(self): self.set_2d() self.draw_label() self.draw_reticle() - if (self.state_machine.state == GameState.PAUSED): - + # Draw the background image first + if self.state_machine.state == GameState.MAIN_MENU: + self.background_sprite.draw() + # Draw the UI elements (buttons, labels, etc.) + if self.state_machine.state == GameState.MAIN_MENU: + self.main_menu_batch.draw() + elif self.state_machine.state == GameState.PAUSED: self.pause_menu_batch.draw() def draw_focused_block(self): @@ -186,7 +194,12 @@ def draw_reticle(self): def enter_main_menu(self): print("Entering Main Menu") - # Add logic to display the main menu (e.g., render buttons, text) + self.create_main_menu() + self.set_exclusive_mouse(False) + # Unregister pause menu buttons (if necessary) + for widget in self.gui_widgets: + if widget._batch == self.pause_menu_batch: + widget.enabled = False def update_main_menu(self, dt): @@ -196,24 +209,21 @@ def update_main_menu(self, dt): def enter_playing(self): print("Entering Playing State") self.set_exclusive_mouse(True) - # Add logic to initialize the game world, player, etc. def update_playing(self, dt): # Handle game logic (e.g., player movement, block placement) - #if some_condition_to_pause_game: pass def enter_paused(self): - print("Entering Paused State") self.create_pause_menu() - # Create Pause menu + # Unregister main menu buttons (if necessary) + for widget in self.gui_widgets: + if widget._batch == self.main_menu_batch: + widget.enabled = False def update_paused(self, dt): # Handle input for the pause menu (e.g., resume, quit) - #if some_condition_to_resume_game: - self.pause_menu_batch - - + pass def create_pause_menu(self): # Create a container for the pause menu @@ -258,7 +268,6 @@ def create_pause_menu(self): depressed=resume_depressed_image, batch=self.pause_menu_batch ) - self.resume_button_label = pyglet.text.Label( "Resume", font_name="Arial", @@ -272,32 +281,109 @@ def create_pause_menu(self): self.resume_button.on_press = self.resume_button_pressed # Set the callback # Create "Quit" button - self.quit_button = pyglet.gui.PushButton( + self.quittomain_button = pyglet.gui.PushButton( x=window_size[0] / 2 - 135, y=window_size[1] / 2 - 100, pressed=quit_pressed_image, depressed=quit_depressed_image, batch=self.pause_menu_batch, ) - self.quit_button_label = pyglet.text.Label( + self.quittomain_button_label = pyglet.text.Label( "Quit to Main Menu", font_name="Arial", font_size=24, + x=self.quittomain_button.x + (self.quittomain_button.width // 2), + y=self.quittomain_button.y + (self.quittomain_button.height // 2), + anchor_x="center", + anchor_y="center", + batch=self.pause_menu_batch + ) + self.quittomain_button.on_press = self.quittomain_button_pressed # Set the callback + + # Add buttons to the GUI widgets list + self.gui_widgets.extend([self.quittomain_button, self.resume_button]) + + def resume_button_pressed(self): + print("Resume button pressed") + self.state_machine.change_state(GameState.PLAYING) + + def quittomain_button_pressed(self): + self.state_machine.change_state(GameState.MAIN_MENU) + + def create_main_menu(self): + # Create a container for the pause menu + self.main_menu_batch = pyglet.graphics.Batch() + + window_size = self.get_size() + + # Create a semi-transparent background + self.background_image = pyglet.image.load('MainMenu_background.jpg') + self.background_sprite = pyglet.sprite.Sprite(self.background_image) + self.background_sprite.scale_x = self.width / self.background_image.width + self.background_sprite.scale_y = self.height / self.background_image.height + + # Create images for the button states + resume_depressed_image = pyglet.image.SolidColorImagePattern((100, 100, 100, 255)).create_image(150, 50) # Gray + resume_pressed_image = pyglet.image.SolidColorImagePattern((150, 150, 150, 255)).create_image(150, 50) # Light gray + quit_depressed_image = pyglet.image.SolidColorImagePattern((100, 100, 100, 255)).create_image(275, 50) # Gray + quit_pressed_image = pyglet.image.SolidColorImagePattern((150, 150, 150, 255)).create_image(275, 50) # Light gray + + self.splash_Text_label = pyglet.text.Label( + "Now in Python!!!", + font_name="Arial", + font_size=36, + x=window_size[0] // 2, + y=window_size[1] // 2 + 100, + anchor_x="center", + anchor_y="center", + batch=self.main_menu_batch + ) + + self.play_button = pyglet.gui.PushButton( + x=window_size[0] // 2 - 75, + y=window_size[1] // 2, + pressed=resume_pressed_image, + depressed=resume_depressed_image, + batch=self.main_menu_batch + ) + self.play_button_label = pyglet.text.Label( + "Play", + font_name="Arial", + font_size=24, + x=self.play_button.x + (self.play_button.width // 2), + y=self.play_button.y + (self.play_button.height // 2), + anchor_x="center", + anchor_y="center", + batch=self.main_menu_batch + ) + self.play_button.on_press = self.play_button_pressed # Set the callback + + # Create "Quit" button + self.quit_button = pyglet.gui.PushButton( + x=window_size[0] / 2 - 135, + y=window_size[1] / 2 - 100, + pressed=quit_pressed_image, + depressed=quit_depressed_image, + batch=self.main_menu_batch, + ) + self.quit_button_label = pyglet.text.Label( + "Quit to Desktop", + font_name="Arial", + font_size=24, x=self.quit_button.x + (self.quit_button.width // 2), y=self.quit_button.y + (self.quit_button.height // 2), anchor_x="center", anchor_y="center", - batch=self.pause_menu_batch + batch=self.main_menu_batch ) self.quit_button.on_press = self.quit_button_pressed # Set the callback # Add buttons to the GUI widgets list - self.gui_widgets.extend([self.quit_button, self.resume_button]) + self.gui_widgets.extend([self.quit_button, self.play_button]) - def resume_button_pressed(self): + def play_button_pressed(self): print("Resume button pressed") self.state_machine.change_state(GameState.PLAYING) def quit_button_pressed(self): - print("Quit button pressed") - self.state_machine.change_state(GameState.MAIN_MENU) \ No newline at end of file + pyglet.app.exit() \ No newline at end of file From 34de70708fc379e619d82f2c94bec1ff8eeb21f5 Mon Sep 17 00:00:00 2001 From: Elijah Kelting Date: Fri, 7 Mar 2025 15:15:47 -0700 Subject: [PATCH 22/46] added indent --- player.py | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/player.py b/player.py index ab18ddc9..5a9fd12d 100644 --- a/player.py +++ b/player.py @@ -182,16 +182,16 @@ def on_mouse_press(self, x, y, button, modifiers): if (self.state_machine.state == GameState.PLAYING): if self.exclusive: - vector = self.get_sight_vector() - selectedBlock, previous = self.hit_test(vector) - if (button == mouse.RIGHT) or ((button == mouse.LEFT) and (modifiers & key.MOD_CTRL)): - # ON OSX, control + left click = right click. - if previous: - self.model.add_block(previous, self.inventory.block) - elif button == pyglet.window.mouse.LEFT and selectedBlock: # noqa: F405 - texture = self.model.world[selectedBlock] - if texture != block.STONE: - self.model.remove_block(selectedBlock) + vector = self.get_sight_vector() + selectedBlock, previous = self.hit_test(vector) + if (button == mouse.RIGHT) or ((button == mouse.LEFT) and (modifiers & key.MOD_CTRL)): + # ON OSX, control + left click = right click. + if previous: + self.model.add_block(previous, self.inventory.block) + elif button == pyglet.window.mouse.LEFT and selectedBlock: # noqa: F405 + texture = self.model.world[selectedBlock] + if texture != block.STONE: + self.model.remove_block(selectedBlock) else: self.window.set_exclusive_mouse(True) if self.state_machine.state == GameState.PAUSED: From f007d2446930772ab490311377b09ce54f3db0d1 Mon Sep 17 00:00:00 2001 From: Kyle Wadas Date: Sat, 8 Mar 2025 13:51:13 -0700 Subject: [PATCH 23/46] Updated Textures --- Textures.png | Bin 75304 -> 153940 bytes Textures_Numbered.png | Bin 0 -> 164218 bytes block.py | 22 ++++++++++++---------- inventory.py | 4 ++-- model.py | 4 ++-- 5 files changed, 16 insertions(+), 14 deletions(-) create mode 100644 Textures_Numbered.png diff --git a/Textures.png b/Textures.png index ecad4fb7e055f11b343443cbba195907dd045739..4b9ffcd289c6a092af75fbda7d1f77be63e1fb3f 100644 GIT binary patch literal 153940 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

cGM|WMgnX)D_Cd}d8@JLai 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 z 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 q$4v%E@P+se@C($)5ddn4+XI3vb028Z Date: Sat, 8 Mar 2025 14:31:02 -0700 Subject: [PATCH 24/46] Fixed blurry texture --- main.py | 2 -- model.py | 3 +++ 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/main.py b/main.py index c607d858..420d9ca2 100644 --- a/main.py +++ b/main.py @@ -35,8 +35,6 @@ def setup(): # "is generally faster than GL_LINEAR, but it can produce textured images # with sharper edges because the transition between texture elements is not # as smooth." - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST) # noqa: F405 - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST) # noqa: F405 setup_fog() def main(): diff --git a/model.py b/model.py index 7b82ee50..581e4bac 100644 --- a/model.py +++ b/model.py @@ -85,6 +85,9 @@ def __init__(self): # _show_block() and _hide_block() calls self.queue = deque() + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST) # noqa: F405 + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST) # noqa: F405 + self._initialize() def _initialize(self): From 1a0a1815540bd6fc414392cc1067dd1952924fb0 Mon Sep 17 00:00:00 2001 From: Kyle Wadas Date: Sat, 8 Mar 2025 14:46:34 -0700 Subject: [PATCH 25/46] Moved Visual Functions to Window --- main.py | 34 +--------------------------------- window.py | 34 +++++++++++++++++++++++++++++++++- 2 files changed, 34 insertions(+), 34 deletions(-) diff --git a/main.py b/main.py index 420d9ca2..3b7a4bd2 100644 --- a/main.py +++ b/main.py @@ -5,43 +5,11 @@ import window from pyglet.gl import * # noqa: F403 -def setup_fog(): - """ Configure the OpenGL fog properties. - """ - # Enable fog. Fog "blends a fog color with each rasterized pixel fragment's - # post-texturing color." - glEnable(GL_FOG) # noqa: F405 - # Set the fog color. - glFogfv(GL_FOG_COLOR, (GLfloat * 4)(0.5, 0.69, 1.0, 1)) # noqa: F405 - # Say we have no preference between rendering speed and quality. - glHint(GL_FOG_HINT, GL_DONT_CARE) # noqa: F405 - # Specify the equation used to compute the blending factor. - glFogi(GL_FOG_MODE, GL_LINEAR) # noqa: F405 - # How close and far away fog starts and ends. The closer the start and end, - # the denser the fog in the fog range. - glFogf(GL_FOG_START, 20.0) # noqa: F405 - glFogf(GL_FOG_END, 60.0) # noqa: F405 - -def setup(): - """ Basic OpenGL configuration. - """ - # Set the color of "clear", i.e. the sky, in rgba. - glClearColor(0.5, 0.69, 1.0, 1) # noqa: F405 - # Enable culling (not rendering) of back-facing facets -- facets that aren't - # visible to you. - glEnable(GL_CULL_FACE) # noqa: F405 - # Set the texture minification/magnification function to GL_NEAREST (nearest - # in Manhattan distance) to the specified texture coordinates. GL_NEAREST - # "is generally faster than GL_LINEAR, but it can produce textured images - # with sharper edges because the transition between texture elements is not - # as smooth." - setup_fog() - def main(): userWindow = window.Window(width=800, height=600, caption='Py Minecraft', resizable=True) # Hide the mouse cursor and prevent the mouse from leaving the window. userWindow.set_exclusive_mouse(False) - setup() + userWindow.setup() pyglet.app.run() # noqa: F405 if __name__ == '__main__': diff --git a/window.py b/window.py index eb9d7cab..50cb0148 100644 --- a/window.py +++ b/window.py @@ -14,7 +14,7 @@ class Window(pyglet.window.Window): def __init__(self, *args, **kwargs): super(Window, self).__init__(*args, **kwargs) - # Initialize the state machine + # Initialize the state machine self.state_machine = StateMachine(GameState.MAIN_MENU) # Add states with their respective callbacks @@ -191,6 +191,38 @@ def draw_reticle(self): """ glColor3d(0, 0, 0) self.reticle.draw(GL_LINES) + + def setup_fog(self): + """ Configure the OpenGL fog properties. + """ + # Enable fog. Fog "blends a fog color with each rasterized pixel fragment's + # post-texturing color." + glEnable(GL_FOG) # noqa: F405 + # Set the fog color. + glFogfv(GL_FOG_COLOR, (GLfloat * 4)(0.5, 0.69, 1.0, 1)) # noqa: F405 + # Say we have no preference between rendering speed and quality. + glHint(GL_FOG_HINT, GL_DONT_CARE) # noqa: F405 + # Specify the equation used to compute the blending factor. + glFogi(GL_FOG_MODE, GL_LINEAR) # noqa: F405 + # How close and far away fog starts and ends. The closer the start and end, + # the denser the fog in the fog range. + glFogf(GL_FOG_START, 20.0) # noqa: F405 + glFogf(GL_FOG_END, 60.0) # noqa: F405 + + def setup(self): + """ Basic OpenGL configuration. + """ + # Set the color of "clear", i.e. the sky, in rgba. + glClearColor(0.5, 0.69, 1.0, 1) # noqa: F405 + # Enable culling (not rendering) of back-facing facets -- facets that aren't + # visible to you. + glEnable(GL_CULL_FACE) # noqa: F405 + # Set the texture minification/magnification function to GL_NEAREST (nearest + # in Manhattan distance) to the specified texture coordinates. GL_NEAREST + # "is generally faster than GL_LINEAR, but it can produce textured images + # with sharper edges because the transition between texture elements is not + # as smooth." + self.setup_fog() def enter_main_menu(self): print("Entering Main Menu") From d039f860ef3a4d8bd8356c2c918b0154c0b6779f Mon Sep 17 00:00:00 2001 From: Kyle Wadas Date: Sat, 8 Mar 2025 20:08:17 -0700 Subject: [PATCH 26/46] Added New Terrain Generation & Updated Player Interaction with Blocks --- block.py | 21 +++++++++++++----- inventory.py | 2 +- mmath.py | 8 +++++++ model.py | 63 ++++++++++++++++++++++++++-------------------------- player.py | 9 ++++---- window.py | 4 ++-- 6 files changed, 62 insertions(+), 45 deletions(-) diff --git a/block.py b/block.py index 33db584d..8d59c899 100644 --- a/block.py +++ b/block.py @@ -21,15 +21,24 @@ def tex_coords(top, bottom, side): result.extend(side * 4) return result +NONE = None #Row 1 STONE = tex_coords((19, 15), (19, 15), (19, 15)) -GRASS_BLOCK = tex_coords((2, 15), (18, 14), (3, 15)) +GRASS_BLOCK = tex_coords((2, 15), (18, 14), (10, 15)) DIRT = tex_coords((18, 14), (18, 14), (18, 14)) -BRICK = tex_coords((29, 14), (29, 14), (29, 14)) -WOOD_PLANK = tex_coords((4, 15), (4, 15), (4, 15)) +PODZOL = tex_coords((19, 14), (18, 14), (20, 14)) +COBBLESTONE = tex_coords((26, 15), (26, 15), (26, 15)) +OAK_WOOD_PLANK = tex_coords((21, 14), (21, 14), (21, 14)) +SPRUCE_WOOD_PLANK = tex_coords((22, 14), (22, 14), (22, 14)) +BIRCH_WOOD_PLANK = tex_coords((23, 14), (23, 14), (23, 14)) +JUNGLE_WOOD_PLANK = tex_coords((24, 14), (24, 14), (24, 14)) +ACACIA_WOOD_PLANK = tex_coords((25, 14), (25, 14), (25, 14)) +DARK_OAK_WOOD_PLANK = tex_coords((26, 14), (26, 14), (26, 14)) #Row 2 -SAND = tex_coords((2, 14), (2, 14), (2, 14)) +BRICK = tex_coords((29, 14), (29, 14), (29, 14)) +SAND = tex_coords((5, 14), (5, 14), (5, 14)) #Row 5 -LAMP = tex_coords((12, 11), (12, 11), (12, 11)) -PORTAL = tex_coords((13, 11), (13, 11), (13, 11)) +LAMP = tex_coords((25, 7), (25, 7), (25, 7)) +PORTAL = tex_coords((26, 6), (26, 6), (26, 6)) +WATER_BLOCK = tex_coords((0, 1),(0, 1),(0, 1)) \ No newline at end of file diff --git a/inventory.py b/inventory.py index 65c44751..1554836c 100644 --- a/inventory.py +++ b/inventory.py @@ -2,6 +2,6 @@ class Inventory: def __init__(self, *args, **kwargs): - self.hotbar = [block.DIRT, block.GRASS_BLOCK, block.SAND, block.DIRT, block.PORTAL, block.LAMP] + self.hotbar = [block.STONE, block.SPRUCE_WOOD_PLANK, block.BIRCH_WOOD_PLANK, block.JUNGLE_WOOD_PLANK, block.ACACIA_WOOD_PLANK, block.DARK_OAK_WOOD_PLANK] self.block = self.hotbar[0] \ No newline at end of file diff --git a/mmath.py b/mmath.py index 277dac44..ed1c11b0 100644 --- a/mmath.py +++ b/mmath.py @@ -1,3 +1,11 @@ +from opensimplex import OpenSimplex +import random + +gen = OpenSimplex(random.randrange(1, 10000)) +def noise(nx, ny): + # Rescale from -1.0:+1.0 to 0.0:1.0 + return gen.noise2(nx, ny) / 2.0 + 0.5 + def normalize(position): """ Accepts `position` of arbitrary precision and returns the block containing that position. diff --git a/model.py b/model.py index 375c613c..e732fda6 100644 --- a/model.py +++ b/model.py @@ -11,6 +11,8 @@ from pyglet.gl import * # noqa: F403 from pyglet.graphics import TextureGroup + + if sys.version_info[0] >= 3: xrange = range @@ -97,37 +99,32 @@ def _initialize(self): n = 160 # 1/2 width and height of world s = 1 # step size y = 0 # initial y height - for x in xrange(-n, n + 1, s): - for z in xrange(-n, n + 1, s): + f = 2 # frequency + + elevation = [] + for h in xrange(n*2): + elevation.append([0] * n*2) + for w in xrange(n): + nx = w/n - 0.5 + ny = h/n - 0.5 + elevation[h][w] = mmath.noise(f * nx, f * ny) + + + for x in xrange(0, n, s): + for z in xrange(0, n, s): # create a layer stone an grass everywhere. - self.add_block((x, y - 2, z), block.GRASS_BLOCK, immediate=False) - self.add_block((x, y - 3, z), block.STONE, immediate=False) - if x in (-n, n) or z in (-n, n): - # create outer walls. - for dy in xrange(-2, 3): - self.add_block((x, y + dy, z), block.STONE, immediate=False) - - # generate the hills randomly - o = n - 5 - for _ in xrange(120): - a = random.randint(-o, o) # x position of the hill - b = random.randint(-o, o) # z position of the hill - c = -1 # base of the hill - h = random.randint(1, 4) # height of the hill - s = random.randint(4, 8) # 2 * s is the side length of the hill - d = 1 # how quickly to taper off the hills - t = block.GRASS_BLOCK # random.choice([block.GRASS, block.SAND, block.BRICK]) - for y in xrange(c, c + h): - for x in xrange(a - s, a + s + 1): - for z in xrange(b - s, b + s + 1): - if (x - a) ** 2 + (z - b) ** 2 > (s + 1) ** 2: - continue - if (x - 0) ** 2 + (z - 0) ** 2 < 5 ** 2: - continue - if (not self.exposed((x, y, z))): - t = block.DIRT - self.add_block((x, y, z), t, immediate=False) - s -= d # decrement side length so hills taper off + if (int(elevation[z][x]*10) < 2): + self.add_block((x, int(elevation[z][x]*10), z), block.SAND, immediate=False) + elif (int(elevation[z][x] < 3)): + self.add_block((x, int(elevation[z][x]*10), z), block.GRASS_BLOCK, immediate=False) + else: + self.add_block((x, int(elevation[z][x]*10), z), block.STONE, immediate=False) + # self.add_block((x, y - 3, z), block.STONE, immediate=False) + # if x in (-n, n) or z in (-n, n): + # # create outer walls. + # for dy in xrange(-2, 3): + # self.add_block((x, y + dy, z), block.STONE, immediate=False) + def exposed(self, position): """ Returns False is given `position` is surrounded on all 6 sides by @@ -154,6 +151,8 @@ def add_block(self, position, texture, immediate=True): Whether or not to draw the block immediately. """ + if (texture == block.NONE): + return if position in self.world: self.remove_block(position, immediate) self.world[position] = texture @@ -229,7 +228,7 @@ def _show_block(self, position, texture): texture : list of len 3 The coordinates of the texture squares. Use `tex_coords()` to generate. - + """ x, y, z = position vertex_data = cube_vertices(x, y, z, 0.5) @@ -330,7 +329,7 @@ def collide(self, player, position): # have to count as a collision. If 0, touching terrain at all counts as # a collision. If .49, you sink into the ground, as if walking through # tall grass. If >= .5, you'll fall through the ground. - pad = 0.25 + pad = 0.0 p = list(position) np = mmath.normalize(position) for face in FACES: # check all surrounding blocks diff --git a/player.py b/player.py index 5a9fd12d..b0caea43 100644 --- a/player.py +++ b/player.py @@ -46,7 +46,7 @@ def __init__(self, model: Model, window, statemachine, *args, **kwargs): # Current (x, y, z) position in the world, specified with floats. Note # that, perhaps unlike in math class, the y-axis is the vertical axis. - self.position = (0, 0, 0) + self.position = (80, 10, 80) # First element is -1 when moving forward, 1 when moving back, and 0 # otherwise. The second element is -1 when moving left, 1 when moving @@ -189,9 +189,10 @@ def on_mouse_press(self, x, y, button, modifiers): if previous: self.model.add_block(previous, self.inventory.block) elif button == pyglet.window.mouse.LEFT and selectedBlock: # noqa: F405 - texture = self.model.world[selectedBlock] - if texture != block.STONE: - self.model.remove_block(selectedBlock) + # texture = self.model.world[selectedBlock] + self.model.remove_block(selectedBlock) + # if texture != block.STONE: + # self.model.remove_block(selectedBlock) else: self.window.set_exclusive_mouse(True) if self.state_machine.state == GameState.PAUSED: diff --git a/window.py b/window.py index 50cb0148..c587eb4b 100644 --- a/window.py +++ b/window.py @@ -206,8 +206,8 @@ def setup_fog(self): glFogi(GL_FOG_MODE, GL_LINEAR) # noqa: F405 # How close and far away fog starts and ends. The closer the start and end, # the denser the fog in the fog range. - glFogf(GL_FOG_START, 20.0) # noqa: F405 - glFogf(GL_FOG_END, 60.0) # noqa: F405 + glFogf(GL_FOG_START, 40.0) # noqa: F405 + glFogf(GL_FOG_END, 80.0) # noqa: F405 def setup(self): """ Basic OpenGL configuration. From fbed6e6af255de52c1e104f2a87f9256c98b3844 Mon Sep 17 00:00:00 2001 From: StephenieDugan Date: Sat, 8 Mar 2025 20:10:59 -0700 Subject: [PATCH 27/46] Teleport blocks added and removed from list minor fixes to textures --- __pycache__/block.cpython-312.pyc | Bin 1358 -> 1464 bytes __pycache__/inventory.cpython-312.pyc | Bin 851 -> 869 bytes __pycache__/model.cpython-312.pyc | Bin 16928 -> 17114 bytes __pycache__/player.cpython-312.pyc | Bin 11976 -> 15384 bytes __pycache__/window.cpython-312.pyc | Bin 8498 -> 20520 bytes block.py | 16 ++++++++-------- inventory.py | 2 +- model.py | 5 +++++ 8 files changed, 14 insertions(+), 9 deletions(-) diff --git a/__pycache__/block.cpython-312.pyc b/__pycache__/block.cpython-312.pyc index c8359db074266e18bc1d4ba40734af5227c49e8c..72933ddac613f1195d82dc6e2f312e97fa6d60b8 100644 GIT binary patch delta 784 zcmY+BK}-`t6ozMZXSUm2cg2Dh2qt)vMy*OT8lonxKp`b9X%P&;aA2C21Vgf5D0Pji z;XrR~dT_m!8%7UCFC6i#F_^v3xp~|hYU06@Z?@9lPTuVI{`dCHo3~%JJ>C3l7#f1- z;P;neg4E64@ekm=Ld;-z3(q4aZJ~KAp#o;ISZ`&KjnKRlXoOLwbTm28C}_04l8$Q( zRwt+iL7l=IacOncVry0u1ikT2 zUU+^w$n(45<^N*|*y?NR5uuBAW0Eia%&~r6@IYHXdxBwt9bJ_0L+zY?!3t~{Xi6O5 zcZq;@*Am5pemKp~WHV!2PvsK%{9_L zJESMLfhBJEN4@iSl|5N0+_U1~1_OQxa3o`le@QBy!asX-9QiST!riso?!#u;Q?EI+ zW%jz!=Fo1+GjBM0D|Dtd%q@EFk-Z@-$zUI+{nZ%`B@PY?hAp^wh4Ky1|(418X_9N1Ze>cWT;5#Y-s6M$ z?#h2)r+U1f4PlTAvmuY%x4RKPbU*AK@=w_#_?$bomyhZ4mpvs7CRebbqwwVLotj<1 z0})}ptTmr))a#rz_%#%);cxXxCl&j~a)>d8tXaShpP#}~KwU}`eJtC@M%1rQ>GCQs zY8Nj&B?r#uF}XZ&yt~jIlwIHN2)ddtR|NIl(yGu_%K3W*q4|}y(tSaT?xS^~udkIW zZjsAB$K|wKp60J{XS>c`ZPo7b8%X0jY#=yM0pLtY!0kV28`7ss#Jt+ig}EpqlD9?$R18pBRy@MWwV9Y)C;}H8=1HE^mwX&-F~L$ diff --git a/__pycache__/inventory.cpython-312.pyc b/__pycache__/inventory.cpython-312.pyc index 2b80b7f3940d763546dcb01ffd6ab4064f779ecf..363953a9ca729fdb6066726665e36070d8f0330c 100644 GIT binary patch delta 240 zcmcc2_LPnHG%qg~0}#CWawh%7M&3?F<02*?SCiuwYf?^ra`r8*aDRW7_y8YAKkr*C zE}lUlx47Md9D{@7oqYVAfkMHKelC;uF)p)k2Wo3zxFareU0nU5xcVB=^-?RPwuD|c zb-QTlc82vl*GaA`A(7WZ5-x@$TuDm5o|JPjDd&P%?&PUV4$(qD%_|v-gn?9%Ac$ar z5zIhFF*}fGVff6%%&G!W1CrKcDq@4FDiQ~=;M#w2*yQG?l;)(`6-i7sV3ubA$p8Re Ch(R3y delta 248 zcmaFLcA1U$G%qg~0}!xeoJzmDk++jk<0UJQtI2VTH7O@QIr|o?Q;?^#_bpcUAjja~ zTP(qjelE9ITs(t9CZA+nX6OJ^+rV%~TxNRp#Ofuk%e@zRZxP)twNYwM=>DjkQD;QY z%bb+C5*~9sJn>?9;svp!$;+7>>V$#1Rx%Wc0I4D&5WxZ?n1PI9b|BHh@R^C3RRy93 zB(2F*1QLfRl>o8e+JAA_<4B>M#kF=Jl|PZ7*#$o012=j E0FIkJ!2kdN diff --git a/__pycache__/model.cpython-312.pyc b/__pycache__/model.cpython-312.pyc index dc262de21939441e3b8210e8f11a6be3b9ceebbd..caaf4c9098e03af464afa6e0e78dc7d388d460a5 100644 GIT binary patch delta 1618 zcmZuxT})J05WeT`4?oM@-Mh=Wuvpv`C@fG=1Vj{J(FF-Vl|L&*U03%43kwTpmjYX` zwxwx}q(Y`?j3ur3ptPi^&3$PTAKE^(p%0ppnB17!rcE0Agf@MsNq^4l<+t%Xe0OHf z%$zgdnYq`eiSiaPE(=03$JRH$ec!7u|J?YqfxIiP8VsZ_>OwoN=x+7Pr0fmp`E_YY zqe_H(W<=h)U-TIflU#oR%vCy)2sgpGNsD_2>=rI`nR-JV()e*d^$$u>i3Sy+zRB0& zJ=xLO=Jk~vRcu?-=7ttuT|-lcw@pcA<`%D~&D-9w-NjSC<^mrH)#Nff6#5*$CfetP zmE1#j`d1Pg9&A;h-k3`)a@cr>5H}Q>KNC{|!V<66F~tY?DFKqjOc)Yf7fO%3fvyatgf{`?UuOwM9mN}L!Ow)PZ{B^(E&pi+pe&do4KUr zCizJrX6Lvmer8e2&61fyEjM9uo8g9~id=`EECo&-OYvx&0cC#NBP~KALOO#McM|Ne zW~3PE+dS>{@Z|f8flymAsIA)dS16^c^NHvwT&*z0nTFXSfIT|R6373dk}{=Yg-L3Or`EX$qQ%e-OJ{R|Z3)}-|?|Bcs; z^o7UNGJllc%zckf>t(z29H!h>njebuZR8Kxo6nP~VYaR4S$D7*bn}~(L|AWd>s*d7 zdE=PAU_erj(aF;VLqv#kf^;CI@NZ!iG00Ufgot^R*;KNSC;AF}S+s|w%D)#q})*Flce>6iq~mQV&`N5aM$XV^X}M|Jhq?*g`W@l#TMJcI}&sNNn%5G*^>kdWR zGdgr$(fVm`WIKt-ZOphfSJKePs5C0|KzZdaWDXn$^GQhd9{iL~e4n`?t?;y}l0@XP z!#PBcHd+d2t82&wSg7tiQH};2RJFaZb7>a>_Nm%v_|Wlgqxcq^tk7vxuOP%4w+tM3wL~bP~ z-~%}ZTkVx3pzX8YCgf=ll$)heRKCGuB91%FNBPrI+Ga`|cT|SMn_Td%y%ciJvTbQ$ z&EQ=9l|P3qHwgTqRFY{BoIw(SdWJm^b%qM<$5;VMX6nG<3T{0pa5JjFP4bgcb_*7r zIU{fv$V`*KjXV4b9C5XfLon~!*^Topk1?Rkk6RWIu!rRWgklE0{*AggM#G6=RWA%j zqeHKaBqPUk>&mgOuf4w?On05mguZ+j~28Ye!$tvj_clS__RuhbjXsQ&xE{ z8C6FDL-9mB9S@Jhv+65MopP|&-{f)yoMeYvMLkgB-UJ)mV;271ZkTq5N;khR%}Vo` zs}q+eKI*!8;QE2v)-P>KwtHorKRCMJclUb%kMF8{SzaIuyB5ON#&4A`W-iG;dAk0z zab-{CESz_DPUaNng~PMrEP1GCi<=#U)WSDge0BR-13Dkgrf}XTRz9krc7r-LnoOzD ztYo&mBEF>+d8RC60Om?6nroRO^%>r2bu68sDs5m=3Ms^7MkdkO2Aud{^!xA^4-*OFq-YZTI-b^$pQM=Jvm-utwHlwv~z{Pnk`9t=YHV ziy@vf7V)_oZ|y3Ht{Nh)VjfOfYl1Icywj#oc5@SCyoR&>LS}G zHLd!2wq{DT+mpnI)iU`IUTdvR5Xs;N+eX4+siuV#X#doV5J!sXOyaO4O+zYJD=LKb z(+L08lxuf_OMF8Un%oThgyL(a^$dFbR^5_P)3gOOafFiy_@s>GU)&uGJVrFy)?b4z zARW4Z-O>!RL$atC0(CoxR~x9Su)1RygD;VK5sd3@fpdFy)*#8cI64v@SE;dubP6?O zROb_;y6}29qUt10pU1HMaDPudY0$il^Q7QqrZG79qN&u4vJ3X1a}w);howd7%a1vIpuvUQ;LBEmE9d3(rf ma9@J*B?SEEq&pD$pt>VS7GSXBxYA)IzIVF+=J2F0X8jLD^>^6- diff --git a/__pycache__/player.cpython-312.pyc b/__pycache__/player.cpython-312.pyc index 45149d8df8945c79f0cd1514b09d575d11d37416..ccd85c93eb735eacbe9f20414afd5d293ad75b9a 100644 GIT binary patch delta 5973 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 Cj7)U^ delta 3186 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 H*arUv>AvS5 diff --git a/block.py b/block.py index 33db584d..74808c20 100644 --- a/block.py +++ b/block.py @@ -22,14 +22,14 @@ def tex_coords(top, bottom, side): return result #Row 1 -STONE = tex_coords((19, 15), (19, 15), (19, 15)) -GRASS_BLOCK = tex_coords((2, 15), (18, 14), (3, 15)) -DIRT = tex_coords((18, 14), (18, 14), (18, 14)) -BRICK = tex_coords((29, 14), (29, 14), (29, 14)) -WOOD_PLANK = tex_coords((4, 15), (4, 15), (4, 15)) +STONE = tex_coords((19, 15), (19, 15), (19, 15)) #correct +GRASS_BLOCK = tex_coords((2, 15), (18, 14), (3, 15)) #correct +DIRT = tex_coords((18, 14), (18, 14), (18, 14)) #correct +BRICK = tex_coords((29, 14), (29, 14), (29, 14)) #correct +WOOD_PLANK = tex_coords((21, 14), (21, 14), (21, 14)) # fixed #Row 2 -SAND = tex_coords((2, 14), (2, 14), (2, 14)) +SAND = tex_coords((5, 14), (5, 14), (5, 14)) #fixed #Row 5 -LAMP = tex_coords((12, 11), (12, 11), (12, 11)) -PORTAL = tex_coords((13, 11), (13, 11), (13, 11)) +LAMP = tex_coords((25, 7), (25, 7), (25, 7)) #fixed +PORTAL = tex_coords((26, 6), (26, 6), (26, 6)) #fixed diff --git a/inventory.py b/inventory.py index 65c44751..8904ec16 100644 --- a/inventory.py +++ b/inventory.py @@ -2,6 +2,6 @@ class Inventory: def __init__(self, *args, **kwargs): - self.hotbar = [block.DIRT, block.GRASS_BLOCK, block.SAND, block.DIRT, block.PORTAL, block.LAMP] + self.hotbar = [block.WOOD_PLANK, block.DIRT, block.GRASS_BLOCK, block.SAND, block.PORTAL, block.LAMP] self.block = self.hotbar[0] \ No newline at end of file diff --git a/model.py b/model.py index 375c613c..4af76e17 100644 --- a/model.py +++ b/model.py @@ -84,6 +84,9 @@ def __init__(self): # Simple function queue implementation. The queue is populated with # _show_block() and _hide_block() calls self.queue = deque() + + #A constant running list for placed teleport blocks in the world and their positions + self.teleport_blocks = [] glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST) # noqa: F405 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST) # noqa: F405 @@ -158,6 +161,8 @@ def add_block(self, position, texture, immediate=True): self.remove_block(position, immediate) self.world[position] = texture self.sectors.setdefault(sectorize(position), []).append(position) + if texture == block.PORTAL: # Replace with the desired block type + self.teleport_blocks.append(position) if immediate: if self.exposed(position): self.show_block(position) From 3b0b403d107bfbf3a4cc18a1216ea34bf55b6742 Mon Sep 17 00:00:00 2001 From: Kyle Wadas Date: Sat, 8 Mar 2025 20:42:20 -0700 Subject: [PATCH 28/46] Updated New Terrain Generation & Updated Player Block Interaction --- block.py | 3 +++ main.py | 2 +- model.py | 20 +++++++++++--------- player.py | 7 +++---- 4 files changed, 18 insertions(+), 14 deletions(-) diff --git a/block.py b/block.py index 8d59c899..7cf43385 100644 --- a/block.py +++ b/block.py @@ -36,9 +36,12 @@ def tex_coords(top, bottom, side): DARK_OAK_WOOD_PLANK = tex_coords((26, 14), (26, 14), (26, 14)) #Row 2 BRICK = tex_coords((29, 14), (29, 14), (29, 14)) +BEDROCK = tex_coords((0, 14), (0, 14), (0, 14)) SAND = tex_coords((5, 14), (5, 14), (5, 14)) #Row 5 LAMP = tex_coords((25, 7), (25, 7), (25, 7)) PORTAL = tex_coords((26, 6), (26, 6), (26, 6)) +STONE_SLAB = tex_coords((27, 14),(27, 14),(28, 14)) + WATER_BLOCK = tex_coords((0, 1),(0, 1),(0, 1)) \ No newline at end of file diff --git a/main.py b/main.py index 3b7a4bd2..00bd85dd 100644 --- a/main.py +++ b/main.py @@ -6,7 +6,7 @@ from pyglet.gl import * # noqa: F403 def main(): - userWindow = window.Window(width=800, height=600, caption='Py Minecraft', resizable=True) + userWindow = window.Window(width=1280, height=720, caption='Py Minecraft', resizable=True) # Hide the mouse cursor and prevent the mouse from leaving the window. userWindow.set_exclusive_mouse(False) userWindow.setup() diff --git a/model.py b/model.py index e732fda6..86788939 100644 --- a/model.py +++ b/model.py @@ -115,17 +115,19 @@ def _initialize(self): # create a layer stone an grass everywhere. if (int(elevation[z][x]*10) < 2): self.add_block((x, int(elevation[z][x]*10), z), block.SAND, immediate=False) - elif (int(elevation[z][x] < 3)): - self.add_block((x, int(elevation[z][x]*10), z), block.GRASS_BLOCK, immediate=False) else: - self.add_block((x, int(elevation[z][x]*10), z), block.STONE, immediate=False) + self.add_block((x, int(elevation[z][x]*10), z), block.GRASS_BLOCK, immediate=False) + + for dy in xrange(0, int(elevation[z][x]*10)): + if dy == 0: + self.add_block((x, dy, z), block.BEDROCK, immediate=True) + else: + self.add_block((x, dy, z), block.DIRT, immediate=False) # self.add_block((x, y - 3, z), block.STONE, immediate=False) - # if x in (-n, n) or z in (-n, n): - # # create outer walls. - # for dy in xrange(-2, 3): - # self.add_block((x, y + dy, z), block.STONE, immediate=False) - - + if x in (0, n-1) or z in (0, n-1): + # create outer walls. + for dy in xrange(-5, 18): + self.add_block((x, y + dy, z), block.STONE_SLAB, immediate=False) def exposed(self, position): """ Returns False is given `position` is surrounded on all 6 sides by blocks, True otherwise. diff --git a/player.py b/player.py index b0caea43..daea5f39 100644 --- a/player.py +++ b/player.py @@ -189,10 +189,9 @@ def on_mouse_press(self, x, y, button, modifiers): if previous: self.model.add_block(previous, self.inventory.block) elif button == pyglet.window.mouse.LEFT and selectedBlock: # noqa: F405 - # texture = self.model.world[selectedBlock] - self.model.remove_block(selectedBlock) - # if texture != block.STONE: - # self.model.remove_block(selectedBlock) + texture = self.model.world[selectedBlock] + if texture != block.BEDROCK: + self.model.remove_block(selectedBlock) else: self.window.set_exclusive_mouse(True) if self.state_machine.state == GameState.PAUSED: From dda1416fd6357dd30a7ba444c4ed7c16b16c1c1d Mon Sep 17 00:00:00 2001 From: StephenieDugan Date: Mon, 10 Mar 2025 22:59:00 -0600 Subject: [PATCH 29/46] teleport blocks add/remove in list --- model.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/model.py b/model.py index 6bee88aa..046babec 100644 --- a/model.py +++ b/model.py @@ -164,6 +164,7 @@ def add_block(self, position, texture, immediate=True): self.sectors.setdefault(sectorize(position), []).append(position) if texture == block.PORTAL: # Replace with the desired block type self.teleport_blocks.append(position) + print("portal added to list") if immediate: if self.exposed(position): self.show_block(position) @@ -182,6 +183,9 @@ def remove_block(self, position, immediate=True): """ del self.world[position] self.sectors[sectorize(position)].remove(position) + if position in self.teleport_blocks: + self.teleport_blocks.remove(position) + print("teleporter removed") if immediate: if position in self.shown: self.hide_block(position) From 327df379d1f684a0350631bdbb2d07ac5974c5d3 Mon Sep 17 00:00:00 2001 From: Kyle Wadas Date: Tue, 11 Mar 2025 01:05:52 -0600 Subject: [PATCH 30/46] Updated Terrain Generation --- block.py | 5 ++++- inventory.py | 2 +- model.py | 57 +++++++++++++++++++++++++++++++++++++++++++--------- player.py | 4 ++-- window.py | 3 +++ 5 files changed, 57 insertions(+), 14 deletions(-) diff --git a/block.py b/block.py index 7cf43385..9f4abc8d 100644 --- a/block.py +++ b/block.py @@ -44,4 +44,7 @@ def tex_coords(top, bottom, side): STONE_SLAB = tex_coords((27, 14),(27, 14),(28, 14)) -WATER_BLOCK = tex_coords((0, 1),(0, 1),(0, 1)) \ No newline at end of file +WATER_BLOCK = tex_coords((0, 1),(0, 1),(0, 1)) + +OAK_LOG = tex_coords((4, 12), (4, 12), (3, 12)) +OAK_LEAF = tex_coords((7, 10), (7, 10), (7, 10)) \ No newline at end of file diff --git a/inventory.py b/inventory.py index 1554836c..9d027a92 100644 --- a/inventory.py +++ b/inventory.py @@ -2,6 +2,6 @@ class Inventory: def __init__(self, *args, **kwargs): - self.hotbar = [block.STONE, block.SPRUCE_WOOD_PLANK, block.BIRCH_WOOD_PLANK, block.JUNGLE_WOOD_PLANK, block.ACACIA_WOOD_PLANK, block.DARK_OAK_WOOD_PLANK] + self.hotbar = [block.OAK_LEAF, block.SPRUCE_WOOD_PLANK, block.BIRCH_WOOD_PLANK, block.JUNGLE_WOOD_PLANK, block.ACACIA_WOOD_PLANK, block.DARK_OAK_WOOD_PLANK] self.block = self.hotbar[0] \ No newline at end of file diff --git a/model.py b/model.py index 86788939..0d36090c 100644 --- a/model.py +++ b/model.py @@ -112,22 +112,47 @@ def _initialize(self): for x in xrange(0, n, s): for z in xrange(0, n, s): - # create a layer stone an grass everywhere. - if (int(elevation[z][x]*10) < 2): - self.add_block((x, int(elevation[z][x]*10), z), block.SAND, immediate=False) - else: - self.add_block((x, int(elevation[z][x]*10), z), block.GRASS_BLOCK, immediate=False) + y = int(elevation[z][x]*10) + block_texture = block.STONE + if (y < 2): + block_texture = block.WATER_BLOCK + if (y < 3): + block_texture = block.SAND + elif (y < 8): + block_texture = block.GRASS_BLOCK + self.add_block((x, y, z), block_texture, immediate=False) - for dy in xrange(0, int(elevation[z][x]*10)): - if dy == 0: - self.add_block((x, dy, z), block.BEDROCK, immediate=True) - else: - self.add_block((x, dy, z), block.DIRT, immediate=False) + if block_texture == block.GRASS_BLOCK and random.random() < 0.01: + self.grow_tree((x, y, z)) + + self.add_block((x, 0, z), block.BEDROCK, immediate=True) + for dy in xrange(1, y): + self.add_block((x, dy, z), block.DIRT, immediate=False) # self.add_block((x, y - 3, z), block.STONE, immediate=False) if x in (0, n-1) or z in (0, n-1): # create outer walls. for dy in xrange(-5, 18): self.add_block((x, y + dy, z), block.STONE_SLAB, immediate=False) + + def grow_tree(self, position): + y = random.randrange(3, 6) + for ty in xrange(0, y): + self.add_block((position[0], position[1] + ty, position[2]), block.OAK_LOG, immediate=False) + + for tx in xrange(-2, 3, 1): + for tz in xrange(-2, 3, 1): + if tx in (1, -1) or tz in (1, -1): + self.add_block((position[0]+tx, position[1] + y, position[2]+tz), block.OAK_LEAF, immediate=False) + elif tx == 0 or tz == 0: + self.add_block((position[0]+tx, position[1] + y, position[2]+tz), block.OAK_LEAF, immediate=False) + self.add_block((position[0]+tx, position[1] + y + 1, position[2]+tz), block.OAK_LEAF, immediate=False) + + for tx in xrange(-1, 2, 1): + for tz in xrange(-1, 2, 1): + self.add_block((position[0]+tx, position[1] + y+2, position[2]+tz), block.OAK_LEAF, immediate=False) + if tx == 0 or tz == 0: + self.add_block((position[0]+tx, position[1] + y+3, position[2]+tz), block.OAK_LEAF, immediate=False) + def exposed(self, position): """ Returns False is given `position` is surrounded on all 6 sides by blocks, True otherwise. @@ -138,6 +163,18 @@ def exposed(self, position): if (x + dx, y + dy, z + dz) not in self.world: return True return False + + def exposed_faces(self, position): + """ Returns any exposed faces. + """ + faces = [] + + x, y, z = position + for dx, dy, dz in FACES: + if (x + dx, y + dy, z + dz) not in self.world: + faces.append((x + dx, y + dy, z + dz)) + return faces + def add_block(self, position, texture, immediate=True): """ Add a block with the given `texture` and `position` to the world. diff --git a/player.py b/player.py index daea5f39..2ff6226d 100644 --- a/player.py +++ b/player.py @@ -15,7 +15,7 @@ xrange = range class Player(): - def __init__(self, model: Model, window, statemachine, *args, **kwargs): + def __init__(self, model: Model, window, statemachine, position = (80, 10, 80), *args, **kwargs): self.WALKING_SPEED = 5 self.FLYING_SPEED = 15 @@ -46,7 +46,7 @@ def __init__(self, model: Model, window, statemachine, *args, **kwargs): # Current (x, y, z) position in the world, specified with floats. Note # that, perhaps unlike in math class, the y-axis is the vertical axis. - self.position = (80, 10, 80) + self.position = position # First element is -1 when moving forward, 1 when moving back, and 0 # otherwise. The second element is -1 when moving left, 1 when moving diff --git a/window.py b/window.py index c587eb4b..9bb8d680 100644 --- a/window.py +++ b/window.py @@ -3,6 +3,7 @@ import math import model import player +import random from states import GameState, StateMachine #from collections import deque @@ -39,6 +40,8 @@ def __init__(self, *args, **kwargs): # Instance of the player that interacts with the world. self.player = player.Player(self.model, self, self.state_machine) + while (self.model.collide(self.player, self.player.position) < self.player.position): + self.player.position = (self.player.position[0], self.player.position[1]+1, self.player.position[2]) # Which sector the player is currently in. self.sector = None From 3852da6286637830075957be9a72425a31c130d9 Mon Sep 17 00:00:00 2001 From: StephenieDugan Date: Tue, 11 Mar 2025 01:39:52 -0600 Subject: [PATCH 31/46] teleport kinda works --- __pycache__/block.cpython-312.pyc | Bin 1464 -> 2123 bytes __pycache__/inventory.cpython-312.pyc | Bin 869 -> 995 bytes __pycache__/mmath.cpython-312.pyc | Bin 903 -> 1290 bytes __pycache__/model.cpython-312.pyc | Bin 17114 -> 19293 bytes __pycache__/player.cpython-312.pyc | Bin 15384 -> 15403 bytes __pycache__/window.cpython-312.pyc | Bin 20520 -> 20524 bytes inventory.py | 2 +- model.py | 50 ++++++++++++++++++++++---- 8 files changed, 44 insertions(+), 8 deletions(-) diff --git a/__pycache__/block.cpython-312.pyc b/__pycache__/block.cpython-312.pyc index 72933ddac613f1195d82dc6e2f312e97fa6d60b8..86d351f1a4c66d7fda4483710490308a30f42fa4 100644 GIT binary patch delta 1149 zcmZ9Ky>HV%7{=|yU$Gk}PTa&zDMbR&bfF*w3IZY7Nz{axIC5IG$`Tt}&|L%G3UVnU7PP6K1IxRDBovi;j zXbPWIWB8F}m@f=kLF_TxV^HFl>9Hu;OC*@rEaI@fCUFJB^pb?}NI)WG9AN@5fij*j z30R6UfiM|?C=-DVS)^c5D3Rb20#TMCER8^v$%Ls0M43WZ27xGBA}otQl%)yN5NJrD zN?;CwD9aF*MDkMD!aF83U)U;Ain;fMI(2>ewj;;;SS z4){of0h+_bkwAR33e#1ixZkS-?&1vmVmP0`K8yYGK!s_5I}EwD)2@encLz_(wmbgG zWrsq?sr4K?RH}|;+4aSu>X@zmp5xT|9ouZTLap0zcdPX{%34jg+K3bF#cq4s{wJiF zRkPYO(+ZV6 zbEoe1EgQmPnJ*1ZctHH{Zw(kPk}S*qNl2{C{?-*XcTr-bC67Coa-+&*-#-eZ`yM}6 zjY-ijPaA>y$W!K`HY!gV{$U_)dE7jeA2lY2Qz=M2@C2MR{K|AcP#;55TgADV6lhO8 zb*|r>98HZ^vr3>pJ7ctYeht^n%0d3=8I!$SrmKrIy)E4GjcH}J9~7RSG5P=cll9Tw u{xJU7SczR1VS)J^36uEBJ!{E>Q1%QU)1#0e=Ar7X)zt delta 496 zcmX>tu!EcLG%qg~0}x#Jb|&4CWg?$M{U#u9IztL?3S$dn6hjJA3quqm6GJLv3Nr|< zW(KKdV2EM@i?O7zrm(@qn89MKKrvRh7zjuaq-i?M;lI8!V+Q#j#* z>|jBz6d;6)ae&3RQ-BaI##zau$+vkGV;b{hL00uRkQ<96frKX0OIZ+G2ErCaVzVN# zK}uh;L)1ut*la+;Pm`&L3B(ZqNpKbM0jVN!ATe2+O}d`dDag~=`xaNYzrRa-fRCe} z_brxSM?aTaEIy9D0k_x!{DVRqeTrB>n)pEkFOc}fVUwGmQks)$SEL8zG6HdN6Oj18 z%*e?2nTdnZhw+mLH>1!;83s<_2^KRV7F1m3Flb=C$tN*Ge1XOa_se`H4cs@`1t+L$ q%SnwE diff --git a/__pycache__/inventory.cpython-312.pyc b/__pycache__/inventory.cpython-312.pyc index 363953a9ca729fdb6066726665e36070d8f0330c..54bb372fe905b9bd6c2be0f1f6c8cdd5dd933341 100644 GIT binary patch delta 439 zcmaFL_L!aTG%qg~0}$w(JfE(`IFYZ5n;ppG2jb5>j1w2{m@Lo8t;z>dfeO;uYZ&4= zU}7~4Spt)D8TIQqZ?Puj^qPq^OG1}NFO1%zdfmwLqLJqr)9c=e7rhg&BxhVtuDY09^@V|-UcfYYIg>-3FwlaP3`HV9sz?Y#u)qjrAfp%* zfGrH4nV4BsAZkF;noLD(FjYkoAQoKvFAkgB{FKt1RJ$Tcpadfj7lVxbz|6?Vc$UM_pJl9FC zD5lpFGAGXbU^Lq=s9qQ=TWG{FOE zgc`DL5Kmt(a(km-6-~aMZpf)Z&p1G?&EvBK5Eax`3gHrV{iK8)nf)h+a7a2^FjCTS zFIvK$4KS4SOupT{(so{#4eBX*ZhM;T6kI-sA+`5W4_vuI<(s4zRKFyU3RF~g2;m4m z^zQT2Y3gG8Dp}Wus!B~Ct>$XF@fa{#*Z{YScVs}wYkOha5mweLl(^`_I9%DJt5kGV zu4y*rH>f!?YZXNTi-VP3Wun}Lo)PkN2e0G)T}Q~rdYZ`E%(1+%w5WM5ERO8qx4clJ*yu4R=le delta 201 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 LeSz3W@?rl!Rx>N7 diff --git a/__pycache__/player.cpython-312.pyc b/__pycache__/player.cpython-312.pyc index ccd85c93eb735eacbe9f20414afd5d293ad75b9a..1e59e61876130c568df0d32309a6a8eb747ab5a2 100644 GIT binary patch delta 1299 zcmZvcPiz}S6vne&dzUuewxTUjXwoLCQ@V&KDAYoZi;EpQe_F>0i7Bd7;X3g&HQnr1 zZ`WXpgT=pc;DBI|KnR35REQ!Zkkw019N>Tu2U;YgxpL}-11H3Z_steTtNQTsn|ZTu zzIos5e$@S{>-^+6yNCE!F8sWG;#=pGX`}}$<~hS~xCYvkm$;UA6sAV@!wu#Tb5sC;M7 z=#yE56<`4<1Ixe?aGDX?jEVS1Ir;0JAGplNdvBWkDJ+R=air{)*d`%Dm1;&!f0mv@ z`Y3>d&^p82P4{hx8p`f9n*O#Yl--Sk2kJm4?&{z_$_;MsUocq9qX)O55wMBZ2N3;Q~$n#^_V~6$1O)uEGtgI_N-Zr8Mq>D({rAm2yb^eUJF;+5O zlz)wtpT1YIvNk(W6!>b_PS9#!YzqphgeRR)cw#FOtrAMp85xdetQ-pa^3(C(t?AFF zZ;i~ztB3z!&7C9C?5}dN<~juJ)BvEIE&y6JdaKNxW|z_S=_Mp4fXhhi4gAJV&lyCJ5Dfz# Z0`Wr}{r%8Met9~cD9~r}yL>%~%s;N_AwB>A delta 1320 zcmZvc&u<$=6vs2(cui`%tw=)@$Pb#jh;4wBRFO$jTAbKvqBN-Fm7@tb{b z-n@O^H@@5XsFVIKo!-+!&;8%O-iWNbXVmbh)OaXFQIh8>fYJcII+y+cQj!JG&3z#MQI zSO69YeuD61^oXqdZSU8V=I*|GM)D9sc5=1*54^F0^+CV}N(5_JAKBXOHXT>haZ-(dCt1>x~&+e{Qnd@6Y;I&j=)2lb$Y;fU= zm#{DGbC=fwUY|o^u_UjKWXvqmy7G&WU(AVH6F&?-D?c9nlg-G9fuZo$*d=3onF4Gp zEl|C94M6SUbwJmRb}FM;?GPF*u?dGRwgJaJuT^P!TRtZS4X-7d^wvr|++(esR#EHe zQ&6O0`d=B5_F{PF&=bs@A-finM+XjsKWDBO+htnYRw@#*AAyeoQ^0xPDPRED0v-p( zffPX{YM$#h>U>9e6{`m%Q=9X;V)baMbY&Q={|sJ%mOcbe?Na=Yr&maExjH=*mXCa% z(8W0mwlyX&m5RMA^gOY$VmZa~Dqb$-<_l4YLx?bo<;A51M}Liq7w4U|qW%UW+1^4|+{Ux{B z<>I;U@2RyI-GJ5U&x{I$qE@7ID+HC+qnjZv!+HmJ7kD4g>Ro}Q@28gVJz82uG&|Sf zLN&fY&{c%zXZEu`OoweTF)RJ!lhZFC>*zqHTlY{lQ{u13491do5=d>krQ<1wp@Nv+>}4gI=%4x17r&+8UO$Q diff --git a/__pycache__/window.cpython-312.pyc b/__pycache__/window.cpython-312.pyc index eff31be89d4775bf9219d7f05045a18b3ee28958..ffc7530afa48284f5ec0a4bc1d4924476f4faa6a 100644 GIT binary patch delta 877 zcmZXSUr19?9LGC)xmrtGfuWhXYZh*8u7`38O)O_Fn44xjNQg)b8=2F)E4pdfM1mfo z;s^bEvZn;KjAK3+u8b@pt)5D+U9*ox5t>)>Sd9Ntrju+@QDT+U z67f+pfUQ78AR-A^#8Ta`y7-U$I%eyDb^xf7Z+ ztVwuc9V_!&)721J3$C&_e^_8+@(p3DH|e`IH!CEhzELzQKkoB296nfHq29r6obR+X zGj^U|*%N1`VOT!Hr|pigi9?P859pd>uQVnk{XCFOpB#hcyYPE}d%y_w7hd|OqS)zN zt*~#&<`$--M%6yVGXk+qHSHnIqJ=G#~VSzugGvg#ChdU9iH zt1bmQL)w2OE3{a3HdjNpULXc^0o{P{XAM%!pSNusu?{Q(`+#L&g~t4Itc5NI+-#I) M1DPy^J_io{0VI#U@VU*?suj@A;kcyZ4^MjrY?)KN((U zWTb7A*YwJpVZ)g$TG48<{wNgDYD_y6YUPV+3AOQk)k$IgsOD0;_FJ7zv9-w-t0GF| zP3#7HKv>eENX+sQE|fa7pLx|}YelvLbSCs3U#;)7zpPTk`+!9S$1P8Xc9} z^Cz$($u5~zZ-XMqLq$x=+a~<&@JWiY&1s?u_Bsn>jySEEQMn?aJ6qopxm+)LIPP@F z?_F{Z5shoTB}Rn?`JPMNx%F@sdCoOcfGxyFmB zs63B;a8>yQOY$I6g+s1Oq}DYzCzSfuVEDh54gOl*nG?a&Zh&^s0XjkQr-}15f9}3< fj2FQ&C Date: Tue, 11 Mar 2025 02:06:36 -0600 Subject: [PATCH 32/46] Added More Variance to World Generation --- model.py | 52 +++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 39 insertions(+), 13 deletions(-) diff --git a/model.py b/model.py index 0d36090c..fc0559e7 100644 --- a/model.py +++ b/model.py @@ -99,7 +99,10 @@ def _initialize(self): n = 160 # 1/2 width and height of world s = 1 # step size y = 0 # initial y height - f = 2 # frequency + f = 4 # frequency + a = (1, 0.5, 0.334) # amplitude layers + exp = 2 # elevation exponent + adj = 1.2 # adjustment to pre-power elevation value elevation = [] for h in xrange(n*2): @@ -107,33 +110,56 @@ def _initialize(self): for w in xrange(n): nx = w/n - 0.5 ny = h/n - 0.5 - elevation[h][w] = mmath.noise(f * nx, f * ny) + e = a[0] * mmath.noise(f * nx, f * ny) + e += a[1] * mmath.noise((f * 2) * nx + 5.3, (f * 2) * ny + 9.1) + e += a[2] * mmath.noise((f * 4) * nx + 17.8, (f * 4) * ny + 23.5) + e = e / (a[0] + a[1] + a[2]) + elevation[h][w] = pow(e * adj, exp) for x in xrange(0, n, s): for z in xrange(0, n, s): y = int(elevation[z][x]*10) - block_texture = block.STONE - if (y < 2): - block_texture = block.WATER_BLOCK - if (y < 3): - block_texture = block.SAND - elif (y < 8): - block_texture = block.GRASS_BLOCK + if y <= 0: + y = 1 + block_texture = self.set_environment(elevation[z][x]) self.add_block((x, y, z), block_texture, immediate=False) + # Add tree if block_texture == block.GRASS_BLOCK and random.random() < 0.01: self.grow_tree((x, y, z)) + # Add bottom of the map self.add_block((x, 0, z), block.BEDROCK, immediate=True) - for dy in xrange(1, y): - self.add_block((x, dy, z), block.DIRT, immediate=False) - # self.add_block((x, y - 3, z), block.STONE, immediate=False) + + if y > 1: + # Fill below the surface + if block_texture == block.STONE: + for dy in xrange(1, y): + self.add_block((x, dy, z), block.STONE, immediate=False) + else: + midpoint = int(y / 2) + for dy in xrange(1, y): + if dy >= midpoint: + self.add_block((x, dy, z), block.DIRT, immediate=False) + else: + self.add_block((x, dy, z), block.STONE, immediate=False) + + # create outer walls. if x in (0, n-1) or z in (0, n-1): - # create outer walls. for dy in xrange(-5, 18): self.add_block((x, y + dy, z), block.STONE_SLAB, immediate=False) + def set_environment(self, elevation): + block_texture = block.STONE + if (elevation < 0.1): + block_texture = block.WATER_BLOCK + elif (elevation < 0.2): + block_texture = block.SAND + elif (elevation < 0.6): + block_texture = block.GRASS_BLOCK + return block_texture + def grow_tree(self, position): y = random.randrange(3, 6) for ty in xrange(0, y): From 774d3ad157109563f7ab53487f43d3b44e5b5fd9 Mon Sep 17 00:00:00 2001 From: StephenieDugan Date: Tue, 11 Mar 2025 19:05:15 -0600 Subject: [PATCH 33/46] Command Line inputs p.1 --- __pycache__/block.cpython-312.pyc | Bin 2123 -> 2246 bytes __pycache__/model.cpython-312.pyc | Bin 19293 -> 22873 bytes __pycache__/player.cpython-312.pyc | Bin 15403 -> 16314 bytes __pycache__/window.cpython-312.pyc | Bin 20524 -> 24483 bytes main.py | 3 +- player.py | 12 ++++- states.py | 1 + window.py | 69 +++++++++++++++++++++++++++-- 8 files changed, 79 insertions(+), 6 deletions(-) diff --git a/__pycache__/block.cpython-312.pyc b/__pycache__/block.cpython-312.pyc index 86d351f1a4c66d7fda4483710490308a30f42fa4..0a13aae9d88498e1716db6843a99f7f8c50d7b3d 100644 GIT binary patch delta 233 zcmX>ta7>W*G%qg~0}xnlxsbkYBCjOJGDZf5=?p0{8}%v}b(k1Z8B-*IP--TpittSU~FeK?E<5_{Cw9o1apelWJGw3giNv$WUyuS({yw nQMrNpA(zO6@EPd~$}e;2H?ZI27M+kjqkIMXWp0B;4zLjbQ;#$R delta 110 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 O@89+h0{`ylgG_0Ab}N@l`7Kf+)6dTOZU*a2wf7 z#xnG{Sr?aK;xbU&z-yu(%r=*qIZYhSxoM-uWSYf&89MiAOV~LrD!62EC+Y8=|MUD` z=k(TTxbp!-UNIPSh^#aBzi<7!Xf(1!4{zbM`qV;`!1ls=jbIYg zTv$a?;HIX~m-|$kd!~)g$0lu@9$sG^i)5XkB9p+-cD69PkXJA3U*ItP&=)f$6`i1; z5@vQN%*h_C)yXQE_metK3lVLL3l(=7ybwzci^w^ZA#7q%7jH4(eWuD>T99AEhWAPz z(u-4WfgsnmV}~fTxqM>X!@njbCLYETL6wEaYvN`>8}5lS^{}$Fu? zuc!!WZDsZvx?%0BYwCi!+PdnhGG}e2)n+kBi-`v*nm`b|Qe^1c66C~oahJ>2=5YsM zYY=t^8TTIY>yivqJBn&CLYJ3PsZ*B}gB#*glOB+}wGWL)AVc(ixXBx)0zMYMw&!+w z=BM+H%^P%$qz|=>xXz`Iwp>py?&kt&2l#;FVALZmic1++quAsp(I_?{0D<`d*Wr}? z*4w6;0c)UhAnmZTAMP9D1KdE`5q`jNBx;bkmXLkjNPPZa%)4n!I9zq0YQTEjJGgYj zF;sL8hDy&ZxHhl&dS=O2&@+}{`=;#MH5b;5t#|fU-7q%Y`)`Ag{?GRMYxepvS4)4@ zkH*&f=G1|h<0}Tak+dP691(Snxt6u;`s~7=%tigSoAHSxkKH#Dl0J?+5;+Ki3kEv} z{AXT0TRd8P$(|L6ypiCz_b=hH(PfuRR8~FCp_#?wJWe(z!+l(6UI;1JV>aV=OE~3X zx(=Wgk7dk-$Ypc=y34ft)AWC=OP42hQq7pKrt`V#Bc!ZZ zMk*!|u|+jCJ;LzPmypC2j;IYou?aLvd@%#y$L5mRuost>#6g16P~rwnDCZ`8xzrA` zl&IzH5Zyz}!&RUKkoMtstoe|soVVU(@*dJING1Xnkm${p3JFwM)IpV3^hs9A*-7CI z3cdI{`y&06(vh5I;N&tMUdP#GHpo|Yls!-(b1$%Dw0@o1&ii*ajKu_3(HVaB9;Zaro@I&ZwY9a=8W14r!R0 ul;eWN4dzf+XHxnz3iPFx=2ED~LydXxCBD_@iRn~B(*E*45&cRti1Z(qKu2`| diff --git a/__pycache__/player.cpython-312.pyc b/__pycache__/player.cpython-312.pyc index 1e59e61876130c568df0d32309a6a8eb747ab5a2..d928b444da1af406497f4e65456c15feb8a4a0dc 100644 GIT binary patch delta 1879 zcmZvcTWk|Y6oz-a-ZhD@!7)*S(-5#JCM0natYDHhIKDt+$0Wp}BE1;LyCg2YgjuH~ zh&Hr@O1(%0jVc-`E#(1G%0r7*su1dHRkgejT9jyn)EiWyQl+%K^`YvVS*QwPq7>vnssz{bIEZcH2tU2)W*r$w;YxSwJ;E2zR4QiL&+VpEVR9x^GW zd1=h7*hvg^uXRv)xR{$&F_lUcMJ?tf{cSXlOvlZ{DYmrK92c@~9*jY$Wmf$|YeG=0 z`jB`4Ase}9?$CcTA3!@S)U2t+L)gZ=@KX%brd4xQwUonCjMOtKH6HjqU}W3U^hQ9ukZ z0N4#k0QN8#fj97hd&phK*DTCs=QYu~30xk;nsV14+zWOqAPpF12-M=oPJm6+GMmkn zCyFYy%ovj=9t?UI=K^t$e#f0a?C>^Ev&G*6aU`A;Eb*AbsmOuB^lt2D79Ig4Ny!^( z@^a7dVkLi=%2TuK*eXvc?k8V))96KFZI1OkdP^#gPgkpzGOb}^77i6utl?b{#?Dkx z^Ho(DfN*$_yw&WJd*H01{zdaLyB%rsH0tMDj)`+a>~lI`$8b~p5&-UrUk30yLh7hk z%FQqo%6JkMKxwS}wwgDQpr>BH?K>&XjWRnOuoWNz8qfrQ+T(>uE%{2ZSWwgl zDpQkEWs*#(szQ-sR1m)zl+pi+EY3^~#I-%5?(bXnLjFcVji%dcNHG-9U*FncM&FSi zJ4eVr9cRqPQB@#AW-mD%l2Dv{ysm-#WO9?vV1!i7Zrf$VLb8E`SxJAtb2}nuIzzAm z{?4ng`{8(HfQ+;^pcaUMV&qD@yH!%;CV}-O{5n2nrAKxo_zui>43eKs_2iRv9=7*L z&`WxQ?~0aO2l=CQy?!U?MLe&WL>gyUq<|koYf|()=CzMTDT+`OqtfVbBpNqT+z1|W zYIM(FBE!|7QYxC+m*P@TIX)VV49AV)m;hHX6B)qI@L5qUV_xF&WTiTu!#FR@v2;J7 z>ZmP0$=XiM8ePNdO@SDa`l?#4QhR)VJe|qziKJtxc#NVbwMF+14KXvD8cfG&%|IlY zssqkGd^kzDM z0^&V*IPXD!;13xB2=@|gXJ>i`d`SZMOyx7GD5cs2l_qHvzP(3|n~!Ia1N2xkAq{d-LxdmX2X V>T~!4`M!71nUawIF9FD%{snP_#*F{~ delta 1477 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 delta 3593 zcmai14Qx}_6@J%0&ra-^5a-7MJGDbX;t&!NlA=&B0h3Z72@oihF!FHxUW~!9z5AY% z;Gpp{)PYu&Wv80Du9{kP8;eL8ZMtcj)^*)ai&jcIX=|rP*TR^fS%1U|T{|kI-E(b| zgl*cB{Nc0+;eZ9d5KIsMI5gc6yyu+`lD%-MwhTI2o$!RgM+#wyxdi@N>$FXf(?;|z2m}%aS60FXSG-QRU??RA z$Hq$jr%=a6Cv+Q2s}2hLDl$f9;tbP*=7S^i-Eg+l>NqG!g*h>;8b+48;ipCy{MqDd zEz0p_fk_q5qDpd91m{X~l-2+Z>)qfo7w5?a*(jT2^Feq{ELkX<(`;L1QMSm|iM-R+ zi~>`gpHpQ~x53jrZm-smW9?g>8%_V+w~}wxYa5*oIbZYUCib<%g^p6FwH6p`-LS#B zfaox09U?xk=G_PVd81I2Ujf1VFWhdXlAg088kZBp4U!a%M>R=uFs6ExK(DRAa9xBq zZN+fL_6Q{Hjf|Y!T=1yThFeOPA=JWDVMSpb8|v0%LXB$CM4Z+`(cHFWZOAmp8m-3x z8PtiSn%U5cA6>~t+(fz{>pzv0Lz)tRqjS%Z0PK0F9OR;(k@-;JT;xGpvph$?(g_33d&mxW*jYsalc$~EA@|K;^HT-{69e5i)Ew>h=h3B%pqL-J7}=t%#1u`@ z&BIYy+e@2qq7jaicxt)3tw?hwCYbB#B(92#z!l&c;FS_D>4R$}z&wwZzCa991e#n= zESPOTw+=;>;bekpD#nx5{n#~+3_@P{H`r=NOUoxG%P$$oPI$~+xoH=Z(yftLM?BOY zQ|NB=--jR}>_G@2^dp2B=#EG%wOOHRQVDC(A-1N0SR$lR1qJHB>}d`LQOq8RZKI*M z8e=;>;J47(anb=4pRwAsYGE9VmwjxxY0o@ylyTHs;3#*&^Pa2j03*YMLGHs8V}5R& zHNfrWn#qe5Ck*hu?_Tdt#_aYN>E>`u2~nysQqPOTf{9pyE|pm&1uCnXBFN2`X=qrA zh5D74Zs%jFXi=s{vG8=Ws&G^oT=Qh!Jb?;R(6eJVzm zDLCDdh)ZZN?Z_5gmVT6ps2>X8S}s}5HBNxxf^vXKd zcXw>1M^JfsPw7EMr=8jToSCg(z>|v>F>B{*$|o-`sv*lZGs$c0$G%Iet`(nIcR5{r zbrqe*Xo}T=$!Fi%_UvF=d$->~qp)i6n0=;KcxSPf{043>eu!D$-thhY$C(!WHo_fS z-F_2Rdk|}lml%z*dEL&^5`3_e6QN_z~!Z@{=fekkXp)Z0%69p{;`EV+0tq` z^h@-}0Wa;TZy{hCA2-pLaB3R(yc2C;Zg>g$jhQiLAo#@@XLb5YC`W}622*^54Tu&X zS%tZyn-DMtT@3T(ja#S_dBq6R2eAxE7Xr7nk&VX9*?D+mg)4|`UF=cR)SyC-F=Fa# z4AOJAq@tQvOL)6j5qP^;%kx)cIt2D2-Mj|-A1_C`3$Cr$De`8}1oy9OF67?%N=lh5 zZHD73j}&IgSQ*ijxI8Y>HYg8hRlF(v9R0bnr4ptJYrWERr!`GJ7uaabo{WhtNqBgT zXDP2c-m2~4y`gwSk!E!4N_2X6J?ik*8XxI_&(}0$ZM6q?)nom!=7pB%6hfxu|2G5g z!mGh*vK>BRn7K~t*LtiaFQP0@_^)vEGQzK+ue0WoRxI0Im3DDM4VS5VC%imET z0R26Eex4*FU%GA#C6l^I8HsBDp?yn$sh$e&_n5X?$g~d&@7Rk@ZaA^wy(7U_(5I##Y&r9B7cOV%-&=8Iyq!I8b!mpo9BR`F#7r}>sJ&sl(V7H+)2w2Qi zM|c;Z1>rMM}K~#A1@L& yMncG6gnO Date: Tue, 11 Mar 2025 20:34:22 -0600 Subject: [PATCH 34/46] Updated Terrain Generation & Improved Inventory --- block.py | 1 + inventory.py | 3 +-- model.py | 23 +++++++++++++++-------- player.py | 8 ++++++-- 4 files changed, 23 insertions(+), 12 deletions(-) diff --git a/block.py b/block.py index 9f4abc8d..6bb9e18f 100644 --- a/block.py +++ b/block.py @@ -38,6 +38,7 @@ def tex_coords(top, bottom, side): BRICK = tex_coords((29, 14), (29, 14), (29, 14)) BEDROCK = tex_coords((0, 14), (0, 14), (0, 14)) SAND = tex_coords((5, 14), (5, 14), (5, 14)) +CACTUS = tex_coords((15, 10), (15, 10), (16, 10)) #Row 5 LAMP = tex_coords((25, 7), (25, 7), (25, 7)) PORTAL = tex_coords((26, 6), (26, 6), (26, 6)) diff --git a/inventory.py b/inventory.py index e3e3a737..21d587ab 100644 --- a/inventory.py +++ b/inventory.py @@ -3,5 +3,4 @@ class Inventory: def __init__(self, *args, **kwargs): self.hotbar = [block.PORTAL, block.STONE, block.SPRUCE_WOOD_PLANK, block.BIRCH_WOOD_PLANK, block.JUNGLE_WOOD_PLANK, block.ACACIA_WOOD_PLANK, block.DARK_OAK_WOOD_PLANK] - - self.block = self.hotbar[0] \ No newline at end of file + self.index = 0 \ No newline at end of file diff --git a/model.py b/model.py index 314851db..ea273f87 100644 --- a/model.py +++ b/model.py @@ -100,7 +100,8 @@ def _initialize(self): """ Initialize the world by placing all the blocks. """ - n = 160 # 1/2 width and height of world + n = 160 # 1/2 width and length of world + h = 0 # y-level for bottom layer (bedrock) s = 1 # step size y = 0 # initial y height f = 4 # frequency @@ -109,16 +110,16 @@ def _initialize(self): adj = 1.2 # adjustment to pre-power elevation value elevation = [] - for h in xrange(n*2): + for l in xrange(n*2): elevation.append([0] * n*2) for w in xrange(n): nx = w/n - 0.5 - ny = h/n - 0.5 + ny = l/n - 0.5 e = a[0] * mmath.noise(f * nx, f * ny) e += a[1] * mmath.noise((f * 2) * nx + 5.3, (f * 2) * ny + 9.1) e += a[2] * mmath.noise((f * 4) * nx + 17.8, (f * 4) * ny + 23.5) e = e / (a[0] + a[1] + a[2]) - elevation[h][w] = pow(e * adj, exp) + elevation[l][w] = pow(e * adj, exp) for x in xrange(0, n, s): @@ -132,18 +133,20 @@ def _initialize(self): # Add tree if block_texture == block.GRASS_BLOCK and random.random() < 0.01: self.grow_tree((x, y, z)) + elif block_texture == block.SAND and random.random() < 0.005: + self.grow_cactus((x, y, z)) # Add bottom of the map - self.add_block((x, 0, z), block.BEDROCK, immediate=True) + self.add_block((x, -h, z), block.BEDROCK, immediate=True) if y > 1: # Fill below the surface if block_texture == block.STONE: - for dy in xrange(1, y): + for dy in xrange(h+1, y): self.add_block((x, dy, z), block.STONE, immediate=False) else: midpoint = int(y / 2) - for dy in xrange(1, y): + for dy in xrange(h+1, y): if dy >= midpoint: self.add_block((x, dy, z), block.DIRT, immediate=False) else: @@ -166,7 +169,7 @@ def set_environment(self, elevation): def grow_tree(self, position): y = random.randrange(3, 6) - for ty in xrange(0, y): + for ty in xrange(1, y): self.add_block((position[0], position[1] + ty, position[2]), block.OAK_LOG, immediate=False) for tx in xrange(-2, 3, 1): @@ -183,6 +186,10 @@ def grow_tree(self, position): if tx == 0 or tz == 0: self.add_block((position[0]+tx, position[1] + y+3, position[2]+tz), block.OAK_LEAF, immediate=False) + def grow_cactus(self, position): + for ty in xrange(1, random.randrange(2, 4)): + self.add_block((position[0], position[1] + ty, position[2]), block.CACTUS, immediate=False) + def exposed(self, position): """ Returns False is given `position` is surrounded on all 6 sides by blocks, True otherwise. diff --git a/player.py b/player.py index 2ff6226d..81a99040 100644 --- a/player.py +++ b/player.py @@ -187,11 +187,15 @@ def on_mouse_press(self, x, y, button, modifiers): if (button == mouse.RIGHT) or ((button == mouse.LEFT) and (modifiers & key.MOD_CTRL)): # ON OSX, control + left click = right click. if previous: - self.model.add_block(previous, self.inventory.block) + self.model.add_block(previous, self.inventory.hotbar[self.inventory.index]) elif button == pyglet.window.mouse.LEFT and selectedBlock: # noqa: F405 texture = self.model.world[selectedBlock] if texture != block.BEDROCK: self.model.remove_block(selectedBlock) + elif button == mouse.MIDDLE: + if previous: + texture = self.model.world[selectedBlock] + self.inventory.hotbar[self.inventory.index] = texture else: self.window.set_exclusive_mouse(True) if self.state_machine.state == GameState.PAUSED: @@ -297,7 +301,7 @@ def on_key_press(self, symbol, modifiers): self.flying = not self.flying elif symbol in self.num_keys: index = (symbol - self.num_keys[0]) % len(self.inventory.hotbar) - self.inventory.block = self.inventory.hotbar[index] + self.inventory.index = index if self.state_machine.state == GameState.PLAYING: if symbol == key.ESCAPE: From b93b5b51fb53327345b1faf17535561f15a72816 Mon Sep 17 00:00:00 2001 From: Elijah Kelting Date: Tue, 11 Mar 2025 21:29:23 -0600 Subject: [PATCH 35/46] starting the inventory bar --- EventDispatcher.py | 17 +++++++++++++++++ __pycache__/block.cpython-312.pyc | Bin 1358 -> 2095 bytes __pycache__/inventory.cpython-312.pyc | Bin 851 -> 1241 bytes __pycache__/mmath.cpython-312.pyc | Bin 903 -> 1262 bytes __pycache__/model.cpython-312.pyc | Bin 16928 -> 17053 bytes __pycache__/player.cpython-312.pyc | Bin 11976 -> 15417 bytes __pycache__/window.cpython-312.pyc | Bin 8498 -> 21074 bytes inventory.py | 10 +++++++--- player.py | 2 +- window.py | 13 ++++++++++++- 10 files changed, 37 insertions(+), 5 deletions(-) create mode 100644 EventDispatcher.py diff --git a/EventDispatcher.py b/EventDispatcher.py new file mode 100644 index 00000000..69bd4881 --- /dev/null +++ b/EventDispatcher.py @@ -0,0 +1,17 @@ +BLOCK_CHANGED = "block_changed" + +class EventDispatcher: + def __init__(self): + self.listeners = {} + + def register_listener(self, event_type, listener): + """Register a listener for a specific event type.""" + if event_type not in self.listeners: + self.listeners[event_type] = [] + self.listeners[event_type].append(listener) + + def dispatch_event(self, event_type, *args, **kwargs): + """Trigger all listeners for a specific event type.""" + if event_type in self.listeners: + for listener in self.listeners[event_type]: + listener(*args, **kwargs) \ No newline at end of file diff --git a/__pycache__/block.cpython-312.pyc b/__pycache__/block.cpython-312.pyc index c8359db074266e18bc1d4ba40734af5227c49e8c..753b452c6583ecc2be0ff5a2787c1f0062b78812 100644 GIT binary patch literal 2095 zcmai!PfXiZ9LJv>$8lm32uVYLb@jBW1F55Hr)`W?ot%V!BM_88sSpyPJda0vN(&KFUN4;WB};HVol1KV?A-;j#c_Aq?R%k+OCS z;j%W$IxvLGf|P|Zgv&ydbz%sYwNnI`xGVbvursSo{SK>?L z;&x%y1?8oLj8e5CFH9EKm1S*d#aMW_sxE&wu(9L#A%(?dRn@Q- zf@R>uB0U2)6P*eu*irsqf7Bd40&#nP&Kx=N2cFLEcbf?!?(g@25Q9&(@*T_jY{=3o zcdFiBhN{}Z$jcvoO}u7b-~Uali4!$$;tZBV%jc(^Xhcdv%kTokb7YV=(^f)1qrKKX z1AV4toP|D{M|+-<=iAm5-TAN1*J99rIGF!+u$UobZ}ri#jyKD?B&`;8YB8)jwQW_n^mrp4d`d-t~)%O17#iebB@PQHypk(#o>tG;Wb6yTs3qu zfs|Maf^Y(E;dHGF032bY=ip|dzXc>l%ekkw%;cM3%;IaoYv#xsK)5FMnyI5;J5-Vj z{51J^vi#v87i;Pphg^44U$?@~`VP6?BQb1FYVEM@R6kpfz_U&|pjmim-3{GII5|JS z$&c}zYjL9AYw&1`?s?~_Uuog77EL~?Ik$Bk^2&3rU3;hNS6ej5rl(GR$4&or&~+c& zVB^W$I{dpy&b{zxzKf*W^xq&Ja+<(TzPH{%^c7k(y6X-%m6;lLytx_j5J$6eF1MIS zXOa^Rmm1H`IQ(=bHJ?d4VltCRq=y^6P)43uoXccVi_>X&YQhQUrn9rj;a1d<7|$lh zT1ohu*{RX=1yfi~%E@uL)fGv}*@?wV>w6Q~amdJ*7*1trYB_l-<#1_va+)NVosrW{ zfTp&XOUnsIoRepUvyJc2$g!gbfS$Xz!re6$Z>}o$G#LiS-so|-pL!UEIb#JT&HNP= znasHpZQ&EsdmM^eU6sD-m>v4e6pwx3a-TI;DcHVSCU@+Ql*g<> zRj~cHO`bU8mBH!*JM=j?!@b0JAlTtA&Cqf5eQUcKKNz&5cWWqo9JxxS9rW3euWG2{ z^5`XVOsd4Ig9i`n*u5HxTuLtxEzeo`%9b6tW%@{ZA6Z{iMs43s_>c=dlI*B8SIOJ{ h0h2!oc3A=}+h+$qH3KJ*daS}%9@(LR$0FUie*kBX?YRH| delta 804 zcmY+B&ubGw6vt4Hv)}jT?aZeeKiyM5d_FgV zb&>m?+mPE+^MUt}y+zbZ@e$4-DjlH=mXL+1ObJy!%0i7$d-=|D7X=%F3~@v%1sgHN zVHyP+F_*)13N~WuNar3gt?CK-1_buX%AHd@y&i`U2E%o!=0WI{Tt{`era(mM_&QSR zq%K^pfp#LgBI2vunUj)FT^v_9u5w)DxWFY^0k7IFC|hvWWh}d7KCvxko2jz(a?dK} zEi+Qe?iZ|L**4RAc}AaEyUg4UnQN82UCtMCt0ii6zDjpfUTA~C?I=7N=v+g(x4C<) zHjH1oySaTl(^&Z*czjLP3UzTi+zoYE&v1+No0{F!gn}qhEb(7Riw1WV8!eUgjtlYP={Iy>r@gMXOdwE!V!o z40BWNr(f%z8D2Gwj1`?;ZL0&dtLpdzI8c_giyWw@3!%$h37&}ufa$t701a?+-Yjlbo;K%T2eQST~AleL0HG)$gGtKFA zV>*45$u={kMy7P6>1O~H^pN{wiN63bZh@o57$-3!6DI(}E8L#&`pWUmAQk@Op^^I1 z{?hxv{?k3-jkiVbf}Fj-OyS#KYla@`bU;OB?V=*{>Y{3A9S__25YUmLgveVx?6;eX z74{bpmP15jfC`;OjFCag4PUMxX?X>k3$S_pqDf9WTTuNPWjk=}@xArG@;5!>4bS+& z%Ws~$WQYO@(ZzbLNo56N!;5jbB5#z~*@yA74XI=yge4*Dzx@DaocRdC24ON*l+G4@ z7fw0e6>NEtYtnLLKB7R_)*JpPD=E_19_022{g(g$ delta 487 zcmcb~d6|vxG%qg~0}!xeoJzmTFp*C}M*+y2&XB^8!kEJl#lXbi&XB^?!jQtenhB(i zfgy^ql2Mc8C5Y)aF<(qo2*{YukO~w}VTfW%VQgWDVyGD~r4PTDP&#G>@#TWs0oAi9_tXr_XK!Y|)s ztC-N@)S}{;;F8pWjMTi$)EJli;xab-DLK?=7O+r8Y|K3EdyHGwO`!d6|Ck$k-WGE5=QbnN9 zDgs#pCP0oZW(N{244;{pSydovK+>8_MIdpAQV9?XuKgE>O>TZlX-=wLkt9%p5r~UH Z#(rRCWMsU}!1JAjg;C`b1CRjg0RZMjg%SV& diff --git a/__pycache__/mmath.cpython-312.pyc b/__pycache__/mmath.cpython-312.pyc index 4230997d2e27f7582e0208f89436ff0b09fa1dec..6eb7d1c06de422d116c7028905085f04e1a85ce6 100644 GIT binary patch delta 635 zcmZ8e%}X0W6n`_D-6UNjnp(jYB}8c5QiYbDf>e*a_(44gA(w4tx?S1XU1lSgAjCtV zc&dqha%N=zLE+YR9zBQdSQu;AsAsj7znfIO_*e*q+VwUg*0!ktD4xq#_&$o(@$&+^5+*MIWGPQF-Zzi;zy{$1CY-O=tT RC2#LD!{kM;VBnV&?IWZRiVFY$ delta 273 zcmaFI+0JfrnwOW00SK%%9ZwfyVqka-;=lkSl<`>r$e7NM!qCDH#gM`XBpEB2G?_O~ zW8BXe^UE{YDkiizwWv5IxFoe8BQ-BGHO3`BximL5ucSC8BqOsZB{DU!C??P-#snt$W@G!vza}ZJ~K?- z%A6?32^6@+nw*oETTmnjWD8DKXVLKC2D1D#nZU}y!bQA5ks^?A5lF``4x8Nkl+v73 gyCNYV7v!U2ejxFInURt46B8e!=w}5sMlrAk0Gs(lUH||9 diff --git a/__pycache__/model.cpython-312.pyc b/__pycache__/model.cpython-312.pyc index dc262de21939441e3b8210e8f11a6be3b9ceebbd..ad2f93cbd0c248e1ff2ee240bf36bcaa5b93fbbf 100644 GIT binary patch delta 3144 zcmbVOeN0=|6@T~n*~a!WV6ee44#b3n7@DNed^&N!#12VDoPr?>`Ka;w9*zmv;o2kt zJw~@?653d6daGjAb#b?9F-kWj^`xcJ{@A2xtF#Y=hA!wSS|csf#H3Y8+WpgM&CY#} z!DN{>?MeRKbMHN0_ndR@arzQ^>l?`U8>3Orz!xk2UHHLu@++<$S+k#TpR3Wc*(JROp;xl^4F+^3;h;+Bm#EE+K-Dc%8}rmv zRgOZ;QzbU#`4Uf&keGo+GVQYI5Hrd+k>6QCYK>p*EeQ{Hix-~{fxlux#1Yxp-VyBf z9q;bx@&%i{vZY{pJT zS5*03<3j!3pA9S&9lBFEA??NW`+g5cn_&brjs$j`6;$IYfg9(-%(yy%^2d^pz>TRH z=IY}WFLU}7!;EVrHF0b*9~V?%Bq7SMnhl~=prSx{8whJ9Eyx%^Mm+|p950eItLD0d zn(!w3gv3cjR5gq`#RoR$m86z5Yk-urdjY3*aLm*TT!BGBB_WB;C(g?x(dpA*M!(|H zQ#cL*hasU`KDSz`H7G{(6a`IT5CrZlxPo^{Bxf?YyQoG>zyu=Htvry4^qvDZHFY%APK4=23b%kC} zZBck8mU;4#8!+dom2tJBQ{5aR>1hrGmKH!id!C6KB*POcY!XeG3J#?g33dukRSxVG8lXDtgOxrT)^Y^%7*qXPaqI%o9H;Y|4XvA&FAf+1m``})h+7- z-ADbtV4%a(<}~8%pc9u;#VC%8m9byeiG$+#P$CkG%IJ)YF34>3BK$_Nk#d(%E>;+g z)7iSh51Z)za{yzeBQZgo7~B$!L?ekvXfQG+24Ow^XSmNVG53oYW9cMX!R5@9;&CxS`;N9Mk}|6Ra$+uJkm?YSB1 zPx=?k;d{1qY12FVGrDVzIUY=u++gQ7xo*|%`Gak5vTd<)4V>e`qSb!6c(yo$GR>Lc z^w>|f|I~fm{ed@C{E_u==iPtXbX|9SV4<5w@9UT<_kEr*TT-T!Cl#9ApDLPmr#%@* zrZY1<7syzDaO7TfUAik%_Pr>1)m*vu_RjYCo$WUR$EkepLlslA`C$!HvEhM=DRYpy z#wxP5;%{g>d9bch0~K-+calw&P3UEEqB5d?0Wv?sNNj>3(|hcC<$*w>@a&VOy%k00 z8C(W^PD_TZW^%NaXC;=dlg+hS(rLG_0|wH`m)FpeQ$7jhyFr-AU*~}mkluhyfOZWw zfx2=aYgEjD1;%RfW4rdfH9thW0eeA*%=zISkSjK)7PrD2A0x7D{R!nl*y+ADAzn<3 zU=h>y5a$4Bt>UWw9|hF%gTF6b#*1WlHF1L9o7+`JWdM7D8PHg;FA>k0Gv8Zqix;P zO;}Jv*Ku+HX+cN`*LodB25k(dOzFYxXG?xKB?jYhTit%DNmA?It%)3wx_NM zaYrD3?1Hg*_Rbe|@T^{rMBHgazQJPGkLu?x9p>*MUp z^{=zme%Qq!YJXK6`pDJ>3;HbUYhaN(2HUa*;tl_Goa{>c;`C9?r{x^b%Vy3*1Tkku zlfBd!MMfonGkL7fo9Y1xX>hnrqN`a=f_>RcGI9R;%HW#6?uX zLVJ#YUL8Mb#KCP%!H-6eozS$Zsku}gjh1d|DrLtb~&(@PRC1F)`{w4+5Ycc)LjRORG nw(8#n65_|iW8|u5qZ%3&rzH!XJtnUj*(VSDouMNx2abOM?7{ML delta 3022 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 HDV+ZUh*#yn diff --git a/__pycache__/player.cpython-312.pyc b/__pycache__/player.cpython-312.pyc index 45149d8df8945c79f0cd1514b09d575d11d37416..1a87c980be1214bd62beae541c7ce6256dd2b9c3 100644 GIT binary patch delta 6216 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 Gul_fTzKPNR delta 3416 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 O%ts9*xWXaoCjSGJXglEm diff --git a/__pycache__/window.cpython-312.pyc b/__pycache__/window.cpython-312.pyc index d157655c875674010d93d78ae61ac3f85424f093..6d6e019353417aa4cfda1327867509568e426acb 100644 GIT binary patch literal 21074 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 W@%pv5Cf|~LA<-B5UlgX0_WvJ%d)dzb delta 2099 zcmZWqTTB#J7@jli%nq{`ki7`Y0t<5K3IQ)IHdwWYXhbd&w5_^iTy}=aV_M!p(QnJX zA#Ie7@p17HD#eK{srr;|>e);`W60VRikBB(AfCJhO=M{8Y3?XF=o{kV9$S1<ky z6j?sX{xOUa_Iq-TfQxU3M|~kU9CO2G>%6?>fo4w>+S|gLXSu5dyR)1kEbFTrQB z(lTe26(~3v4Z~mc0ZAn)uNJ8;xKSQ%R$Vj9wJNBh>b@pjEvPYbzW*Eeni(kF9w4(& zS{`z##g+)eJEIU3SMhQ`^oSF+>Acdyws@H>n3Fk;Qjv*lNm2BSZYc`fcCUlS?s{mD z4)yh1YOdM4eKRkcK) zp3zb?Icg=QokX_gj?vX{OA5L%X!AM;_oV2n;mQk#<`2Q}Y1dhKN#s^nU6`1kxU}Pw zo)3F&y1os+!sMO>Ca)|Imt^qB?fjA#2IZ~9hIO$`9>Q76rGi_fAuI%ZRT+eT z`Xm_exIy&>Ez;FdTSam2Nr05q--z@>h9<1GI|`S{~S z)~e-v&l0t0xyZ-Kis!raAsFz6;J5YwKOTaUu^^oDE);oaIlSYmE{!;O&Sg#AV*N;? z@TsqT4{c!5xImk5lUFSoMS@J&L@}{@Vz_8Cqnwj7zI*_a7t{^p+e6$c{3D{V(S!(}mo!$P7Tt`nmVsHsAQqd;JLv##X-(r6lvgr% zI>#-^T(SS`=y~4tM< zKw9q92KMq>U(~dvDP5b+WvOLiAgJbC$req`QZ}g1QkQ4K9r&X{f{!Eo7P*NjCXWaQ4~ND*PtZL6%{8wvc>+60%ItKeT* zhRc-?K(20&?P6N}aoHA91{*;-g073xMpxFz(v2$Xxx>{B1N%`bt28;S7|9XMu)PjV zHA`n|SBMjwNicwXvfSB>f=6cjg+?pzlkA9@f`*!u@V!*YY9EgIc@lw!x>%?jo%m9d zBbqX$QD#{)sRjq@+PbRQ4&9EB#xv5cUS)89=Z+!U&8VHbdwUD%vBfDZWo4-?j2PL} zk(Kn&B;2d35}p1ZgU5B%9-cPL<*NekHD2!0P!HRC z<$Arl`@4te5wx(9RXWc2nLr_<&sX3g9B*nCTiABo4~=^pPOL_2_$JT}gl+^ZqElaL zAT@@dBcNH^rzj~SX__g`Fcc+D@H@nTz6l+j6Rl4^=V z@dcp?1WY$|9=hV(u{4|b*0kZ&#uoEm0!RG{mp6rF{abo%BCAds+E#jo=$EM3C|&aX(M$Prvc*@R{Kse6{y|wSRCZaSZ+k?S=Z> diff --git a/inventory.py b/inventory.py index 1554836c..0458ab7b 100644 --- a/inventory.py +++ b/inventory.py @@ -1,7 +1,11 @@ import block +from EventDispatcher import BLOCK_CHANGED class Inventory: - def __init__(self, *args, **kwargs): + def __init__(self, dispatcher, *args, **kwargs): self.hotbar = [block.STONE, block.SPRUCE_WOOD_PLANK, block.BIRCH_WOOD_PLANK, block.JUNGLE_WOOD_PLANK, block.ACACIA_WOOD_PLANK, block.DARK_OAK_WOOD_PLANK] - - self.block = self.hotbar[0] \ No newline at end of file + self.dispatcher = dispatcher + self.block = self.hotbar[0] + + def change_block(self): + self.dispatcher.dispatch_event(BLOCK_CHANGED) \ No newline at end of file diff --git a/player.py b/player.py index daea5f39..200c3e02 100644 --- a/player.py +++ b/player.py @@ -35,9 +35,9 @@ def __init__(self, model: Model, window, statemachine, *args, **kwargs): self.PLAYER_HEIGHT = 2 - self.inventory = inventory.Inventory() self.model = model self.window = window + self.inventory = inventory.Inventory(window.dispatcher) self.state_machine = statemachine self.window.push_handlers(self) diff --git a/window.py b/window.py index c587eb4b..debb104a 100644 --- a/window.py +++ b/window.py @@ -3,6 +3,7 @@ import math import model import player +from EventDispatcher import EventDispatcher, BLOCK_CHANGED from states import GameState, StateMachine #from collections import deque @@ -34,6 +35,10 @@ def __init__(self, *args, **kwargs): update_callback=self.update_paused ) + # Instance of Event Dispatcher + self.dispatcher = EventDispatcher() + + self.dispatcher.register_listener(BLOCK_CHANGED, self.on_block_changed) # Instance of the model that handles the world. self.model = model.Model() @@ -418,4 +423,10 @@ def play_button_pressed(self): self.state_machine.change_state(GameState.PLAYING) def quit_button_pressed(self): - pyglet.app.exit() \ No newline at end of file + pyglet.app.exit() + + def on_block_changed(self): + self.create_inventory_bar() + + def create_inventory_bar(self): + pass \ No newline at end of file From 93f6d9095d95ef2d34367dac5a60d925c30496fb Mon Sep 17 00:00:00 2001 From: Elijah Kelting Date: Tue, 11 Mar 2025 21:35:55 -0600 Subject: [PATCH 36/46] Delete MainMenu.py --- MainMenu.py | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 MainMenu.py diff --git a/MainMenu.py b/MainMenu.py deleted file mode 100644 index e69de29b..00000000 From d2302795102a8dc459293872f561dfcb67e4dd31 Mon Sep 17 00:00:00 2001 From: Kyle Wadas Date: Wed, 12 Mar 2025 00:27:25 -0600 Subject: [PATCH 37/46] Updated Terrain Generation & Removed Non-Functional Player Spawn Code --- model.py | 2 +- window.py | 6 ++---- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/model.py b/model.py index ea273f87..6b4274a2 100644 --- a/model.py +++ b/model.py @@ -187,7 +187,7 @@ def grow_tree(self, position): self.add_block((position[0]+tx, position[1] + y+3, position[2]+tz), block.OAK_LEAF, immediate=False) def grow_cactus(self, position): - for ty in xrange(1, random.randrange(2, 4)): + for ty in xrange(1, random.randrange(2, 5)): self.add_block((position[0], position[1] + ty, position[2]), block.CACTUS, immediate=False) def exposed(self, position): diff --git a/window.py b/window.py index 9bb8d680..d3120b96 100644 --- a/window.py +++ b/window.py @@ -40,8 +40,6 @@ def __init__(self, *args, **kwargs): # Instance of the player that interacts with the world. self.player = player.Player(self.model, self, self.state_machine) - while (self.model.collide(self.player, self.player.position) < self.player.position): - self.player.position = (self.player.position[0], self.player.position[1]+1, self.player.position[2]) # Which sector the player is currently in. self.sector = None @@ -209,8 +207,8 @@ def setup_fog(self): glFogi(GL_FOG_MODE, GL_LINEAR) # noqa: F405 # How close and far away fog starts and ends. The closer the start and end, # the denser the fog in the fog range. - glFogf(GL_FOG_START, 40.0) # noqa: F405 - glFogf(GL_FOG_END, 80.0) # noqa: F405 + glFogf(GL_FOG_START, 20.0) # noqa: F405 + glFogf(GL_FOG_END, 60.0) # noqa: F405 def setup(self): """ Basic OpenGL configuration. From 000a7ea3e6c7fe0ce332c56fb0115b2c4824781e Mon Sep 17 00:00:00 2001 From: Elijah Kelting Date: Wed, 12 Mar 2025 11:34:46 -0600 Subject: [PATCH 38/46] hotbar there, but textures not loading. --- inventory.py | 11 ++++- player.py | 2 +- window.py | 125 +++++++++++++++++++++++++++++++++++++++++++++++---- 3 files changed, 127 insertions(+), 11 deletions(-) diff --git a/inventory.py b/inventory.py index d07aa3d2..882b05e5 100644 --- a/inventory.py +++ b/inventory.py @@ -2,7 +2,16 @@ from EventDispatcher import BLOCK_CHANGED class Inventory: - def __init__(self, *args, **kwargs): + def __init__(self, dispatcher, *args, **kwargs): self.hotbar = [block.PORTAL, block.STONE, block.SPRUCE_WOOD_PLANK, block.BIRCH_WOOD_PLANK, block.JUNGLE_WOOD_PLANK, block.ACACIA_WOOD_PLANK, block.DARK_OAK_WOOD_PLANK] self.index = 0 + self.dispatcher = dispatcher + def set_index(self, index): + """Set the selected slot index and notify listeners.""" + self.index = index + self.dispatcher.dispatch_event(BLOCK_CHANGED) + + def get_selected_block(self): + """Get the block in the currently selected slot.""" + return self.hotbar[self.index] \ No newline at end of file diff --git a/player.py b/player.py index d56fb202..b49bc5d2 100644 --- a/player.py +++ b/player.py @@ -301,7 +301,7 @@ def on_key_press(self, symbol, modifiers): self.flying = not self.flying elif symbol in self.num_keys: index = (symbol - self.num_keys[0]) % len(self.inventory.hotbar) - self.inventory.index = index + self.inventory.set_index(index) # Update the selected slot if self.state_machine.state == GameState.PLAYING: if symbol == key.ESCAPE: diff --git a/window.py b/window.py index 014fc27d..5a74fea3 100644 --- a/window.py +++ b/window.py @@ -4,10 +4,14 @@ import model import player import random +import block from states import GameState, StateMachine +from EventDispatcher import EventDispatcher, BLOCK_CHANGED #from collections import deque from pyglet.gl import * # noqa: F403 +from pyglet import image +from pyglet import sprite class Window(pyglet.window.Window): @@ -35,17 +39,26 @@ def __init__(self, *args, **kwargs): update_callback=self.update_paused ) - # Instance of Event Dispatcher + # Instance of the model that handles the world. + self.model = model.Model() + + # Load the block texture atlas + self.block_texture = image.load('Textures.png') + self.block_texture_atlas = self.block_texture.get_texture() + + glEnable(self.block_texture_atlas.target) # typically target is GL_TEXTURE_2D + glBindTexture(self.block_texture_atlas.target, self.block_texture_atlas.id) + + # Initialize the inventory bar + self.dispatcher = EventDispatcher() self.dispatcher.register_listener(BLOCK_CHANGED, self.on_block_changed) - # Instance of the model that handles the world. - self.model = model.Model() # Instance of the player that interacts with the world. self.player = player.Player(self.model, self, self.state_machine) - while (self.model.collide(self.player, self.player.position) < self.player.position): - self.player.position = (self.player.position[0], self.player.position[1]+1, self.player.position[2]) + + self.inventory_bar = self.create_inventory_bar() # Which sector the player is currently in. self.sector = None @@ -158,6 +171,7 @@ def on_draw(self): self.set_2d() self.draw_label() self.draw_reticle() + self.inventory_bar[0].draw() # Draw the inventory bar batch # Draw the background image first if self.state_machine.state == GameState.MAIN_MENU: self.background_sprite.draw() @@ -420,6 +434,76 @@ def create_main_menu(self): # Add buttons to the GUI widgets list self.gui_widgets.extend([self.quit_button, self.play_button]) + def create_inventory_bar(self): + """Create the inventory bar with slots and block textures, close to Minecraft's style.""" + slot_size = 40 + slot_spacing = 5 + num_slots = len(self.player.inventory.hotbar) + + total_width = num_slots * slot_size + (num_slots - 1) * slot_spacing + start_x = (self.width - total_width) // 2 + start_y = 20 + + inventory_batch = pyglet.graphics.Batch() + + # Background for the inventory bar (a semi-transparent dark background) + bar_bg = pyglet.shapes.Rectangle( + x=start_x - 5, y=start_y - 5, + width=total_width + 10, height=slot_size + 10, + color=(0, 0, 0), batch=inventory_batch + ) + bar_bg.opacity = 150 # Make the background semi-transparent + + # Slots and their corresponding textures + slots = [] + for i in range(num_slots): + slot_x = start_x + i * (slot_size + slot_spacing) + slot_rect = pyglet.shapes.Rectangle( + x=slot_x, y=start_y, width=slot_size, height=slot_size, + color=(200, 200, 200), batch=inventory_batch + ) + + # Block texture + block_texture = self.player.inventory.hotbar[i] + if block_texture != block.NONE: + reversed_coords = self.reverse_tex_coords_list(block_texture) + pixel_coords = self.get_texture_pixel_position(reversed_coords["side"][0][0], reversed_coords["side"][0][1]) + # Get the correct texture region for the block + texture_region = self.block_texture_atlas.get_region( + pixel_coords[0], + pixel_coords[1], + 16, 16 # width and height of the texture + ) + texture_sprite = sprite.Sprite( + img=texture_region, + x=slot_x + 4, y=start_y + 4, batch=inventory_batch + ) + texture_sprite.scale = (slot_size - 8) / 32 + + slots.append((slot_rect, texture_sprite)) + + # Highlight the selected slot + selected_slot_index = self.player.inventory.index + selected_slot_rect = pyglet.shapes.Rectangle( + x=start_x + selected_slot_index * (slot_size + slot_spacing) - 2, + y=start_y - 2, + width=slot_size + 4, + height=slot_size + 4, + color=(255, 255, 255), batch=inventory_batch + ) + selected_slot_rect.opacity = 255 + + selected_slot_border = pyglet.shapes.Rectangle( + x=start_x + selected_slot_index * (slot_size + slot_spacing) - 2, + y=start_y - 2, + width=slot_size + 4, + height=slot_size + 4, + color=(255, 223, 64), batch=inventory_batch + ) + selected_slot_border.opacity = 255 + + return inventory_batch, slots, selected_slot_rect, selected_slot_border + def play_button_pressed(self): print("Resume button pressed") self.state_machine.change_state(GameState.PLAYING) @@ -428,7 +512,30 @@ def quit_button_pressed(self): pyglet.app.exit() def on_block_changed(self): - self.create_inventory_bar() - - def create_inventory_bar(self): - pass \ No newline at end of file + """Update the inventory bar when the inventory changes.""" + self.inventory_bar = self.create_inventory_bar() + + def reverse_tex_coord(self, dx, dy, w=32, h=16): + """ Reverse the texture coordinates back to (x, y). """ + width = 1.0 / w + height = 1.0 / h + x = int(dx / width) + y = int(dy / height) + return x, y + + def reverse_tex_coords_list(self, coord_list, w=32, h=16): + """ Reverse a full list of texture coordinates back to their original (x, y) pairs for a 3D block model. """ + result = { + "top": [], + "bottom": [], + "side": [] # Only one side entry since it's repeated + } + result["top"].append(self.reverse_tex_coord(coord_list[0], coord_list[1], w, h)) + result["bottom"].append(self.reverse_tex_coord(coord_list[8], coord_list[9], w, h)) + result["side"].append(self.reverse_tex_coord(coord_list[16], coord_list[17], w, h)) + return result + + def get_texture_pixel_position(self, column, row, texture_size=16): + x = column * texture_size + y = row * texture_size + return (x, y) From 8a1f0ed5288c0a2a7d5d6a16fbd63dec156ad81a Mon Sep 17 00:00:00 2001 From: Elijah Kelting Date: Wed, 12 Mar 2025 12:19:32 -0600 Subject: [PATCH 39/46] inventory complete --- Steve_Hand.png | Bin 0 -> 8923 bytes inventory.py | 1 + player.py | 4 +++ window.py | 71 ++++++++++++++++++++++++++----------------------- 4 files changed, 42 insertions(+), 34 deletions(-) create mode 100644 Steve_Hand.png diff --git a/Steve_Hand.png b/Steve_Hand.png new file mode 100644 index 0000000000000000000000000000000000000000..d71f18d6cfc2ab5ef40285416ed6ad22c7c14b31 GIT binary patch literal 8923 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 Y-4o%ye?P;zDSt2OD$kTl6fML5AB|5ZO#lD@ literal 0 HcmV?d00001 diff --git a/inventory.py b/inventory.py index 882b05e5..b78fde19 100644 --- a/inventory.py +++ b/inventory.py @@ -14,4 +14,5 @@ def set_index(self, index): def get_selected_block(self): """Get the block in the currently selected slot.""" + self.dispatcher.dispatch_event(BLOCK_CHANGED) return self.hotbar[self.index] \ No newline at end of file diff --git a/player.py b/player.py index b49bc5d2..9489a41b 100644 --- a/player.py +++ b/player.py @@ -196,6 +196,7 @@ def on_mouse_press(self, x, y, button, modifiers): if previous: texture = self.model.world[selectedBlock] self.inventory.hotbar[self.inventory.index] = texture + self.inventory.get_selected_block() else: self.window.set_exclusive_mouse(True) if self.state_machine.state == GameState.PAUSED: @@ -313,6 +314,9 @@ def on_key_press(self, symbol, modifiers): self.window.set_exclusive_mouse(True) self.state_machine.change_state(GameState.PLAYING) return pyglet.event.EVENT_HANDLED + elif self.state_machine.state == GameState.MAIN_MENU: + if symbol == key.ESCAPE: + return pyglet.event.EVENT_HANDLED def on_key_release(self, symbol, modifiers): """ Called when the player releases a key. See pyglet docs for key diff --git a/window.py b/window.py index 5a74fea3..178e3dbe 100644 --- a/window.py +++ b/window.py @@ -172,6 +172,7 @@ def on_draw(self): self.draw_label() self.draw_reticle() self.inventory_bar[0].draw() # Draw the inventory bar batch + self.draw_bottom_right_image("Steve_Hand.png").draw() # Draw the background image first if self.state_machine.state == GameState.MAIN_MENU: self.background_sprite.draw() @@ -435,7 +436,7 @@ def create_main_menu(self): self.gui_widgets.extend([self.quit_button, self.play_button]) def create_inventory_bar(self): - """Create the inventory bar with slots and block textures, close to Minecraft's style.""" + """Create the inventory bar with only block textures.""" slot_size = 40 slot_spacing = 5 num_slots = len(self.player.inventory.hotbar) @@ -446,22 +447,27 @@ def create_inventory_bar(self): inventory_batch = pyglet.graphics.Batch() - # Background for the inventory bar (a semi-transparent dark background) - bar_bg = pyglet.shapes.Rectangle( - x=start_x - 5, y=start_y - 5, - width=total_width + 10, height=slot_size + 10, - color=(0, 0, 0), batch=inventory_batch + # Create groups for z-order control + background_group = pyglet.graphics.OrderedGroup(0) + foreground_group = pyglet.graphics.OrderedGroup(1) + + # Highlight the selected slot (background layer) + selected_slot_index = self.player.inventory.index + selected_slot_border = pyglet.shapes.Rectangle( + x=start_x + selected_slot_index * (slot_size + slot_spacing) - 2, + y=start_y - 2, + width=slot_size + 4, + height=slot_size + 4, + color=(255, 223, 64), + batch=inventory_batch, + group=background_group ) - bar_bg.opacity = 150 # Make the background semi-transparent + selected_slot_border.opacity = 180 # Softer effect # Slots and their corresponding textures slots = [] for i in range(num_slots): slot_x = start_x + i * (slot_size + slot_spacing) - slot_rect = pyglet.shapes.Rectangle( - x=slot_x, y=start_y, width=slot_size, height=slot_size, - color=(200, 200, 200), batch=inventory_batch - ) # Block texture block_texture = self.player.inventory.hotbar[i] @@ -472,37 +478,34 @@ def create_inventory_bar(self): texture_region = self.block_texture_atlas.get_region( pixel_coords[0], pixel_coords[1], - 16, 16 # width and height of the texture + 16, 16 ) texture_sprite = sprite.Sprite( img=texture_region, - x=slot_x + 4, y=start_y + 4, batch=inventory_batch + x=slot_x + 4, y=start_y + 4, + batch=inventory_batch, + group=foreground_group # Textures drawn in front ) - texture_sprite.scale = (slot_size - 8) / 32 + texture_sprite.scale = (slot_size - 8) / 16 + slots.append(texture_sprite) - slots.append((slot_rect, texture_sprite)) + return inventory_batch, slots, selected_slot_border - # Highlight the selected slot - selected_slot_index = self.player.inventory.index - selected_slot_rect = pyglet.shapes.Rectangle( - x=start_x + selected_slot_index * (slot_size + slot_spacing) - 2, - y=start_y - 2, - width=slot_size + 4, - height=slot_size + 4, - color=(255, 255, 255), batch=inventory_batch - ) - selected_slot_rect.opacity = 255 + def draw_bottom_right_image(self, image_path): + texture_image = pyglet.image.load(image_path) - selected_slot_border = pyglet.shapes.Rectangle( - x=start_x + selected_slot_index * (slot_size + slot_spacing) - 2, - y=start_y - 2, - width=slot_size + 4, - height=slot_size + 4, - color=(255, 223, 64), batch=inventory_batch - ) - selected_slot_border.opacity = 255 + image_width = texture_image.width + image_height = texture_image.height + x_position = self.width - image_width + y_position = 0 - return inventory_batch, slots, selected_slot_rect, selected_slot_border + # Create and draw the sprite + texture_sprite = sprite.Sprite( + img=texture_image, + x=x_position, + y=y_position + ) + return texture_sprite def play_button_pressed(self): print("Resume button pressed") From 0b0a7c826260f6b84029a93ffce660d5049a4d32 Mon Sep 17 00:00:00 2001 From: StephenieDugan Date: Wed, 12 Mar 2025 13:01:33 -0600 Subject: [PATCH 40/46] command prompt is done --- __pycache__/player.cpython-312.pyc | Bin 16314 -> 16338 bytes __pycache__/window.cpython-312.pyc | Bin 24483 -> 24515 bytes player.py | 2 +- window.py | 19 ++++++++++--------- 4 files changed, 11 insertions(+), 10 deletions(-) diff --git a/__pycache__/player.cpython-312.pyc b/__pycache__/player.cpython-312.pyc index d928b444da1af406497f4e65456c15feb8a4a0dc..437beba4c9494d967c189b9036e88bc4535884c6 100644 GIT binary patch delta 91 zcmV-h0HpuAf6{*q%MA?*00000W!KSXfw2ueDgp4bODb#!0m75GF(m;hlio2hli)EF xvk)??0|5}TyfvBv94jxcJE=R@D?`yML%>78QqU_%kOY?tkqgxjD6?)jOb6&=Am#u7 delta 99 zcmV-p0G$8Qf4YAS%MA?*00000V8_sBda(^XDgxXHk~t}p%_=0bnJOL!0l1U6F(m;X zlYlZR2V@0g1{wf-vm-LB0|5-P&^4L@7$hjCOQB2GBs|e1Jh)T1V$dW(kOb8bA+v@! FOb2u4A$kA+ diff --git a/__pycache__/window.cpython-312.pyc b/__pycache__/window.cpython-312.pyc index 2e6ab489e7e49af2460ae3efe1c37ce67bd3873e..be3abd15e57a940f678b54302749aea56096a855 100644 GIT binary patch delta 3648 zcmai13s98T72dmV*nd|L7g%xEU0{Lbp*)26KtUd{$^t6BNR;1Y{~uWW+1=dT6+s(_ zCPv#dn%qvNoypkPByFjg&X}D}Yih^Xc8oRVK`I4*O{>$6#F{va=4mH0z32W*0F#+6 z@Nw?F=bn4-Io~<=?#pM&4?no%05GQMTHpHv^}?eztPv_YrB`Y9&u5zk#wz zjmd^i#@kJ6)K#AvRqmo+Hl1i1%dH&AtsLhv#?$TN>6zn}lw)<{)~uI$#^>funpN(q zdn$uF`LOn~(KVS8|GBwZW6Gr~;6{K7ax2AQsswQXi{6 z(NWO}AKV0rFnhqfH4qd+eT!mY!50y1sxA?ZGuLP)(k&+D*(Z z5A7NY@@jX__hB;p=eB>=DsU^jpS&hc)y>>c9A$acG(o@Bs2U;iVjAGuE~woLN6{pJEM zZTb;~sSm^hoO$mR4f(n}KYrDrRU-|#?mWn_lKj+_scjR~`^n&PD;gk8TAP};KJRsq zH=Pc&pUnAQI;nBm_5GTDjYms9c2&8sgW7BHWXL+dB>FHOq)j=gTdEI9AzUF)vaHH> zmtp8l7O=06mwcU~By&v0Vl+UfVc?dmi$v)OG58thkRN9k43r@_aD}5>@uWdzsYTcuugtZmQ6*`}b6P8u-NrgaevgRh@x=%}K>G6*yQ}F4 z-U;v|=or^{`3;*_H?+wHDm}c`>xI~pck=A$adJD)u4gIr6tUzx&}mYVf1EP-QvOA> zYdSHR#dLiZ1pA^`PJf^tLtE5JHQHbjA`$}TUI@l~g3pR&sb&WMY^-n@i8F-Q}V4@~vtZy&fO8aP z?Wmaiv3$NMnJ$h01PaQk|1JMT4R{2<0q_HWKLDJeFl+iE+VKrH5*vUDAXv!tirW9b z{9?i{v6-whmWLAk;*v^3-bGlDK{}Ogy#P>7VOWdbh9L#W7b`rAluH6S?EnWU++xX4 z0?kxt=7N+0aFMiB7o&q@U$v(mG-drpF%s()@iEY2WKZ1?3q+mKkh7V_#@S4Zna6>@ z$#_{;$0{4J1b2~%>UKR##Z~0tl@FQNURV;=ki#pVNKuF-?v08;VOURVf^Ahaw+W`6 zr!bJ22%aB{w4U*z;Oc7|!sJk$y@D|Tjv{mZ9$&Cqs+Xtd|9_BVXL8cNWq?r%vUWYCEAu?QLfZp#raa#uMs`O-VUKIt z?^uRujEr!7Yy$nRwji>X#Wz6J^( z0wh9L+nk~Q7qtIPb~M+ckI0GUWloj?A4Bga6e4;G@Ti!|{yK8Mc>xN>Gg|gd2kNn` zPhrAm01pO3OO|e2X!RVxL8B4+$~a93sIt2PHZLozoN zFp9LLf2UeG`Sm7y**RF>q^xf=zi-JMHM;S)o-Xi~*3iFuvNI zF&HOW=r{&T_&tF4DR`0|jP^4y#G?HVkp2m99pDB9k5ZZO9V*YNN@nu-)`j}Nz*aGN zc`Me98W&Rk?A$il$|!#rEHKKKg2Y}YaONq4z=@d#*?S~Pb9m-^1lptIXYFhC?D%Rj zl0Pr5e&irR+sUCvhdPc^BeG5k^@$kofn_QI*c%+yl9RXiq?p)W&*ByQqq^AH50YH6I?#thS zQ~&_C61z%pF-TC;@nV4U0C1t>+W>U{TIyA704RfIxr%CHGqh6yvM9)Ap7%?>NW?En z63=^(^2LCTsA_Q&De1^E)aY8#-8waC?Xc-GbR~DoNpDA2l||>io2}KkKj%!k<&0Gr znB+0b$voc`i^j0X^B9PQ`vKr-L?7Qtyr&qdGhET|ZG}xz?mGw#`zCVVSlt^EVv@KD gyGaLMnAL7T%MWiky5q=>F|%vL?D|XvJ#5kc0b8oDFaQ7m delta 3768 zcmaJ^eQZL9**Bj;?%L7`<@9H z))-1x*u>ZFKh-u(W7ArpN~7RyEmI4dkOpnHkxZ~;Z!iUkwPlsI48}A~L)tm-+4*WU zC;Iu`bI(2Z+;e~D-0K_H$&aoR>nB!gk_JBXqsgK5m#y~+*%JMNT-GNX)r@qq6~*}$ zX(Nu~XJjiQsp+JfT~5h#^r*7M$frmZ@%~6J8!?rTRCdO6)BKq#oojZLM^7bwov?iK z)jT^0!zsJGem*c>&2e78SK_!75Q^i`Idi90J7_2%^Z1 zg@lkGCyIhc3Q%uYp!KM;7GWK`zhXmDJF07W3A*;Q4BJ*5K|5he1as%`f)EW4bvtZXkS*rkFz!zecE*n zFZHROe?5AjP)G8+K-oh8;vYRUFv3sP=$JdZIC`NdQA@NexIT*==*eKW?PfOX=v^jx zBR`!59Et3BaXL#WF4AicYh5~4Ri_wWPE* zfYKzMy2m-6dqD8X7Nt!E$qUmcGEUZu66}&DK$|+)os#mGD^Z*pbcaNN8x{N^Zon;h zhG{j5t)9T>sN2u0vWr9sjfi`+E1Z#y0Y8U}gp*_Bi}l|G710(Qbn1!Ck~(cEoU#;7 zTS}%ZC3h{Qb2?3O3!zntyD9sz-DMpfYu2b_0{Mv$mfQ~jgI*~#)ka*4fN{(a!|7T3pQVj-Ut zt1W26I0Rf942rVOC-~KbG;rc@VB8N}4^SUZl}z{==+a{Vt^}1N^E{{Mi-=Lh<<)$8 z4SL}fvAE2iiq?0Hov(}lh105jRWSiNN^U7;Wm9Jl*VEP8@gn^u+FJ-TJ;9z;<&aw} zYgHv|q;*vb$=L%cu^Ken{8`3NIv<2HK5eFj>^s$kWQ<*{K5toUh4t6i$!#`Xvm4f) ztogC|0UKn_gWDMlQ75SaI#A zo10OqA7KNUFvJ*i5<5mg$xHsCR*9HwfYJfM7PT-K57bK5RhLKp&V;&MVD-Z~SGJOY zFM!Gty)yQ!E-lqMphE3NylocGU z^aC9D5aAlYl65LT5YAjuO}U`Yec0>o`kYH?-!hmAGm89>N<4?;~6VSYoq^ zZEnaR3GAhY7S)5z|IdR}Fg={H%md6&-n`&I^jSl%(Qp%&yUDgUWtwkcQw28Gk% z#|1bN0eED?7N$I1fn6uIQW0*lTTN9Y!k#v{k|Q9H4KD~{XjGu5S=FY(?D-6o^{q;M zz|*B3=H9f&prpk{_RCG{%*v8j_-PZ2_YPk1V4Y#K-(E>mJC~Q{06hO6p)l? zWlOg%#-(#@r|XqNR4SFlGwk*c3EZNBRgM#vAMQi8t=&QPG1^|O*paI6Xdy$<3Vnir zc}X1z%O`)%Hg}Z5oi_y76+PXt)->^J)KjAP5w<=?_yi!F+8Y?Rd;Rupho#|w-{Ej5 zA*8=U1*EeYN4)E)awxa4HHk2V@OuC`VH@y>p2q$k0KzHTLte=)1?=sD_=*$=x*U0Q zKGbv?^%PR!Ek|eAzTT?dZ(tMSEE`3S+b3{`lsh-xJ52wG3NnIvFsQmh1Oki0+zvPj z^>U!IsPTYJ_qLJ0u)MwvO?X!H5yD>qmR#E?#4HbI$2jSs0$d~9sN3sTE)70}Tf8d+=k*Iz;pOt3)PQ=}7Tby7hkKQaPZ|yI!WH)Io#ioZ-`Uyd`AQqB(MC?(25fAJ ziTBWHv+A_TI+^UeYbvE*dT5}6^3XUF9qTs|iv)f3Gm?gn+pNrZf8m=q9%T=Tpt=B?b6E|B93T1xEaRmbjaC-!T7353oPvK#8?gyoSAA#W| zMSz{yTSa7cdGFsQ>@cSOcY0mkRbidR_YD5jQzog;3CvFA0r(%&MyLWIpRkEK*{fVd-fkmlJlTJC T->H4mR>zdp@l=BnWzqiu0OrdR diff --git a/player.py b/player.py index 20e541bf..aba6569e 100644 --- a/player.py +++ b/player.py @@ -314,7 +314,7 @@ def on_key_press(self, symbol, modifiers): return pyglet.event.EVENT_HANDLED elif self.state_machine.state == GameState.COMMAND_LINE: if symbol == key.BACKSPACE: - self.command_text = self.window.command_text[:-1] + self.window.command_text = self.window.command_text[:-1] elif symbol == key.ENTER: self.window.process_command(self.window.command_text) self.state_machine.change_state(GameState.PLAYING) diff --git a/window.py b/window.py index 65c99073..669e915a 100644 --- a/window.py +++ b/window.py @@ -63,6 +63,14 @@ def __init__(self, *args, **kwargs): x=10, y=self.height - 10, anchor_x='left', anchor_y='top', color=(0, 0, 0, 255)) + self.command_prompt_label = pyglet.text.Label( + "Command: ", + font_name="Arial", + font_size=18, + x=10, y=10, + anchor_x="left", anchor_y="bottom", + color=(255, 255, 255, 255) + ) self.create_main_menu() # This call schedules the `update()` method to be called @@ -170,7 +178,9 @@ def on_draw(self): elif self.state_machine.state == GameState.PAUSED: self.pause_menu_batch.draw() elif self.state_machine.state == GameState.COMMAND_LINE: + self.command_prompt_label.text = 'Command: ' + self.command_text self.command_batch.draw() + self.command_prompt_label.draw() def draw_focused_block(self): """ Draw black edges around the block that is currently under the @@ -455,15 +465,6 @@ def create_command_line(self): ) self.background.opacity = 25 - self.command_prompt_label = pyglet.text.Label( - "Command: " + self.command_text, - font_name="Arial", - font_size=18, - x=10, y=10, - anchor_x="left", anchor_y="bottom", - color=(255, 255, 255, 255), - batch= self.command_batch - ) def on_text(self, text): """Handles text input in command mode.""" From afe53935f5575e5c42d0cd59e4a45f1a663a54ab Mon Sep 17 00:00:00 2001 From: Elijah Kelting Date: Wed, 12 Mar 2025 13:22:24 -0600 Subject: [PATCH 41/46] Revert "Merge branch 'PRO250-ThanosBaddies' into SteefBranch" This reverts commit ad850814e73990c160a0dd9a5358a5b8e4c81581, reversing changes made to 4501bbbc7d4d563851d950bf4bb9a9dd72de9948. --- EventDispatcher.py | 17 ---- MainMenu.py | 0 Steve_Hand.png | Bin 8923 -> 0 bytes inventory.py | 16 +--- player.py | 18 +++-- window.py | 188 +++++++++++++++------------------------------ 6 files changed, 78 insertions(+), 161 deletions(-) delete mode 100644 EventDispatcher.py create mode 100644 MainMenu.py delete mode 100644 Steve_Hand.png diff --git a/EventDispatcher.py b/EventDispatcher.py deleted file mode 100644 index 69bd4881..00000000 --- a/EventDispatcher.py +++ /dev/null @@ -1,17 +0,0 @@ -BLOCK_CHANGED = "block_changed" - -class EventDispatcher: - def __init__(self): - self.listeners = {} - - def register_listener(self, event_type, listener): - """Register a listener for a specific event type.""" - if event_type not in self.listeners: - self.listeners[event_type] = [] - self.listeners[event_type].append(listener) - - def dispatch_event(self, event_type, *args, **kwargs): - """Trigger all listeners for a specific event type.""" - if event_type in self.listeners: - for listener in self.listeners[event_type]: - listener(*args, **kwargs) \ No newline at end of file diff --git a/MainMenu.py b/MainMenu.py new file mode 100644 index 00000000..e69de29b diff --git a/Steve_Hand.png b/Steve_Hand.png deleted file mode 100644 index d71f18d6cfc2ab5ef40285416ed6ad22c7c14b31..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8923 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 Y-4o%ye?P;zDSt2OD$kTl6fML5AB|5ZO#lD@ diff --git a/inventory.py b/inventory.py index b78fde19..21d587ab 100644 --- a/inventory.py +++ b/inventory.py @@ -1,18 +1,6 @@ import block -from EventDispatcher import BLOCK_CHANGED class Inventory: - def __init__(self, dispatcher, *args, **kwargs): + def __init__(self, *args, **kwargs): self.hotbar = [block.PORTAL, block.STONE, block.SPRUCE_WOOD_PLANK, block.BIRCH_WOOD_PLANK, block.JUNGLE_WOOD_PLANK, block.ACACIA_WOOD_PLANK, block.DARK_OAK_WOOD_PLANK] - self.index = 0 - self.dispatcher = dispatcher - - def set_index(self, index): - """Set the selected slot index and notify listeners.""" - self.index = index - self.dispatcher.dispatch_event(BLOCK_CHANGED) - - def get_selected_block(self): - """Get the block in the currently selected slot.""" - self.dispatcher.dispatch_event(BLOCK_CHANGED) - return self.hotbar[self.index] \ No newline at end of file + self.index = 0 \ No newline at end of file diff --git a/player.py b/player.py index 9489a41b..2f70578f 100644 --- a/player.py +++ b/player.py @@ -35,9 +35,9 @@ def __init__(self, model: Model, window, statemachine, position = (80, 10, 80), self.PLAYER_HEIGHT = 2 + self.inventory = inventory.Inventory() self.model = model self.window = window - self.inventory = inventory.Inventory(window.dispatcher) self.state_machine = statemachine self.window.push_handlers(self) @@ -196,7 +196,6 @@ def on_mouse_press(self, x, y, button, modifiers): if previous: texture = self.model.world[selectedBlock] self.inventory.hotbar[self.inventory.index] = texture - self.inventory.get_selected_block() else: self.window.set_exclusive_mouse(True) if self.state_machine.state == GameState.PAUSED: @@ -302,22 +301,29 @@ def on_key_press(self, symbol, modifiers): self.flying = not self.flying elif symbol in self.num_keys: index = (symbol - self.num_keys[0]) % len(self.inventory.hotbar) - self.inventory.set_index(index) # Update the selected slot + self.inventory.index = index if self.state_machine.state == GameState.PLAYING: if symbol == key.ESCAPE: self.window.set_exclusive_mouse(False) self.state_machine.change_state(GameState.PAUSED) return pyglet.event.EVENT_HANDLED + if symbol == key.C: + self.window.set_exclusive_mouse(True) + self.state_machine.change_state(GameState.COMMAND_LINE) elif self.state_machine.state == GameState.PAUSED: if symbol == key.ESCAPE: self.window.set_exclusive_mouse(True) self.state_machine.change_state(GameState.PLAYING) return pyglet.event.EVENT_HANDLED - elif self.state_machine.state == GameState.MAIN_MENU: - if symbol == key.ESCAPE: + elif self.state_machine.state == GameState.COMMAND_LINE: + if symbol == key.BACKSPACE: + self.window.command_text = self.window.command_text[:-1] + elif symbol == key.ENTER: + self.window.process_command(self.window.command_text) + self.state_machine.change_state(GameState.PLAYING) return pyglet.event.EVENT_HANDLED - + def on_key_release(self, symbol, modifiers): """ Called when the player releases a key. See pyglet docs for key mappings. diff --git a/window.py b/window.py index 6f831c46..df0ff7ea 100644 --- a/window.py +++ b/window.py @@ -4,14 +4,10 @@ import model import player import random -import block from states import GameState, StateMachine -from EventDispatcher import EventDispatcher, BLOCK_CHANGED #from collections import deque from pyglet.gl import * # noqa: F403 -from pyglet import image -from pyglet import sprite class Window(pyglet.window.Window): @@ -21,7 +17,9 @@ def __init__(self, *args, **kwargs): # Initialize the state machine self.state_machine = StateMachine(GameState.MAIN_MENU) - + self.command_text = "" + self.player_position = (0, 0, 0) # Placeholder for player position + # Add states with their respective callbacks self.state_machine.add_state( GameState.MAIN_MENU, @@ -38,27 +36,17 @@ def __init__(self, *args, **kwargs): enter_callback=self.enter_paused, update_callback=self.update_paused ) + self.state_machine.add_state( + GameState.COMMAND_LINE, + enter_callback=self.enter_command_mode, + exit_callback=self.exit_command_mode + ) # Instance of the model that handles the world. self.model = model.Model() - - # Load the block texture atlas - self.block_texture = image.load('Textures.png') - self.block_texture_atlas = self.block_texture.get_texture() - - glEnable(self.block_texture_atlas.target) # typically target is GL_TEXTURE_2D - glBindTexture(self.block_texture_atlas.target, self.block_texture_atlas.id) - - # Initialize the inventory bar - - self.dispatcher = EventDispatcher() - - self.dispatcher.register_listener(BLOCK_CHANGED, self.on_block_changed) # Instance of the player that interacts with the world. self.player = player.Player(self.model, self, self.state_machine) - - self.inventory_bar = self.create_inventory_bar() # Which sector the player is currently in. self.sector = None @@ -73,6 +61,14 @@ def __init__(self, *args, **kwargs): x=10, y=self.height - 10, anchor_x='left', anchor_y='top', color=(0, 0, 0, 255)) + self.command_prompt_label = pyglet.text.Label( + "Command: ", + font_name="Arial", + font_size=18, + x=10, y=10, + anchor_x="left", anchor_y="bottom", + color=(255, 255, 255, 255) + ) self.create_main_menu() # This call schedules the `update()` method to be called @@ -171,8 +167,6 @@ def on_draw(self): self.set_2d() self.draw_label() self.draw_reticle() - self.inventory_bar[0].draw() # Draw the inventory bar batch - self.draw_bottom_right_image("Steve_Hand.png").draw() # Draw the background image first if self.state_machine.state == GameState.MAIN_MENU: self.background_sprite.draw() @@ -181,7 +175,11 @@ def on_draw(self): self.main_menu_batch.draw() elif self.state_machine.state == GameState.PAUSED: self.pause_menu_batch.draw() - + elif self.state_machine.state == GameState.COMMAND_LINE: + self.command_prompt_label.text = 'Command: ' + self.command_text + self.command_batch.draw() + self.command_prompt_label.draw() + def draw_focused_block(self): """ Draw black edges around the block that is currently under the crosshairs. @@ -255,7 +253,6 @@ def enter_main_menu(self): if widget._batch == self.pause_menu_batch: widget.enabled = False - def update_main_menu(self, dt): # Handle input for the main menu (e.g., start game, quit) pass @@ -435,110 +432,53 @@ def create_main_menu(self): # Add buttons to the GUI widgets list self.gui_widgets.extend([self.quit_button, self.play_button]) - def create_inventory_bar(self): - """Create the inventory bar with only block textures.""" - slot_size = 40 - slot_spacing = 5 - num_slots = len(self.player.inventory.hotbar) - - total_width = num_slots * slot_size + (num_slots - 1) * slot_spacing - start_x = (self.width - total_width) // 2 - start_y = 20 - - inventory_batch = pyglet.graphics.Batch() - - # Create groups for z-order control - background_group = pyglet.graphics.OrderedGroup(0) - foreground_group = pyglet.graphics.OrderedGroup(1) - - # Highlight the selected slot (background layer) - selected_slot_index = self.player.inventory.index - selected_slot_border = pyglet.shapes.Rectangle( - x=start_x + selected_slot_index * (slot_size + slot_spacing) - 2, - y=start_y - 2, - width=slot_size + 4, - height=slot_size + 4, - color=(255, 223, 64), - batch=inventory_batch, - group=background_group - ) - selected_slot_border.opacity = 180 # Softer effect - - # Slots and their corresponding textures - slots = [] - for i in range(num_slots): - slot_x = start_x + i * (slot_size + slot_spacing) - - # Block texture - block_texture = self.player.inventory.hotbar[i] - if block_texture != block.NONE: - reversed_coords = self.reverse_tex_coords_list(block_texture) - pixel_coords = self.get_texture_pixel_position(reversed_coords["side"][0][0], reversed_coords["side"][0][1]) - # Get the correct texture region for the block - texture_region = self.block_texture_atlas.get_region( - pixel_coords[0], - pixel_coords[1], - 16, 16 - ) - texture_sprite = sprite.Sprite( - img=texture_region, - x=slot_x + 4, y=start_y + 4, - batch=inventory_batch, - group=foreground_group # Textures drawn in front - ) - texture_sprite.scale = (slot_size - 8) / 16 - slots.append(texture_sprite) - - return inventory_batch, slots, selected_slot_border - - def draw_bottom_right_image(self, image_path): - texture_image = pyglet.image.load(image_path) - - image_width = texture_image.width - image_height = texture_image.height - x_position = self.width - image_width - y_position = 0 - - # Create and draw the sprite - texture_sprite = sprite.Sprite( - img=texture_image, - x=x_position, - y=y_position - ) - return texture_sprite - def play_button_pressed(self): print("Resume button pressed") self.state_machine.change_state(GameState.PLAYING) def quit_button_pressed(self): pyglet.app.exit() + + def enter_command_mode(self): + self.command_text = "" + self.create_command_line() + print("Entered command mode. Type a command and press Enter.") - def on_block_changed(self): - """Update the inventory bar when the inventory changes.""" - self.inventory_bar = self.create_inventory_bar() - - def reverse_tex_coord(self, dx, dy, w=32, h=16): - """ Reverse the texture coordinates back to (x, y). """ - width = 1.0 / w - height = 1.0 / h - x = int(dx / width) - y = int(dy / height) - return x, y - - def reverse_tex_coords_list(self, coord_list, w=32, h=16): - """ Reverse a full list of texture coordinates back to their original (x, y) pairs for a 3D block model. """ - result = { - "top": [], - "bottom": [], - "side": [] # Only one side entry since it's repeated - } - result["top"].append(self.reverse_tex_coord(coord_list[0], coord_list[1], w, h)) - result["bottom"].append(self.reverse_tex_coord(coord_list[8], coord_list[9], w, h)) - result["side"].append(self.reverse_tex_coord(coord_list[16], coord_list[17], w, h)) - return result - - def get_texture_pixel_position(self, column, row, texture_size=16): - x = column * texture_size - y = row * texture_size - return (x, y) + def exit_command_mode(self): + print("Exited command mode.") + + def create_command_line(self): + # Create a container for the pause menu + self.command_batch = pyglet.graphics.Batch() + window_size = self.get_size() + + # Create a semi-transparent background + self.background = pyglet.shapes.Rectangle( + x=0, + y=0, + width=window_size[0], + height=window_size[1]/8, + color=(0, 0, 0), + batch=self.command_batch + ) + self.background.opacity = 25 + + + def on_text(self, text): + """Handles text input in command mode.""" + if self.state_machine.state == GameState.COMMAND_LINE: + self.command_text += text + print(self.command_text) + + def process_command(self, command): + """Processes player commands.""" + parts = command.split() + if len(parts) == 4 and parts[0].lower() == "teleport": + try: + x, y, z = float(parts[1]), float(parts[2]), float(parts[3]) + self.player.position = (x, y, z) # Move player + print(f"Teleported to ({x}, {y}, {z})") + except ValueError: + print("Invalid coordinates!") + else: + print("Invalid command. Use: teleport x y z") \ No newline at end of file From 7174a872edf81e115172fb0efcea7245e7b67454 Mon Sep 17 00:00:00 2001 From: Elijah Kelting Date: Wed, 12 Mar 2025 14:14:16 -0600 Subject: [PATCH 42/46] Update main.py --- main.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/main.py b/main.py index 00bd85dd..46e2aa95 100644 --- a/main.py +++ b/main.py @@ -13,4 +13,5 @@ def main(): pyglet.app.run() # noqa: F405 if __name__ == '__main__': - main() \ No newline at end of file + main() + \ No newline at end of file From 19ff8685045c70c44a4c5f7632937760a834a93c Mon Sep 17 00:00:00 2001 From: StephenieDugan Date: Tue, 11 Mar 2025 19:05:15 -0600 Subject: [PATCH 43/46] Command Line inputs p.1 --- __pycache__/block.cpython-312.pyc | Bin 2123 -> 2246 bytes __pycache__/model.cpython-312.pyc | Bin 19293 -> 22873 bytes __pycache__/player.cpython-312.pyc | Bin 15403 -> 16314 bytes __pycache__/window.cpython-312.pyc | Bin 20524 -> 24483 bytes player.py | 12 ++++- states.py | 1 + window.py | 68 +++++++++++++++++++++++++++-- 7 files changed, 77 insertions(+), 4 deletions(-) diff --git a/__pycache__/block.cpython-312.pyc b/__pycache__/block.cpython-312.pyc index 86d351f1a4c66d7fda4483710490308a30f42fa4..0a13aae9d88498e1716db6843a99f7f8c50d7b3d 100644 GIT binary patch delta 233 zcmX>ta7>W*G%qg~0}xnlxsbkYBCjOJGDZf5=?p0{8}%v}b(k1Z8B-*IP--TpittSU~FeK?E<5_{Cw9o1apelWJGw3giNv$WUyuS({yw nQMrNpA(zO6@EPd~$}e;2H?ZI27M+kjqkIMXWp0B;4zLjbQ;#$R delta 110 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 O@89+h0{`ylgG_0Ab}N@l`7Kf+)6dTOZU*a2wf7 z#xnG{Sr?aK;xbU&z-yu(%r=*qIZYhSxoM-uWSYf&89MiAOV~LrD!62EC+Y8=|MUD` z=k(TTxbp!-UNIPSh^#aBzi<7!Xf(1!4{zbM`qV;`!1ls=jbIYg zTv$a?;HIX~m-|$kd!~)g$0lu@9$sG^i)5XkB9p+-cD69PkXJA3U*ItP&=)f$6`i1; z5@vQN%*h_C)yXQE_metK3lVLL3l(=7ybwzci^w^ZA#7q%7jH4(eWuD>T99AEhWAPz z(u-4WfgsnmV}~fTxqM>X!@njbCLYETL6wEaYvN`>8}5lS^{}$Fu? zuc!!WZDsZvx?%0BYwCi!+PdnhGG}e2)n+kBi-`v*nm`b|Qe^1c66C~oahJ>2=5YsM zYY=t^8TTIY>yivqJBn&CLYJ3PsZ*B}gB#*glOB+}wGWL)AVc(ixXBx)0zMYMw&!+w z=BM+H%^P%$qz|=>xXz`Iwp>py?&kt&2l#;FVALZmic1++quAsp(I_?{0D<`d*Wr}? z*4w6;0c)UhAnmZTAMP9D1KdE`5q`jNBx;bkmXLkjNPPZa%)4n!I9zq0YQTEjJGgYj zF;sL8hDy&ZxHhl&dS=O2&@+}{`=;#MH5b;5t#|fU-7q%Y`)`Ag{?GRMYxepvS4)4@ zkH*&f=G1|h<0}Tak+dP691(Snxt6u;`s~7=%tigSoAHSxkKH#Dl0J?+5;+Ki3kEv} z{AXT0TRd8P$(|L6ypiCz_b=hH(PfuRR8~FCp_#?wJWe(z!+l(6UI;1JV>aV=OE~3X zx(=Wgk7dk-$Ypc=y34ft)AWC=OP42hQq7pKrt`V#Bc!ZZ zMk*!|u|+jCJ;LzPmypC2j;IYou?aLvd@%#y$L5mRuost>#6g16P~rwnDCZ`8xzrA` zl&IzH5Zyz}!&RUKkoMtstoe|soVVU(@*dJING1Xnkm${p3JFwM)IpV3^hs9A*-7CI z3cdI{`y&06(vh5I;N&tMUdP#GHpo|Yls!-(b1$%Dw0@o1&ii*ajKu_3(HVaB9;Zaro@I&ZwY9a=8W14r!R0 ul;eWN4dzf+XHxnz3iPFx=2ED~LydXxCBD_@iRn~B(*E*45&cRti1Z(qKu2`| diff --git a/__pycache__/player.cpython-312.pyc b/__pycache__/player.cpython-312.pyc index 1e59e61876130c568df0d32309a6a8eb747ab5a2..d928b444da1af406497f4e65456c15feb8a4a0dc 100644 GIT binary patch delta 1879 zcmZvcTWk|Y6oz-a-ZhD@!7)*S(-5#JCM0natYDHhIKDt+$0Wp}BE1;LyCg2YgjuH~ zh&Hr@O1(%0jVc-`E#(1G%0r7*su1dHRkgejT9jyn)EiWyQl+%K^`YvVS*QwPq7>vnssz{bIEZcH2tU2)W*r$w;YxSwJ;E2zR4QiL&+VpEVR9x^GW zd1=h7*hvg^uXRv)xR{$&F_lUcMJ?tf{cSXlOvlZ{DYmrK92c@~9*jY$Wmf$|YeG=0 z`jB`4Ase}9?$CcTA3!@S)U2t+L)gZ=@KX%brd4xQwUonCjMOtKH6HjqU}W3U^hQ9ukZ z0N4#k0QN8#fj97hd&phK*DTCs=QYu~30xk;nsV14+zWOqAPpF12-M=oPJm6+GMmkn zCyFYy%ovj=9t?UI=K^t$e#f0a?C>^Ev&G*6aU`A;Eb*AbsmOuB^lt2D79Ig4Ny!^( z@^a7dVkLi=%2TuK*eXvc?k8V))96KFZI1OkdP^#gPgkpzGOb}^77i6utl?b{#?Dkx z^Ho(DfN*$_yw&WJd*H01{zdaLyB%rsH0tMDj)`+a>~lI`$8b~p5&-UrUk30yLh7hk z%FQqo%6JkMKxwS}wwgDQpr>BH?K>&XjWRnOuoWNz8qfrQ+T(>uE%{2ZSWwgl zDpQkEWs*#(szQ-sR1m)zl+pi+EY3^~#I-%5?(bXnLjFcVji%dcNHG-9U*FncM&FSi zJ4eVr9cRqPQB@#AW-mD%l2Dv{ysm-#WO9?vV1!i7Zrf$VLb8E`SxJAtb2}nuIzzAm z{?4ng`{8(HfQ+;^pcaUMV&qD@yH!%;CV}-O{5n2nrAKxo_zui>43eKs_2iRv9=7*L z&`WxQ?~0aO2l=CQy?!U?MLe&WL>gyUq<|koYf|()=CzMTDT+`OqtfVbBpNqT+z1|W zYIM(FBE!|7QYxC+m*P@TIX)VV49AV)m;hHX6B)qI@L5qUV_xF&WTiTu!#FR@v2;J7 z>ZmP0$=XiM8ePNdO@SDa`l?#4QhR)VJe|qziKJtxc#NVbwMF+14KXvD8cfG&%|IlY zssqkGd^kzDM z0^&V*IPXD!;13xB2=@|gXJ>i`d`SZMOyx7GD5cs2l_qHvzP(3|n~!Ia1N2xkAq{d-LxdmX2X V>T~!4`M!71nUawIF9FD%{snP_#*F{~ delta 1477 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 delta 3593 zcmai14Qx}_6@J%0&ra-^5a-7MJGDbX;t&!NlA=&B0h3Z72@oihF!FHxUW~!9z5AY% z;Gpp{)PYu&Wv80Du9{kP8;eL8ZMtcj)^*)ai&jcIX=|rP*TR^fS%1U|T{|kI-E(b| zgl*cB{Nc0+;eZ9d5KIsMI5gc6yyu+`lD%-MwhTI2o$!RgM+#wyxdi@N>$FXf(?;|z2m}%aS60FXSG-QRU??RA z$Hq$jr%=a6Cv+Q2s}2hLDl$f9;tbP*=7S^i-Eg+l>NqG!g*h>;8b+48;ipCy{MqDd zEz0p_fk_q5qDpd91m{X~l-2+Z>)qfo7w5?a*(jT2^Feq{ELkX<(`;L1QMSm|iM-R+ zi~>`gpHpQ~x53jrZm-smW9?g>8%_V+w~}wxYa5*oIbZYUCib<%g^p6FwH6p`-LS#B zfaox09U?xk=G_PVd81I2Ujf1VFWhdXlAg088kZBp4U!a%M>R=uFs6ExK(DRAa9xBq zZN+fL_6Q{Hjf|Y!T=1yThFeOPA=JWDVMSpb8|v0%LXB$CM4Z+`(cHFWZOAmp8m-3x z8PtiSn%U5cA6>~t+(fz{>pzv0Lz)tRqjS%Z0PK0F9OR;(k@-;JT;xGpvph$?(g_33d&mxW*jYsalc$~EA@|K;^HT-{69e5i)Ew>h=h3B%pqL-J7}=t%#1u`@ z&BIYy+e@2qq7jaicxt)3tw?hwCYbB#B(92#z!l&c;FS_D>4R$}z&wwZzCa991e#n= zESPOTw+=;>;bekpD#nx5{n#~+3_@P{H`r=NOUoxG%P$$oPI$~+xoH=Z(yftLM?BOY zQ|NB=--jR}>_G@2^dp2B=#EG%wOOHRQVDC(A-1N0SR$lR1qJHB>}d`LQOq8RZKI*M z8e=;>;J47(anb=4pRwAsYGE9VmwjxxY0o@ylyTHs;3#*&^Pa2j03*YMLGHs8V}5R& zHNfrWn#qe5Ck*hu?_Tdt#_aYN>E>`u2~nysQqPOTf{9pyE|pm&1uCnXBFN2`X=qrA zh5D74Zs%jFXi=s{vG8=Ws&G^oT=Qh!Jb?;R(6eJVzm zDLCDdh)ZZN?Z_5gmVT6ps2>X8S}s}5HBNxxf^vXKd zcXw>1M^JfsPw7EMr=8jToSCg(z>|v>F>B{*$|o-`sv*lZGs$c0$G%Iet`(nIcR5{r zbrqe*Xo}T=$!Fi%_UvF=d$->~qp)i6n0=;KcxSPf{043>eu!D$-thhY$C(!WHo_fS z-F_2Rdk|}lml%z*dEL&^5`3_e6QN_z~!Z@{=fekkXp)Z0%69p{;`EV+0tq` z^h@-}0Wa;TZy{hCA2-pLaB3R(yc2C;Zg>g$jhQiLAo#@@XLb5YC`W}622*^54Tu&X zS%tZyn-DMtT@3T(ja#S_dBq6R2eAxE7Xr7nk&VX9*?D+mg)4|`UF=cR)SyC-F=Fa# z4AOJAq@tQvOL)6j5qP^;%kx)cIt2D2-Mj|-A1_C`3$Cr$De`8}1oy9OF67?%N=lh5 zZHD73j}&IgSQ*ijxI8Y>HYg8hRlF(v9R0bnr4ptJYrWERr!`GJ7uaabo{WhtNqBgT zXDP2c-m2~4y`gwSk!E!4N_2X6J?ik*8XxI_&(}0$ZM6q?)nom!=7pB%6hfxu|2G5g z!mGh*vK>BRn7K~t*LtiaFQP0@_^)vEGQzK+ue0WoRxI0Im3DDM4VS5VC%imET z0R26Eex4*FU%GA#C6l^I8HsBDp?yn$sh$e&_n5X?$g~d&@7Rk@ZaA^wy(7U_(5I##Y&r9B7cOV%-&=8Iyq!I8b!mpo9BR`F#7r}>sJ&sl(V7H+)2w2Qi zM|c;Z1>rMM}K~#A1@L& yMncG6gnO Date: Wed, 12 Mar 2025 13:01:33 -0600 Subject: [PATCH 44/46] command prompt is done --- __pycache__/player.cpython-312.pyc | Bin 16314 -> 16338 bytes __pycache__/window.cpython-312.pyc | Bin 24483 -> 24515 bytes player.py | 2 +- window.py | 19 ++++++++++--------- 4 files changed, 11 insertions(+), 10 deletions(-) diff --git a/__pycache__/player.cpython-312.pyc b/__pycache__/player.cpython-312.pyc index d928b444da1af406497f4e65456c15feb8a4a0dc..437beba4c9494d967c189b9036e88bc4535884c6 100644 GIT binary patch delta 91 zcmV-h0HpuAf6{*q%MA?*00000W!KSXfw2ueDgp4bODb#!0m75GF(m;hlio2hli)EF xvk)??0|5}TyfvBv94jxcJE=R@D?`yML%>78QqU_%kOY?tkqgxjD6?)jOb6&=Am#u7 delta 99 zcmV-p0G$8Qf4YAS%MA?*00000V8_sBda(^XDgxXHk~t}p%_=0bnJOL!0l1U6F(m;X zlYlZR2V@0g1{wf-vm-LB0|5-P&^4L@7$hjCOQB2GBs|e1Jh)T1V$dW(kOb8bA+v@! FOb2u4A$kA+ diff --git a/__pycache__/window.cpython-312.pyc b/__pycache__/window.cpython-312.pyc index 2e6ab489e7e49af2460ae3efe1c37ce67bd3873e..be3abd15e57a940f678b54302749aea56096a855 100644 GIT binary patch delta 3648 zcmai13s98T72dmV*nd|L7g%xEU0{Lbp*)26KtUd{$^t6BNR;1Y{~uWW+1=dT6+s(_ zCPv#dn%qvNoypkPByFjg&X}D}Yih^Xc8oRVK`I4*O{>$6#F{va=4mH0z32W*0F#+6 z@Nw?F=bn4-Io~<=?#pM&4?no%05GQMTHpHv^}?eztPv_YrB`Y9&u5zk#wz zjmd^i#@kJ6)K#AvRqmo+Hl1i1%dH&AtsLhv#?$TN>6zn}lw)<{)~uI$#^>funpN(q zdn$uF`LOn~(KVS8|GBwZW6Gr~;6{K7ax2AQsswQXi{6 z(NWO}AKV0rFnhqfH4qd+eT!mY!50y1sxA?ZGuLP)(k&+D*(Z z5A7NY@@jX__hB;p=eB>=DsU^jpS&hc)y>>c9A$acG(o@Bs2U;iVjAGuE~woLN6{pJEM zZTb;~sSm^hoO$mR4f(n}KYrDrRU-|#?mWn_lKj+_scjR~`^n&PD;gk8TAP};KJRsq zH=Pc&pUnAQI;nBm_5GTDjYms9c2&8sgW7BHWXL+dB>FHOq)j=gTdEI9AzUF)vaHH> zmtp8l7O=06mwcU~By&v0Vl+UfVc?dmi$v)OG58thkRN9k43r@_aD}5>@uWdzsYTcuugtZmQ6*`}b6P8u-NrgaevgRh@x=%}K>G6*yQ}F4 z-U;v|=or^{`3;*_H?+wHDm}c`>xI~pck=A$adJD)u4gIr6tUzx&}mYVf1EP-QvOA> zYdSHR#dLiZ1pA^`PJf^tLtE5JHQHbjA`$}TUI@l~g3pR&sb&WMY^-n@i8F-Q}V4@~vtZy&fO8aP z?Wmaiv3$NMnJ$h01PaQk|1JMT4R{2<0q_HWKLDJeFl+iE+VKrH5*vUDAXv!tirW9b z{9?i{v6-whmWLAk;*v^3-bGlDK{}Ogy#P>7VOWdbh9L#W7b`rAluH6S?EnWU++xX4 z0?kxt=7N+0aFMiB7o&q@U$v(mG-drpF%s()@iEY2WKZ1?3q+mKkh7V_#@S4Zna6>@ z$#_{;$0{4J1b2~%>UKR##Z~0tl@FQNURV;=ki#pVNKuF-?v08;VOURVf^Ahaw+W`6 zr!bJ22%aB{w4U*z;Oc7|!sJk$y@D|Tjv{mZ9$&Cqs+Xtd|9_BVXL8cNWq?r%vUWYCEAu?QLfZp#raa#uMs`O-VUKIt z?^uRujEr!7Yy$nRwji>X#Wz6J^( z0wh9L+nk~Q7qtIPb~M+ckI0GUWloj?A4Bga6e4;G@Ti!|{yK8Mc>xN>Gg|gd2kNn` zPhrAm01pO3OO|e2X!RVxL8B4+$~a93sIt2PHZLozoN zFp9LLf2UeG`Sm7y**RF>q^xf=zi-JMHM;S)o-Xi~*3iFuvNI zF&HOW=r{&T_&tF4DR`0|jP^4y#G?HVkp2m99pDB9k5ZZO9V*YNN@nu-)`j}Nz*aGN zc`Me98W&Rk?A$il$|!#rEHKKKg2Y}YaONq4z=@d#*?S~Pb9m-^1lptIXYFhC?D%Rj zl0Pr5e&irR+sUCvhdPc^BeG5k^@$kofn_QI*c%+yl9RXiq?p)W&*ByQqq^AH50YH6I?#thS zQ~&_C61z%pF-TC;@nV4U0C1t>+W>U{TIyA704RfIxr%CHGqh6yvM9)Ap7%?>NW?En z63=^(^2LCTsA_Q&De1^E)aY8#-8waC?Xc-GbR~DoNpDA2l||>io2}KkKj%!k<&0Gr znB+0b$voc`i^j0X^B9PQ`vKr-L?7Qtyr&qdGhET|ZG}xz?mGw#`zCVVSlt^EVv@KD gyGaLMnAL7T%MWiky5q=>F|%vL?D|XvJ#5kc0b8oDFaQ7m delta 3768 zcmaJ^eQZL9**Bj;?%L7`<@9H z))-1x*u>ZFKh-u(W7ArpN~7RyEmI4dkOpnHkxZ~;Z!iUkwPlsI48}A~L)tm-+4*WU zC;Iu`bI(2Z+;e~D-0K_H$&aoR>nB!gk_JBXqsgK5m#y~+*%JMNT-GNX)r@qq6~*}$ zX(Nu~XJjiQsp+JfT~5h#^r*7M$frmZ@%~6J8!?rTRCdO6)BKq#oojZLM^7bwov?iK z)jT^0!zsJGem*c>&2e78SK_!75Q^i`Idi90J7_2%^Z1 zg@lkGCyIhc3Q%uYp!KM;7GWK`zhXmDJF07W3A*;Q4BJ*5K|5he1as%`f)EW4bvtZXkS*rkFz!zecE*n zFZHROe?5AjP)G8+K-oh8;vYRUFv3sP=$JdZIC`NdQA@NexIT*==*eKW?PfOX=v^jx zBR`!59Et3BaXL#WF4AicYh5~4Ri_wWPE* zfYKzMy2m-6dqD8X7Nt!E$qUmcGEUZu66}&DK$|+)os#mGD^Z*pbcaNN8x{N^Zon;h zhG{j5t)9T>sN2u0vWr9sjfi`+E1Z#y0Y8U}gp*_Bi}l|G710(Qbn1!Ck~(cEoU#;7 zTS}%ZC3h{Qb2?3O3!zntyD9sz-DMpfYu2b_0{Mv$mfQ~jgI*~#)ka*4fN{(a!|7T3pQVj-Ut zt1W26I0Rf942rVOC-~KbG;rc@VB8N}4^SUZl}z{==+a{Vt^}1N^E{{Mi-=Lh<<)$8 z4SL}fvAE2iiq?0Hov(}lh105jRWSiNN^U7;Wm9Jl*VEP8@gn^u+FJ-TJ;9z;<&aw} zYgHv|q;*vb$=L%cu^Ken{8`3NIv<2HK5eFj>^s$kWQ<*{K5toUh4t6i$!#`Xvm4f) ztogC|0UKn_gWDMlQ75SaI#A zo10OqA7KNUFvJ*i5<5mg$xHsCR*9HwfYJfM7PT-K57bK5RhLKp&V;&MVD-Z~SGJOY zFM!Gty)yQ!E-lqMphE3NylocGU z^aC9D5aAlYl65LT5YAjuO}U`Yec0>o`kYH?-!hmAGm89>N<4?;~6VSYoq^ zZEnaR3GAhY7S)5z|IdR}Fg={H%md6&-n`&I^jSl%(Qp%&yUDgUWtwkcQw28Gk% z#|1bN0eED?7N$I1fn6uIQW0*lTTN9Y!k#v{k|Q9H4KD~{XjGu5S=FY(?D-6o^{q;M zz|*B3=H9f&prpk{_RCG{%*v8j_-PZ2_YPk1V4Y#K-(E>mJC~Q{06hO6p)l? zWlOg%#-(#@r|XqNR4SFlGwk*c3EZNBRgM#vAMQi8t=&QPG1^|O*paI6Xdy$<3Vnir zc}X1z%O`)%Hg}Z5oi_y76+PXt)->^J)KjAP5w<=?_yi!F+8Y?Rd;Rupho#|w-{Ej5 zA*8=U1*EeYN4)E)awxa4HHk2V@OuC`VH@y>p2q$k0KzHTLte=)1?=sD_=*$=x*U0Q zKGbv?^%PR!Ek|eAzTT?dZ(tMSEE`3S+b3{`lsh-xJ52wG3NnIvFsQmh1Oki0+zvPj z^>U!IsPTYJ_qLJ0u)MwvO?X!H5yD>qmR#E?#4HbI$2jSs0$d~9sN3sTE)70}Tf8d+=k*Iz;pOt3)PQ=}7Tby7hkKQaPZ|yI!WH)Io#ioZ-`Uyd`AQqB(MC?(25fAJ ziTBWHv+A_TI+^UeYbvE*dT5}6^3XUF9qTs|iv)f3Gm?gn+pNrZf8m=q9%T=Tpt=B?b6E|B93T1xEaRmbjaC-!T7353oPvK#8?gyoSAA#W| zMSz{yTSa7cdGFsQ>@cSOcY0mkRbidR_YD5jQzog;3CvFA0r(%&MyLWIpRkEK*{fVd-fkmlJlTJC T->H4mR>zdp@l=BnWzqiu0OrdR diff --git a/player.py b/player.py index e66a94cb..ebffba7e 100644 --- a/player.py +++ b/player.py @@ -322,7 +322,7 @@ def on_key_press(self, symbol, modifiers): return pyglet.event.EVENT_HANDLED elif self.state_machine.state == GameState.COMMAND_LINE: if symbol == key.BACKSPACE: - self.command_text = self.window.command_text[:-1] + self.window.command_text = self.window.command_text[:-1] elif symbol == key.ENTER: self.window.process_command(self.window.command_text) self.state_machine.change_state(GameState.PLAYING) diff --git a/window.py b/window.py index 90b0f417..37adada8 100644 --- a/window.py +++ b/window.py @@ -80,6 +80,14 @@ def __init__(self, *args, **kwargs): x=10, y=self.height - 10, anchor_x='left', anchor_y='top', color=(0, 0, 0, 255)) + self.command_prompt_label = pyglet.text.Label( + "Command: ", + font_name="Arial", + font_size=18, + x=10, y=10, + anchor_x="left", anchor_y="bottom", + color=(255, 255, 255, 255) + ) self.create_main_menu() # This call schedules the `update()` method to be called @@ -189,7 +197,9 @@ def on_draw(self): elif self.state_machine.state == GameState.PAUSED: self.pause_menu_batch.draw() elif self.state_machine.state == GameState.COMMAND_LINE: + self.command_prompt_label.text = 'Command: ' + self.command_text self.command_batch.draw() + self.command_prompt_label.draw() def draw_focused_block(self): """ Draw black edges around the block that is currently under the @@ -576,15 +586,6 @@ def create_command_line(self): ) self.background.opacity = 25 - self.command_prompt_label = pyglet.text.Label( - "Command: " + self.command_text, - font_name="Arial", - font_size=18, - x=10, y=10, - anchor_x="left", anchor_y="bottom", - color=(255, 255, 255, 255), - batch= self.command_batch - ) def on_text(self, text): """Handles text input in command mode.""" From 1f578700d48a8a552a1e3cde2a7b2c5961638d22 Mon Sep 17 00:00:00 2001 From: Elijah Kelting Date: Wed, 12 Mar 2025 14:26:45 -0600 Subject: [PATCH 45/46] Merge branch 'PRO250-ThanosBaddies' into SteefBranch --- EventDispatcher.py | 17 --------- MainMenu.py | 0 Steve_Hand.png | Bin 8923 -> 0 bytes inventory.py | 16 +------- player.py | 10 ++--- window.py | 93 --------------------------------------------- 6 files changed, 5 insertions(+), 131 deletions(-) delete mode 100644 EventDispatcher.py create mode 100644 MainMenu.py delete mode 100644 Steve_Hand.png diff --git a/EventDispatcher.py b/EventDispatcher.py deleted file mode 100644 index 69bd4881..00000000 --- a/EventDispatcher.py +++ /dev/null @@ -1,17 +0,0 @@ -BLOCK_CHANGED = "block_changed" - -class EventDispatcher: - def __init__(self): - self.listeners = {} - - def register_listener(self, event_type, listener): - """Register a listener for a specific event type.""" - if event_type not in self.listeners: - self.listeners[event_type] = [] - self.listeners[event_type].append(listener) - - def dispatch_event(self, event_type, *args, **kwargs): - """Trigger all listeners for a specific event type.""" - if event_type in self.listeners: - for listener in self.listeners[event_type]: - listener(*args, **kwargs) \ No newline at end of file diff --git a/MainMenu.py b/MainMenu.py new file mode 100644 index 00000000..e69de29b diff --git a/Steve_Hand.png b/Steve_Hand.png deleted file mode 100644 index d71f18d6cfc2ab5ef40285416ed6ad22c7c14b31..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8923 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 Y-4o%ye?P;zDSt2OD$kTl6fML5AB|5ZO#lD@ diff --git a/inventory.py b/inventory.py index b78fde19..21d587ab 100644 --- a/inventory.py +++ b/inventory.py @@ -1,18 +1,6 @@ import block -from EventDispatcher import BLOCK_CHANGED class Inventory: - def __init__(self, dispatcher, *args, **kwargs): + def __init__(self, *args, **kwargs): self.hotbar = [block.PORTAL, block.STONE, block.SPRUCE_WOOD_PLANK, block.BIRCH_WOOD_PLANK, block.JUNGLE_WOOD_PLANK, block.ACACIA_WOOD_PLANK, block.DARK_OAK_WOOD_PLANK] - self.index = 0 - self.dispatcher = dispatcher - - def set_index(self, index): - """Set the selected slot index and notify listeners.""" - self.index = index - self.dispatcher.dispatch_event(BLOCK_CHANGED) - - def get_selected_block(self): - """Get the block in the currently selected slot.""" - self.dispatcher.dispatch_event(BLOCK_CHANGED) - return self.hotbar[self.index] \ No newline at end of file + self.index = 0 \ No newline at end of file diff --git a/player.py b/player.py index ebffba7e..ade69da1 100644 --- a/player.py +++ b/player.py @@ -35,9 +35,9 @@ def __init__(self, model: Model, window, statemachine, position = (80, 10, 80), self.PLAYER_HEIGHT = 2 + self.inventory = inventory.Inventory() self.model = model self.window = window - self.inventory = inventory.Inventory(window.dispatcher) self.state_machine = statemachine self.window.push_handlers(self) @@ -196,7 +196,6 @@ def on_mouse_press(self, x, y, button, modifiers): if previous: texture = self.model.world[selectedBlock] self.inventory.hotbar[self.inventory.index] = texture - self.inventory.get_selected_block() else: self.window.set_exclusive_mouse(True) if self.state_machine.state == GameState.PAUSED: @@ -302,7 +301,7 @@ def on_key_press(self, symbol, modifiers): self.flying = not self.flying elif symbol in self.num_keys: index = (symbol - self.num_keys[0]) % len(self.inventory.hotbar) - self.inventory.set_index(index) # Update the selected slot + self.inventory.index = index if self.state_machine.state == GameState.PLAYING: if symbol == key.ESCAPE: @@ -317,9 +316,6 @@ def on_key_press(self, symbol, modifiers): self.window.set_exclusive_mouse(True) self.state_machine.change_state(GameState.PLAYING) return pyglet.event.EVENT_HANDLED - elif self.state_machine.state == GameState.MAIN_MENU: - if symbol == key.ESCAPE: - return pyglet.event.EVENT_HANDLED elif self.state_machine.state == GameState.COMMAND_LINE: if symbol == key.BACKSPACE: self.window.command_text = self.window.command_text[:-1] @@ -327,7 +323,7 @@ def on_key_press(self, symbol, modifiers): self.window.process_command(self.window.command_text) self.state_machine.change_state(GameState.PLAYING) return pyglet.event.EVENT_HANDLED - + def on_key_release(self, symbol, modifiers): """ Called when the player releases a key. See pyglet docs for key mappings. diff --git a/window.py b/window.py index 37adada8..b1a1c0ba 100644 --- a/window.py +++ b/window.py @@ -4,14 +4,10 @@ import model import player import random -import block from states import GameState, StateMachine -from EventDispatcher import EventDispatcher, BLOCK_CHANGED #from collections import deque from pyglet.gl import * # noqa: F403 -from pyglet import image -from pyglet import sprite class Window(pyglet.window.Window): @@ -48,24 +44,9 @@ def __init__(self, *args, **kwargs): # Instance of the model that handles the world. self.model = model.Model() - - # Load the block texture atlas - self.block_texture = image.load('Textures.png') - self.block_texture_atlas = self.block_texture.get_texture() - - glEnable(self.block_texture_atlas.target) # typically target is GL_TEXTURE_2D - glBindTexture(self.block_texture_atlas.target, self.block_texture_atlas.id) - - # Initialize the inventory bar - - self.dispatcher = EventDispatcher() - - self.dispatcher.register_listener(BLOCK_CHANGED, self.on_block_changed) # Instance of the player that interacts with the world. self.player = player.Player(self.model, self, self.state_machine) - - self.inventory_bar = self.create_inventory_bar() # Which sector the player is currently in. self.sector = None @@ -186,8 +167,6 @@ def on_draw(self): self.set_2d() self.draw_label() self.draw_reticle() - self.inventory_bar[0].draw() # Draw the inventory bar batch - self.draw_bottom_right_image("Steve_Hand.png").draw() # Draw the background image first if self.state_machine.state == GameState.MAIN_MENU: self.background_sprite.draw() @@ -453,78 +432,6 @@ def create_main_menu(self): # Add buttons to the GUI widgets list self.gui_widgets.extend([self.quit_button, self.play_button]) - def create_inventory_bar(self): - """Create the inventory bar with only block textures.""" - slot_size = 40 - slot_spacing = 5 - num_slots = len(self.player.inventory.hotbar) - - total_width = num_slots * slot_size + (num_slots - 1) * slot_spacing - start_x = (self.width - total_width) // 2 - start_y = 20 - - inventory_batch = pyglet.graphics.Batch() - - # Create groups for z-order control - background_group = pyglet.graphics.OrderedGroup(0) - foreground_group = pyglet.graphics.OrderedGroup(1) - - # Highlight the selected slot (background layer) - selected_slot_index = self.player.inventory.index - selected_slot_border = pyglet.shapes.Rectangle( - x=start_x + selected_slot_index * (slot_size + slot_spacing) - 2, - y=start_y - 2, - width=slot_size + 4, - height=slot_size + 4, - color=(255, 223, 64), - batch=inventory_batch, - group=background_group - ) - selected_slot_border.opacity = 180 # Softer effect - - # Slots and their corresponding textures - slots = [] - for i in range(num_slots): - slot_x = start_x + i * (slot_size + slot_spacing) - - # Block texture - block_texture = self.player.inventory.hotbar[i] - if block_texture != block.NONE: - reversed_coords = self.reverse_tex_coords_list(block_texture) - pixel_coords = self.get_texture_pixel_position(reversed_coords["side"][0][0], reversed_coords["side"][0][1]) - # Get the correct texture region for the block - texture_region = self.block_texture_atlas.get_region( - pixel_coords[0], - pixel_coords[1], - 16, 16 - ) - texture_sprite = sprite.Sprite( - img=texture_region, - x=slot_x + 4, y=start_y + 4, - batch=inventory_batch, - group=foreground_group # Textures drawn in front - ) - texture_sprite.scale = (slot_size - 8) / 16 - slots.append(texture_sprite) - - return inventory_batch, slots, selected_slot_border - - def draw_bottom_right_image(self, image_path): - texture_image = pyglet.image.load(image_path) - - image_width = texture_image.width - image_height = texture_image.height - x_position = self.width - image_width - y_position = 0 - - # Create and draw the sprite - texture_sprite = sprite.Sprite( - img=texture_image, - x=x_position, - y=y_position - ) - return texture_sprite - def play_button_pressed(self): print("Resume button pressed") self.state_machine.change_state(GameState.PLAYING) From 7d2ae94d013a3c0f48ef24b7ef11dd3043d21c5b Mon Sep 17 00:00:00 2001 From: Elijah Kelting Date: Wed, 12 Mar 2025 14:37:26 -0600 Subject: [PATCH 46/46] Merge branch 'SteefBranch' of https://github.com/Elispse/Minecraft into SteefBranch --- __pycache__/player.cpython-312.pyc | Bin 16338 -> 16314 bytes __pycache__/window.cpython-312.pyc | Bin 24515 -> 24483 bytes player.py | 2 +- window.py | 20 ++++++++++---------- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/__pycache__/player.cpython-312.pyc b/__pycache__/player.cpython-312.pyc index 437beba4c9494d967c189b9036e88bc4535884c6..d928b444da1af406497f4e65456c15feb8a4a0dc 100644 GIT binary patch delta 99 zcmV-p0G$8Qf4YAS%MA?*00000V8_sBda(^XDgxXHk~t}p%_=0bnJOL!0l1U6F(m;X zlYlZR2V@0g1{wf-vm-LB0|5-P&^4L@7$hjCOQB2GBs|e1Jh)T1V$dW(kOb8bA+v@! FOb2u4A$kA+ delta 91 zcmV-h0HpuAf6{*q%MA?*00000W!KSXfw2ueDgp4bODb#!0m75GF(m;hlio2hli)EF xvk)??0|5}TyfvBv94jxcJE=R@D?`yML%>78QqU_%kOY?tkqgxjD6?)jOb6&=Am#u7 diff --git a/__pycache__/window.cpython-312.pyc b/__pycache__/window.cpython-312.pyc index be3abd15e57a940f678b54302749aea56096a855..2e6ab489e7e49af2460ae3efe1c37ce67bd3873e 100644 GIT binary patch delta 3768 zcmaJ^eQZL9**Bj;?%L7`<@9H z))-1x*u>ZFKh-u(W7ArpN~7RyEmI4dkOpnHkxZ~;Z!iUkwPlsI48}A~L)tm-+4*WU zC;Iu`bI(2Z+;e~D-0K_H$&aoR>nB!gk_JBXqsgK5m#y~+*%JMNT-GNX)r@qq6~*}$ zX(Nu~XJjiQsp+JfT~5h#^r*7M$frmZ@%~6J8!?rTRCdO6)BKq#oojZLM^7bwov?iK z)jT^0!zsJGem*c>&2e78SK_!75Q^i`Idi90J7_2%^Z1 zg@lkGCyIhc3Q%uYp!KM;7GWK`zhXmDJF07W3A*;Q4BJ*5K|5he1as%`f)EW4bvtZXkS*rkFz!zecE*n zFZHROe?5AjP)G8+K-oh8;vYRUFv3sP=$JdZIC`NdQA@NexIT*==*eKW?PfOX=v^jx zBR`!59Et3BaXL#WF4AicYh5~4Ri_wWPE* zfYKzMy2m-6dqD8X7Nt!E$qUmcGEUZu66}&DK$|+)os#mGD^Z*pbcaNN8x{N^Zon;h zhG{j5t)9T>sN2u0vWr9sjfi`+E1Z#y0Y8U}gp*_Bi}l|G710(Qbn1!Ck~(cEoU#;7 zTS}%ZC3h{Qb2?3O3!zntyD9sz-DMpfYu2b_0{Mv$mfQ~jgI*~#)ka*4fN{(a!|7T3pQVj-Ut zt1W26I0Rf942rVOC-~KbG;rc@VB8N}4^SUZl}z{==+a{Vt^}1N^E{{Mi-=Lh<<)$8 z4SL}fvAE2iiq?0Hov(}lh105jRWSiNN^U7;Wm9Jl*VEP8@gn^u+FJ-TJ;9z;<&aw} zYgHv|q;*vb$=L%cu^Ken{8`3NIv<2HK5eFj>^s$kWQ<*{K5toUh4t6i$!#`Xvm4f) ztogC|0UKn_gWDMlQ75SaI#A zo10OqA7KNUFvJ*i5<5mg$xHsCR*9HwfYJfM7PT-K57bK5RhLKp&V;&MVD-Z~SGJOY zFM!Gty)yQ!E-lqMphE3NylocGU z^aC9D5aAlYl65LT5YAjuO}U`Yec0>o`kYH?-!hmAGm89>N<4?;~6VSYoq^ zZEnaR3GAhY7S)5z|IdR}Fg={H%md6&-n`&I^jSl%(Qp%&yUDgUWtwkcQw28Gk% z#|1bN0eED?7N$I1fn6uIQW0*lTTN9Y!k#v{k|Q9H4KD~{XjGu5S=FY(?D-6o^{q;M zz|*B3=H9f&prpk{_RCG{%*v8j_-PZ2_YPk1V4Y#K-(E>mJC~Q{06hO6p)l? zWlOg%#-(#@r|XqNR4SFlGwk*c3EZNBRgM#vAMQi8t=&QPG1^|O*paI6Xdy$<3Vnir zc}X1z%O`)%Hg}Z5oi_y76+PXt)->^J)KjAP5w<=?_yi!F+8Y?Rd;Rupho#|w-{Ej5 zA*8=U1*EeYN4)E)awxa4HHk2V@OuC`VH@y>p2q$k0KzHTLte=)1?=sD_=*$=x*U0Q zKGbv?^%PR!Ek|eAzTT?dZ(tMSEE`3S+b3{`lsh-xJ52wG3NnIvFsQmh1Oki0+zvPj z^>U!IsPTYJ_qLJ0u)MwvO?X!H5yD>qmR#E?#4HbI$2jSs0$d~9sN3sTE)70}Tf8d+=k*Iz;pOt3)PQ=}7Tby7hkKQaPZ|yI!WH)Io#ioZ-`Uyd`AQqB(MC?(25fAJ ziTBWHv+A_TI+^UeYbvE*dT5}6^3XUF9qTs|iv)f3Gm?gn+pNrZf8m=q9%T=Tpt=B?b6E|B93T1xEaRmbjaC-!T7353oPvK#8?gyoSAA#W| zMSz{yTSa7cdGFsQ>@cSOcY0mkRbidR_YD5jQzog;3CvFA0r(%&MyLWIpRkEK*{fVd-fkmlJlTJC T->H4mR>zdp@l=BnWzqiu0OrdR delta 3648 zcmai13s98T72dmV*nd|L7g%xEU0{Lbp*)26KtUd{$^t6BNR;1Y{~uWW+1=dT6+s(_ zCPv#dn%qvNoypkPByFjg&X}D}Yih^Xc8oRVK`I4*O{>$6#F{va=4mH0z32W*0F#+6 z@Nw?F=bn4-Io~<=?#pM&4?no%05GQMTHpHv^}?eztPv_YrB`Y9&u5zk#wz zjmd^i#@kJ6)K#AvRqmo+Hl1i1%dH&AtsLhv#?$TN>6zn}lw)<{)~uI$#^>funpN(q zdn$uF`LOn~(KVS8|GBwZW6Gr~;6{K7ax2AQsswQXi{6 z(NWO}AKV0rFnhqfH4qd+eT!mY!50y1sxA?ZGuLP)(k&+D*(Z z5A7NY@@jX__hB;p=eB>=DsU^jpS&hc)y>>c9A$acG(o@Bs2U;iVjAGuE~woLN6{pJEM zZTb;~sSm^hoO$mR4f(n}KYrDrRU-|#?mWn_lKj+_scjR~`^n&PD;gk8TAP};KJRsq zH=Pc&pUnAQI;nBm_5GTDjYms9c2&8sgW7BHWXL+dB>FHOq)j=gTdEI9AzUF)vaHH> zmtp8l7O=06mwcU~By&v0Vl+UfVc?dmi$v)OG58thkRN9k43r@_aD}5>@uWdzsYTcuugtZmQ6*`}b6P8u-NrgaevgRh@x=%}K>G6*yQ}F4 z-U;v|=or^{`3;*_H?+wHDm}c`>xI~pck=A$adJD)u4gIr6tUzx&}mYVf1EP-QvOA> zYdSHR#dLiZ1pA^`PJf^tLtE5JHQHbjA`$}TUI@l~g3pR&sb&WMY^-n@i8F-Q}V4@~vtZy&fO8aP z?Wmaiv3$NMnJ$h01PaQk|1JMT4R{2<0q_HWKLDJeFl+iE+VKrH5*vUDAXv!tirW9b z{9?i{v6-whmWLAk;*v^3-bGlDK{}Ogy#P>7VOWdbh9L#W7b`rAluH6S?EnWU++xX4 z0?kxt=7N+0aFMiB7o&q@U$v(mG-drpF%s()@iEY2WKZ1?3q+mKkh7V_#@S4Zna6>@ z$#_{;$0{4J1b2~%>UKR##Z~0tl@FQNURV;=ki#pVNKuF-?v08;VOURVf^Ahaw+W`6 zr!bJ22%aB{w4U*z;Oc7|!sJk$y@D|Tjv{mZ9$&Cqs+Xtd|9_BVXL8cNWq?r%vUWYCEAu?QLfZp#raa#uMs`O-VUKIt z?^uRujEr!7Yy$nRwji>X#Wz6J^( z0wh9L+nk~Q7qtIPb~M+ckI0GUWloj?A4Bga6e4;G@Ti!|{yK8Mc>xN>Gg|gd2kNn` zPhrAm01pO3OO|e2X!RVxL8B4+$~a93sIt2PHZLozoN zFp9LLf2UeG`Sm7y**RF>q^xf=zi-JMHM;S)o-Xi~*3iFuvNI zF&HOW=r{&T_&tF4DR`0|jP^4y#G?HVkp2m99pDB9k5ZZO9V*YNN@nu-)`j}Nz*aGN zc`Me98W&Rk?A$il$|!#rEHKKKg2Y}YaONq4z=@d#*?S~Pb9m-^1lptIXYFhC?D%Rj zl0Pr5e&irR+sUCvhdPc^BeG5k^@$kofn_QI*c%+yl9RXiq?p)W&*ByQqq^AH50YH6I?#thS zQ~&_C61z%pF-TC;@nV4U0C1t>+W>U{TIyA704RfIxr%CHGqh6yvM9)Ap7%?>NW?En z63=^(^2LCTsA_Q&De1^E)aY8#-8waC?Xc-GbR~DoNpDA2l||>io2}KkKj%!k<&0Gr znB+0b$voc`i^j0X^B9PQ`vKr-L?7Qtyr&qdGhET|ZG}xz?mGw#`zCVVSlt^EVv@KD gyGaLMnAL7T%MWiky5q=>F|%vL?D|XvJ#5kc0b8oDFaQ7m diff --git a/player.py b/player.py index 2f70578f..db3afa8e 100644 --- a/player.py +++ b/player.py @@ -318,7 +318,7 @@ def on_key_press(self, symbol, modifiers): return pyglet.event.EVENT_HANDLED elif self.state_machine.state == GameState.COMMAND_LINE: if symbol == key.BACKSPACE: - self.window.command_text = self.window.command_text[:-1] + self.command_text = self.window.command_text[:-1] elif symbol == key.ENTER: self.window.process_command(self.window.command_text) self.state_machine.change_state(GameState.PLAYING) diff --git a/window.py b/window.py index 0421b412..b24a9ecf 100644 --- a/window.py +++ b/window.py @@ -77,14 +77,7 @@ def __init__(self, *args, **kwargs): anchor_x="left", anchor_y="bottom", color=(255, 255, 255, 255) ) - self.command_prompt_label = pyglet.text.Label( - "Command: ", - font_name="Arial", - font_size=18, - x=10, y=10, - anchor_x="left", anchor_y="bottom", - color=(255, 255, 255, 255) - ) + self.create_main_menu() # This call schedules the `update()` method to be called @@ -192,9 +185,7 @@ def on_draw(self): elif self.state_machine.state == GameState.PAUSED: self.pause_menu_batch.draw() elif self.state_machine.state == GameState.COMMAND_LINE: - self.command_prompt_label.text = 'Command: ' + self.command_text self.command_batch.draw() - self.command_prompt_label.draw() elif self.state_machine.state == GameState.COMMAND_LINE: self.command_prompt_label.text = 'Command: ' + self.command_text @@ -484,6 +475,15 @@ def create_command_line(self): ) self.background.opacity = 25 + self.command_prompt_label = pyglet.text.Label( + "Command: " + self.command_text, + font_name="Arial", + font_size=18, + x=10, y=10, + anchor_x="left", anchor_y="bottom", + color=(255, 255, 255, 255), + batch= self.command_batch + ) def on_text(self, text): """Handles text input in command mode."""

o*d)P*gDX`^J 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 KlWLV05&sXEqR!g@ literal 75304 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 P0+)iEifoCD@rVBd4MO3J diff --git a/Textures_Numbered.png b/Textures_Numbered.png new file mode 100644 index 0000000000000000000000000000000000000000..fbd4219d6fef02ced21da4b3f7376c536b74b667 GIT binary patch literal 164218 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