diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index b5472fd..dba7ff9 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -20,7 +20,7 @@ jobs: python-version: '3.10' - run: pip install -r requirements.txt - run: pyinstaller --noconsole creeper_adventure/creeper.py - - run: cp -r creeper_adventure/assets dist/creeper + - run: cp -r assets dist/creeper - name: Step 3 - Use the Upload Artifact GitHub Action uses: actions/upload-artifact@v2 with: @@ -82,9 +82,9 @@ jobs: git add . git commit -m "Bump version: `hatch version`" git tag v$NEW_VERSION - git push --force - git push --tags --force + git push + git push --tags - name: publish run: | - hatch build - hatch publish + runner hatch build + runner hatch publish diff --git a/.gitignore b/.gitignore index 26750c3..1930ca0 100644 --- a/.gitignore +++ b/.gitignore @@ -956,4 +956,3 @@ FodyWeavers.xsd # Additional files built by Visual Studio # End of https://www.toptal.com/developers/gitignore/api/vim,node,data,emacs,python,pycharm,executable,sublimetext,visualstudio,visualstudiocode -.null-ls_574349_tetris.py diff --git a/README.md b/README.md index 6a25d87..0319349 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,5 @@ - - - # creeper-adventure -Creeper adventure is a top down 2d adventure game that I am building with my son using pygame. - [![PyPI - Version](https://img.shields.io/pypi/v/creeper-adventure.svg)](https://pypi.org/project/creeper-adventure) [![PyPI - Python Version](https://img.shields.io/pypi/pyversions/creeper-adventure.svg)](https://pypi.org/project/creeper-adventure) @@ -21,31 +16,6 @@ Creeper adventure is a top down 2d adventure game that I am building with my son pip install creeper-adventure ``` -## Running - -```console -# run the game -creeper-adventure - -# run in debug mode -creeper-adventure --debug - -# see all options available -creeper-adventure --help -``` - -## running with pipx - -`creeper-adventure` can also run using pipx if you have pipx installed. - -```console -pipx run creeper-adventure -``` - -## Download an exe - -pre-built binaries are available from the website [creeper-adventure](https://creeper-adventure.waylonwalker.com). - ## License `creeper-adventure` is distributed under the terms of the [MIT](https://spdx.org/licenses/MIT.html) license. diff --git a/aforest.py b/aforest.py deleted file mode 100644 index 47db5fe..0000000 --- a/aforest.py +++ /dev/null @@ -1,108 +0,0 @@ -import math - -import noise -import pygame - -# set up pygame -pygame.init() - -# set up the window -screen_width, screen_height = 1280, 800 -screen = pygame.display.set_mode((screen_width, screen_height)) -# set up the noise surface -noise_width, noise_height = 1280, 800 -noise_scale = 10 -noise_width = int(screen_width / noise_scale) -noise_height = int(screen_height / noise_scale) -# noise_width, noise_height = round(1280 / 10), round(800 / 10) -noise_surface = pygame.Surface((noise_width, noise_height)) -# set up the colors -BLACK = (0, 0, 0) -GREEN = (0, 255, 0) -BLUE = (0, 0, 255) -colors = [(0, 128, 0), (0, 64, 0), (0, 32, 0)] -# set up the noise -octaves = 1 -freq = 256 * octaves -# generate the noise -noise_map = [ - [ - noise.pnoise2(x / freq, y / freq, octaves, repeatx=3024, repeaty=3024) - for x in range(screen_width) - ] - for y in range(screen_height) -] -# set up the clock -clock = pygame.time.Clock() -# set up the animation -frame = 0 -# set up the noise surface cache -noise_surface_cache = [] -# set up the noise surface cache index -noise_surface_cache_index = 0 -# set up the noise surface cache size -noise_surface_cache_size = 120 -# set up the noise surface cache -for i in range(noise_surface_cache_size): - - print(f"caching {i} of {noise_surface_cache_size}") - # draw the background - for y in range(noise_height): - for x in range(noise_width): - color = colors[2] - if ( - noise_map[y * noise_scale][x * noise_scale] - + math.sin(i * (3.14 / noise_surface_cache_size)) - > 0.2 - ): - color = colors[1] - elif ( - noise_map[y * noise_scale][x * noise_scale] - + math.sin(i * (3.14 / noise_surface_cache_size)) - < 0.15 - ): - color = colors[0] - noise_surface.set_at((x, y), color) - # cache the noise surface - - noise_surface_scaled = pygame.transform.scale( - noise_surface, (screen_width, screen_height) - ) - # noise_surface_scaled_pil = Image.frombytes( - # "RGB", - # (screen_width, screen_height), - # pygame.image.tostring(noise_surface_scaled, "RGB", False), - # ) - - # noise_surface_scaled_pil = noise_surface_scaled_pil.filter( - # ImageFilter.GaussianBlur(radius=20) - # ) - # noise_surface_scaled = pygame.image.fromstring( - # noise_surface_scaled_pil.tobytes(), (screen_width, screen_height), "RGB" - # ) - noise_surface_cache.append(noise_surface_scaled) - -noise_surface_cache.extend([n for n in noise_surface_cache[::-1]]) -# main loop -running = True -print("running") -while running: - # keep loop running at the right speed - clock.tick(60) - # process events - for event in pygame.event.get(): - if event.type == pygame.QUIT: - running = False - # increment the frame - frame += 0.2 - if frame > noise_surface_cache_size - 1: - frame = 0 - # draw the noise surface onto the screen - screen.blit(noise_surface_cache[int(frame)], (0, 0)) - - # display the fps on the screen - pygame.display.set_caption(str(clock.get_fps())) - # update the display - pygame.display.flip() - -pygame.quit() diff --git a/camera.py b/camera.py deleted file mode 100644 index 807f8e7..0000000 --- a/camera.py +++ /dev/null @@ -1,180 +0,0 @@ -"""Basic showcase on how the transform property on SpaceDebugDrawOptions can -be used as a camera to allow panning. Use arrows to move the camera. -""" - -__docformat__ = "reStructuredText" - -import random -import sys - -import pygame -import pymunk.pygame_util -from pymunk.vec2d import Vec2d - -random.seed(0) - - -def main(): - pygame.init() - screen = pygame.display.set_mode((600, 600)) - clock = pygame.time.Clock() - running = True - font = pygame.font.Font(None, 16) - text = font.render( - "Use Arrows (up, down, left, right) to move the camera, " - "a and z to zoom in / out and s and x to rotate.", - True, - pygame.Color("black"), - ) - - ### Physics stuff - space = pymunk.Space() - space.gravity = Vec2d(0.0, 900.0) - draw_options = pymunk.pygame_util.DrawOptions(screen) - - ## Balls - balls = [] - - body = pymunk.Body() - body.position = pymunk.Vec2d(407, 354) - s1 = pymunk.Segment(body, Vec2d(-300, -30), Vec2d(0, 0), 1.0) - s2 = pymunk.Segment(body, Vec2d(0, 0), Vec2d(0, -100), 1.0) - s1.density = 0.1 - s2.density = 0.1 - s1.friction = 1 - s2.friction = 1 - space.add(body, s1, s2) - - c1 = pymunk.constraints.DampedSpring( - space.static_body, - body, - (427, 200), - (0, -100), - Vec2d(407, 254).get_distance((427, 200)), - 2000, - 100, - ) - - c2 = pymunk.constraints.DampedSpring( - space.static_body, - body, - (87, 200), - (-300, -30), - Vec2d(107, 324).get_distance((87, 200)), - 2000, - 100, - ) - space.add(c1, c2) - - # extra to show how constraints are drawn when very small / large - body = pymunk.Body(1, 100) - body.position = 450, 305 - c3 = pymunk.constraints.DampedSpring( - space.static_body, body, (450, 300), (0, 0), 5, 1000, 100 - ) - space.add(body, c3) - body = pymunk.Body(1, 100) - body.position = 500, 2025 - c3 = pymunk.constraints.DampedSpring( - space.static_body, body, (500, 25), (0, 0), 2000, 1000, 100 - ) - space.add(body, c3) - - ticks_to_next_ball = 10 - - translation = pymunk.Transform() - scaling = 1 - rotation = 0 - - while running: - for event in pygame.event.get(): - if ( - event.type == pygame.QUIT - or event.type == pygame.KEYDOWN - and event.key == pygame.K_ESCAPE - ): - running = False - elif event.type == pygame.KEYDOWN and event.key == pygame.K_p: - pygame.image.save(screen, "camera.png") - - keys = pygame.key.get_pressed() - left = int(keys[pygame.K_LEFT]) - up = int(keys[pygame.K_UP]) - down = int(keys[pygame.K_DOWN]) - right = int(keys[pygame.K_RIGHT]) - - zoom_in = int(keys[pygame.K_a]) - zoom_out = int(keys[pygame.K_z]) - rotate_left = int(keys[pygame.K_s]) - rotate_right = int(keys[pygame.K_x]) - - translate_speed = 10 - translation = translation.translated( - translate_speed * left - translate_speed * right, - translate_speed * up - translate_speed * down, - ) - - zoom_speed = 0.1 - scaling *= 1 + (zoom_speed * zoom_in - zoom_speed * zoom_out) - - rotation_speed = 0.1 - rotation += rotation_speed * rotate_left - rotation_speed * rotate_right - - # to zoom with center of screen as origin we need to offset with - # center of screen, scale, and then offset back - draw_options.transform = ( - pymunk.Transform.translation(300, 300) - @ pymunk.Transform.scaling(scaling) - @ translation - @ pymunk.Transform.rotation(rotation) - @ pymunk.Transform.translation(-300, -300) - ) - - ticks_to_next_ball -= 1 - if ticks_to_next_ball <= 0: - ticks_to_next_ball = 100 - mass = 10 - radius = 25 - inertia = pymunk.moment_for_circle(mass, 0, radius, (0, 0)) - body = pymunk.Body(mass, inertia) - x = random.randint(115, 350) - body.position = x, 100 - if random.random() > 0.5: - shape = pymunk.Circle(body, radius) - else: - shape = pymunk.Poly.create_box( - body, size=(radius * 2, radius * 2), radius=2 - ) - shape.friction = 1 - space.add(body, shape) - balls.append(shape) - - ### Clear screen - screen.fill(pygame.Color("white")) - - ### Draw stuff - space.debug_draw(draw_options) - - balls_to_remove = [] - for ball in balls: - if ball.body.position.y > 500: - balls_to_remove.append(ball) - - for ball in balls_to_remove: - space.remove(ball, ball.body) - balls.remove(ball) - - screen.blit(text, (5, 5)) - - ### Update physics - dt = 1.0 / 60.0 - space.step(dt) - - ### Flip screen - pygame.display.flip() - clock.tick(50) - pygame.display.set_caption("fps: " + str(clock.get_fps())) - - -if __name__ == "__main__": - sys.exit(main()) diff --git a/constraints.py b/constraints.py deleted file mode 100644 index a9d518d..0000000 --- a/constraints.py +++ /dev/null @@ -1,250 +0,0 @@ -""" -Pymunk constraints demo. Showcase of all the constraints included in Pymunk. - -Adapted from the Chipmunk Joints demo: -https://github.com/slembcke/Chipmunk2D/blob/master/demo/Joints.c -""" - -import inspect -import math - -import pygame -import pymunk.pygame_util -from pymunk.vec2d import Vec2d - -pygame.init() -screen = pygame.display.set_mode((1200, 600)) -clock = pygame.time.Clock() -font = pygame.font.Font(None, 24) - - -help_txt = font.render( - "Pymunk constraints demo. Use mouse to drag/drop. Hover to see descr.", - True, - pygame.Color("darkgray"), -) - -space = pymunk.Space() -space.gravity = (0.0, 900.0) -draw_options = pymunk.pygame_util.DrawOptions(screen) - -# containers -box_size = 200 -w = screen.get_width() -h = screen.get_height() -for i in range(6): - sw = pymunk.Segment(space.static_body, (0, i * box_size), (w, i * box_size), 1) - sw.friction = 1 - sw.elasticity = 1 - sh = pymunk.Segment( - space.static_body, (i * box_size, 0), (i * box_size, h - box_size), 1 - ) - sh.friction = 1 - sh.elasticity = 1 - space.add(sw, sh) - - -def add_ball(space, pos, box_offset): - body = pymunk.Body() - body.position = Vec2d(*pos) + box_offset - shape = pymunk.Circle(body, 20) - shape.mass = 1 - shape.friction = 0.7 - space.add(body, shape) - return body - - -def add_bar(space, pos, box_offset): - body = pymunk.Body() - body.position = Vec2d(*pos) + box_offset - shape = pymunk.Segment(body, (0, 40), (0, -40), 6) - shape.mass = 2 - shape.friction = 0.7 - space.add(body, shape) - return body - - -def add_lever(space, pos, box_offset): - body = pymunk.Body() - body.position = pos + Vec2d(*box_offset) + (0, -20) - shape = pymunk.Segment(body, (0, 20), (0, -20), 5) - shape.mass = 1 - shape.friction = 0.7 - space.add(body, shape) - return body - - -def main(): - txts = {} - - box_offset = 0, 0 - b1 = add_ball(space, (50, 60), box_offset) - b2 = add_ball(space, (150, 60), box_offset) - c: pymunk.Constraint = pymunk.PinJoint(b1, b2, (20, 0), (-20, 0)) - txts[box_offset] = inspect.getdoc(c) - space.add(c) - - box_offset = box_size, 0 - b1 = add_ball(space, (50, 60), box_offset) - b2 = add_ball(space, (150, 60), box_offset) - c = pymunk.SlideJoint(b1, b2, (20, 0), (-20, 0), 40, 80) - txts[box_offset] = inspect.getdoc(c) - space.add(c) - - box_offset = box_size * 2, 0 - b1 = add_ball(space, (50, 60), box_offset) - b2 = add_ball(space, (150, 60), box_offset) - c = pymunk.PivotJoint(b1, b2, Vec2d(*box_offset) + (100, 60)) - txts[box_offset] = inspect.getdoc(c) - space.add(c) - - box_offset = box_size * 3, 0 - b1 = add_ball(space, (50, 60), box_offset) - b2 = add_ball(space, (150, 60), box_offset) - c = pymunk.GrooveJoint(b1, b2, (50, 50), (50, -50), (-50, 0)) - txts[box_offset] = inspect.getdoc(c) - space.add(c) - - box_offset = box_size * 4, 0 - b1 = add_ball(space, (50, 60), box_offset) - b2 = add_ball(space, (150, 60), box_offset) - c = pymunk.DampedSpring(b1, b2, (30, 0), (-30, 0), 20, 5, 0.3) - txts[box_offset] = inspect.getdoc(c) - space.add(c) - - box_offset = box_size * 5, 0 - b1 = add_bar(space, (50, 80), box_offset) - b2 = add_bar(space, (150, 80), box_offset) - # Add some joints to hold the circles in place. - space.add(pymunk.PivotJoint(b1, space.static_body, (50, 80) + Vec2d(*box_offset))) - space.add(pymunk.PivotJoint(b2, space.static_body, (150, 80) + Vec2d(*box_offset))) - c = pymunk.DampedRotarySpring(b1, b2, 0, 3000, 60) - txts[box_offset] = inspect.getdoc(c) - space.add(c) - - box_offset = 0, box_size - b1 = add_lever(space, (50, 100), box_offset) - b2 = add_lever(space, (150, 100), box_offset) - # Add some joints to hold the circles in place. - space.add(pymunk.PivotJoint(b1, space.static_body, (50, 100) + Vec2d(*box_offset))) - space.add(pymunk.PivotJoint(b2, space.static_body, (150, 100) + Vec2d(*box_offset))) - # Hold their rotation within 90 degrees of each other. - c = pymunk.RotaryLimitJoint(b1, b2, math.pi / 2, math.pi / 2) - txts[box_offset] = inspect.getdoc(c) - space.add(c) - - box_offset = box_size, box_size - b1 = add_lever(space, (50, 100), box_offset) - b2 = add_lever(space, (150, 100), box_offset) - # Add some pin joints to hold the circles in place. - space.add(pymunk.PivotJoint(b1, space.static_body, (50, 100) + Vec2d(*box_offset))) - space.add(pymunk.PivotJoint(b2, space.static_body, (150, 100) + Vec2d(*box_offset))) - # Ratchet every 90 degrees - c = pymunk.RatchetJoint(b1, b2, 0, math.pi / 2) - txts[box_offset] = inspect.getdoc(c) - space.add(c) - - box_offset = box_size * 2, box_size - b1 = add_bar(space, (50, 100), box_offset) - b2 = add_bar(space, (150, 100), box_offset) - # Add some pin joints to hold the circles in place. - space.add(pymunk.PivotJoint(b1, space.static_body, (50, 100) + Vec2d(*box_offset))) - space.add(pymunk.PivotJoint(b2, space.static_body, (150, 100) + Vec2d(*box_offset))) - # Force one to sping 2x as fast as the other - c = pymunk.GearJoint(b1, b2, 0, 2) - txts[box_offset] = inspect.getdoc(c) - space.add(c) - - box_offset = box_size * 3, box_size - b1 = add_bar(space, (50, 100), box_offset) - b2 = add_bar(space, (150, 100), box_offset) - # Add some pin joints to hold the circles in place. - space.add(pymunk.PivotJoint(b1, space.static_body, (50, 100) + Vec2d(*box_offset))) - space.add(pymunk.PivotJoint(b2, space.static_body, (150, 100) + Vec2d(*box_offset))) - # Make them spin at 1/2 revolution per second in relation to each other. - c = pymunk.SimpleMotor(b1, b2, math.pi) - txts[box_offset] = inspect.getdoc(c) - space.add(c) - - # TODO add one or two advanced constraints examples, such as a car or rope - - mouse_joint = None - mouse_body = pymunk.Body(body_type=pymunk.Body.KINEMATIC) - - # Build rendered help texts - box_texts = {} - for k in txts: - l = 0 - box_texts[k] = [] - # Only take the first 5 lines. - for line in txts[k].splitlines()[:5]: - txt = font.render(line, True, pygame.Color("black")) - box_texts[k].append(txt) - - while True: - for event in pygame.event.get(): - if event.type == pygame.QUIT: - exit() - elif event.type == pygame.KEYDOWN and event.key == pygame.K_ESCAPE: - exit() - elif event.type == pygame.MOUSEBUTTONDOWN: - if mouse_joint is not None: - space.remove(mouse_joint) - mouse_joint = None - - p = Vec2d(*event.pos) - hit = space.point_query_nearest(p, 5, pymunk.ShapeFilter()) - if hit is not None and hit.shape.body.body_type == pymunk.Body.DYNAMIC: - shape = hit.shape - # Use the closest point on the surface if the click is outside - # of the shape. - if hit.distance > 0: - nearest = hit.point - else: - nearest = p - mouse_joint = pymunk.PivotJoint( - mouse_body, - shape.body, - (0, 0), - shape.body.world_to_local(nearest), - ) - mouse_joint.max_force = 50000 - mouse_joint.error_bias = (1 - 0.15) ** 60 - space.add(mouse_joint) - - elif event.type == pygame.MOUSEBUTTONUP: - if mouse_joint is not None: - space.remove(mouse_joint) - mouse_joint = None - - screen.fill(pygame.Color("white")) - - screen.blit(help_txt, (5, screen.get_height() - 20)) - - mouse_pos = pygame.mouse.get_pos() - - # Display help message - x = mouse_pos[0] // box_size * box_size - y = mouse_pos[1] // box_size * box_size - - if (x, y) in box_texts: - txts = box_texts[(x, y)] - i = 0 - for txt in txts: - pos = (5, box_size * 2 + 10 + i * 20) - screen.blit(txt, pos) - i += 1 - - mouse_body.position = mouse_pos - - space.step(1.0 / 60) - - space.debug_draw(draw_options) - pygame.display.flip() - - clock.tick(60) - pygame.display.set_caption(f"fps: {clock.get_fps()}") - - -if __name__ == "__main__": - main() diff --git a/creeper_adventure/__about__.py b/creeper_adventure/__about__.py index 79f884d..b5a47bc 100644 --- a/creeper_adventure/__about__.py +++ b/creeper_adventure/__about__.py @@ -1,4 +1,4 @@ # SPDX-FileCopyrightText: 2023-present Waylon S. Walker # # SPDX-License-Identifier: MIT -__version__ = '11.0.0' +__version__ = '1.0.0' diff --git a/creeper_adventure/assets/bee/idle/1.png b/creeper_adventure/assets/bee/idle/1.png old mode 100644 new mode 100755 diff --git a/creeper_adventure/assets/creeper/idle/1.png b/creeper_adventure/assets/creeper/idle/1.png old mode 100644 new mode 100755 diff --git a/creeper_adventure/assets/creeper/idle/2.png b/creeper_adventure/assets/creeper/idle/2.png old mode 100644 new mode 100755 diff --git a/creeper_adventure/assets/creeper/idle/3.png b/creeper_adventure/assets/creeper/idle/3.png old mode 100644 new mode 100755 diff --git a/creeper_adventure/assets/creeper/idle/4.png b/creeper_adventure/assets/creeper/idle/4.png old mode 100644 new mode 100755 diff --git a/creeper_adventure/assets/creeper/idle/5.png b/creeper_adventure/assets/creeper/idle/5.png old mode 100644 new mode 100755 diff --git a/creeper_adventure/assets/leaf.png b/creeper_adventure/assets/leaf.png old mode 100644 new mode 100755 diff --git a/creeper_adventure/assets/oak_trees/1.png b/creeper_adventure/assets/oak_trees/1.png old mode 100644 new mode 100755 diff --git a/creeper_adventure/assets/oak_trees/2.png b/creeper_adventure/assets/oak_trees/2.png old mode 100644 new mode 100755 diff --git a/creeper_adventure/assets/oak_trees/4.png b/creeper_adventure/assets/oak_trees/4.png old mode 100644 new mode 100755 diff --git a/creeper_adventure/assets/oak_trees/5.png b/creeper_adventure/assets/oak_trees/5.png old mode 100644 new mode 100755 diff --git a/creeper_adventure/assets/oak_trees/6.png b/creeper_adventure/assets/oak_trees/6.png deleted file mode 100644 index 908228e..0000000 Binary files a/creeper_adventure/assets/oak_trees/6.png and /dev/null differ diff --git a/creeper_adventure/assets/plank-bottom.png b/creeper_adventure/assets/plank-bottom.png deleted file mode 100644 index bf2efab..0000000 Binary files a/creeper_adventure/assets/plank-bottom.png and /dev/null differ diff --git a/creeper_adventure/assets/plank-top.png b/creeper_adventure/assets/plank-top.png deleted file mode 100644 index 18e5437..0000000 Binary files a/creeper_adventure/assets/plank-top.png and /dev/null differ diff --git a/creeper_adventure/assets/spotlight.png b/creeper_adventure/assets/spotlight.png old mode 100644 new mode 100755 diff --git a/creeper_adventure/cli/__init__.py b/creeper_adventure/cli/__init__.py index b7e0d8e..76b12d9 100644 --- a/creeper_adventure/cli/__init__.py +++ b/creeper_adventure/cli/__init__.py @@ -15,4 +15,5 @@ from ..creeper import main @click.pass_context @click.option("--debug", is_flag=True, help="start with the debug menu open") def creeper_adventure(ctx: click.Context, debug): + print(debug) main(debug) diff --git a/creeper_adventure/creeper.py b/creeper_adventure/creeper.py old mode 100644 new mode 100755 index f9eccd1..e90309d --- a/creeper_adventure/creeper.py +++ b/creeper_adventure/creeper.py @@ -1,91 +1,45 @@ +import random from copy import copy from itertools import cycle, repeat from pathlib import Path -import random -from typing import List, Optional -from more_itertools import flatten -from pydantic import BaseModel import pygame +from more_itertools import flatten from creeper_adventure.game import Game ASSETS = Path(__file__).parent / "assets" -class Button: - def __init__(self, game, surf, text, x, y, w, h, on_click=lambda: ...): - self.game = game - self.surf = surf - self.text = text - self.x = x - self.y = y - self.w = w - self.h = h - self.on_click = on_click - self.font = pygame.font.SysFont(None, 32) - - def draw(self): - pygame.draw.rect(self.surf, (255, 255, 255), (self.x, self.y, self.w, self.h)) - label = self.font.render(self.text, True, (0, 0, 0)) - label_rect = label.get_rect() - label_rect.center = (self.x + self.w / 2, self.y + self.h / 2) - self.surf.blit(label, label_rect) - for event in self.game.events: - if event.type == pygame.MOUSEBUTTONDOWN: - if self.is_clicked(event.pos): - self.on_click() - # elif quit_button.is_clicked(event.pos): - # running = False - # if self.is_clicked: - # self.on_click() - - def is_clicked(self, pos): - if pos[0] > self.x and pos[0] < self.x + self.w: - if pos[1] > self.y and pos[1] < self.y + self.h: - return True - return False - - class MouseSprite: - def __init__(self, game, surf, hotbar): - self.game = game + def __init__(self, surf, hotbar): self.surf = surf self.hotbar = hotbar @property def mouse_pos(self): - return ( - pygame.mouse.get_pos()[0] - 2 - self.game.camera[0], - pygame.mouse.get_pos()[1] - 2 - self.game.camera[1], - ) + return [i - 2 for i in pygame.mouse.get_pos()] @property def rect(self): return pygame.Rect(self.mouse_pos, (4, 4)) def get_nearest_block_pos(self): - return ( - [ - self.mouse_pos[0] - (self.mouse_pos[0] % 16), - self.mouse_pos[1] - (self.mouse_pos[1] % 16), - ], - ) + return ([i - (i % 16) for i in pygame.mouse.get_pos()],) def draw(self): if self.hotbar.selected.type is None: pygame.draw.rect(self.surf, (255, 0, 0), self.rect) else: - self.img = self.game.get_img(self.hotbar.selected.type).convert() + self.img = pygame.image.load(ASSETS / f"{self.hotbar.selected.type}.png") self.surf.blit( - pygame.transform.scale(self.img, (64, 64)), + pygame.transform.scale(self.img, (16, 16)), self.get_nearest_block_pos(), ) class TreeSprite: - def __init__(self, game, tree, x, y, scale, flip, surf): - self.game = game + def __init__(self, tree, x, y, scale, flip, surf): self.image = tree self.health = 100 self.x = x @@ -93,7 +47,7 @@ class TreeSprite: self.scale = scale self.flip = flip self.surf = surf - self.leafs = [Leaf(self.game, self.surf, (x + 25, y + 25)) for i in range(2)] + self.leafs = [Leaf(self, self.surf, (x + 25, y + 25)) for i in range(2)] self.shaking = 0 def shake(self): @@ -103,7 +57,7 @@ class TreeSprite: self.leafs.extend( [ Leaf( - self.game, + self, self.surf, ( self.x + 25 + random.randint(-10, 10), @@ -161,11 +115,7 @@ class HotBar: self.game = game self.items = [ HotBarItem( - game=self.game, - surf=self.ui, - pos=pos, - scale=self.scale, - margin=self.margin, + game=self, surf=self.ui, pos=pos, scale=self.scale, margin=self.margin ) for pos in range(num) ] @@ -214,7 +164,6 @@ class HotBarItem: self.selected = False self.surf.fill((0, 0, 0)) self.type = None - self.font = pygame.font.SysFont(None, self.scale) def draw(self): self.surf.fill((0, 0, 0, 60)) @@ -222,7 +171,7 @@ class HotBarItem: self.surf.fill((185, 185, 205, 60)) if self.type: - self.img = self.game.get_img(self.type) + self.img = pygame.image.load(ASSETS / f"{self.type}.png") self.ui.blit( pygame.transform.scale( self.img, @@ -230,8 +179,9 @@ class HotBarItem: ), (self.pos * self.scale + self.margin, self.margin), ) - qty = str(self.game.inventory[self.type]) - img = self.font.render(qty, True, (255, 255, 255)) + font = pygame.font.SysFont(None, self.scale) + qty = str(self.game.game.inventory[self.type]) + img = font.render(qty, True, (255, 255, 255)) self.ui.blit( pygame.transform.scale(img, (self.scale * 0.6, self.scale * 0.6)), (self.pos * self.scale + self.margin, self.margin), @@ -258,12 +208,10 @@ class Menu: self.scale = scale self.margin = margin self.alpha = alpha - self.font = pygame.font.SysFont(None, 20) - self.surf = pygame.Surface(self.game.screen.get_size()).convert_alpha() def draw(self): if self.is_open: - # self.surf = pygame.Surface(self.game.screen.get_size()).convert_alpha() + self.surf = pygame.Surface(self.game.screen.get_size()).convert_alpha() self.surf.fill((0, 0, 0, self.alpha)) font = pygame.font.SysFont(None, self.scale) img = font.render(self.title, True, (255, 255, 255)) @@ -283,6 +231,7 @@ class Menu: class DebugMenu(Menu): def __init__(self, game): super().__init__(title="Debug Menu", game=game, alpha=0) + self.font = pygame.font.SysFont(None, 20) def _draw(self): self.surf.blit( @@ -313,54 +262,6 @@ class DebugMenu(Menu): ), (10, 80), ) - self.surf.blit( - self.font.render( - f"fps: {round(self.game.clock.get_fps())}", - True, - (255, 255, 255), - ), - (10, 95), - ) - self.surf.blit( - self.font.render( - f"fullscreen: {pygame.FULLSCREEN}", - True, - (255, 255, 255), - ), - (10, 110), - ) - self.surf.blit( - self.font.render( - f"elapsed: {self.game.elapsed}", - True, - (255, 255, 255), - ), - (10, 125), - ) - - -class MainMenu(Menu): - def __init__(self, game, title): - super().__init__(game=game, title=title) - self.set_button_text() - - @property - def start_button(self): - w = 200 - h = 50 - x = self.game.screen.get_size()[0] / 2 - w / 2 - y = 300 - return Button(self.game, self.surf, self.button_text, x, y, w, h, self.toggle) - - def set_button_text(self): - self.button_text = "Start Game" if self.game.frames < 100 else "Continue" - - def toggle(self): - self.set_button_text() - self.is_open = not self.is_open - - def _draw(self): - self.start_button.draw() class LightSource: @@ -370,7 +271,7 @@ class LightSource: self.img = img self.center = center self.sx, self.sy = center - self.spot = self.game.get_img("spotlight") + self.spot = pygame.image.load(ASSETS / "spotlight.png") class Leaf: @@ -380,12 +281,11 @@ class Leaf: self.center = center self.sx, self.sy = center self.img = pygame.transform.scale( - self.game.get_img("leaf"), (4, 4) - ) # .convert_alpha() + pygame.image.load(ASSETS / "leaf.png"), (4, 4) + ).convert_alpha() self.lifespan = lifespan self.r = random.randint(0, 360) self.x, self.y = [int(i) + random.randint(-8, 8) for i in self.center] - self.speed = 3 self.restart() def restart(self): @@ -401,13 +301,13 @@ class Leaf: ) if self.y < self.sy + 40: - self.y += random.randint(0, 5) / 4 * self.speed * self.game.elapsed - self.x += random.randint(-15, 5) / 10 * self.speed * self.game.elapsed - self.r += random.randint(-10, 10) * self.speed / 3 * self.game.elapsed + self.y += random.randint(0, 5) / 4 + self.x += random.randint(-15, 5) / 10 + self.r += random.randint(-10, 10) elif self.y < self.sy + 45: - self.y += random.randint(-2, 5) / 10 * self.speed * self.game.elapsed - self.x += random.randint(-18, 2) / 10 * self.speed * self.game.elapsed - self.r += random.randint(-10, 25) * self.speed * self.game.elapsed + self.y += random.randint(-2, 5) / 10 + self.x += random.randint(-18, 2) / 10 + self.r += random.randint(-10, 25) else: self.restart() if self.x > self.sx + 100: @@ -435,19 +335,15 @@ class Bee: class Creeper(Game): def __init__(self, debug=False): super().__init__() - self.inventory = {"plank-bottom": 1, "plank-top": 1} - self._imgs = {} - self.blocks = {} - self.camera = (0, 0) + self.inventory = {} self.day_len = 1000 * 60 self.background = pygame.Surface(self.screen.get_size()) self.foreground = pygame.Surface(self.screen.get_size()) self.build = pygame.Surface(self.screen.get_size()) - # self.darkness = pygame.Surface(self.screen.get_size()) + self.darkness = pygame.Surface(self.screen.get_size()).convert_alpha() self.axe_sound = pygame.mixer.Sound(ASSETS / "sounds/axe.mp3") self.walking_sound = pygame.mixer.Sound(ASSETS / "sounds/walking.mp3") self.walking_sound_is_playing = False - self.speed = 5 self.background.fill((0, 255, 247)) self.x, self.y = [i / 2 for i in self.screen.get_size()] @@ -476,21 +372,20 @@ class Creeper(Game): self.trees = [] x_range = [ - 0, - self.screen.get_size()[0], + self.screen.get_size()[0] * 0.1, + self.screen.get_size()[0] * 0.9, ] y_range = [ self.screen.get_size()[1] * 0.35, self.screen.get_size()[1] * 0.5, ] - for i in range(30): + for i in range(10): x = random.randint(*x_range) y = random.randint(*y_range) scale = random.randint(42, 86) self.trees.append( TreeSprite( - game=self, tree=random.choice(self.tree_imgs), x=x, y=y, @@ -500,35 +395,17 @@ class Creeper(Game): ) ) - self.mouse_box = MouseSprite(self, self.background, hotbar=self.hotbar) + self.mouse_box = MouseSprite(self.screen, hotbar=self.hotbar) self.joysticks = {} - self.hotbar_back_debounce = 1 self.hotbar_forward_debounce = 1 self.inventory_open_debounce = 1 self.debug_open_debounce = 1 self.main_open_debounce = 1 - - self.controller_hotbar_back_debounce = 1 - self.controller_hotbar_forward_debounce = 1 - self.controller_inventory_open_debounce = 1 - self.controller_debug_open_debounce = 1 - self.controller_main_open_debounce = 1 - - self.debounce_walk_img = 0 - self.inventory_menu = Menu(self, title="inventory") self.debug_menu = DebugMenu(self) self.debug_menu.is_open = debug - self.main_menu = MainMenu(self, title="main menu") - self.main_menu.is_open = True - - def get_img(self, img): - try: - return self._imgs[img] - except KeyError: - self._imgs[img] = pygame.image.load(ASSETS / f"{img}.png") - return self._imgs[img] + self.main_menu = Menu(self, title="main menu") def attack(self): @@ -546,12 +423,8 @@ class Creeper(Game): return True def place_block(self): - # if self.hotbar.selected.type is None: - # return False - self.blocks[str(self.mouse_box.get_nearest_block_pos())] = Block( - self.hotbar.selected.type, self.mouse_box.get_nearest_block_pos() - ) - print(self.blocks) + if self.hotbar.selected.type is None: + return False def process_deaths(self): for i, tree in enumerate(copy(self.trees)): @@ -566,14 +439,14 @@ class Creeper(Game): def normal_keys(self): keys = self.keys - if keys[pygame.K_a] or keys[pygame.K_LEFT]: - self.x -= 10 * self.speed * self.elapsed - if keys[pygame.K_d] or keys[pygame.K_RIGHT]: - self.x += 10 * self.speed * self.elapsed - if keys[pygame.K_w] or keys[pygame.K_UP]: - self.y -= 10 * self.speed * self.elapsed - if keys[pygame.K_s] or keys[pygame.K_DOWN]: - self.y += 10 * self.speed * self.elapsed + if keys[pygame.K_a]: + self.x -= 10 + if keys[pygame.K_d]: + self.x += 10 + if keys[pygame.K_w]: + self.y -= 10 + if keys[pygame.K_d]: + self.y += 10 if keys[pygame.K_k]: self.hotbar.next(1) if keys[pygame.K_j]: @@ -596,136 +469,80 @@ class Creeper(Game): if event.type == pygame.JOYDEVICEREMOVED: del self.joysticks[event.instance_id] - if not self.joysticks: - if (keys[pygame.K_ESCAPE]) and self.main_open_debounce: - self.main_menu.is_open = not self.main_menu.is_open - self.main_open_debounce = 0 - elif not keys[pygame.K_ESCAPE]: - self.main_open_debounce = 1 - - if keys[pygame.K_e] and self.inventory_open_debounce: - self.inventory_menu.is_open = not self.inventory_menu.is_open - self.inventory_open_debounce = 0 - elif not keys[pygame.K_e]: - self.inventory_open_debounce = 1 - for joystick in self.joysticks.values(): - if joystick.get_axis(5) > 0: - if self.attack(): - joystick.rumble(0.1, 0.0, 100) - if joystick.get_button(4) and self.controller_hotbar_back_debounce: - print(self.controller_hotbar_back_debounce) + if joystick.get_button(4) and self.hotbar_back_debounce: self.hotbar.next(-1) - self.controller_hotbar_back_debounce = 0 - print(self.hotbar_back_debounce) - if not joystick.get_button(4): - self.controller_hotbar_back_debounce = 1 + self.hotbar_back_debounce = 0 + elif not joystick.get_button(4): + self.hotbar_back_debounce = 1 - if joystick.get_button(5) and self.controller_hotbar_forward_debounce: + if joystick.get_button(5) and self.hotbar_forward_debounce: self.hotbar.next(1) - self.controller_hotbar_forward_debounce = 0 + self.hotbar_forward_debounce = 0 elif not joystick.get_button(5): - self.controller_hotbar_forward_debounce = 1 + self.hotbar_forward_debounce = 1 if ( keys[pygame.K_e] or joystick.get_button(2) - ) and self.controller_inventory_open_debounce: + ) and self.inventory_open_debounce: self.inventory_menu.is_open = not self.inventory_menu.is_open - self.controller_inventory_open_debounce = 0 - elif not keys[pygame.K_e] and not joystick.get_button(2): - self.controller_inventory_open_debounce = 1 + self.inventory_open_debounce = 0 + elif not (keys[pygame.K_e] or joystick.get_button(2)): + self.inventory_open_debounce = 1 if ( keys[pygame.K_ESCAPE] or joystick.get_button(9) - ) and self.controller_main_open_debounce: + ) and self.main_open_debounce: self.main_menu.is_open = not self.main_menu.is_open - self.controller_main_open_debounce = 0 + self.main_open_debounce = 0 elif not (keys[pygame.K_ESCAPE] or joystick.get_button(9)): - self.controller_main_open_debounce = 1 + self.main_open_debounce = 1 - if keys[pygame.K_F3] and self.controller_debug_open_debounce: + if keys[pygame.K_F3] and self.debug_open_debounce: self.debug_menu.is_open = not self.debug_menu.is_open - self.controller_debug_open_debounce = 0 + self.debug_open_debounce = 0 elif not keys[pygame.K_F3]: - self.controller_debug_open_debounce = 1 + self.debug_open_debounce = 1 hats = joystick.get_numhats() for i in range(hats): hat = joystick.get_hat(i) if hat[0] == 1: - self.x += 10 * self.speed * self.elapsed + self.x += 10 if hat[0] == -1: - self.x -= 10 * self.speed * self.elapsed + self.x -= 10 if hat[1] == -1: - self.y += 10 * self.speed * self.elapsed + self.y += 10 if hat[1] == 1: - self.y -= 10 * self.speed * self.elapsed + self.y -= 10 if abs(joystick.get_axis(0)) > 0.2: - self.x += joystick.get_axis(0) * 10 * self.speed * self.elapsed + self.x += joystick.get_axis(0) * 10 if abs(joystick.get_axis(1)) > 0.2: - self.y += joystick.get_axis(1) * 10 * self.speed * self.elapsed - - if abs(joystick.get_axis(3)) > 0.2 and abs(joystick.get_axis(4)) > 0.2: - pygame.mouse.set_pos( - ( - pygame.mouse.get_pos()[0] + joystick.get_axis(3) * 32, - pygame.mouse.get_pos()[1] + joystick.get_axis(4) * 32, - ) - ) - elif abs(joystick.get_axis(3)) > 0.2: - pygame.mouse.set_pos( - ( - pygame.mouse.get_pos()[0] + joystick.get_axis(3) * 32, - pygame.mouse.get_pos()[1], - ) - ) - elif abs(joystick.get_axis(4)) > 0.2: - pygame.mouse.set_pos( - ( - pygame.mouse.get_pos()[0], - pygame.mouse.get_pos()[1] + joystick.get_axis(4) * 32, - ) - ) + self.y += joystick.get_axis(1) * 10 def inventory_keys(self): keys = self.keys - if not self.joysticks: - if keys[pygame.K_e] and self.inventory_open_debounce: - self.inventory_menu.is_open = not self.inventory_menu.is_open - self.inventory_open_debounce = 0 - elif not keys[pygame.K_e]: - self.inventory_open_debounce = 1 - for joystick in self.joysticks.values(): if ( keys[pygame.K_e] or joystick.get_button(2) - ) and self.controller_inventory_open_debounce: + ) and self.inventory_open_debounce: self.inventory_menu.is_open = not self.inventory_menu.is_open - self.controller_inventory_open_debounce = 0 - elif not keys[pygame.K_e] and not joystick.get_button(2): - self.controller_inventory_open_debounce = 1 + self.inventory_open_debounce = 0 + elif not (keys[pygame.K_e] or joystick.get_button(2)): + self.inventory_open_debounce = 1 def main_keys(self): keys = self.keys - - if not self.joysticks: - if (keys[pygame.K_ESCAPE]) and self.main_open_debounce: - print("opens") - self.main_menu.is_open = not self.main_menu.is_open - self.main_open_debounce = 0 - elif not keys[pygame.K_ESCAPE]: - self.main_open_debounce = 1 - for joystick in self.joysticks.values(): if ( keys[pygame.K_ESCAPE] or joystick.get_button(9) - ) and self.controller_main_open_debounce: + ) and self.main_open_debounce: self.main_menu.is_open = not self.main_menu.is_open - self.controller_main_open_debounce = 0 + self.main_open_debounce = 0 elif not (keys[pygame.K_ESCAPE] or joystick.get_button(9)): - self.controller_main_open_debounce = 1 + self.main_open_debounce = 1 def make_sound(self): if not hasattr(self, "last_x"): @@ -743,22 +560,14 @@ class Creeper(Game): ) and not self.walking_sound_is_playing: self.walking_sound.play() self.walking_sound_is_playing = True - if ( - self.last_x != self.x or self.last_y != self.y - ) and self.debounce_walk_img < 0: + if self.last_x != self.x or self.last_y != self.y: + self.creeper = next(self.creepers) - self.debounce_walk_img = 0.15 self.last_x = self.x self.last_y = self.y def game(self): - # self.camera = (self.camera[0] + 1, self.camera[1]) - - self.debounce_walk_img -= self.elapsed - self.screen.blit(self.background, self.camera) - for block in self.blocks.values(): - self.screen.blit(block.img, block.pos) - + self.screen.blit(self.background, (0, 0)) self.background.fill((0, 255, 247)) self.process_deaths() for tree in self.trees: @@ -778,27 +587,29 @@ class Creeper(Game): light_level = pygame.time.get_ticks() % self.day_len light_level = abs(light_level * (255 * 2 / self.day_len) - 255) - # self.darkness.fill((light_level, light_level, light_level)) - # if self.light_power < 500: - # self.light_power = min(self.light_power**1.1, 500) - # self.darkness.blit( - # pygame.transform.smoothscale( - # self.spot, [self.light_power, self.light_power] - # ), - # (self.x - self.light_power / 2, self.y - self.light_power / 2), - # ) - # self.screen.blit( - # pygame.transform.scale(self.darkness, self.screen.get_size()).convert(), - # (0, 0), - # special_flags=pygame.BLEND_MULT, - # ) + self.darkness.fill((light_level, light_level, light_level)) + if self.light_power < 500: + self.light_power = min(self.light_power**1.1, 500) + self.darkness.blit( + pygame.transform.smoothscale( + self.spot, [self.light_power, self.light_power] + ), + (self.x - self.light_power / 2, self.y - self.light_power / 2), + ) + self.screen.blit( + self.darkness, + (0, 0), + special_flags=pygame.BLEND_RGBA_MULT, + ) self.hotbar.draw() self.debug_menu.draw() self.inventory_menu.draw() self.main_menu.draw() - self.mouse_box = MouseSprite(self, self.background, hotbar=self.hotbar) + self.mouse_box = MouseSprite(self.screen, hotbar=self.hotbar) + + self.mouse_box.draw() self.make_sound() @@ -808,7 +619,6 @@ class Creeper(Game): self.main_keys() else: self.normal_keys() - self.mouse_box.draw() def main(debug=False): diff --git a/creeper_adventure/game.py b/creeper_adventure/game.py old mode 100644 new mode 100755 index 7cfeeb9..852a343 --- a/creeper_adventure/game.py +++ b/creeper_adventure/game.py @@ -4,22 +4,17 @@ import pygame class Game: def __init__(self): pygame.init() - # pygame.mouse.set_visible(False) pygame.mixer.init() pygame.display.set_caption(__file__) self.screen_size = (854, 480) self.screen_size = (1280, 800) self.screen_size = (1920, 1080) - # pygame.display.set_mode(resolution, flags, bpp) - flags = pygame.DOUBLEBUF - self.screen = pygame.display.set_mode(self.screen_size, flags) + self.screen = pygame.display.set_mode(self.screen_size) self.clock = pygame.time.Clock() self.running = True self.surfs = [] - self.elapsed = 0 - self.frames = 0 def should_quit(self): for event in self.events: @@ -30,8 +25,7 @@ class Game: ... def reset_screen(self): - ... - # self.screen.fill((0, 0, 0)) + self.screen.fill((0, 0, 0)) def run(self): while self.running: @@ -43,8 +37,7 @@ class Game: for surf in self.surfs: pygame.blit(surf) pygame.display.update() - self.elapsed = self.clock.tick(60) / 100 - self.frames += 1 + self.clock.tick(30) pygame.quit() diff --git a/forest.py b/forest.py deleted file mode 100644 index 3a67d9c..0000000 --- a/forest.py +++ /dev/null @@ -1,63 +0,0 @@ -import math - -from noise import pnoise2 -import pygame - -# Initialize pygame -pygame.init() - -base = 0 -persistence = 0.4 -lacunarity = 2.0 -more_x = 0 -# Set up the drawing window -screen = pygame.display.set_mode([800, 600]) - - -def S(): - i = 0 - while True: - i += 0.1 - yield math.sin(i) - - -s = S() - -# Run until the user asks to quit -running = True -while running: - - # Did the user click the window close button? - for event in pygame.event.get(): - if event.type == pygame.QUIT: - running = False - - # Fill the background with white - screen.fill((255, 255, 255)) - - m = next(s) - # Generate Perlin noise - for x in range(800): - for y in range(600): - noise = pnoise2( - x / 10, - y / 10, - octaves=4, - persistence=persistence + m / 10, - lacunarity=lacunarity, - repeatx=1024, - repeaty=1024, - base=base, - ) - if noise > 0.2: - pygame.draw.rect(screen, (0, 255, 0), (x, y, 1, 1)) - elif noise > 0: - pygame.draw.rect(screen, (0, 128, 0), (x, y, 1, 1)) - else: - pygame.draw.rect(screen, (0, 64, 0), (x, y, 1, 1)) - - # Flip the display - pygame.display.flip() - -# Done! Time to quit. -pygame.quit() diff --git a/gpt-menu.py b/gpt-menu.py deleted file mode 100644 index 12c26fe..0000000 --- a/gpt-menu.py +++ /dev/null @@ -1,85 +0,0 @@ -import pygame - -# Initialize Pygame -pygame.init() - -EVENTS = [] -# Set screen size -screen = pygame.display.set_mode((800, 600)) - -# Set title -pygame.display.set_caption("My RPG Game") - -# Load font -font = pygame.font.Font(None, 30) - -# Define button class -class Button: - def __init__(self, text, x, y, w, h, on_click=lambda: ...): - self.text = text - self.x = x - self.y = y - self.w = w - self.h = h - self.on_click = on_click - - def draw(self, surface): - pygame.draw.rect(surface, (255, 255, 255), (self.x, self.y, self.w, self.h)) - label = font.render(self.text, True, (0, 0, 0)) - label_rect = label.get_rect() - label_rect.center = (self.x + self.w / 2, self.y + self.h / 2) - surface.blit(label, label_rect) - for event in EVENTS: - if event.type == pygame.MOUSEBUTTONDOWN: - if self.is_clicked(event.pos): - self.on_click() - # elif quit_button.is_clicked(event.pos): - # running = False - # if self.is_clicked: - # self.on_click() - - def is_clicked(self, pos): - if pos[0] > self.x and pos[0] < self.x + self.w: - if pos[1] > self.y and pos[1] < self.y + self.h: - return True - return False - - -# Create buttons -start_button = Button( - "Start Game", 300, 300, 200, 50, lambda: print("start this thing") -) -running = True - - -def stop(): - global running - running = False - - -quit_button = Button("Quit Game", 300, 400, 200, 50, stop) - -# Main loop -while running: - EVENTS = pygame.event.get() - for event in pygame.event.get(): - if event.type == pygame.QUIT: - running = False - - # Check for button clicks - - # Draw background - screen.fill((0, 0, 0)) - - # Draw title - title = font.render("Creeper Adventure", True, (255, 255, 255)) - screen.blit(title, (250, 200)) - - # Draw buttons - start_button.draw(screen) - quit_button.draw(screen) - - pygame.display.update() - -# Quit Pygame -pygame.quit() diff --git a/gradients.py b/gradients.py deleted file mode 100644 index 4834b3b..0000000 --- a/gradients.py +++ /dev/null @@ -1,42 +0,0 @@ -from noise import pnoise2 -import pygame -import random - -# Initialize pygame -pygame.init() - -# Set the size of the window -width, height = 800, 600 -screen = pygame.display.set_mode((width, height)) - -# Create a list of 3 random blues -blues = [] -for i in range(3): - blues.append( - (random.randint(0, 255), random.randint(0, 255), random.randint(0, 255)) - ) - -# Create a perlin noise surface -noise_surface = pygame.Surface((width, height)) -for x in range(width): - for y in range(height): - # Calculate the perlin noise value - noise_value = pnoise2(x / 100, y / 100) - # Map the noise value to a color - color_index = int(noise_value * (len(blues) - 1)) - color = blues[color_index] - # Set the color of the pixel - noise_surface.set_at((x, y), color) - -# Blit the noise surface to the screen -screen.blit(noise_surface, (0, 0)) - -# Update the display -pygame.display.flip() - -# Keep the window open until it is closed -while True: - for event in pygame.event.get(): - if event.type == pygame.QUIT: - pygame.quit() - exit() diff --git a/grass.png b/grass.png deleted file mode 100644 index 894be7d..0000000 Binary files a/grass.png and /dev/null differ diff --git a/iso.py b/iso.py deleted file mode 100644 index 6923180..0000000 --- a/iso.py +++ /dev/null @@ -1,56 +0,0 @@ -import sys - -import pygame -from pygame.locals import DOUBLEBUF, K_ESCAPE, KEYUP, QUIT - -pygame.init() - -DISPLAYSURF = pygame.display.set_mode( - (640, 480), DOUBLEBUF -) # set the display mode, window title and FPS clock -pygame.display.set_caption("Map Rendering Demo") -FPSCLOCK = pygame.time.Clock() - -map_data = [ - [1, 1, 1, 1, 1], - [1, 0, 0, 0, 1], - [1, 0, 0, 0, 1], - [1, 0, 0, 0, 1], - [1, 0, 0, 0, 1], - [1, 1, 1, 1, 1], -] # the data for the map expressed as [row[tile]]. - -wall = pygame.image.load("wall.png").convert_alpha() # load images -grass = pygame.image.load("grass.png").convert_alpha() - -TILEWIDTH = 64 # holds the tile width and height -TILEHEIGHT = 64 -TILEHEIGHT_HALF = TILEHEIGHT / 2 -TILEWIDTH_HALF = TILEWIDTH / 2 - -for row_nb, row in enumerate(map_data): # for every row of the map... - for col_nb, tile in enumerate(row): - if tile == 1: - tileImage = wall - else: - tileImage = grass - cart_x = row_nb * TILEWIDTH_HALF - cart_y = col_nb * TILEHEIGHT_HALF - iso_x = cart_x - cart_y - iso_y = (cart_x + cart_y) / 2 - centered_x = DISPLAYSURF.get_rect().centerx + iso_x - centered_y = DISPLAYSURF.get_rect().centery / 2 + iso_y - DISPLAYSURF.blit(tileImage, (centered_x, centered_y)) # display the actual tile - -while True: - for event in pygame.event.get(): - if event.type == QUIT: - pygame.quit() - sys.exit() - if event.type == KEYUP: - if event.key == K_ESCAPE: - pygame.quit() - sys.exit() - - pygame.display.flip() - FPSCLOCK.tick(30) diff --git a/pyproject.toml b/pyproject.toml index 58be8c4..ec8968e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -26,7 +26,6 @@ classifiers = [ dependencies = [ "click", "pygame", - "noise", "more_itertools", ] dynamic = ["version"] diff --git a/requirements.txt b/requirements.txt old mode 100644 new mode 100755 diff --git a/site/static/creeper-1.png b/site/static/creeper-1.png old mode 100644 new mode 100755 diff --git a/spacegame.py b/spacegame.py deleted file mode 100644 index f2aecf6..0000000 --- a/spacegame.py +++ /dev/null @@ -1,99 +0,0 @@ -import pygame - -# Define some colors -BLACK = (0, 0, 0) -WHITE = (255, 255, 255) -GREEN = (0, 255, 0) -RED = (255, 0, 0) -BLUE = (0, 0, 255) - -# Define some constants -WIDTH = 800 -HEIGHT = 600 -FPS = 60 -GRAVITY = 0.5 - -# Define some variables -x = WIDTH / 2 -y = HEIGHT / 2 -vx = 0 -vy = 0 - -# Define some functions - - -def draw_dot(x, y): - pygame.draw.circle(window, BLACK, (int(x), int(y)), 10) - - -def move_dot(x, y, vx, vy): - x += vx - y += vy - return x, y - - -def apply_gravity(vy): - vy += GRAVITY - return vy - - -def jump(vy): - vy = -10 - return vy - - -# Initialize pygame -pygame.init() - -# Create a window -# Create a clock -clock = pygame.time.Clock() - -# Create a window -window = pygame.display.set_mode((WIDTH, HEIGHT)) - -# Set window title -pygame.display.set_caption("My Game") - -# Game loop -running = True -# Set the frame rate -clock.tick(FPS) - -while running: - # Process events - for event in pygame.event.get(): - if event.type == pygame.QUIT: - running = False - if event.type == pygame.KEYDOWN: - if event.key == pygame.K_a: - vx = -5 - if event.key == pygame.K_d: - vx = 5 - if event.key == pygame.K_SPACE: - vy = jump(vy) - if event.type == pygame.KEYUP: - if event.key == pygame.K_a: - vx = 0 - if event.key == pygame.K_d: - vx = 0 - - running = False - x, y = move_dot(x, y, vx, vy) - vy = apply_gravity(vy) - - # Render - # Clear the screen - - # Draw the dot - draw_dot(x, y) - - # Update the display - # Update - - # Render - window.fill((255, 255, 255)) - pygame.display.update() - -# Close window on quit -pygame.quit() diff --git a/tetris.py b/tetris.py deleted file mode 100644 index 33626bf..0000000 --- a/tetris.py +++ /dev/null @@ -1,521 +0,0 @@ -# Tetromino (a Tetris clone) -# By Al Sweigart al@inventwithpython.com -# http://inventwithpython.com/pygame -# Released under a "Simplified BSD" license - -import random -import time -import pygame -import sys -from pygame.locals import * - -FPS = 25 -WINDOWWIDTH = 640 -WINDOWZE = 20 -BOARHEIGHT = 480 -BOXSIDWIDTH = 10 -BOARDHEIGHT = 20 -BLANK = '.' - -MOVESIDEWAYSFREQ = 0.15 -MOVEDOWNFREQ = 0.1 - -XMARGIN = int((WINDOWWIDTH - BOARDWIDTH * BOXSIZE) / 2) -TOPMARGIN = WINDOWHEIGHT - (BOARDHEIGHT * BOXSIZE) - 5 - -# R G B -WHITE = (255, 255, 255) -GRAY = (185, 185, 185) -BLACK = (0, 0, 0) -RED = (155, 0, 0) -LIGHTRED = (175, 20, 20) -GREEN = (0, 155, 0) -LIGHTGREEN = (20, 175, 20) -BLUE = (0, 0, 155) -LIGHTBLUE = (20, 20, 175) -YELLOW = (155, 155, 0) -LIGHTYELLOW = (175, 175, 20) - -BORDERCOLOR = BLUE -BGCOLOR = BLACK -TEXTCOLOR = WHITE -TEXTSHADOWCOLOR = GRAY -COLORS = (BLUE, GREEN, RED, YELLOW) -LIGHTCOLORS = (LIGHTBLUE, LIGHTGREEN, LIGHTRED, LIGHTYELLOW) -assert len(COLORS) == len(LIGHTCOLORS) # each color must have light color - -TEMPLATEWIDTH = 5 -TEMPLATEHEIGHT = 5 - -S_SHAPE_TEMPLATE = [['.....', - '.....', - '..OO.', - '.OO..', - '.....'], - ['.....', - '..O..', - '..OO.', - '...O.', - '.....']] - -Z_SHAPE_TEMPLATE = [['.....', - '.....', - '.OO..', - '..OO.', - '.....'], - ['.....', - '..O..', - '.OO..', - '.O...', - '.....']] - -I_SHAPE_TEMPLATE = [['..O..', - '..O..', - '..O..', - '..O..', - '.....'], - ['.....', - '.....', - 'OOOO.', - '.....', - '.....']] - -O_SHAPE_TEMPLATE = [['.....', - '.....', - '.OO..', - '.OO..', - '.....']] - -J_SHAPE_TEMPLATE = [['.....', - '.O...', - '.OOO.', - '.....', - '.....'], - ['.....', - '..OO.', - '..O..', - '..O..', - '.....'], - ['.....', - '.....', - '.OOO.', - '...O.', - '.....'], - ['.....', - '..O..', - '..O..', - '.OO..', - '.....']] - -L_SHAPE_TEMPLATE = [['.....', - '...O.', - '.OOO.', - '.....', - '.....'], - ['.....', - '..O..', - '..O..', - '..OO.', - '.....'], - ['.....', - '.....', - '.OOO.', - '.O...', - '.....'], - ['.....', - '.OO..', - '..O..', - '..O..', - '.....']] - -T_SHAPE_TEMPLATE = [['.....', - '..O..', - '.OOO.', - '.....', - '.....'], - ['.....', - '..O..', - '..OO.', - '..O..', - '.....'], - ['.....', - '.....', - '.OOO.', - '..O..', - '.....'], - ['.....', - '..O..', - '.OO..', - '..O..', - '.....']] - -PIECES = {'S': S_SHAPE_TEMPLATE, - 'Z': Z_SHAPE_TEMPLATE, - 'J': J_SHAPE_TEMPLATE, - 'L': L_SHAPE_TEMPLATE, - 'I': I_SHAPE_TEMPLATE, - 'O': O_SHAPE_TEMPLATE, - 'T': T_SHAPE_TEMPLATE} - - -def main(): - global FPSCLOCK, DISPLAYSURF, BASICFONT, BIGFONT - pygame.init() - FPSCLOCK = pygame.time.Clock() - DISPLAYSURF = pygame.display.set_mode((WINDOWWIDTH, WINDOWHEIGHT)) - BASICFONT = pygame.font.Font('freesansbold.ttf', 18) - BIGFONT = pygame.font.Font('freesansbold.ttf', 100) - pygame.display.set_caption('Tetromino') - - showTextScreen('Tetromino') - while True: # game loop - # if random.randint(0, 1) == 0: - # pygame.mixer.music.load('tetrisb.mid') - # else: - # pygame.mixer.music.load('tetrisc.mid') - #pygame.mixer.music.play(-1, 0.0) - runGame() - # pygame.mixer.music.stop() - showTextScreen('Game Over') - - -def runGame(): - # setup variables for the start of the game - board = getBlankBoard() - lastMoveDownTime = time.time() - lastMoveSidewaysTime = time.time() - lastFallTime = time.time() - movingDown = False # note: there is no movingUp variable - movingLeft = False - movingRight = False - score = 0 - level, fallFreq = calculateLevelAndFallFreq(score) - - fallingPiece = getNewPiece() - nextPiece = getNewPiece() - - while True: # game loop - if fallingPiece == None: - # No falling piece in play, so start a new piece at the top - fallingPiece = nextPiece - nextPiece = getNewPiece() - lastFallTime = time.time() # reset lastFallTime - - if not isValidPosition(board, fallingPiece): - return # can't fit a new piece on the board, so game over - - checkForQuit() - for event in pygame.event.get(): # event handling loop - if event.type == KEYUP: - if (event.key == K_p): - # Pausing the game - DISPLAYSURF.fill(BGCOLOR) - pygame.mixer.music.stop() - showTextScreen('Paused') # pause until a key press - pygame.mixer.music.play(-1, 0.0) - lastFallTime = time.time() - lastMoveDownTime = time.time() - lastMoveSidewaysTime = time.time() - elif (event.key == K_LEFT or event.key == K_a): - movingLeft = False - elif (event.key == K_RIGHT or event.key == K_d): - movingRight = False - elif (event.key == K_DOWN or event.key == K_s): - movingDown = False - - elif event.type == KEYDOWN: - # moving the piece sideways - if (event.key == K_LEFT or event.key == K_a) and isValidPosition(board, fallingPiece, adjX=-1): - fallingPiece['x'] -= 1 - movingLeft = True - movingRight = False - lastMoveSidewaysTime = time.time() - - elif (event.key == K_RIGHT or event.key == K_d) and isValidPosition(board, fallingPiece, adjX=1): - fallingPiece['x'] += 1 - movingRight = True - movingLeft = False - lastMoveSidewaysTime = time.time() - - # rotating the piece (if there is room to rotate) - elif (event.key == K_UP or event.key == K_w): - fallingPiece['rotation'] = ( - fallingPiece['rotation'] + 1) % len(PIECES[fallingPiece['shape']]) - if not isValidPosition(board, fallingPiece): - fallingPiece['rotation'] = ( - fallingPiece['rotation'] - 1) % len(PIECES[fallingPiece['shape']]) - elif (event.key == K_q): # rotate the other direction - fallingPiece['rotation'] = ( - fallingPiece['rotation'] - 1) % len(PIECES[fallingPiece['shape']]) - if not isValidPosition(board, fallingPiece): - fallingPiece['rotation'] = ( - fallingPiece['rotation'] + 1) % len(PIECES[fallingPiece['shape']]) - - # making the piece fall faster with the down key - elif (event.key == K_DOWN or event.key == K_s): - movingDown = True - if isValidPosition(board, fallingPiece, adjY=1): - fallingPiece['y'] += 1 - lastMoveDownTime = time.time() - - # move the current piece all the way down - elif event.key == K_SPACE: - movingDown = False - movingLeft = False - movingRight = False - for i in range(1, BOARDHEIGHT): - if not isValidPosition(board, fallingPiece, adjY=i): - break - fallingPiece['y'] += i - 1 - - # handle moving the piece because of user input - if (movingLeft or movingRight) and time.time() - lastMoveSidewaysTime > MOVESIDEWAYSFREQ: - if movingLeft and isValidPosition(board, fallingPiece, adjX=-1): - fallingPiece['x'] -= 1 - elif movingRight and isValidPosition(board, fallingPiece, adjX=1): - fallingPiece['x'] += 1 - lastMoveSidewaysTime = time.time() - - if movingDown and time.time() - lastMoveDownTime > MOVEDOWNFREQ and isValidPosition(board, fallingPiece, adjY=1): - fallingPiece['y'] += 1 - lastMoveDownTime = time.time() - - # let the piece fall if it is time to fall - if time.time() - lastFallTime > fallFreq: - # see if the piece has landed - if not isValidPosition(board, fallingPiece, adjY=1): - # falling piece has landed, set it on the board - addToBoard(board, fallingPiece) - score += removeCompleteLines(board) - level, fallFreq = calculateLevelAndFallFreq(score) - fallingPiece = None - else: - # piece did not land, just move the piece down - fallingPiece['y'] += 1 - lastFallTime = time.time() - - # drawing everything on the screen - DISPLAYSURF.fill(BGCOLOR) - drawBoard(board) - drawStatus(score, level) - drawNextPiece(nextPiece) # Here - if fallingPiece != None: - drawPiece(fallingPiece) - - pygame.display.update() - FPSCLOCK.tick(FPS) - - -def makeTextObjs(text, font, color): - surf = font.render(text, True, color) - return surf, surf.get_rect() - - -def terminate(): - pygame.quit() - sys.exit() - - -def checkForKeyPress(): - # Go through event queue looking for a KEYUP event. - # Grab KEYDOWN events to remove them from the event queue. - checkForQuit() - - for event in pygame.event.get([KEYDOWN, KEYUP]): - if event.type == KEYDOWN: - continue - return event.key - return None - - -def showTextScreen(text): - # This function displays large text in the - # center of the screen until a key is pressed. - # Draw the text drop shadow - titleSurf, titleRect = makeTextObjs(text, BIGFONT, TEXTSHADOWCOLOR) - titleRect.center = (int(WINDOWWIDTH / 2), int(WINDOWHEIGHT / 2)) - DISPLAYSURF.blit(titleSurf, titleRect) - - # Draw the text - titleSurf, titleRect = makeTextObjs(text, BIGFONT, TEXTCOLOR) - titleRect.center = (int(WINDOWWIDTH / 2) - 3, int(WINDOWHEIGHT / 2) - 3) - DISPLAYSURF.blit(titleSurf, titleRect) - - # Draw the additional "Press a key to play." text. - pressKeySurf, pressKeyRect = makeTextObjs( - 'Press a key to play.', BASICFONT, TEXTCOLOR) - pressKeyRect.center = (int(WINDOWWIDTH / 2), int(WINDOWHEIGHT / 2) + 100) - DISPLAYSURF.blit(pressKeySurf, pressKeyRect) - - while checkForKeyPress() == None: - pygame.display.update() - FPSCLOCK.tick() - - -def checkForQuit(): - for event in pygame.event.get(QUIT): # get all the QUIT events - terminate() # terminate if any QUIT events are present - for event in pygame.event.get(KEYUP): # get all the KEYUP events - if event.key == K_ESCAPE: - terminate() # terminate if the KEYUP event was for the Esc key - pygame.event.post(event) # put the other KEYUP event objects back - - -def calculateLevelAndFallFreq(score): - # Based on the score, return the level the player is on and - # how many seconds pass until a falling piece falls one space. - level = int(score / 10) + 1 - fallFreq = 0.27 - (level * 0.02) - return level, fallFreq - - -def getNewPiece(): - # return a random new piece in a random rotation and color - shape = random.choice(list(PIECES.keys())) - newPiece = {'shape': shape, - 'rotation': random.randint(0, len(PIECES[shape]) - 1), - 'x': int(BOARDWIDTH / 2) - int(TEMPLATEWIDTH / 2), - 'y': -2, # start it above the board (i.e. less than 0) - 'color': random.randint(0, len(COLORS) - 1)} - return newPiece - - -def addToBoard(board, piece): - # fill in the board based on piece's location, shape, and rotation - for x in range(TEMPLATEWIDTH): - for y in range(TEMPLATEHEIGHT): - if PIECES[piece['shape']][piece['rotation']][y][x] != BLANK: - board[x + piece['x']][y + piece['y']] = piece['color'] - - -def getBlankBoard(): - # create and return a new blank board data structure - board = [] - for i in range(BOARDWIDTH): - board.append([BLANK] * BOARDHEIGHT) - return board - - -def isOnBoard(x, y): - return x >= 0 and x < BOARDWIDTH and y < BOARDHEIGHT - - -def isValidPosition(board, piece, adjX=0, adjY=0): - # Return True if the piece is within the board and not colliding - for x in range(TEMPLATEWIDTH): - for y in range(TEMPLATEHEIGHT): - isAboveBoard = y + piece['y'] + adjY < 0 - if isAboveBoard or PIECES[piece['shape']][piece['rotation']][y][x] == BLANK: - continue - if not isOnBoard(x + piece['x'] + adjX, y + piece['y'] + adjY): - return False - if board[x + piece['x'] + adjX][y + piece['y'] + adjY] != BLANK: - return False - return True - - -def isCompleteLine(board, y): - # Return True if the line filled with boxes with no gaps. - for x in range(BOARDWIDTH): - if board[x][y] == BLANK: - return False - return True - - -def removeCompleteLines(board): - # Remove any completed lines on the board, move everything above them down, and return the number of complete lines. - numLinesRemoved = 0 - y = BOARDHEIGHT - 1 # start y at the bottom of the board - while y >= 0: - if isCompleteLine(board, y): - # Remove the line and pull boxes down by one line. - for pullDownY in range(y, 0, -1): - for x in range(BOARDWIDTH): - board[x][pullDownY] = board[x][pullDownY - 1] - # Set very top line to blank. - for x in range(BOARDWIDTH): - board[x][0] = BLANK - numLinesRemoved += 1 - # Note on the next iteration of the loop, y is the same. - # This is so that if the line that was pulled down is also - # complete, it will be removed. - else: - y -= 1 # move on to check next row up - return numLinesRemoved - - -def convertToPixelCoords(boxx, boxy): - # Convert the given xy coordinates of the board to xy - # coordinates of the location on the screen. - return (XMARGIN + (boxx * BOXSIZE)), (TOPMARGIN + (boxy * BOXSIZE)) - - -def drawBox(boxx, boxy, color, pixelx=None, pixely=None): - # draw a single box (each tetromino piece has four boxes) - # at xy coordinates on the board. Or, if pixelx & pixely - # are specified, draw to the pixel coordinates stored in - # pixelx & pixely (this is used for the "Next" piece). - if color == BLANK: - return - if pixelx == None and pixely == None: - pixelx, pixely = convertToPixelCoords(boxx, boxy) - pygame.draw.rect(DISPLAYSURF, COLORS[color], - (pixelx + 1, pixely + 1, BOXSIZE - 1, BOXSIZE - 1)) - pygame.draw.rect( - DISPLAYSURF, LIGHTCOLORS[color], (pixelx + 1, pixely + 1, BOXSIZE - 4, BOXSIZE - 4)) - - -def drawBoard(board): - # draw the border around the board - pygame.draw.rect(DISPLAYSURF, BORDERCOLOR, (XMARGIN - 3, TOPMARGIN - 7, - (BOARDWIDTH * BOXSIZE) + 8, (BOARDHEIGHT * BOXSIZE) + 8), 5) - - # fill the background of the board - pygame.draw.rect(DISPLAYSURF, BGCOLOR, (XMARGIN, TOPMARGIN, - BOXSIZE * BOARDWIDTH, BOXSIZE * BOARDHEIGHT)) - # draw the individual boxes on the board - for x in range(BOARDWIDTH): - for y in range(BOARDHEIGHT): - drawBox(x, y, board[x][y]) - - -def drawStatus(score, level): - # draw the score text - scoreSurf = BASICFONT.render('Score: %s' % score, True, TEXTCOLOR) - scoreRect = scoreSurf.get_rect() - scoreRect.topleft = (WINDOWWIDTH - 150, 20) - DISPLAYSURF.blit(scoreSurf, scoreRect) - - # draw the level text - levelSurf = BASICFONT.render('Level: %s' % level, True, TEXTCOLOR) - levelRect = levelSurf.get_rect() - levelRect.topleft = (WINDOWWIDTH - 150, 50) - DISPLAYSURF.blit(levelSurf, levelRect) - - -def drawPiece(piece, pixelx=None, pixely=None): - shapeToDraw = PIECES[piece['shape']][piece['rotation']] - if pixelx == None and pixely == None: - # if pixelx & pixely hasn't been specified, use the location stored in the piece data structure - pixelx, pixely = convertToPixelCoords(piece['x'], piece['y']) - - # draw each of the boxes that make up the piece - for x in range(TEMPLATEWIDTH): - for y in range(TEMPLATEHEIGHT): - if shapeToDraw[y][x] != BLANK: - drawBox(None, None, piece['color'], pixelx - + (x * BOXSIZE), pixely + (y * BOXSIZE)) - - -def drawNextPiece(piece): - # draw the "next" text - nextSurf = BASICFONT.render('Next:', True, TEXTCOLOR) - nextRect = nextSurf.get_rect() - nextRect.topleft = (WINDOWWIDTH - 120, 80) - DISPLAYSURF.blit(nextSurf, nextRect) - # draw the "next" piece - drawPiece(piece, pixelx=WINDOWWIDTH - 120, pixely=100) - - -if __name__ == '__main__': - main() diff --git a/tmp.py b/tmp.py deleted file mode 100644 index a82b9ca..0000000 --- a/tmp.py +++ /dev/null @@ -1,41 +0,0 @@ -import noise -import pygame - -# Initialize pygame -pygame.init() - -# Set up the drawing window -screen = pygame.display.set_mode([800, 600]) - -# Run until the user asks to quit -running = True -while running: - - # Did the user click the window close button? - for event in pygame.event.get(): - if event.type == pygame.QUIT: - running = False - - # Fill the background with black - screen.fill((0, 0, 0)) - - # Draw stars - for i in range(2000): - x = int(noise.pnoise1(i / 10.0, octaves=4) * 800) - y = int(noise.pnoise1(i / 10.0 + 1000, octaves=4) * 600) - pygame.draw.circle(screen, (255, 255, 255), (x, y), 2) - - # Draw the moon - pygame.draw.circle(screen, (180, 180, 180), (400, 5600 - 200), 5000, 0) # moon - - # Draw craters on the surface of the moon (masked by the shape of the moon) - for i in range(20): - x = int(noise.pnoise1(i / 10.0, octaves=4) * 800) - y = int(noise.pnoise1(i / 10.0 + 1000, octaves=4) * 600) - pygame.draw.circle(screen, (100, 100, 100), (x, y), 20, 0) - - # Flip the display - pygame.display.flip() - -# Done! Time to quit. -pygame.quit() diff --git a/wall.png b/wall.png deleted file mode 100644 index a81bb68..0000000 Binary files a/wall.png and /dev/null differ