From 31eee2c0912101bfeb1d81e1d85041708a15db11 Mon Sep 17 00:00:00 2001 From: gresm <> Date: Wed, 6 Oct 2021 19:57:03 +0200 Subject: [PATCH 01/80] personal folder --- 01-fog-of-war/polastyn2030/main.py | 65 ++++++++++++ 01-fog-of-war/polastyn2030/objects.py | 142 ++++++++++++++++++++++++++ 01-fog-of-war/polastyn2030/utils.py | 40 ++++++++ 3 files changed, 247 insertions(+) create mode 100644 01-fog-of-war/polastyn2030/main.py create mode 100644 01-fog-of-war/polastyn2030/objects.py create mode 100644 01-fog-of-war/polastyn2030/utils.py diff --git a/01-fog-of-war/polastyn2030/main.py b/01-fog-of-war/polastyn2030/main.py new file mode 100644 index 0000000..f6eb3b8 --- /dev/null +++ b/01-fog-of-war/polastyn2030/main.py @@ -0,0 +1,65 @@ +import sys +from pathlib import Path + +try: + import wclib +except ImportError: + # wclib may not be in the path because of the architecture + # of all the challenges and the fact that there are many + # way to run them (through the showcase, or on their own) + + ROOT_FOLDER = Path(__file__).parent.parent.parent + sys.path.append(str(ROOT_FOLDER)) + import wclib + +# This line tells python how to handle the relative imports +# when you run this file directly. +__package__ = "01-fog-of-war." + Path(__file__).parent.name + +# ---- Recommended: don't modify anything above this line ---- # + +# Metadata about your submission +__author__ = "Your Discord Tag Goes Here#7777" +__achievements__ = [ # Uncomment the ones you've done + # "Casual", + # "Ambitious", + # "Adventurous", +] + + +from operator import attrgetter +import pygame + +# To import the modules in yourname/, you need to use relative imports, +# otherwise your project will not be compatible with the showcase. +from .objects import Ghost, Player, SolidObject + +BACKGROUND = 0x66856C + + +def mainloop(): + player = Player((100, 100)) + trees = SolidObject.generate_many(36) + ghosts = [Ghost() for _ in range(16)] + + all_objects = trees + [player] + ghosts + + clock = pygame.time.Clock() + while True: + screen, events = yield + for event in events: + if event.type == pygame.QUIT: + return + + for obj in all_objects: + obj.logic(objects=all_objects) + + screen.fill(BACKGROUND) + for object in sorted(all_objects, key=attrgetter("rect.bottom")): + object.draw(screen) + + clock.tick(60) + + +if __name__ == "__main__": + wclib.run(mainloop()) diff --git a/01-fog-of-war/polastyn2030/objects.py b/01-fog-of-war/polastyn2030/objects.py new file mode 100644 index 0000000..e507e56 --- /dev/null +++ b/01-fog-of-war/polastyn2030/objects.py @@ -0,0 +1,142 @@ +""" +This file provides objects that can be used to make up +a basic playground for the challenges. + +This code is provided so that you can focus on implementing +a fog of war, without needed +Feel free to modify everything in this file to your liking. +""" +from random import choice, gauss + +import pygame + +from wclib import SIZE +from .utils import clamp, from_polar, load_image, random_in_rect + +SCREEN = pygame.Rect(0, 0, *SIZE) + + +class Object: + """The base class for all objects of the game.""" + + def __init__(self, pos, sprite: pygame.Surface): + self.pos = pygame.Vector2(pos) + self.size = pygame.Vector2(sprite.get_size()) + self.sprite = sprite + + def __str__(self): + return f"<{self.__class__.__name__}(pos={self.pos}, size={self.size})>" + + @property + def rect(self): + return pygame.Rect(self.pos, self.size) + + def draw(self, screen): + screen.blit(self.sprite, self.pos) + + def logic(self, **kwargs): + pass + + +class Object8Directional(Object): + SCALE = 3 + SIZE = 16 + SHEET = "blue_ghost" + + ACCELERATION = 0.5 + DAMPING = 0.85 + + # Asymptotic velocity will be solution of + # x = x * DAMPING + ACCELERATION + # That is, + # x = ACCELERATION / (1 - DAMPING) + + def __init__(self, pos): + self.velocity = pygame.Vector2() + self.acceleration = pygame.Vector2() + + super().__init__(pos, self.get_image()) + + def get_image(self): + angle = self.velocity.as_polar()[1] + idx = int((-angle + 90 + 45 / 2) % 360 / 360 * 8) + sheet = load_image(self.SHEET, self.SCALE) + unit = self.SIZE * self.SCALE + return sheet.subsurface(idx * unit, 0, unit, unit) + + def logic(self, **kwargs): + self.velocity *= self.DAMPING + self.velocity += self.acceleration + self.pos += self.velocity + self.sprite = self.get_image() + + self.pos.x = clamp(self.pos.x, 0, SIZE[0]) + self.pos.y = clamp(self.pos.y, 0, SIZE[1]) + + +class Player(Object8Directional): + def logic(self, **kwargs): + pressed = pygame.key.get_pressed() + direction_x = pressed[pygame.K_RIGHT] - pressed[pygame.K_LEFT] + direction_y = pressed[pygame.K_DOWN] - pressed[pygame.K_UP] + + self.acceleration = pygame.Vector2(direction_x, direction_y) * self.ACCELERATION + super().logic(**kwargs) + + +class Ghost(Object8Directional): + SHEET = "pink_ghost" + ACCELERATION = 0.2 + DAMPING = 0.9 + + def __init__(self, pos=None): + if pos is None: + pos = random_in_rect(SCREEN) + super().__init__(pos) + self.goal = self.new_goal() + + def new_goal(self): + direction = from_polar(60, gauss(self.velocity.as_polar()[1], 30)) + return self.rect.center + direction + + def logic(self, **kwargs): + middle_area = SCREEN.inflate(-30, -30) + while self.rect.collidepoint(self.goal) or not middle_area.collidepoint( + self.goal + ): + self.goal = self.new_goal() + + self.acceleration = ( + self.goal - self.rect.center + ).normalize() * self.ACCELERATION + super().logic(**kwargs) + + +class SolidObject(Object): + SHEET_RECT = [ + (0, 0, 24, 31), + (24, 0, 24, 24), + (48, 0, 24, 24), + (72, 0, 16, 24), + (88, 0, 48, 43), + (136, 0, 16, 16), + ] + SCALE = 3 + + def __init__(self, pos): + sheet = load_image("tileset", self.SCALE) + sheet.set_colorkey(0xFFFFFF) + rect = choice(self.SHEET_RECT) + rect = [x * self.SCALE for x in rect] + super().__init__(pos, sheet.subsurface(rect)) + + @classmethod + def generate_many(cls, nb=16, max_tries=1000): + objects = [] + tries = 0 # avoids infinite loop + while len(objects) < nb and tries < max_tries: + pos = random_in_rect(SCREEN) + obj = cls(pos) + if not any(obj.rect.colliderect(other.rect) for other in objects): + objects.append(obj) + return objects diff --git a/01-fog-of-war/polastyn2030/utils.py b/01-fog-of-war/polastyn2030/utils.py new file mode 100644 index 0000000..28d56ff --- /dev/null +++ b/01-fog-of-war/polastyn2030/utils.py @@ -0,0 +1,40 @@ +from functools import lru_cache +from pathlib import Path +from random import uniform + +import pygame + +SUBMISSION_DIR = Path(__file__).parent +ASSETS = SUBMISSION_DIR.parent / "assets" + + +@lru_cache() +def load_image(name: str, scale=1): + image = pygame.image.load(ASSETS / f"{name}.png") + if scale != 1: + new_size = image.get_width() * scale, image.get_height() * scale + image = pygame.transform.scale(image, new_size) + return image.convert_alpha() + + +def clamp(value, mini, maxi): + """Clamp value between mini and maxi""" + if value < mini: + return mini + elif maxi < value: + return maxi + else: + return value + + +def random_in_rect(rect): + """Return a random point uniformly in a rectangle.""" + rect = pygame.Rect(rect) + return pygame.Vector2(uniform(rect.left, rect.right), uniform(rect.top, rect.bottom)) + + +def from_polar(rho, theta): + """Create a Vector2 from its polar representation.""" + v = pygame.Vector2() + v.from_polar((rho, theta)) + return v From 24881ca7a6fe3a4095d95c53ec612ea1331ab2db Mon Sep 17 00:00:00 2001 From: gresm <> Date: Wed, 6 Oct 2021 21:39:18 +0200 Subject: [PATCH 02/80] flood_iter.py - added --- 01-fog-of-war/polastyn2030/flood_iter.py | 143 +++++++++++++++++++++++ 1 file changed, 143 insertions(+) create mode 100644 01-fog-of-war/polastyn2030/flood_iter.py diff --git a/01-fog-of-war/polastyn2030/flood_iter.py b/01-fog-of-war/polastyn2030/flood_iter.py new file mode 100644 index 0000000..8655244 --- /dev/null +++ b/01-fog-of-war/polastyn2030/flood_iter.py @@ -0,0 +1,143 @@ +from __future__ import annotations + + +from typing import Tuple, Set, Iterator, List + + +class Flood: + def __init__(self, start_x: int, start_y: int, max_iterations: int): + self.start_x = start_x + self.start_y = start_y + self.max_iterations = max_iterations + + def __iter__(self) -> "FloodIter": + return FloodIter(self).start() + + +class FloodIter: + iterator: Iterator[Tuple[int, int]] + + def __init__(self, flood_info: Flood): + self.flood_info = flood_info + self.visited_places: Set[Tuple[int, int]] = set() + self.routes: Set[Tuple[int, int]] = set() + self.asking_routes: Set[Tuple[int, int]] = set() + self.possible_movement = PossibleMovement() + self.first_time: bool = True + self.iterator = iterator((self.flood_info.start_x, self.flood_info.start_y), self.possible_movement, + self.flood_info.max_iterations) + + def start(self): + self.iterator = iterator((self.flood_info.start_x, self.flood_info.start_y), self.possible_movement, + self.flood_info.max_iterations) + return self + + def __iter__(self) -> "FloodIter": + return self.start() + + def __next__(self) -> Tuple[int, int, "PossibleMovement"]: + if self.first_time: + self.first_time = False + return self.flood_info.start_x, self.flood_info.start_y, self.possible_movement + return next(self.iterator) + (self.possible_movement,) + + +class PossibleMovement: + def __init__(self): + self.left = False + self.up = False + self.right = False + self.down = False + + self.left_teleport: Tuple[int, int] = (-1, -1) + self.up_teleport: Tuple[int, int] = (-1, -1) + self.right_teleport: Tuple[int, int] = (-1, -1) + self.down_teleport: Tuple[int, int] = (-1, -1) + + def get_movement(self, pos: Tuple[int, int]): + raw = self.raw_movement(pos) + ret: Set[Tuple[int, int]] = set() + + if self.left: + ret.add(raw[0]) + + if self.up: + ret.add(raw[1]) + + if self.right: + ret.add(raw[2]) + + if self.down: + ret.add(raw[3]) + return ret + + def raw_movement(self, pos: Tuple[int, int], reset: bool = True): + _pos = pos + ret: List[Tuple[int, int]] = [] + + if self.left_teleport != (-1, -1): + pos = self.left_teleport + if reset: + self.left_teleport = (-1, -1) + ret.append((pos[0] - 1, pos[1])) + pos = _pos + + if self.up_teleport != (-1, -1): + pos = self.up_teleport + if reset: + self.up_teleport = (-1, -1) + ret.append((pos[0], pos[1] - 1)) + pos = _pos + + if self.right_teleport != (-1, -1): + pos = self.right_teleport + if reset: + self.right_teleport = (-1, -1) + ret.append((pos[0] + 1, pos[1])) + pos = _pos + + if self.down_teleport != (-1, -1): + pos = self.down_teleport + if reset: + self.down_teleport = (-1, -1) + ret.append((pos[0], pos[1] + 1)) + + return ret + + def all_true(self): + self.left = True + self.up = True + self.up = True + self.down = True + + def all_false(self): + self.left = False + self.up = False + self.up = False + self.down = False + + +def iterator(start_pos: Tuple[int, int], is_correct: PossibleMovement, max_depth: int) -> Iterator[Tuple[int, int]]: + routes: Set[Tuple[int, int]] = set() + visited: Set[Tuple[int, int]] = set() + + def get_correct_spread(check_pos: Tuple[int, int]) -> Set[Tuple[int, int]]: + return is_correct.get_movement(check_pos).difference(visited) + + routes.update(get_correct_spread(start_pos)) + cnt = 0 + + while len(routes): + if cnt >= max_depth: + break + new_routes = set() + old_routes = set() + for rout in routes: + visited.add(rout) + new_routes.update(get_correct_spread(rout)) + old_routes.add(rout) + yield rout + cnt += 1 + + routes.update(new_routes) + routes.difference_update(old_routes) From 7dbde9467122d5590a93f0cc8ae921bcd6103100 Mon Sep 17 00:00:00 2001 From: gresm <> Date: Wed, 6 Oct 2021 23:02:49 +0200 Subject: [PATCH 03/80] fog.py - added --- 01-fog-of-war/polastyn2030/flood_iter.py | 19 +++++++ 01-fog-of-war/polastyn2030/fog.py | 68 ++++++++++++++++++++++++ 01-fog-of-war/polastyn2030/main.py | 4 +- 3 files changed, 89 insertions(+), 2 deletions(-) create mode 100644 01-fog-of-war/polastyn2030/fog.py diff --git a/01-fog-of-war/polastyn2030/flood_iter.py b/01-fog-of-war/polastyn2030/flood_iter.py index 8655244..90bf053 100644 --- a/01-fog-of-war/polastyn2030/flood_iter.py +++ b/01-fog-of-war/polastyn2030/flood_iter.py @@ -1,3 +1,22 @@ +# Copyright <2021> - MIT LICENSE +# +# Permission is hereby granted, free of charge, +# to any person obtaining a copy of this software and associated documentation files (the "Software"), +# to deal in the Software without restriction, +# including without limitation the rights to +# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, +# and to permit persons to whom the Software is furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +# INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +# DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE + from __future__ import annotations diff --git a/01-fog-of-war/polastyn2030/fog.py b/01-fog-of-war/polastyn2030/fog.py new file mode 100644 index 0000000..ab62697 --- /dev/null +++ b/01-fog-of-war/polastyn2030/fog.py @@ -0,0 +1,68 @@ +import pygame as pg + + +from .flood_iter import Flood + + +class InfiniteMap: + def __init__(self): + self.map = {} + self.default = 0 + + def get(self, pos): + if pos in self.map: + return self.map[pos] + return self.default + + def set(self, pos, value): + self.map[pos] = value + + +class FogArea: + def __init__(self, rect_w, rect_h, width, height, max_visibility): + self.rect_w = rect_w + self.rect_h = rect_h + self.width = width + self.height = height + self.discovered = InfiniteMap() + self.max_steps = max_visibility + self._trans_tile = pg.Surface((rect_w, rect_h), pg.SRCALPHA) + self._trans_tile.fill((0, 0, 0, 0)) + self._fog_of_war = self._trans_tile.copy() + self._fog_of_war.fill((0, 0, 0, 125)) + self._unknown_area_tile = self._trans_tile.copy() + self._unknown_area_tile.fill((0, 0, 0)) + + def pos_to_grid(self, pos): + fixed_x = pos[0] - pos[0] % self.rect_w + fixed_y = pos[1] - pos[1] % self.rect_h + grid_x = fixed_x / self.rect_w + grid_y = fixed_y / self.rect_h + return grid_x, grid_y + + def grid_to_pos(self, grid): + return grid[0] * self.rect_w, grid[1] * self.rect_h + + def in_visible_range(self, player_pos, check_pos): + grid_pos = self.grid_to_pos(check_pos) + for x, y, _ in Flood(player_pos[0], player_pos[1], self.max_steps): + if (x, y) == grid_pos: + return True + return False + + def get_mask(self, player_pos): + pos = self.pos_to_grid(player_pos) + int_pos = int(pos[0]), int(pos[1]) + + mask = pg.Surface((self.rect_w * self.width, self.rect_h * self.height), pg.SRCALPHA) + + for i in range(self.width): + for j in range(self.height): + tile_pos = (i, j) + if self.discovered.get(tile_pos): + if self.in_visible_range(pos, tile_pos): + pass + else: + mask.blit(self._fog_of_war, self.grid_to_pos(tile_pos)) + else: + mask.blit(self._unknown_area_tile, self.grid_to_pos(tile_pos)) diff --git a/01-fog-of-war/polastyn2030/main.py b/01-fog-of-war/polastyn2030/main.py index f6eb3b8..9003d63 100644 --- a/01-fog-of-war/polastyn2030/main.py +++ b/01-fog-of-war/polastyn2030/main.py @@ -55,8 +55,8 @@ def mainloop(): obj.logic(objects=all_objects) screen.fill(BACKGROUND) - for object in sorted(all_objects, key=attrgetter("rect.bottom")): - object.draw(screen) + for obj in sorted(all_objects, key=attrgetter("rect.bottom")): + obj.draw(screen) clock.tick(60) From d3c236ece9c4d07c260e2cb874a7a90beef0f5d6 Mon Sep 17 00:00:00 2001 From: gresm <> Date: Thu, 7 Oct 2021 20:42:25 +0200 Subject: [PATCH 04/80] fog test 1 --- 01-fog-of-war/polastyn2030/fog.py | 52 ++++++++++++++++++++---------- 01-fog-of-war/polastyn2030/main.py | 6 ++++ 2 files changed, 41 insertions(+), 17 deletions(-) diff --git a/01-fog-of-war/polastyn2030/fog.py b/01-fog-of-war/polastyn2030/fog.py index ab62697..405e85b 100644 --- a/01-fog-of-war/polastyn2030/fog.py +++ b/01-fog-of-war/polastyn2030/fog.py @@ -1,3 +1,6 @@ +from __future__ import annotations + + import pygame as pg @@ -17,14 +20,16 @@ def get(self, pos): def set(self, pos, value): self.map[pos] = value + def clear(self): + self.map = {} + class FogArea: - def __init__(self, rect_w, rect_h, width, height, max_visibility): + def __init__(self, rect_w, rect_h, max_visibility): self.rect_w = rect_w self.rect_h = rect_h - self.width = width - self.height = height self.discovered = InfiniteMap() + self.lighted_area = InfiniteMap() self.max_steps = max_visibility self._trans_tile = pg.Surface((rect_w, rect_h), pg.SRCALPHA) self._trans_tile.fill((0, 0, 0, 0)) @@ -43,26 +48,39 @@ def pos_to_grid(self, pos): def grid_to_pos(self, grid): return grid[0] * self.rect_w, grid[1] * self.rect_h - def in_visible_range(self, player_pos, check_pos): - grid_pos = self.grid_to_pos(check_pos) - for x, y, _ in Flood(player_pos[0], player_pos[1], self.max_steps): - if (x, y) == grid_pos: - return True - return False - - def get_mask(self, player_pos): - pos = self.pos_to_grid(player_pos) - int_pos = int(pos[0]), int(pos[1]) + def in_visible_range(self, check_pos): + return not not self.lighted_area.get(self.pos_to_grid(check_pos)) - mask = pg.Surface((self.rect_w * self.width, self.rect_h * self.height), pg.SRCALPHA) + def get_mask(self, size: tuple[int, int]): + mask = pg.Surface(size, pg.SRCALPHA) + x_grid = (size[0] - size[0] % self.rect_w) // self.rect_w + y_grid = (size[1] - size[1] % self.rect_h) // self.rect_h - for i in range(self.width): - for j in range(self.height): + i = 0 + while i <= x_grid: + j = 0 + while j <= y_grid: tile_pos = (i, j) if self.discovered.get(tile_pos): - if self.in_visible_range(pos, tile_pos): + if self.in_visible_range(tile_pos): pass else: mask.blit(self._fog_of_war, self.grid_to_pos(tile_pos)) else: mask.blit(self._unknown_area_tile, self.grid_to_pos(tile_pos)) + j += 1 + i += 1 + return mask + + def draw(self, screen: pg.Surface): + screen.blit(self.get_mask(screen.get_size()), (0, 0)) + + def logic(self, player): + self.lighted_area.clear() + + pos = self.pos_to_grid(player.pos) + + for x, y, check in Flood(pos[0], pos[1], self.max_steps): + check.all_true() + self.lighted_area.set((x, y), 1) + self.discovered.set((x, y), 1) diff --git a/01-fog-of-war/polastyn2030/main.py b/01-fog-of-war/polastyn2030/main.py index 9003d63..12500d1 100644 --- a/01-fog-of-war/polastyn2030/main.py +++ b/01-fog-of-war/polastyn2030/main.py @@ -33,12 +33,14 @@ # To import the modules in yourname/, you need to use relative imports, # otherwise your project will not be compatible with the showcase. from .objects import Ghost, Player, SolidObject +from .fog import FogArea BACKGROUND = 0x66856C def mainloop(): player = Player((100, 100)) + fog = FogArea(100, 100, 5) trees = SolidObject.generate_many(36) ghosts = [Ghost() for _ in range(16)] @@ -54,10 +56,14 @@ def mainloop(): for obj in all_objects: obj.logic(objects=all_objects) + fog.logic(player) + screen.fill(BACKGROUND) for obj in sorted(all_objects, key=attrgetter("rect.bottom")): obj.draw(screen) + fog.draw(screen) + clock.tick(60) From d5518dcd171dd7a2e88cb4c2857c81b663353cb3 Mon Sep 17 00:00:00 2001 From: gresm <> Date: Thu, 7 Oct 2021 21:16:15 +0200 Subject: [PATCH 05/80] small fix for lib --- wclib/showcase.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/wclib/showcase.py b/wclib/showcase.py index 00e6525..8d8f061 100644 --- a/wclib/showcase.py +++ b/wclib/showcase.py @@ -1,7 +1,7 @@ import importlib import json import sys -from functools import lru_cache +from functools import lru_cache, partial from pathlib import Path from typing import Callable, List @@ -92,7 +92,7 @@ def __init__(self, app: "App", title, buttons): self.buttons = [ Button( *button, - lambda: self.button_click(button), + partial(self.button_click, button), self.button_position(i), ) for i, button in enumerate(buttons) From 35084f368e052a476f2c647e863871dfc00498b2 Mon Sep 17 00:00:00 2001 From: gresm <> Date: Thu, 7 Oct 2021 21:48:38 +0200 Subject: [PATCH 06/80] entry end commit --- 01-fog-of-war/polastyn2030/flood_iter.py | 29 ++---------------------- 01-fog-of-war/polastyn2030/fog.py | 25 +++++++++++++++----- 01-fog-of-war/polastyn2030/main.py | 5 ++-- 3 files changed, 24 insertions(+), 35 deletions(-) diff --git a/01-fog-of-war/polastyn2030/flood_iter.py b/01-fog-of-war/polastyn2030/flood_iter.py index 90bf053..69e402b 100644 --- a/01-fog-of-war/polastyn2030/flood_iter.py +++ b/01-fog-of-war/polastyn2030/flood_iter.py @@ -68,11 +68,6 @@ def __init__(self): self.right = False self.down = False - self.left_teleport: Tuple[int, int] = (-1, -1) - self.up_teleport: Tuple[int, int] = (-1, -1) - self.right_teleport: Tuple[int, int] = (-1, -1) - self.down_teleport: Tuple[int, int] = (-1, -1) - def get_movement(self, pos: Tuple[int, int]): raw = self.raw_movement(pos) ret: Set[Tuple[int, int]] = set() @@ -91,34 +86,14 @@ def get_movement(self, pos: Tuple[int, int]): return ret def raw_movement(self, pos: Tuple[int, int], reset: bool = True): - _pos = pos ret: List[Tuple[int, int]] = [] - if self.left_teleport != (-1, -1): - pos = self.left_teleport - if reset: - self.left_teleport = (-1, -1) ret.append((pos[0] - 1, pos[1])) - pos = _pos - if self.up_teleport != (-1, -1): - pos = self.up_teleport - if reset: - self.up_teleport = (-1, -1) ret.append((pos[0], pos[1] - 1)) - pos = _pos - if self.right_teleport != (-1, -1): - pos = self.right_teleport - if reset: - self.right_teleport = (-1, -1) ret.append((pos[0] + 1, pos[1])) - pos = _pos - if self.down_teleport != (-1, -1): - pos = self.down_teleport - if reset: - self.down_teleport = (-1, -1) ret.append((pos[0], pos[1] + 1)) return ret @@ -126,13 +101,13 @@ def raw_movement(self, pos: Tuple[int, int], reset: bool = True): def all_true(self): self.left = True self.up = True - self.up = True + self.right = True self.down = True def all_false(self): self.left = False self.up = False - self.up = False + self.right = False self.down = False diff --git a/01-fog-of-war/polastyn2030/fog.py b/01-fog-of-war/polastyn2030/fog.py index 405e85b..76a4523 100644 --- a/01-fog-of-war/polastyn2030/fog.py +++ b/01-fog-of-war/polastyn2030/fog.py @@ -20,6 +20,10 @@ def get(self, pos): def set(self, pos, value): self.map[pos] = value + def remove(self, pos): + if pos in self.map: + del self.map[pos] + def clear(self): self.map = {} @@ -30,9 +34,10 @@ def __init__(self, rect_w, rect_h, max_visibility): self.rect_h = rect_h self.discovered = InfiniteMap() self.lighted_area = InfiniteMap() + self.more_lighted_area = InfiniteMap() self.max_steps = max_visibility self._trans_tile = pg.Surface((rect_w, rect_h), pg.SRCALPHA) - self._trans_tile.fill((0, 0, 0, 0)) + self._trans_tile.fill((0, 0, 0, 64)) self._fog_of_war = self._trans_tile.copy() self._fog_of_war.fill((0, 0, 0, 125)) self._unknown_area_tile = self._trans_tile.copy() @@ -48,9 +53,6 @@ def pos_to_grid(self, pos): def grid_to_pos(self, grid): return grid[0] * self.rect_w, grid[1] * self.rect_h - def in_visible_range(self, check_pos): - return not not self.lighted_area.get(self.pos_to_grid(check_pos)) - def get_mask(self, size: tuple[int, int]): mask = pg.Surface(size, pg.SRCALPHA) x_grid = (size[0] - size[0] % self.rect_w) // self.rect_w @@ -62,10 +64,14 @@ def get_mask(self, size: tuple[int, int]): while j <= y_grid: tile_pos = (i, j) if self.discovered.get(tile_pos): - if self.in_visible_range(tile_pos): - pass + if self.lighted_area.get(tile_pos): + if not self.more_lighted_area.get(tile_pos): + mask.blit(self._trans_tile, self.grid_to_pos(tile_pos)) else: mask.blit(self._fog_of_war, self.grid_to_pos(tile_pos)) + + if self.more_lighted_area.get(tile_pos): + self.more_lighted_area.remove(tile_pos) else: mask.blit(self._unknown_area_tile, self.grid_to_pos(tile_pos)) j += 1 @@ -84,3 +90,10 @@ def logic(self, player): check.all_true() self.lighted_area.set((x, y), 1) self.discovered.set((x, y), 1) + + for x, y, check in Flood(pos[0], pos[1], self.max_steps//2): + check.all_true() + self.more_lighted_area.set((x, y), 1) + + def lighted_up(self, pos): + return self.lighted_area.get(self.pos_to_grid(pos)) diff --git a/01-fog-of-war/polastyn2030/main.py b/01-fog-of-war/polastyn2030/main.py index 12500d1..6df162d 100644 --- a/01-fog-of-war/polastyn2030/main.py +++ b/01-fog-of-war/polastyn2030/main.py @@ -40,7 +40,7 @@ def mainloop(): player = Player((100, 100)) - fog = FogArea(100, 100, 5) + fog = FogArea(20, 20, 10) trees = SolidObject.generate_many(36) ghosts = [Ghost() for _ in range(16)] @@ -60,7 +60,8 @@ def mainloop(): screen.fill(BACKGROUND) for obj in sorted(all_objects, key=attrgetter("rect.bottom")): - obj.draw(screen) + if not isinstance(obj, Ghost) or fog.lighted_up(obj.pos): + obj.draw(screen) fog.draw(screen) From 12f5614f19d6ddd540d075d2a6b8ddbb543c08ce Mon Sep 17 00:00:00 2001 From: gresm <> Date: Thu, 7 Oct 2021 21:53:22 +0200 Subject: [PATCH 07/80] small license fix --- 01-fog-of-war/polastyn2030/flood_iter.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/01-fog-of-war/polastyn2030/flood_iter.py b/01-fog-of-war/polastyn2030/flood_iter.py index 69e402b..14cede4 100644 --- a/01-fog-of-war/polastyn2030/flood_iter.py +++ b/01-fog-of-war/polastyn2030/flood_iter.py @@ -1,4 +1,4 @@ -# Copyright <2021> - MIT LICENSE +# Copyright <2021> - MIT LICENSE # # Permission is hereby granted, free of charge, # to any person obtaining a copy of this software and associated documentation files (the "Software"), From e139e68dec51ba9d78597be5350c8a7bba299751 Mon Sep 17 00:00:00 2001 From: gresm <> Date: Fri, 8 Oct 2021 08:24:49 +0200 Subject: [PATCH 08/80] add iterations number to flood_iter.py --- 01-fog-of-war/polastyn2030/flood_iter.py | 29 ++++++++++++------------ 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/01-fog-of-war/polastyn2030/flood_iter.py b/01-fog-of-war/polastyn2030/flood_iter.py index 14cede4..7477e66 100644 --- a/01-fog-of-war/polastyn2030/flood_iter.py +++ b/01-fog-of-war/polastyn2030/flood_iter.py @@ -34,7 +34,7 @@ def __iter__(self) -> "FloodIter": class FloodIter: - iterator: Iterator[Tuple[int, int]] + iterator: Iterator[Tuple[int, int, int]] def __init__(self, flood_info: Flood): self.flood_info = flood_info @@ -54,10 +54,10 @@ def start(self): def __iter__(self) -> "FloodIter": return self.start() - def __next__(self) -> Tuple[int, int, "PossibleMovement"]: + def __next__(self) -> Tuple[int, int, int, "PossibleMovement"]: if self.first_time: self.first_time = False - return self.flood_info.start_x, self.flood_info.start_y, self.possible_movement + return self.flood_info.start_x, self.flood_info.start_y, 0, self.possible_movement return next(self.iterator) + (self.possible_movement,) @@ -85,16 +85,12 @@ def get_movement(self, pos: Tuple[int, int]): ret.add(raw[3]) return ret - def raw_movement(self, pos: Tuple[int, int], reset: bool = True): - ret: List[Tuple[int, int]] = [] - - ret.append((pos[0] - 1, pos[1])) - - ret.append((pos[0], pos[1] - 1)) - - ret.append((pos[0] + 1, pos[1])) - - ret.append((pos[0], pos[1] + 1)) + # noinspection PyMethodMayBeStatic + def raw_movement(self, pos: Tuple[int, int]): + ret: List[Tuple[int, int]] = [ + (pos[0] - 1, pos[1]), (pos[0], pos[1] - 1), + (pos[0] + 1, pos[1]), (pos[0], pos[1] + 1) + ] return ret @@ -111,7 +107,10 @@ def all_false(self): self.down = False -def iterator(start_pos: Tuple[int, int], is_correct: PossibleMovement, max_depth: int) -> Iterator[Tuple[int, int]]: +def iterator( + start_pos: Tuple[int, int], is_correct: PossibleMovement, max_depth: int +) -> Iterator[Tuple[int, int, int]]: + routes: Set[Tuple[int, int]] = set() visited: Set[Tuple[int, int]] = set() @@ -130,7 +129,7 @@ def get_correct_spread(check_pos: Tuple[int, int]) -> Set[Tuple[int, int]]: visited.add(rout) new_routes.update(get_correct_spread(rout)) old_routes.add(rout) - yield rout + yield rout + (cnt,) cnt += 1 routes.update(new_routes) From 1df4606c78301f26e6252583119abb1bead9cfef Mon Sep 17 00:00:00 2001 From: gresm <> Date: Fri, 8 Oct 2021 08:40:19 +0200 Subject: [PATCH 09/80] smooth shadows --- 01-fog-of-war/polastyn2030/fog.py | 40 +++++++++++++++++++++---------- 1 file changed, 27 insertions(+), 13 deletions(-) diff --git a/01-fog-of-war/polastyn2030/fog.py b/01-fog-of-war/polastyn2030/fog.py index 76a4523..839a726 100644 --- a/01-fog-of-war/polastyn2030/fog.py +++ b/01-fog-of-war/polastyn2030/fog.py @@ -36,12 +36,22 @@ def __init__(self, rect_w, rect_h, max_visibility): self.lighted_area = InfiniteMap() self.more_lighted_area = InfiniteMap() self.max_steps = max_visibility + self._semi_trans = 64 + self._fog_of_war = 125 + self._unknown = 255 self._trans_tile = pg.Surface((rect_w, rect_h), pg.SRCALPHA) - self._trans_tile.fill((0, 0, 0, 64)) - self._fog_of_war = self._trans_tile.copy() - self._fog_of_war.fill((0, 0, 0, 125)) - self._unknown_area_tile = self._trans_tile.copy() - self._unknown_area_tile.fill((0, 0, 0)) + self._trans_tile.fill((0, 0, 0, 0)) + + self._created_tiles: dict[int, pg.Surface] = {} + + def _get_tile(self, trans): + if trans in self._created_tiles: + return self._created_tiles[trans] + + copy = self._trans_tile.copy() + copy.fill((0, 0, 0, trans)) + self._created_tiles[trans] = copy + return copy def pos_to_grid(self, pos): fixed_x = pos[0] - pos[0] % self.rect_w @@ -65,15 +75,18 @@ def get_mask(self, size: tuple[int, int]): tile_pos = (i, j) if self.discovered.get(tile_pos): if self.lighted_area.get(tile_pos): - if not self.more_lighted_area.get(tile_pos): - mask.blit(self._trans_tile, self.grid_to_pos(tile_pos)) + if self.more_lighted_area.get(tile_pos): + by = self.more_lighted_area.get(tile_pos) + mask.blit(self._get_tile(self._semi_trans+by*5), self.grid_to_pos(tile_pos)) + else: + mask.blit(self._get_tile(self._semi_trans), self.grid_to_pos(tile_pos)) else: - mask.blit(self._fog_of_war, self.grid_to_pos(tile_pos)) + mask.blit(self._get_tile(self._fog_of_war), self.grid_to_pos(tile_pos)) if self.more_lighted_area.get(tile_pos): self.more_lighted_area.remove(tile_pos) else: - mask.blit(self._unknown_area_tile, self.grid_to_pos(tile_pos)) + mask.blit(self._get_tile(self._unknown), self.grid_to_pos(tile_pos)) j += 1 i += 1 return mask @@ -86,14 +99,15 @@ def logic(self, player): pos = self.pos_to_grid(player.pos) - for x, y, check in Flood(pos[0], pos[1], self.max_steps): + for x, y, step, check in Flood(pos[0], pos[1], self.max_steps): check.all_true() self.lighted_area.set((x, y), 1) self.discovered.set((x, y), 1) + self.more_lighted_area.set((x, y), step + 1) - for x, y, check in Flood(pos[0], pos[1], self.max_steps//2): - check.all_true() - self.more_lighted_area.set((x, y), 1) + # for x, y, step, check in Flood(pos[0], pos[1], self.max_steps//2): + # check.all_true() + # self.more_lighted_area.set((x, y), step + 1) def lighted_up(self, pos): return self.lighted_area.get(self.pos_to_grid(pos)) From f8c2f086ea0fc7514c2802fd418de03b63e3b497 Mon Sep 17 00:00:00 2001 From: gresm <> Date: Fri, 8 Oct 2021 21:42:36 +0200 Subject: [PATCH 10/80] joined fog lightening mechanic --- 01-fog-of-war/polastyn2030/fog.py | 14 ++++++++------ 01-fog-of-war/polastyn2030/main.py | 2 +- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/01-fog-of-war/polastyn2030/fog.py b/01-fog-of-war/polastyn2030/fog.py index 839a726..4a4dc38 100644 --- a/01-fog-of-war/polastyn2030/fog.py +++ b/01-fog-of-war/polastyn2030/fog.py @@ -36,7 +36,8 @@ def __init__(self, rect_w, rect_h, max_visibility): self.lighted_area = InfiniteMap() self.more_lighted_area = InfiniteMap() self.max_steps = max_visibility - self._semi_trans = 64 + self._smooth_trans = 60 + self._semi_trans = 100 self._fog_of_war = 125 self._unknown = 255 self._trans_tile = pg.Surface((rect_w, rect_h), pg.SRCALPHA) @@ -77,7 +78,7 @@ def get_mask(self, size: tuple[int, int]): if self.lighted_area.get(tile_pos): if self.more_lighted_area.get(tile_pos): by = self.more_lighted_area.get(tile_pos) - mask.blit(self._get_tile(self._semi_trans+by*5), self.grid_to_pos(tile_pos)) + mask.blit(self._get_tile(self._smooth_trans+by*5), self.grid_to_pos(tile_pos)) else: mask.blit(self._get_tile(self._semi_trans), self.grid_to_pos(tile_pos)) else: @@ -98,16 +99,17 @@ def logic(self, player): self.lighted_area.clear() pos = self.pos_to_grid(player.pos) + pos = (pos[0] + 1, pos[1] + 1) for x, y, step, check in Flood(pos[0], pos[1], self.max_steps): check.all_true() self.lighted_area.set((x, y), 1) self.discovered.set((x, y), 1) - self.more_lighted_area.set((x, y), step + 1) + # self.more_lighted_area.set((x, y), step + 1) - # for x, y, step, check in Flood(pos[0], pos[1], self.max_steps//2): - # check.all_true() - # self.more_lighted_area.set((x, y), step + 1) + for x, y, step, check in Flood(pos[0], pos[1], self.max_steps//2): + check.all_true() + self.more_lighted_area.set((x, y), step + 1) def lighted_up(self, pos): return self.lighted_area.get(self.pos_to_grid(pos)) diff --git a/01-fog-of-war/polastyn2030/main.py b/01-fog-of-war/polastyn2030/main.py index 6df162d..a266f0a 100644 --- a/01-fog-of-war/polastyn2030/main.py +++ b/01-fog-of-war/polastyn2030/main.py @@ -60,7 +60,7 @@ def mainloop(): screen.fill(BACKGROUND) for obj in sorted(all_objects, key=attrgetter("rect.bottom")): - if not isinstance(obj, Ghost) or fog.lighted_up(obj.pos): + if not isinstance(obj, Ghost) or fog.lighted_up(obj.rect.center): obj.draw(screen) fog.draw(screen) From 6fc43d5c8b4b105f5d68b9cd05be45f611f3f49f Mon Sep 17 00:00:00 2001 From: ddorn Date: Sun, 3 Oct 2021 20:23:00 +0200 Subject: [PATCH 11/80] wip --- 01-fog-of-war/data.json | 4 +- .../assets/Asteroids_128x128_001.png | Bin 0 -> 15266 bytes .../assets/Asteroids_128x128_002.png | Bin 0 -> 13758 bytes .../assets/Asteroids_128x128_003.png | Bin 0 -> 15036 bytes .../assets/Asteroids_128x128_004.png | Bin 0 -> 15557 bytes .../assets/Asteroids_128x128_005.png | Bin 0 -> 17904 bytes .../assets/Asteroids_128x128_006.png | Bin 0 -> 15040 bytes .../assets/Asteroids_128x128_007.png | Bin 0 -> 15697 bytes .../assets/Asteroids_128x128_008.png | Bin 0 -> 17344 bytes .../assets/Asteroids_256x256_001.png | Bin 0 -> 41797 bytes .../assets/Asteroids_256x256_002.png | Bin 0 -> 36264 bytes .../assets/Asteroids_256x256_003.png | Bin 0 -> 41606 bytes .../assets/Asteroids_256x256_004.png | Bin 0 -> 42845 bytes .../assets/Asteroids_256x256_005.png | Bin 0 -> 51001 bytes .../assets/Asteroids_256x256_006.png | Bin 0 -> 42048 bytes .../assets/Asteroids_256x256_007.png | Bin 0 -> 44044 bytes .../assets/Asteroids_256x256_008.png | Bin 0 -> 49284 bytes .../assets/Asteroids_32x32_001.png | Bin 0 -> 4512 bytes .../assets/Asteroids_32x32_002.png | Bin 0 -> 4324 bytes .../assets/Asteroids_32x32_003.png | Bin 0 -> 4482 bytes .../assets/Asteroids_32x32_004.png | Bin 0 -> 4583 bytes .../assets/Asteroids_32x32_005.png | Bin 0 -> 4822 bytes .../assets/Asteroids_32x32_006.png | Bin 0 -> 4492 bytes .../assets/Asteroids_32x32_007.png | Bin 0 -> 4555 bytes .../assets/Asteroids_32x32_008.png | Bin 0 -> 4803 bytes .../assets/Asteroids_64x64_001.png | Bin 0 -> 7585 bytes .../assets/Asteroids_64x64_002.png | Bin 0 -> 7159 bytes .../assets/Asteroids_64x64_003.png | Bin 0 -> 7517 bytes .../assets/Asteroids_64x64_004.png | Bin 0 -> 7736 bytes .../assets/Asteroids_64x64_005.png | Bin 0 -> 8469 bytes .../assets/Asteroids_64x64_006.png | Bin 0 -> 7456 bytes .../assets/Asteroids_64x64_007.png | Bin 0 -> 7706 bytes .../assets/Asteroids_64x64_008.png | Bin 0 -> 8172 bytes 02-particle-system/assets/player.png | Bin 0 -> 1539 bytes 02-particle-system/base/main.py | 64 ++++++++++ 02-particle-system/base/objects.py | 63 ++++++++++ 02-particle-system/base/utils.py | 55 +++++++++ 02-particle-system/data.json | 5 + 02-particle-system/readme.md | 115 ++++++++++++++++++ readme.md | 9 +- 40 files changed, 313 insertions(+), 2 deletions(-) create mode 100644 02-particle-system/assets/Asteroids_128x128_001.png create mode 100644 02-particle-system/assets/Asteroids_128x128_002.png create mode 100644 02-particle-system/assets/Asteroids_128x128_003.png create mode 100644 02-particle-system/assets/Asteroids_128x128_004.png create mode 100644 02-particle-system/assets/Asteroids_128x128_005.png create mode 100644 02-particle-system/assets/Asteroids_128x128_006.png create mode 100644 02-particle-system/assets/Asteroids_128x128_007.png create mode 100644 02-particle-system/assets/Asteroids_128x128_008.png create mode 100644 02-particle-system/assets/Asteroids_256x256_001.png create mode 100644 02-particle-system/assets/Asteroids_256x256_002.png create mode 100644 02-particle-system/assets/Asteroids_256x256_003.png create mode 100644 02-particle-system/assets/Asteroids_256x256_004.png create mode 100644 02-particle-system/assets/Asteroids_256x256_005.png create mode 100644 02-particle-system/assets/Asteroids_256x256_006.png create mode 100644 02-particle-system/assets/Asteroids_256x256_007.png create mode 100644 02-particle-system/assets/Asteroids_256x256_008.png create mode 100644 02-particle-system/assets/Asteroids_32x32_001.png create mode 100644 02-particle-system/assets/Asteroids_32x32_002.png create mode 100644 02-particle-system/assets/Asteroids_32x32_003.png create mode 100644 02-particle-system/assets/Asteroids_32x32_004.png create mode 100644 02-particle-system/assets/Asteroids_32x32_005.png create mode 100644 02-particle-system/assets/Asteroids_32x32_006.png create mode 100644 02-particle-system/assets/Asteroids_32x32_007.png create mode 100644 02-particle-system/assets/Asteroids_32x32_008.png create mode 100644 02-particle-system/assets/Asteroids_64x64_001.png create mode 100644 02-particle-system/assets/Asteroids_64x64_002.png create mode 100644 02-particle-system/assets/Asteroids_64x64_003.png create mode 100644 02-particle-system/assets/Asteroids_64x64_004.png create mode 100644 02-particle-system/assets/Asteroids_64x64_005.png create mode 100644 02-particle-system/assets/Asteroids_64x64_006.png create mode 100644 02-particle-system/assets/Asteroids_64x64_007.png create mode 100644 02-particle-system/assets/Asteroids_64x64_008.png create mode 100644 02-particle-system/assets/player.png create mode 100644 02-particle-system/base/main.py create mode 100644 02-particle-system/base/objects.py create mode 100644 02-particle-system/base/utils.py create mode 100644 02-particle-system/data.json create mode 100644 02-particle-system/readme.md diff --git a/01-fog-of-war/data.json b/01-fog-of-war/data.json index 6412689..a3003d3 100644 --- a/01-fog-of-war/data.json +++ b/01-fog-of-war/data.json @@ -1,3 +1,5 @@ { - "name": "Fog of War" + "name": "Fog of War", + "start": "2021-09-28", + "end": "2021-10-10" } \ No newline at end of file diff --git a/02-particle-system/assets/Asteroids_128x128_001.png b/02-particle-system/assets/Asteroids_128x128_001.png new file mode 100644 index 0000000000000000000000000000000000000000..b67df3719c9004127ec7811d87036831968f8f39 GIT binary patch literal 15266 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:Dkk@8B$^WYpNuH6oogW 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 z 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

~sljPw*DQJ!P7qH^5hf)8U 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 NWqCEZIvMlO{{u#2^`-y- literal 0 HcmV?d00001 diff --git a/02-particle-system/assets/Asteroids_128x128_005.png b/02-particle-system/assets/Asteroids_128x128_005.png new file mode 100644 index 0000000000000000000000000000000000000000..5babd25298b89940db3d1624b325e1a6ed1808f4 GIT binary patch literal 17904 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 literal 0 HcmV?d00001 diff --git a/02-particle-system/assets/Asteroids_128x128_006.png b/02-particle-system/assets/Asteroids_128x128_006.png new file mode 100644 index 0000000000000000000000000000000000000000..e1e989211b46c849045c4eaecdd648522833b467 GIT binary patch literal 15040 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 literal 0 HcmV?d00001 diff --git a/02-particle-system/assets/Asteroids_128x128_007.png b/02-particle-system/assets/Asteroids_128x128_007.png new file mode 100644 index 0000000000000000000000000000000000000000..4efbb54fcdc9bf540d00ff46139ccfa9d1846eff GIT binary patch literal 15697 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 literal 0 HcmV?d00001 diff --git a/02-particle-system/assets/Asteroids_256x256_001.png b/02-particle-system/assets/Asteroids_256x256_001.png new file mode 100644 index 0000000000000000000000000000000000000000..f745382ae32540e8b0857674896b1d4ef90b0c65 GIT binary patch literal 41797 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 JPDHLkV1mwX?(+Zu literal 0 HcmV?d00001 diff --git a/02-particle-system/assets/Asteroids_256x256_002.png b/02-particle-system/assets/Asteroids_256x256_002.png new file mode 100644 index 0000000000000000000000000000000000000000..03d0a2d0f97f020b07c87167ddab2a9029aed457 GIT binary patch literal 36264 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

dsy9=_uJ_i-ks1h+Nfxvr&_i0ib-QGV)d4l+` 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 FV1gK~#u5Mk literal 0 HcmV?d00001 diff --git a/02-particle-system/assets/Asteroids_256x256_005.png b/02-particle-system/assets/Asteroids_256x256_005.png new file mode 100644 index 0000000000000000000000000000000000000000..56261dd3624457d37ad5d164dcddf15db2204d22 GIT binary patch literal 51001 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 A$^ZZW literal 0 HcmV?d00001 diff --git a/02-particle-system/assets/Asteroids_256x256_007.png b/02-particle-system/assets/Asteroids_256x256_007.png new file mode 100644 index 0000000000000000000000000000000000000000..b4d1da908a1815c2d76e4c25aa0e2c897ecbb4ae GIT binary patch literal 44044 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 tsuhl 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 Ux!V}+E&u=k07*qoM6N<$f*2fUwg3PC literal 0 HcmV?d00001 diff --git a/02-particle-system/assets/Asteroids_32x32_004.png b/02-particle-system/assets/Asteroids_32x32_004.png new file mode 100644 index 0000000000000000000000000000000000000000..fac3012425cb8044c0c0730931d76a4aafed9632 GIT binary patch literal 4583 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 Rx9tD`002ovPDHLkV1lpUZ(jfa literal 0 HcmV?d00001 diff --git a/02-particle-system/assets/Asteroids_32x32_005.png b/02-particle-system/assets/Asteroids_32x32_005.png new file mode 100644 index 0000000000000000000000000000000000000000..35238dbc360ca9ecdcde88b0343a201d587097d2 GIT binary patch literal 4822 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 wY-+HHS+=S9(LaAYSo*Xl literal 0 HcmV?d00001 diff --git a/02-particle-system/assets/Asteroids_32x32_006.png b/02-particle-system/assets/Asteroids_32x32_006.png new file mode 100644 index 0000000000000000000000000000000000000000..bdbb052d4e6c2fdf3bc5ef7f5957dea63cbaab63 GIT binary patch literal 4492 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 literal 0 HcmV?d00001 diff --git a/02-particle-system/assets/Asteroids_64x64_001.png b/02-particle-system/assets/Asteroids_64x64_001.png new file mode 100644 index 0000000000000000000000000000000000000000..73baff71c2fe22ae52f5e8a9e75e56351b5f57a7 GIT binary patch literal 7585 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 DGdw{* literal 0 HcmV?d00001 diff --git a/02-particle-system/assets/Asteroids_64x64_002.png b/02-particle-system/assets/Asteroids_64x64_002.png new file mode 100644 index 0000000000000000000000000000000000000000..4556616f52bda4974a6d817d7dba8f5db624b9bc GIT binary patch literal 7159 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 literal 0 HcmV?d00001 diff --git a/02-particle-system/assets/Asteroids_64x64_003.png b/02-particle-system/assets/Asteroids_64x64_003.png new file mode 100644 index 0000000000000000000000000000000000000000..9223f22616dfc2c2c7759078b763554e0f760195 GIT binary patch literal 7517 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 literal 0 HcmV?d00001 diff --git a/02-particle-system/assets/Asteroids_64x64_004.png b/02-particle-system/assets/Asteroids_64x64_004.png new file mode 100644 index 0000000000000000000000000000000000000000..5dc63019b4a082042e089b4f8e392ef84a486079 GIT binary patch literal 7736 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

{xDLLUW^ZkmaX(iztYA z1bk;D2cW=LEM0qNbBgS&3nZ*%$=Xy33k}!q6@&W)Y-_;xIVaQgNK0nwHDf6uKay*eWE|u)?ffWhVFkz%NyWvmtPA zU1L>JcZ?FDvZICXD`Y6NL!ujo6&{r%2?b~J9uZQz!GoclN4s0Y>`+)iR>?BEr5D}FC(e0^jB^}{g7APoYxwmkN=nz zYZC~Mtif;$dv?f##h`-IW!l!QFuqH7NrJ46-2?<%me|VI4;r^fpo*EmH_A+_$mc2Z z(9ece6jWm9+cK>^_?3@rK0RLiqQwKw^8qXeFmPd4>iWVyxa&Sx83+(YiB`W}!LPkc zTIE_WooYS37f)B?N)npRROVRwg8`8i$IKp+oeGmP%?ZQic|OqCxWZJO&jN}3^Qi|p z{I+Lv*u(xPI6m+L_>Gsr&)48bM}vI63NO7Hx(ZIM3Q!I4Av~n>p_KVRpjyopp!lHp zk{G0)9`kNW`wKZrWxs=yyy27fu=0cei2Z@L+yl&_U^Iqreg}5#fEPapX1X$QapXbp zyCu0P&U`V#IngU{V!Tp`G)>R!I2A~Y-y8tc)Z*&kd645V0#uqUS$e_%eEK1l-+C$6 zVfh*`i;SaP20tYxLjxIyKbJfX79x*xM}RW%zZw@DLK*=DkAtV)@p%8l!? z--z95-TJ2FdFV;MHI{==6Qum%BPj9z@u9*)#*FWBoguFbRTDVp6Di8uXq#pJ{MstJ ze_Y+-L>l|YSA6vBFIJq_YjdA@h$Zj2%vugd5E_Q(o}d1IZgkEsrmqXD$0{2_JQAQO zz@ztV8Cas7T973}V$khz`!BNT3BNP+ws~$dnwyPbw$LdT6lU}P>yV&~PRC4Jra%T-EhMx|wW^(x+}30M;Zl762XUizUk+22$4*4W!GV_qxnFopxuAT$67 zv&Aa3*3)`IttlEwl<}pEPIx0F$y3>~<iC zS&ZVx8DPW*j4QyhV>uwo3kX^Z07WZ!Is)L+ee{&^A-V>=9)J9*zdO6M*5|51Tw4u0000KLZ*U+IBfRsybQWXdwQbLP>6pAqfylh#{fb6;Z(vMMVS~$e@S=j*ftg6;Uhf59&ghTmgWD0l;*T zI709Y^p6lP1rIRMx#05C~cW=H_Aw*bJ-5DT&Z2n+x)QHX^p z00esgV8|mQcmRZ%02D^@S3L16t`O%c004NIvOKvYIYoh62rY33S640`D9%Y2D-rV&neh&#Q1i z007~1e$oCcFS8neI|hJl{-P!B1ZZ9hpmq0)X0i`JwE&>$+E?>%_LC6RbVIkUx0b+_+BaR3cnT7Zv!AJxW zizFb)h!jyGOOZ85F;a?DAXP{m@;!0_IfqH8(HlgRxt7s3}k3K`kFu>>-2Q$QMFfPW!La{h336o>X zu_CMttHv6zR;&ZNiS=X8v3CR#fknUxHUxJ0uoBa_M6WNWeqIg~6QE69c9o#eyhGvpiOA@W-aonk<7r1(?fC{oI5N*U!4 zfg=2N-7=cNnjjOr{yriy6mMFgG#l znCF=fnQv8CDz++o6_Lscl}eQ+l^ZHARH>?_s@|##Rr6KLRFA1%Q+=*RRWnoLsR`7U zt5vFIcfW3@?wFpwUVxrVZ>QdQz32KIeJ}k~{cZZE^+ya? z2D1z#2HOnI7(B%_ac?{wFUQ;QQA1tBKtrWrm0_3Rgps+?Jfqb{jYbcQX~taRB;#$y zZN{S}1|}gUOHJxc?wV3fxuz+mJ4`!F$IZ;mqRrNsHJd##*D~ju=bP7?-?v~|cv>vB zsJ6IeNwVZxrdjT`yl#bBIa#GxRa#xMMy;K#CDyyGyQdMSxlWT#tDe?p!?5wT$+oGt z8L;Kp2HUQ-ZMJ=3XJQv;x5ci*?vuTfeY$;({XGW_huIFR9a(?@3)XSs8O^N5RyOM=TTmp(3=8^+zpz2r)C z^>JO{deZfso3oq3?Wo(Y?l$ge?uXo;%ru`Vo>?<<(8I_>;8Eq#KMS9gFl*neeosSB zfoHYnBQIkwkyowPu(zdms`p{<7e4kra-ZWq<2*OsGTvEV%s0Td$hXT+!*8Bnh2KMe zBmZRodjHV?r+_5^X9J0WL4jKW`}lf%A-|44I@@LTvf1rHjG(ze6+w@Jt%Bvjts!X0 z?2xS?_ve_-kiKB_KiJlZ$9G`c^=E@oNG)mWWaNo-3TIW8)$Hg0Ub-~8?KhvJ>$ z3*&nim@mj(aCxE5!t{lw7O5^0EIO7zOo&c6l<+|iDySBWCGrz@C5{St!X3hAA}`T4 z(TLbXTq+(;@<=L8dXnssyft|w#WSTW<++3>sgS%(4NTpeI-VAqb|7ssJvzNHgOZVu zaYCvgO_R1~>SyL=cFU|~g|hy|Zi}}s9+d~lYqOB71z9Z$wnC=pR9Yz4DhIM>Wmjgu z&56o6maCpC&F##y%G;1PobR9i?GnNg;gYtchD%p19a!eQtZF&3JaKv33gZ<8D~47E ztUS1iwkmDaPpj=$m#%)jCVEY4fnLGNg2A-`YwHVD3gv};>)hAvT~AmqS>Lr``i7kw zJ{5_It`yrBmlc25DBO7E8;5VoznR>Ww5hAaxn$2~(q`%A-YuS64wkBy=9dm`4cXeX z4c}I@?e+FW+b@^RDBHV(wnMq2zdX3SWv9u`%{xC-q*U}&`cyXV(%rRT*Z6MH?i+i& z_B8C(+grT%{XWUQ+f@NoP1R=AW&26{v-dx)iK^-Nmiuj8txj!m?Z*Ss1N{dh4z}01 z)YTo*JycSU)+_5r4#yw9{+;i4Ee$peRgIj+;v;ZGdF1K$3E%e~4LaI(jC-u%2h$&R z9cLXcYC@Xwnns&bn)_Q~Te?roKGD|d-g^8;+aC{{G(1^(O7m37Y1-+6)01cN&y1aw zoqc{T`P^XJqPBbIW6s}d4{z_f5Om?vMgNQEJG?v2T=KYd^0M3I6IZxbny)%vZR&LD zJpPl@Psh8QyPB@KTx+@RdcC!KX7}kEo;S|j^u2lU7XQ}Oo;f|;z4Ll+_r>@1-xl3| zawq-H%e&ckC+@AhPrP6BKT#_XdT7&;F71j}Joy zkC~6lh7E@6o;W@^IpRNZ{ptLtL(gQ-CY~4mqW;US7Zxvm_|@yz&e53Bp_lTPlfP|z zrTyx_>lv@x#=^!PzR7qqF<$gm`|ZJZ+;<)Cqu&ot2z=0000WV@Og>004R=004l4008;_004mL004C`008P>0026e000+nl3&F} z000(1Nkl3tU0?JjOF$`nkQ`@0ajqhM3v+OaYI6`t&6; zJ_uYASSNr4K?*^-_mX9otOxT4F$GHo@QjE&^@X3gx&8lz0v`SJ#wPGF;1bxn1VN$@ zN*6pt|64+*1Yq%gW>}{PH8hzk!gvPw=yN~)>hAxO3V8I>8yB;L(4*v5xR@;4=7%hB6Q; zU+IGvr=SJ`)mp*ncTBPixN_QQ!V-j1h*iE$1OrHJ4W{Y}Xu(=TTSFVohh5RuKBKKZ z`~2lw+uv6OJn}0Wmqd6PSVtffLZ||9^F? zV&&I|LKfnIyMncfDwqqspaegsxsqyqRvUZjg`eHM`hQ&kk9=z5Y2dOY!^{YUP%KA^ zz|Bcf=nE18v<>v{q6U z*wkIaT6dF9A*oih)=#9yp8E3NzPk)^#|n7lUu`^XW|!04A4J6cy_`gr&Q!#u(63}D za}X?Y@XP*R@3+ivHN+|_U@2q;1a}c}!J4B)nk#KSyDO->$U@dY{j9B_ZVlVo*kAe5 z&+T2k8wLCyfzW&Z#m3W`>~eFM(8gCtvY<#d;W7|PA(Z}era*8dgu*{B#&O69-I0GM z6oM%5qRij_E|!FyC#c zciY|)GB!X&dQ1^wR%|gSzgP+sOJO~Z!qe~l)TxW#wE}+ppKWYm_A#wJ;Dr3Zp>%&Q z#s%f1AQS;9LT|nO*%k0&f`L3J0wytbqK*U%6#_t?+&-+$-iy~zB z-l0h~q%|a1h8eQn!qdQ?eNz_jo?kwF*^G;w`62GpF0k~FRA*g0|*n0F= zPd|Cr3iz>KI=yLXPh*P$N{?PU1SiqWPl^B{lq&_x7e=j?oS?!p%?d?-&IQu_bD`5U*WcXe=uE+$k%W^jleHXr-9 zXD{Bd0!(ew>vi*k!Ng9UhX`!u(DwvVvjxTUhpR#7sn7Eg;oQR`*56UF_lGq%zH|(c zVfD-52xb0%1f472`s}V_fv}*2a=-?$%t|Qb;@xC{D}rF6B+_l#fnWhlFoW^=5#w_e zryd%!bhdK8Q-`TyfoQR>^Zhe2gcVmt%D!r_@?gmWKQ-|b*Buc;Jo$Hb5a6||NBQp@ zo3auHMf4fzvAe(lx2-Ui9~goaEZGWbiAHB06P8DPHRr{JD`!PdF_I+?*rBDy1g6*K zhzLt(%ibco&@TeoF5F!@^5o>BiR&K`NK@r=ANo4$KRo92pC0qzUtFhH4p~N1crl>e$_>=oF-KgNfi}$k(Yk!2J>4r2Auwr6DAKX z^(*I!7Q*dM^G1aALfMSLJAd&$CU2=2Unro@UP8!9P>&6pcjE#tc0VpE1S>!TsG+J% z^@zsi3+8TvX?KxVjYHjIS8vd0?J)ON-9PlLuO0TVn&2T^TVwU1(Lj$GgWD{oHXW2u zECCU%2BK(A^+dq|lPWiUr}o(xSjH)=4jT_dQKU zQiWv1rFbG3h6VIiEM-DOUFtJGI(8wG-^W_e#t-KL7-EOQm;U~@_||XjW};R4!YKp@ zF|Zsb#3BNG>;wPd{N|mc!QJl1lPW2-v~8QYx?zPo?#_~Nqz4NRWxawr>nO&7^Y30K zl!0<3a{psz300t+6g{9aye@dlPo5%H0c|}dXaklHZSwyTOdcHZfnWb2F8-UhvHH-6 zgBRxmTFneJ(Kv`Vu|kn3>zIA~brJ7&LS*Y7pZdK}g{@G^2~%yv_r3oV_kCcEdcTDPQpyk!FlyhCF`9hHi%-}0O3SJWDqQkWxJYN^X>Yr$c#M{mb zmQe3DOkbN*@3zeM8mu)W2<2*Ib#qL0s^H4ce1pfHc{}AKI72kkyfC3>loo&A%q?K4 zUgc=EPd#lodSym?=-I0|P7l5C#P0S93oy0I*0P>D1}4JMOEqyMES;6?+s@vo;`Miv z>u)g>A&6hwHip)U<$za=bMe&UjKLDBwQ``jqR<|Cyh(Fo{~J?cC6uQkN8g@i7C90# z1-}?rJHA510c=XfG5aJ_%#7+(NhkvKUW33T;1efsfVK9xIuYWOn*_8quD@{Th0t=~ z+@G7U`u0)g<|H>T2Ei3*54^MJWNNia~W)g+N7i;Rh zmN?EACFR-+`xMLTtUOTV3?Nu*9tVKtFmd$C46T*86p$#H$~LSq(kvmtEup4H*>_tA z_zGq6v_5Q|32xmo?tN?(Dc#j#=?JfD#&qu4xs|0(9%Fy|nE6iA6EvOiiLiA73BLVr zj4x{IM5ZQ#WE@{>2o(zo@C)|8Ib-Gi%3UE@1~P^yOmEaQ`z@gi?ETLac2oM2Y7dfVkJ7f9!E$}G!;!-lR`_^ev9KUWTi~SOZ4dHuH?vbzSD60%A8ob znTU8`Hgml2o=>iA0auIc|CyyRnu83zk|Cp9e1svtw#V8B8B1WnFzL*#X8-GRnnPuF zqd^K++`)FuJAU^3fEd%stN_OUdVYsk1@3utgR&}Ewh7B=jYezs!fPmLD0t$~dl*vW z$qMx7l^NO?u^Ljm$dK|ySnq+5qbqZ*uLLF!R8*&m9*LO_=kbNon-T3o?=Bgsc1CCQ ztrgR24RIODH7F)<^zAvv*P0VZ(&NZ*K74t`-ZzfDKd45MM5u(g94N+ta;2bLE+|Hk zs;nqtu~3rxvsJdlnr@(t(HweZWeB$?X!nB!7qDd8n5)A?s1Fk7AD-~?f8Omgf+dg` zIQOmz^=^w0&|uCA%h2Ag)?>yG`B4AedauQj#|{k;v@t4!W9MkMeir{D?yXq4cTBMoc=f*=GQLo{pg|D{s6a4-}{``c! zKPYJq6XUZb=O3P&m>;kt14XtF3k>HI#Eg&wqgkfp2}CJ9JV~OK8Htv?uOE?SZUv)_ zit)J$f}_kdultpkEVU0`7+?Ood)xe-MLr<$Yl>a!`gEEg1USCl5O-QffmP@`v#zv+ z)S08tAf;OK&hFaVE5_$b(%fi|6UA~oISGOgvJ%X|<_=gox}7T58(CF~Qp*g(Xr*B$ zhtx;8myp#syIHez#>tjyyj;r=eWrf)fe%*O7Hrc|R*v%GbO5a& z!Tr}v(R%0)gi?rYAXJtcmBD%c19kM4^R^F3c!qJ{B#@N$IALmii5#K>EP`8tHj1_i zlYIgK%Y0=&SJ2r|7)s^wnTqN4%v+d&N?%Nwy@3L9JM6>O%5(kXSVv6cbf-;Dnc|=$ z6h0l|O6pv~y!XG9dv>{bAwfLCFPOcxM!oN=6f4Oovf~@vRTSg!Sm!O_ruu))9IBg591-)d-&)ya<&43nK8V0zLd26vy<@}!7SEJs#1 zmsx%5GBLYo7g(#clJWV<>HLv*urvW8SH2@30Pw(HE}xbnTn;7P{SEXOvhULN9olfB zQyZ$`9I6hw<~Y&K1Vqmuvs+Ei<%dz%+sgwKmGsqR*P7F0gFDz_b?IHKjyteq!zfLy zq^Z(Qy$jVGr`;ExxOMss`GDRM{$umu2mVrd*$Aj$)NdHt42g>N^xLz0s0p>TRmg(6_VXeBI7}KSqLZ?%gYn71~Vri$`XG1i0nSUU;!$dkuB&9)t4>CX!nUozikAD=(Jj=xy0$%GK!Iq}r~2@rhek z?r1{9l3jIT(oG3*obUdISBgunh%g%3R%f4QTa&`8FEf5_xpapEuRRVNI3+K6%FzBHG%23zi!r!FoEo>(2BoDu(zV z0n$u6f(6Y*LO@aPpx~I!DQj8IpBJGgTAPE`gJ%_(@3z$Y$=$7x6JW;FON6et($?X- z2#hw$oQ2d!?P|r8t6zL#=b1a65i+%Bwfm8r;$}PTfTwk_do(mGs`cpOZQZp^wxY&s z25XI~U53=n8u*|U45M^DEuu7sEotr`>EwMEt4f9rb+>pqQ=}|>My?;dt0AdZpSN9W z?b$AxwuhchmhY|nh7IT(wD!YVPem*DkI;NmpYU9C0e?SlW~9akA^l<9T|&&mSE~i> zvBw*0Z|^X7=D&zBe44CWi4^0AX4BWXbCVc+@rj))cQ+&jsPai^xfG(;`etzUT`S!9 zvN7Ll2r1{?%ojZHlc%V6TeQtVX@Tw0+!3ZpwA%L2wOI18*F*Rm4orB8^B_i(sf}u6EbGO%S&KQH3S2kMkUetq`dos zTFwla6-s%gIAzw_*nLw9$PLL4WA=NBtOtztSb6EQw^)A5h|@o^OtBI;*q*cV)nk_L zE3@#KCzLMtJKSw&3F~HoWB^T?N8AVsmifEI$&`wTBZy?u7B3ymb z3fTDy+Z*rV{j~O6rvw!^{`Q>d^}0u6<;3&8Pl_8Bya4OnDH-il3DG+@{l0(}Bsxg3 z=w+`I3mpU-gs1B}<{DZxGru~b>XuP!usji?@9r0sD!-I zi1>=<;Rsz6zN?`ur@-XaLlC6RR?-5&{DC{(z5_)eZ>G?J$W)VFS+;PEEnMS4B=ZSn z_;=6$t?#`5=&rWS?ffoR&3MR?T^X2R>(gAH?-w>U=)#7FzPF#Fw6+5_=)RX4Z;NS@ ztJDS9Y>Q=fE{A)dlNJUmxdnmxf9II63%vi#d+bSrk0`85Z?8Fs_3!h@ zO2;Xrp`+~9BAz9>#si8@jpo4H;?=sh%uE*0U$A~QuqV9(o((deNS;NkCh_N=`|H>L z#~&rnceQKm?2pT)L_RK&Oa1t2Im{FcqiZ=>=@2ivuCDV54x&Pd(_<-Pgo#go4=Hg0 zdgejuenZx6=W;E6^!X3J_KEMyzQJ>k%0&tCxI`}d_&l#0VD!q-9kwGdLjInV!+SF$ zO%(!^6K|DacB1g<>ydDK`yE0N4$HOp^Uwdy*Pi*lZ=5{;SlA3fE=iQfC9*XrfQ3DT z^!osuAtG@8ui;EjBrHfuN2%mSO{QBgrqks6hzk2QEKbD=Ni?93s zLa|AdixPNeh_WRGTM}jc)Z)30(dCUplx7@Xmjj!@K`2QXNBqjZ?Umwz=00000NkvXXu0mjf D?J#E< literal 0 HcmV?d00001 diff --git a/02-particle-system/assets/Asteroids_64x64_006.png b/02-particle-system/assets/Asteroids_64x64_006.png new file mode 100644 index 0000000000000000000000000000000000000000..0cf8b589996cbc0c5456d5f8b90211d614730847 GIT binary patch literal 7456 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 U#_{peZ~y=R07*qoM6N<$g2ZlJT>t<8 literal 0 HcmV?d00001 diff --git a/02-particle-system/assets/Asteroids_64x64_008.png b/02-particle-system/assets/Asteroids_64x64_008.png new file mode 100644 index 0000000000000000000000000000000000000000..e0b7e2b619a59a31d607e9e0917c37c7af1fc232 GIT binary patch literal 8172 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" + + @property + def rotated_sprite(self): + # We round the rotation to the nearest integer so that + # the cache has a chance to work. Otherwise there would + # always be cache misses: it is very unlikely to have + # to floats that are equal. + return rotate_image(self.sprite, int(self.rotation)) + + def draw(self, screen): + screen.blit( + self.rotated_sprite, self.rotated_sprite.get_rect(center=self.center) + ) + + def logic(self, **kwargs): + self.vel = clamp_vector(self.vel, self.MAX_VEL) + self.center += self.vel + + +class Player(Object): + def __init__(self, pos, vel): + super().__init__(pos, vel, load_image("player")) + + def logic(self, **kwargs): + pressed = pygame.key.get_pressed() + rotation_acc = pressed[pygame.K_RIGHT] - pressed[pygame.K_LEFT] + raw_acceleration = pressed[pygame.K_DOWN] - pressed[pygame.K_UP] + + # self.acceleration = pygame.Vector2(direction_x, direction_y) * self.ACCELERATION + super().logic(**kwargs) diff --git a/02-particle-system/base/utils.py b/02-particle-system/base/utils.py new file mode 100644 index 0000000..98026fa --- /dev/null +++ b/02-particle-system/base/utils.py @@ -0,0 +1,55 @@ +from functools import lru_cache +from pathlib import Path +from random import uniform + +import pygame + +SUBMISSION_DIR = Path(__file__).parent +ASSETS = SUBMISSION_DIR.parent / "assets" + + +@lru_cache() +def load_image(name: str, scale=1): + image = pygame.image.load(ASSETS / f"{name}.png") + if scale != 1: + new_size = image.get_width() * scale, image.get_height() * scale + image = pygame.transform.scale(image, new_size) + return image.convert_alpha() + + +@lru_cache() +def rotate_image(surf, angle: int): + """Rotate function that caches its results for performance.""" + return pygame.transform.rotate(surf, angle) + + +def clamp(value, mini, maxi): + """Clamp value between mini and maxi""" + if value < mini: + return mini + elif maxi < value: + return maxi + else: + return value + + +def random_in_rect(rect): + """Return a random point uniformly in a rectangle.""" + rect = pygame.Rect(rect) + return pygame.Vector2( + uniform(rect.left, rect.right), uniform(rect.top, rect.bottom) + ) + + +def from_polar(rho, theta): + """Create a Vector2 from its polar representation.""" + v = pygame.Vector2() + v.from_polar((rho, theta)) + return v + + +def clamp_vector(v: pygame.Vector2, max_length): + """Ensure that a vector ahs a magnitude less than max_length.""" + if v.length() > max_length: + return v.normalize() * max_length + return v diff --git a/02-particle-system/data.json b/02-particle-system/data.json new file mode 100644 index 0000000..fced453 --- /dev/null +++ b/02-particle-system/data.json @@ -0,0 +1,5 @@ +{ + "name": "Particle System", + "start": "2021-10-11", + "end": "2021-10-18" +} \ No newline at end of file diff --git a/02-particle-system/readme.md b/02-particle-system/readme.md new file mode 100644 index 0000000..1a1eeb1 --- /dev/null +++ b/02-particle-system/readme.md @@ -0,0 +1,115 @@ +# 01 - Fog of War + +The goal of this challenge is to implement a Fog of War mechanic +similar to Age of empires. + +### Achievements + +There are different stages of success for the challenge. +Succeeding in the casual stage is enough to complete the challenge, +however, in order to provide more challenge for the most adventurous +and ambitious of you, we provide two more puzzles. +The harder they are, the less point the reward, +as it is more important to always improve a bit that spend hours and hours +stuck on the same thing. + +Here a more detailed description of the different levels and the amount of +`C`hallenger `P`oints they provide: + +- Casual `+3 CP`: The world around the player is visible but the rest of the map + is hidden in complete darkness. +- Ambitious `+2 CP`: The world is visible around the player and softly fades to dark, as if the player had a light. + In the distance, everything is black. +- Adventurous `+1 CP`: Like in Age of Empires the map starts all dark. The world around the player is visible, + the parts already explored are darker and the unexplored parts are totally dark. + Additionally, in the explored parts the player sees only the static objects (Trees, Houses…) + but not the moving ghosts. + +### Setup + +The setup code in [`base/`](./base) consists of a simple top down game with trees and ghosts moving around. +To get started, duplicate the whole `base` folder and rename the copy with your username +(will call it `yourname/` from now on). All your modifications should be inside the `yourname/` folder, +otherwise it would be impossible to have a showcase of all the submissions. + +In this `yourname/` folder, you'll find a `main.py` file. This is the entry point of your submission and where +most of your code will go. +In this file, you will find a `mainloop` function, which is the only thing that is required so that the submission +appears in the showcase. The showcase needs to have the control of the events and the display, so they are +passed down to `mainloop` in a surprising way: the `send` mechanism of generators. +Don't be afraid if that looks like black magic to you, +you can participate without understanding it. +You may be used to a main loop that looks like this: + +```python +import pygame +def mainloop(): + screen = pygame.display.set_mode((800, 500)) + # More setup... + while True: + for event in pygame.event.get(): + ... # Event handling + + # Logic and rendering of your game... + screen.blit(...) + pygame.display.update() +``` + +But now it will look like this: +```python +def mainloop(): + # Setup, but without setting up the screen + while True: + screen, events = yield + for event in events: + ... # Event handling + # Logic and rendering of your game, on the screen variable + screen.blit(...) + # No need to call pygame.display.update() it is done by the showcase. +``` + +If you are used to classes, you can also have all your code in a class, for instance `App`, +then you only need a statement like `mainloop = App.run` if the `run()` method is your main loop, +to have your submission discovered. + +### Submitting your entry + +Before the deadline, make sure that your entry is runnable both via the showcase, +when you run the top level [`main.py`](../main.py) and when you run it individually +from you own `yourname/main.py`. + +There are two ways to submit an entry: + - send a zip of your code in the discord + - make a pull request directly on this repository + +In either case, you need to post a screenshot of your entry in `#challenge-submission` +with your files if you don't do a PR, and with some comment if you want. +Sharing your code will help others learn, and you may receive good advice too! + +Have fun ! + +### Tips + +##### Use relative imports + +You can structure your code the way you like, but if you use multiple files, +it is very recommended that you use *relative imports*, as it is the simplest way to +make the import system work both in the showcase and when run directly. + +### Credits + + - Tileset: [GameBoy Style Dark Forest Tileset by Cluly](https://cluly.itch.io/gameboy-style-dark-forest-tileset) + - Ghosts: [Free 16x16 Pixel Art 8-Directional Characters by Maytch](https://maytch.itch.io/free-16x16-pixel-art-8-directional-characters) + - Setup code: [CozyFractal](https://cozyfractal.com) + +### Legal stuff + +By submitting your game, you agree that we add its code to the repository +and that it can be: +- used (for instance in the showcase), +- modified (for instance to work with a future version of the showcase), +- shared (for instance as a mean to illustrate the capabilities of pygames). + +But all those uses must be for the good of the community, and never for any individual. +This concerns for instance any profits that could be made: they have to be used for the +benefit of the whole community. diff --git a/readme.md b/readme.md index b312c35..be14846 100644 --- a/readme.md +++ b/readme.md @@ -13,4 +13,11 @@ The first season started on the 26th of September 2021 and will last about 3 mon ### List of challenges - 1. **[current]** [Fog of War](./01-fog-of-war) - 26 Sep → 3 oct 2021 \ No newline at end of file +1. [Fog of War](./01-fog-of-war) - 28 Sep → 10 oct 2021 +2. **[current]** [Particle System](./02-particle-system) - 11 oct 2021 → 17 oct 2021 + + +--- +In case you find contradictory information, the information posted in the +Discord server are always the correct ones. Also, please, if you do find such erroneous information, +tell the organisers so that they can fix it. \ No newline at end of file From 4808890ad59d04bcf4387b0e688cd2cbd34697af Mon Sep 17 00:00:00 2001 From: ddorn Date: Sat, 9 Oct 2021 13:10:12 +0200 Subject: [PATCH 12/80] 02: player movement --- 02-particle-system/assets/player.png | Bin 1539 -> 797 bytes 02-particle-system/base/objects.py | 61 +++++++++++++++++++---- 02-particle-system/base/requirements.txt | 8 +++ 02-particle-system/base/utils.py | 6 +++ 4 files changed, 66 insertions(+), 9 deletions(-) create mode 100644 02-particle-system/base/requirements.txt diff --git a/02-particle-system/assets/player.png b/02-particle-system/assets/player.png index febc2ca00a2f304007220194c8182ac02367d8bd..7d4b8326deaa8d29fe9630dbcb81181f93b17399 100644 GIT binary patch literal 797 zcmV+&1LFLNP)aQ>C?5I_MzckfDl03q?U3wGLg1lv=^6OY)keLXw6gMT)E7;!to9 zUHlsS4|Ek=6$C*ML|ps_{92^M`B(`gufv_lG2()%#r6HCR#{1_Z*yv&^zx;(6limTPg|BOYO8 zsYHB2oUrMF#J60ReSYJt`TWJ%F60*hfzK4R4wgHZm2HD~ia2iQRo1!>|B|R;t}Ig@ zqZ)^UJTgc_gp4XSp~FRzx=ERJ_obS?B~-}6=xw0}n;aU-Mlvmp5%q zJ^-$EfzfA6vZbaJq!LsW__zRuiooza5Lx%LYVG6v2`FsSFS-K`kAO)!AKUl?UyWzL zjXn+^00009a7bBm000XT000XT0n*)m`~Uy}Q%OWYR5(wql)p{_K@i3V!b{j05=n?! zKy0A(o`6_d^9U9uRwnQc6h49R1vnFIpn!mh8jSy9$6EmTNWOJ;&b`}$ZT4ZDT#nKDH2dDAO`qRm(xnoUMc88g8j~(TrR#?? z*BHPoP{-{_LFnc1!pm(mPrP><*TGy*L)|XA1s+tF^!xcEz5bOP9#sX;7?|;nb*^FE zTH!%i5|m)$;O^d4r9H(u;#6#{$aJ4Tbeujy6`ncsdI5YblKIj+r7W2Wb=Rp>uTinK z0tY&%R>+#6j%xL+ZvraPRygQ?9wJzzl!sf7D7cZOhDPl;3I0Pr-qPUST&TO)t<%4ACofX&%yRb?LhTn* b1VsK8)T-5Z*m00G00000NkvXXu0mjfkW_5p literal 1539 zcmb7^`!^E|7{^CwMhz|3l46p(Jj|>Uq4z8C1h44~?`vT2z=d;n9n}4-70#Zcyq~*= zZ}Ex9GPem+*Rqj^K*LR=U>c{NX&CV@q51domMv`9E?zqcN&IIOhWWg&f<~oycV~}3 zz5hXP1jYye5Vdo(vGTlLvi4*)ufbFj;Ncq@r%ajhU08n&#iApSbuQJZ47n>wGCB;sGqeWxog@wueupppg8JT#TjBpS( z67HEl@cW|mnN;c2g~bG*cx;x{Kw#2lXxg5H0k_sFjdl9?PLF;i5IJhuv1@*cmti2B z2{%eEhF}99Q1sEP6S7zWP)$s)f}VNx9z7T+PqK@56PHaNI>t#(4Ox%r2h)j7&oi33 zZgPYKYr}nq+Z^V!lKZTc1exwj<%$}AlD1M=VAi+KX~`ae^B;03bswwRsru0fKgU+7T zn2!j1EH#uVw?=+CD$TH1>(fhpPFS9{EOlw~!eXuYCYTBB*m-v}YMoJW73}hU)%Brs zC#x>C|ME!>5k!rF>4t=X618=3qC378qrc$vt*cK8(U|!D2qQbS-WzF1>*{)bP?VXF z?t*;7-{Yt!g_D&HmuMQVBp%9f-B52I}4!py?N30XmVd0mZ=~xas3IhW-<=v}*xHv6o&h2auA; zQGeCfRM}$l-=IWvjc5v9p<&xEs@U`5jAA?tg}}LSnNo)*7d3&@HG9O{jBfr*4%Wt<-*95F}z|F9a_Tc#UifXHcu3q)^kFr_j9|`<1n5mW+I`Hs}_9Uv!DW(ZhD~ z_hBY>WmNe&(r$>9!p661;ur5|r=Q-;@3_z_*Pysz-vEAD#I1nY{biaDe#dmlwh}!! zgY8ZWXgS=;(BTSGljbsQ>6xx#_Ux!{vHOf zCc9&A)($Q<-Q#_px${j;zaS$~s3k1QWsyD!&iQAiW}x=^#?qq{-KL;lAK*VoFW^t5oM*tLA3<63ZAv1W{jprZ%YD%+@#5G9p!DC{2u3MR1qo>$Civubz z3tz(|Q-;gokd)qBfqPdBmrSA5!6iGt`l*O5q)`xz?gITRPmDTiy_GAr+pz4aatp}Q zv_c<6)?Vs" @@ -40,24 +38,69 @@ def rotated_sprite(self): # to floats that are equal. return rotate_image(self.sprite, int(self.rotation)) + @property + def rect(self): + return self.rotated_sprite.get_rect(center=self.center) + def draw(self, screen): - screen.blit( - self.rotated_sprite, self.rotated_sprite.get_rect(center=self.center) - ) + screen.blit(self.rotated_sprite, self.rect) def logic(self, **kwargs): - self.vel = clamp_vector(self.vel, self.MAX_VEL) + # self.vel = clamp_vector(self.vel, self.MAX_VEL) self.center += self.vel class Player(Object): + ACCELERATION = 0.4 + FRICTION = 0.96 + ROTATION_ACCELERATION = 2 + INITIAL_ROTATION = 90 + def __init__(self, pos, vel): - super().__init__(pos, vel, load_image("player")) + super().__init__(pos, vel, load_image("player", 3)) + + self.speed = 0 def logic(self, **kwargs): pressed = pygame.key.get_pressed() - rotation_acc = pressed[pygame.K_RIGHT] - pressed[pygame.K_LEFT] + rotation_acc = pressed[pygame.K_LEFT] - pressed[pygame.K_RIGHT] raw_acceleration = pressed[pygame.K_DOWN] - pressed[pygame.K_UP] + self.speed += raw_acceleration * self.ACCELERATION + self.speed *= self.FRICTION # friction + + self.rotation += ( + rotation_acc * self.ROTATION_ACCELERATION * min(1, 0.4 + abs(self.speed)) + ) + + self.vel.from_polar((self.speed, self.INITIAL_ROTATION - self.rotation)) + # self.acceleration = pygame.Vector2(direction_x, direction_y) * self.ACCELERATION super().logic(**kwargs) + + self.center.x %= SIZE[0] + self.center.y %= SIZE[1] + + def draw(self, screen): + super().draw(screen) + + # Corners + w, h = SIZE + tl = 0, 0 + tr = w, 0 + br = w, h + bl = 0, h + + for a, b, offset in [ + (tl, tr, (0, h)), + (bl, br, (0, -h)), + (tl, bl, (w, 0)), + (tr, br, (-w, 0)), + ]: + # For each side of the screen that it overlaps + if self.rect.clipline(a, b): + # Draw the spaceship at the other edge too. + screen.blit( + self.rotated_sprite, + self.rotated_sprite.get_rect(center=self.center + offset), + ) diff --git a/02-particle-system/base/requirements.txt b/02-particle-system/base/requirements.txt new file mode 100644 index 0000000..2a1e6fe --- /dev/null +++ b/02-particle-system/base/requirements.txt @@ -0,0 +1,8 @@ +# Add here the extra requirements for your project. +# You cannot specify version numbers (yet). +# Lines starting with a "#" are ignored. +# DO NOT list pygame here. + +# Please try to limit you dependencies as much as you can + +# numpy diff --git a/02-particle-system/base/utils.py b/02-particle-system/base/utils.py index 98026fa..9978011 100644 --- a/02-particle-system/base/utils.py +++ b/02-particle-system/base/utils.py @@ -53,3 +53,9 @@ def clamp_vector(v: pygame.Vector2, max_length): if v.length() > max_length: return v.normalize() * max_length return v + + +def segments(points): + """Return all the segments made from adjacent pairs of points in the list. + Also return the segment made of the last and first point.""" + return zip(points, points[1:] + [points[0]]) From 11176df1986196cfa2e3d11f36d98093216f6b85 Mon Sep 17 00:00:00 2001 From: ddorn Date: Sun, 10 Oct 2021 18:46:17 +0200 Subject: [PATCH 13/80] 02: add asteroids --- .../assets/Asteroids_128x128_001.png | Bin 15266 -> 0 bytes .../assets/Asteroids_128x128_002.png | Bin 13758 -> 0 bytes .../assets/Asteroids_128x128_003.png | Bin 15036 -> 0 bytes .../assets/Asteroids_128x128_004.png | Bin 15557 -> 0 bytes .../assets/Asteroids_128x128_005.png | Bin 17904 -> 0 bytes .../assets/Asteroids_128x128_006.png | Bin 15040 -> 0 bytes .../assets/Asteroids_128x128_007.png | Bin 15697 -> 0 bytes .../assets/Asteroids_256x256_001.png | Bin 41797 -> 0 bytes .../assets/Asteroids_256x256_002.png | Bin 36264 -> 0 bytes .../assets/Asteroids_256x256_003.png | Bin 41606 -> 0 bytes .../assets/Asteroids_256x256_004.png | Bin 42845 -> 0 bytes .../assets/Asteroids_256x256_005.png | Bin 51001 -> 0 bytes .../assets/Asteroids_256x256_006.png | Bin 42048 -> 0 bytes .../assets/Asteroids_256x256_007.png | Bin 44044 -> 0 bytes .../assets/Asteroids_32x32_001.png | Bin 4512 -> 0 bytes .../assets/Asteroids_32x32_002.png | Bin 4324 -> 0 bytes .../assets/Asteroids_32x32_003.png | Bin 4482 -> 0 bytes .../assets/Asteroids_32x32_004.png | Bin 4583 -> 0 bytes .../assets/Asteroids_32x32_005.png | Bin 4822 -> 0 bytes .../assets/Asteroids_32x32_006.png | Bin 4492 -> 0 bytes .../assets/Asteroids_32x32_007.png | Bin 4555 -> 0 bytes .../assets/Asteroids_64x64_001.png | Bin 7585 -> 0 bytes .../assets/Asteroids_64x64_002.png | Bin 7159 -> 0 bytes .../assets/Asteroids_64x64_003.png | Bin 7517 -> 0 bytes .../assets/Asteroids_64x64_004.png | Bin 7736 -> 0 bytes .../assets/Asteroids_64x64_005.png | Bin 8469 -> 0 bytes .../assets/Asteroids_64x64_006.png | Bin 7456 -> 0 bytes .../assets/Asteroids_64x64_007.png | Bin 7706 -> 0 bytes ...roids_128x128_008.png => asteroid-128.png} | Bin ...roids_256x256_008.png => asteroid-256.png} | Bin ...steroids_32x32_008.png => asteroid-32.png} | Bin ...steroids_64x64_008.png => asteroid-64.png} | Bin 02-particle-system/assets/bullet.png | Bin 0 -> 536 bytes 02-particle-system/base/main.py | 18 ++- 02-particle-system/base/objects.py | 122 ++++++++++++++---- 35 files changed, 108 insertions(+), 32 deletions(-) delete mode 100644 02-particle-system/assets/Asteroids_128x128_001.png delete mode 100644 02-particle-system/assets/Asteroids_128x128_002.png delete mode 100644 02-particle-system/assets/Asteroids_128x128_003.png delete mode 100644 02-particle-system/assets/Asteroids_128x128_004.png delete mode 100644 02-particle-system/assets/Asteroids_128x128_005.png delete mode 100644 02-particle-system/assets/Asteroids_128x128_006.png delete mode 100644 02-particle-system/assets/Asteroids_128x128_007.png delete mode 100644 02-particle-system/assets/Asteroids_256x256_001.png delete mode 100644 02-particle-system/assets/Asteroids_256x256_002.png delete mode 100644 02-particle-system/assets/Asteroids_256x256_003.png delete mode 100644 02-particle-system/assets/Asteroids_256x256_004.png delete mode 100644 02-particle-system/assets/Asteroids_256x256_005.png delete mode 100644 02-particle-system/assets/Asteroids_256x256_006.png delete mode 100644 02-particle-system/assets/Asteroids_256x256_007.png delete mode 100644 02-particle-system/assets/Asteroids_32x32_001.png delete mode 100644 02-particle-system/assets/Asteroids_32x32_002.png delete mode 100644 02-particle-system/assets/Asteroids_32x32_003.png delete mode 100644 02-particle-system/assets/Asteroids_32x32_004.png delete mode 100644 02-particle-system/assets/Asteroids_32x32_005.png delete mode 100644 02-particle-system/assets/Asteroids_32x32_006.png delete mode 100644 02-particle-system/assets/Asteroids_32x32_007.png delete mode 100644 02-particle-system/assets/Asteroids_64x64_001.png delete mode 100644 02-particle-system/assets/Asteroids_64x64_002.png delete mode 100644 02-particle-system/assets/Asteroids_64x64_003.png delete mode 100644 02-particle-system/assets/Asteroids_64x64_004.png delete mode 100644 02-particle-system/assets/Asteroids_64x64_005.png delete mode 100644 02-particle-system/assets/Asteroids_64x64_006.png delete mode 100644 02-particle-system/assets/Asteroids_64x64_007.png rename 02-particle-system/assets/{Asteroids_128x128_008.png => asteroid-128.png} (100%) rename 02-particle-system/assets/{Asteroids_256x256_008.png => asteroid-256.png} (100%) rename 02-particle-system/assets/{Asteroids_32x32_008.png => asteroid-32.png} (100%) rename 02-particle-system/assets/{Asteroids_64x64_008.png => asteroid-64.png} (100%) create mode 100644 02-particle-system/assets/bullet.png diff --git a/02-particle-system/assets/Asteroids_128x128_001.png b/02-particle-system/assets/Asteroids_128x128_001.png deleted file mode 100644 index b67df3719c9004127ec7811d87036831968f8f39..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 15266 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:Dkk@8B$^WYpNuH6oogW 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 z =da6RiCGN)fSb65-3Y>ICY)gGU68bBXu2b}i1>Ts7WOg|ElTZf%9xdpRP0gV zIKn!g<2c{V-lV2rG|Nc9&GulvkMulZFBX~Dme^gZ=vBuHyXkqxk!y*+yLpw2W6)Fy z4RlT@Ij0yPHUF-2Lj^5(U7gZ_VR-Ek)_I&W2yiQV_?PVC@A4MDm%Z$v*NOp_=+Q@* zP%(qyHufM0&oSi1jLFmG`yEYh-)uzR>b(1QmgpnC!>44O32Tg4W5fnyhD>6Y&--`- zf55Z+GLN%PnQR~t&()xS`5tayaD@R=_vO3NP6-yKG5A5E9X2VNE{ zJGKB8-Y-*5ZU7?nSM6gcJ@_$+^bJvwc^K<@f*aYz)y(lu_VPXK?VJ;U=l}g8k8zYC zFEHXHlL$g}Std=I2+B9`gQDj>-MjQ7TmJ@c;#c{G&!KIM0V-c29x~yFxr)1Z6PwsL zb=3NpBMQ_Qm?@xVYD<8t&Hu#WCRJy~pu7FW+n!74VVS`&W<4pS(enD~Ef>qwsX91h z3!>;YEP&hZGR$7Dtbpw4OdzcOz7l}R@bw9f$5`WGUgR5`;Up78&GQW$KtZ^P-Q2<+ z06xoczy8|8ne!2BIvwmG%qhB758)&e-okGF4sQW$T>aV#{5aS0Q{2EBrH+Z(vwjPy zn@$~dz*kz_sKjkdz|~mB5X(9hYkq{xkjl>-Br)>7n56-;n}1*dIougoztvhq=iqO=0zisn`RL{Ml%7bk(q(Ugpdq=jqu$!qxm4 zs~trfVmp;&b2>HP((@d^iXIkN_fx;W#gLpV1@&PvK>9*QTb&UyY}J*M6z!?RMjyp27m0P+4iSy^>E zQ2>j3k0`+es6|7#ftzkK5~ak@FCxz(dj#!Fz4mU0%(|G97&C~v@l|HTru}QCk8rP((k}QBa z?r=#JvKcI;yC5W~NqWNRy*nm^IN0yhuqB&RpLDZgBP5Bzms10p0!HAN@fz*2+%->; z@~)zALVl1pW;J>ea~hu4Q2fg^6x75KY@yL!}l$;mgW}Pwl$8ow^G{4uOY$h%fGp6ZrRd!?MFIS*7P;Cg0H0 zGG{4RP-ed|#mz|zE3py0izZa#_L|_;HAtb0_wOQSF!lHONV;5M@QT>;3NTTFnuB=_ zlR{=X8#^Qcfx_)Geyr>%&o@jfk1lEA*ot_gW27qi4Kk&EFtui|b5^i}eO6Vt1C$Za zzTn&DeKKUT+O#%xp?f%((`K|Q2^BP7?Rh-VwaZwh3qp`tha}rdR zaL@br{K}3Mz~c4=s*$vqK22YsjlxE4w4kkqw0zo(>Ls*sd`ddd(I|ShX;Gn4pWI87 z!6g&I!?W$6-g1V*z{JA(q#jk9WgOkKQ?iXFQY3GJja#_%2n{1=Y!)4XL0 zjh>G35*<^^+Jw+8tiUJFt1-mE^;S{6^yt^h2P-pb^)~@qir>^@5AmH?4ZCnVCb=V>*yY7F>TC+OV(gef_0zIpP}MR ztXMWyXO@B?6<^^Lx3P2<%B^$?RywMXZi{DqAD>$}F9oo;Wr=uta}vTRlR{CNo7Jy{ z?~-8APN`43q$eIVO(WkUFx_B6pETo}H6$~kAlUgHW@!fIdSDE;bQr0?xhY*u=cWWh zA3vO6;{AT*8N(!F=&xsy-{VQ%%q|u?PkZ-Fl|0p+wuQCpWF(xI0he_S29T*jXn*Zgp~+=AevyDN4I|mAUOV~*b`7wz1*S0GELiNQ#8kFL zDBp<^Y*4c9d3ag1C~rH_Fj{aHV5?z`B_6Rcx^x3Y`NnTg|a+>}6J{%gx?Xc~L)!ubBd>+66(=Ypb49HLQcvYJ zrG?E2oEg{mw-UGrEDUOh_sj&Uwi1M%z0*`|dSo#Sm(G=C$q#{hl#?9hR6HjS@&Xpe zn_1+qa5Xoxr&D|`qo8kxjB>s%AORjE_pJ#A&?t)jLYki@5kZue5(H?-s#J-LaMHeR z;OR~!5WyG$YoV;K?Xbk08bN8>*+H%Z3w^k9p;mz7LpZkCT8~5T?ebb?CIgVHB3IYen+U%0 zr&%*o^iCi~3A0iIm7p1kQgjM`n@TXLFvEIl8pamZOKfQq-#k?bjChkJwGwo=gNYvm z6KRiwsO{4P(kNRM}Od1r=@v!%M+MoQs7FAG3| z@TGpZ`64wGY~yO5B*9uNNvf6al6?Y$u%X!krmtGHdOJ}92W(ETti@>>a=ln)EN^@Jc<~09oL|Zc$V`0Jk^?d5@sW41t{ZI8E}XvxQ=<2Sx7$5bp(p- zRMK521!%fZ(-x>SC$-+|8in(xdj&`mxu=zE*UAV2?pLbXyj6Qp7LfUTOC zAhTdwDnVu8_(lisCcNHyjNhqgo-W}=evadm)KgLW+1Q&xHIkHm_3K`UKjsB~mhVWq zuF`AW!{|B)C+8moDxK8x{82k`HQc{4OBYSXde1dAt=W<6?iGGSspjUH)|hn{H;FE` z;|_Fouw5nCB0DIR%31}1>tO90ti=Hs{cL}Mo>J~Y3BSTnVfa5B<7fGfgnCAT%cMOB z+4+6=g17*Z>Y5~#wmdi0F2W=@e2xjEj3OIn?xH~4rrM?Z3-u_rL98t_%@!}E61Z$0 zS=|LaVS|zv*kGNKV+@(~QxS|}A8TrOGjq5Wz8;hFRZep=yF142$`p#8J1atXjxHe2 z?VFWrV;_LaYVQqYTn8%}oJ~{4lwKD4^Ct>(C=iB}p1~(^=kBmSLHNcmr4poVXBD64 z7)ROUj2C=Ok1LY-2PQU@=Y-IP%P*~I2wj2Tbiw=QJaoZ=KvWvntlH2NN{13ia%QeE%Tk#LaUV4>`)2HjO!-~sIoM3cr?)@xFoWo z%{9!mx}Za!W0B25sIsXf;ctQ7)Y%F7s#nUe`u%+V$OVc4L?w9b3b-h9sDUAuv2sYN zhbhY^C_&g7ZLDZlp{MVtAF%Xw&M?MuJqs+vLR7mCfE_4-^~@lvO4ZWp`EO_^fyFzB z116g9TzVqR&FtYDoKaiCRZ)9ri z>=H?cS6y*Ij`x$4dtEEL&~Cta3s5QnoTB7WR;hqp%&PTjsb({rUl};Llm3@B%h5L3VMzcxZobnqupI z$#?SxpItRctX^1pdbm{<@LV#0v!#Knff3vYNq?2J`M|~EPh-|iViZMH4P7e`4Egjo zS>ps_-oPx+F$4-0 z$u@RzOuNK#wlMNUml?mp1E94=$xZC$ZS3Z&tVMJ*MEgc5fX%w2FQLy5a~0!OTp%qv zzRN7HJICEb%@$d}ij4tQ+M8#i&zi==Z_l&qXF}2@O#8m;SmaGC@+_N_2($Ej*X~Tx zwL8Y~6dOq|Kt6s(Uw_Mwl5@Z_43ozy^?SO5E7xKmTNNbEsfk}99tfr3gWSNC%)~v0 zMwATwMej2-@_P;SfuG|><|x?oDrsAN87M+c^8Hrdy$u%7wiH1BP^TzUfr*+5cxpfr zTgFHP<&p?Kf8Axw@J8l5JGY3yNr7R;TZ0~kM>xr!a*VIB*74q{66EoY8 z-xa?9z&Dx{e%7yv3@FEojG3k2A94$~v4@ct^iT;tTt<{!#Vr4vecZqzry>VCm4)q? zeW2zhozv<+YYbqr21~tFOnXSG-kzmd9X&-8m&}anio8t*yrKrEGPS*N4}C6Ymdlt? z=3kNkG+bZFfam?Z&8rw>70vek25riD{+NkPFa^SHdaP11gD_E6K5hb?ZuRsxp@U;E0m zZ(gP#iZ&Z-mJ=TJiN1mvo@5w(ejRfQ6H334vSky;E_&?pjUK3=GA|rm$qaAw)Bh#o zG=zeTY(YrvjtT1P84M+k`N%7@F{P}qJjEubnQ%P|+|7+G?%|(ujDO5wzQiim`ghUz zDG3LlSy0;bTHNXn@W_R<09JvzVdjiZ`_kyRYj}+2u-Jqt)Cfv9G=v~=jOAJuILv7; zd?Kh+`cB?C3~yr>k8pxJxRf_C+figXdlk`T1Ess&m`rsC;VjL@w5~qJzBKM)P*}0S zI#097E}sO3BH0zpaT`lK$|~0|pN-v54T<=T9=`N4c5@c$Rg>jC>qj`Hh_ZI@hpC#hX}2#;pc{gbI5S&e#pA@EV!_7L=;g4u6h)#9_eZjKEN^$@J!&fbVP< z@vUkBtAVFu<0LRWtXNcjZKF>#N@>WV z+{hwtWsz%`<2i;5{Sa!Kbp}~AztD8JgIo#Pwe==eAz?-}m_nD8nZ+=|vOvMevm`=u zY`cRejVWd+xRYy=60cLtXp=Fr(xI6gdJm5r*@*&7%>w?A&4-#a!)DPn39moB)~Q~1 zWNxzvR++J+0pm0!U*e?iL~>lg3>J8dHP-xmZ#`jDNB*Vf=Y^5*VP9k0ks{LZ`tDTF zb!GzkcZDgSvlw~CZ=hSX$WqD& zaB;k&M#>~HpDu}DZASk}kws|@n~(%Fs@=hy-*@1oYSkveDqU<{o2Z~pVqc%}->spZ z=>XR#_&fLgHi>N7H3*|#XVmA7J?>w5>sKYj7)i3FqI0^3WYxeBukaM4NiZddv=)ZM`H-1T0*uyRoq!1)pJWOaN^fwZlGEOgw@N6Sc( z*l5?HpDP{ZXp>lsMy-OM)urT|+Af*jw~E|h75T%`Jrt{J&oohUc^&C?E>1n}I-5F3 ziabn#(`^e1=Hu_>3x~J>$Cg8){s-e#hg-3Jr8$M)w=;nJ_Vj4qX2Yh^*V`%YnPwXK z|H{bAZx^LpH*DIftl5Onnn(Zb_q0WKclPB1WN@`nzwVmg$YX9$^^Y#1N zwg5iBdC1`Q*@Oz^yhYGxTH_lf15Pxrl`Vomo75Vl#Yb$Mh{0w&y-=uX&(U?+3?r9B z_GEpHM(ua#vcg#2sHF#InFK0ttijU^;{>#DTMln^a3Wk<_)wE^Y2!zUfW-9M#RD zCp-+)%uVk4&17Zw*7-Q%aPPR#!rztxJj~=Fi(9o@n7z~_Pcw0@6~%VBg}jWrwW6fv zlPNxPdzV&mr9%8|#!=C)h)%$|?$=ZiQ(*#W` z6KKq$$%aGB`-Vzsy+_WLH!4DCNB%k8);YPpgxHO==ZsL98wO6wtbiepJd! z>HB#^t|R)7t#sy*8~~t4ucaOV7s3 zOTwlF{?ygAfu8_k;7gNyF$#G> zPEYDKYNf9GQE%c`eoxW8dx;egRo~CIaFLGPJd*Qy=r8l=ODg>HjsaA{beBaQG)c;r z#smTRGabc~GRENTQgX;9Oj1rkbYWHoaDHnle#_@YvXYj%#g*(N)uE0H`W4?Y6@;Mb~xDD@ph}vH*=0aQne5 zZO0PiQM=2ka9x%lP)Mxmi0j@&ULfv0oJQMDo_E~LL29r7t1MG{ zev*Us==Qq~@Mnj3g&k%mFM0%49o%W-YTd3S=*G;uczV6qIGL|{9Zb2%0t!2W>dRPh z0W}6c?>h=DB*UV+Hk-rH`#z+$&P}I|>5zaR+?Nz(=H=c52#3GOp+@O+h^=!mTIXuoK2Y#Q!g7u!}(A1xxYNRok5>HJ|~-z?e;4(DASCMba5||M#VKoSH&rkBzkMJrudKc(@K4Q;N z3G}{yHYw$3BB#ly5@~%gpZ%8(j!zY%8RrfyEP>0}~zTaFZ$PoLwmozH`dn(>w(-M6DXr>AOw ztNR7+`f2`rl~>Vm-Z4Oa`~^55aG${}Z9gVReZ1b4t3dAns+%dgd_S$2A%ARIa4D@y zWE;`zs#ppf5%|d8;_I*IRe#Zfz$r?wWROn?a`0T0U|Qr)Hia~QuVTvUiYW?`mV(=j z8Il!w@`eq8RYC4GaL?c78?X3P|B@;|IKCU%FUZ{n4xFzNNCN(Dr7XFiyR!*1rGhE# z6`qxmW!1pFg4}aA-+a}W`*X3snDk@qO{Vw zDbFw1H!vgpJ3ddLZHapH)0bW18Jr48w oDR^B0UO!$}fY*<2*W>>W0JKgOmqpzgM*si-07*qoM6N<$g3JKLZ*U+IBfRsybQWXdwQbLP>6pAqfylh#{fb6;Z(vMMVS~$e@S=j*ftg6;Uhf59&ghTmgWD0l;*T zI709Y^p6lP1rIRMx#05C~cW=H_Aw*bJ-5DT&Z2n+x)QHX^p z00esgV8|mQcmRZ%02D^@S3L16t`O%c004NIvOKvYIYoh62rY33S640`D9%Y2D-rV&neh&#Q1i z007~1e$oCcFS8neI|hJl{-P!B1ZZ9hpmq0)X0i`JwE&>$+E?>%_LC6RbVIkUx0b+_+BaR3cnT7Zv!AJxW zizFb)h!jyGOOZ85F;a?DAXP{m@;!0_IfqH8(HlgRxt7s3}k3K`kFu>>-2Q$QMFfPW!La{h336o>X zu_CMttHv6zR;&ZNiS=X8v3CR#fknUxHUxJ0uoBa_M6WNWeqIg~6QE69c9o#eyhGvpiOA@W-aonk<7r1(?fC{oI5N*U!4 zfg=2N-7=cNnjjOr{yriy6mMFgG#l znCF=fnQv8CDz++o6_Lscl}eQ+l^ZHARH>?_s@|##Rr6KLRFA1%Q+=*RRWnoLsR`7U zt5vFIcfW3@?wFpwUVxrVZ>QdQz32KIeJ}k~{cZZE^+ya? z2D1z#2HOnI7(B%_ac?{wFUQ;QQA1tBKtrWrm0_3Rgps+?Jfqb{jYbcQX~taRB;#$y zZN{S}1|}gUOHJxc?wV3fxuz+mJ4`!F$IZ;mqRrNsHJd##*D~ju=bP7?-?v~|cv>vB zsJ6IeNwVZxrdjT`yl#bBIa#GxRa#xMMy;K#CDyyGyQdMSxlWT#tDe?p!?5wT$+oGt z8L;Kp2HUQ-ZMJ=3XJQv;x5ci*?vuTfeY$;({XGW_huIFR9a(?@3)XSs8O^N5RyOM=TTmp(3=8^+zpz2r)C z^>JO{deZfso3oq3?Wo(Y?l$ge?uXo;%ru`Vo>?<<(8I_>;8Eq#KMS9gFl*neeosSB zfoHYnBQIkwkyowPu(zdms`p{<7e4kra-ZWq<2*OsGTvEV%s0Td$hXT+!*8Bnh2KMe zBmZRodjHV?r+_5^X9J0WL4jKW`}lf%A-|44I@@LTvf1rHjG(ze6+w@Jt%Bvjts!X0 z?2xS?_ve_-kiKB_KiJlZ$9G`c^=E@oNG)mWWaNo-3TIW8)$Hg0Ub-~8?KhvJ>$ z3*&nim@mj(aCxE5!t{lw7O5^0EIO7zOo&c6l<+|iDySBWCGrz@C5{St!X3hAA}`T4 z(TLbXTq+(;@<=L8dXnssyft|w#WSTW<++3>sgS%(4NTpeI-VAqb|7ssJvzNHgOZVu zaYCvgO_R1~>SyL=cFU|~g|hy|Zi}}s9+d~lYqOB71z9Z$wnC=pR9Yz4DhIM>Wmjgu z&56o6maCpC&F##y%G;1PobR9i?GnNg;gYtchD%p19a!eQtZF&3JaKv33gZ<8D~47E ztUS1iwkmDaPpj=$m#%)jCVEY4fnLGNg2A-`YwHVD3gv};>)hAvT~AmqS>Lr``i7kw zJ{5_It`yrBmlc25DBO7E8;5VoznR>Ww5hAaxn$2~(q`%A-YuS64wkBy=9dm`4cXeX z4c}I@?e+FW+b@^RDBHV(wnMq2zdX3SWv9u`%{xC-q*U}&`cyXV(%rRT*Z6MH?i+i& z_B8C(+grT%{XWUQ+f@NoP1R=AW&26{v-dx)iK^-Nmiuj8txj!m?Z*Ss1N{dh4z}01 z)YTo*JycSU)+_5r4#yw9{+;i4Ee$peRgIj+;v;ZGdF1K$3E%e~4LaI(jC-u%2h$&R z9cLXcYC@Xwnns&bn)_Q~Te?roKGD|d-g^8;+aC{{G(1^(O7m37Y1-+6)01cN&y1aw zoqc{T`P^XJqPBbIW6s}d4{z_f5Om?vMgNQEJG?v2T=KYd^0M3I6IZxbny)%vZR&LD zJpPl@Psh8QyPB@KTx+@RdcC!KX7}kEo;S|j^u2lU7XQ}Oo;f|;z4Ll+_r>@1-xl3| zawq-H%e&ckC+@AhPrP6BKT#_XdT7&;F71j}Joy zkC~6lh7E@6o;W@^IpRNZ{ptLtL(gQ-CY~4mqW;US7Zxvm_|@yz&e53Bp_lTPlfP|z zrTyx_>lv@x#=^!PzR7qqF<$gm`|ZJZ+;<)Cqu&ot2z=0000WV@Og>004R=004l4008;_004mL004C`008P>0026e000+nl3&F} z001iKNkl6r3IWzY~idQsA+i`5)*l`l%B?^6{X_ERXj-A9UU^-2a z7ENUmZQ&M3Alv8zMJq^(ow}`UNJ{gkKUyh8|FvkDwrPw0s3@ck&^oZFv~^-DvZ%Bc zNr@6K$@`j_bN1?wz4x58*IDPxT=J44WgcK~=iZq+bIw_7ugAB(wKg#`?jGO1hr4?V z?kd3D(4520jR26~J)-kP#27pVQ|&eSQ|eM*MYy zf#>7f&H~r~aQ5L#*tiq!Nmr~#oiE&B3h>3FSOai^flnl1o7dGPbn)EBCu}H5N635z zz&QXf$LF`5V!UM);7dnwG75d2gpkt%6n?T0J`u(1BQP^O`%JJ}0X#Q~!N?V(=QtZ5 z&jL98W-G*7P657j3?~VA1dKI`!3>cQa{L`iDL{nMm2mMz4@O;kc+_APR={}fg%Z@9 zD+K0Kh~J3HaPF=GT<7ulF`OXA<3vI5QuryV^#Dc;OgOw=5U@bNfPjJ=3Rl267cGEC zRoAGwo(h%?cfkOdg%XJ8o^$1xQyHGTm6qX-SAZvvVGY1j1gyIxcxqO9Qid@DS8HG# ze=p)=NWhW<7F|#RN8wXEdwBM!nK7B(l;}FRaUWjA2$>RGzcOq9I1S*jn{5^DXa)GE z$M7hCN1PD4qukdg;lJU-%6BovDJUpF87;svh39F7r>h?`P$g@k9^7RG3}r|zqXtm% zo~**tH&YSrNCo)yV^|~LDWVYIO@%Lnlm6xbyj}x4KK!jjBlsfzUJ|ev6=AxZ1WGl)|UU&7h9qyl{D7)}8A7=RN1R!R74OYlkf3xgpX5$bA!x}IbTaM=Ub zyjbm00fYr8I?%5QA#MPI1#m`eksg(>2ubi$cN3pGk$y4*JMn*ad{DMIUBjmzzJw>< z5(@CeqgW;2B!GtitU>r;EqJ+#(({2UurOE%3Q$i_O~#o5yy1auZUkJ46<;D|0OIqk zV-l?ZDJ!rWg}3E_nwso_I2ZbWgpyGcej+SaGDnW`7X2k{%U&5(7S^>Uz6pu#1 zugXt#q=YY4yi-2kfiNt~r~nnfK2v}z@x~TH=%oV&XoMq8Iw8jlG!mHpw!^@#2d+jl zK1u)2%E|}@C@Fq#{QK03L`!qE4(GZP-AO&$8r-lFyeSIs#iLjU;VA%X@(QJZ3$ldW z{u`;kWe1$y6nZrM1HMp5`5$v`9bj0HuA_*GxDwCt9tRvO;yDTz)pMNu>=8V* z-*Vb_3-E4{qg(4@!{yz7<%O=y3t!d9p-xv@BOVu<3zaIMhs-ut(*2R;F<3;Y)b>wsZmi zsX~wrPMGz^JM*s;gNpVFSSZdj*WT8930fh6eF^Cec-~qYz&>!21S@?ofhN08asUU_a#M z_EY#Ag|Gdi%!w!7!+Q^o_2x~%lERlY%V!*c> z@dbT7XGg%7cY&$8lx>MHm z&mO^v{gB-aTY!Ib6l)ATLmewWU4R$A*WNd{yI4Kxeey$6bm(v} zuiO%ZvefZ2c70B1(qC3rj*lHR-^@bgEoN`z-pz(-;^Cg04$bSD9k&}`DaT$t!& zb_-XS#)9cW7EH{b1cWy$4Sa;TiT0>Z}ulN^L>~)X%wS zSY2T<^}n7FJVN)wa~m}Jz9DemLS9oCL?u|D;9eGD3OW!$;<5uic?dXM=mjQX6Es1j z%q)rsW|iIU;E^{i2Ka|Zu+G4zp!{~axyh#|oIO4F5&gPYE2Wu%hFJtp5Pp0EdsC=MQ0H^YyeS4 z!0U{3l)4j_43~JN0{&O3xhXM_Z;K#zb)Dj}0I1y8DKxDccK2?M{o3p_s(gb)$ec$ERj)OOX`?k%x~AZinr z>Lvq7k0V7BXih7SZP@tat+W82Vqi79qL@2RnY8MrSRDM-_|3nwYxwp)B`_>S*Y7gZ zsJ+LenqX^Z3#0LlY5E}`5z?MzX%>YAI8p!$@h)BVzz+?9`xn&ej|7jAU=1B` zz%LvOtJD0BzxtZD= zdlGJ7!oYvsj@&*aodX1XM+v-d2z>Xz4y5`l0EA-Bg0^Jfw@AQY*O>cMB)U)sod5lU zaL!kKTt%XJCKuqTS#>Np_0)6s6RNi>sNC|{Vc-uZzzY-L%MSSPGVtzl4qQmwB=iZN?AMoF zF!KlEO1E*k6*z67;{H{Z3M#)l%2S)H)T$mSP5QT+z_UBu?w|z}v5p0l zr4aGU4u_bej!^ai2dow$9ynCQ?xJ|ZU#Wm^jGAEWZSnErOX2^o_>Qzz170 z&yT_l``MLlT#IB>slXpS0K8fU z1xl7^TCPUBS+xa3ktmgm8<+&n!Zk=Mz`+Wfy(tR7z^(*nxQXX3iEO|5|&oqYc=qq z5`L=)(qaCsbm+OLOl&ND?gNR$-$xwID_a$6X)Z)1IOIZBa8Gm%D-KwS*}_6pmZ>`v zMWKR#fy-IY8Y*6(oYmCgM0Qk73uN@R_0R9o4eTWiT(^QH*)GK$H$D+9zB*FmOCfx- zp+o(iS&euj{?k@>eL%+vy3GsG_ZFg-0S=WveH~?V4F_EC`G*VO-lF;25&?^7h#?E2 zN;nk6)ULY2AmR>%C}(Ttaz>gZ^XD1?PyOm1py54b0aM=}O^y@weT{9iy2$fYi1Z72 zF+!-4q&Z!o)a1=1Y&R$W7k%&x;~=y?AgL=ZU2-Afzg!0;`<@~2_97>ZNOzJ1TQN|@ z!dE6xO*=PCKC230BE2j)V8A($=0!n^h2KxzONFSsMpt~iW;_Gn{(T36x>kQ5GM94X z^HrPXol(Md(S!0{MQ_F?lPw>Z#ADw^HA@Ps z{y==JMDS?Ig~w39wTWr8Q3K~E;a*&-LqN$&fl?|gNw8@Vcu`rUZYuy6kip0IO#vQ$ zn=mQV9VA#Tpojp<>vfwPs?!~r_7K|CZOsHq@B5?5R?bNN4(Ftgr08P?7Px6yPuH+5gkA|` z)upUTxfT*`!8OR@BM3vQZp;FF?sYN7gl#wQY8@{0rI=E^JPF*o)QY9MdirSDeE?GL z|BxO0X*ZBo)TO#v>2ig85lkktD=UB%xAA@Js1T6C9WR)^uA!5q(z92Y$(9fI?s8Os z5t>%?Y5c&A`(@5iMPUWjXIX*kV+9*me6#@GUWQ6h5^^FpY_nbQLkA&aR_tL}A#0k4 zgoIOyx+Bc~mKVK#Gh9Ym>WK^BSirO$mS8I?TH%E7(NMmVMUZ9d?I`#w32UGxCg=o; zgktD8i34Nk%>F8X;RQ4*NF36n!x2gQ{jo~ZNY%#C-5bY!6+!OTQx-~)eE#Lwm{|$m zIZMy2S%R9fuJ1$YL`pAFX;!S#v{|LY9)v}870_ueNfz|-?fjG>Ji$^wXR zMk8!8opIJGNPaa&$$HF6HfyJc4J4aJEG0PPaMG^%&n*0&BF@ZUaU3+d2Y)EaWDWQ12+&U=!yM+g3rmiI*IWpm8cI)%ax*1IHZtU zpR01XmN{bliA>7vyjjlU@yb7^oBy7HQFD;rBO?ACQFW8rf1wUlzOC3|zDU3aA{E@? z91_{wKdBIl1nfjck2L!O!5&U4c@pE0G&rI#+#hj!7NRb6S;`T|Z0X{*dr1C2_4lWqKY8=Mx(j?` z+@zdI@m`t$&+P)gc&Lfe%}yj`j?;UV3D`+UpI-UMd5hC_G{LUcAe=>FP4Pgwmn1To zx^V-?_X7wzCrvDI-oQy68o3jzXx}vmZa}W&T96V`5Itcu^UEt*^)DvD92Xt?V0xGziFn$*@g@1K*c1&y`j*GEoklV+Wcx zD>dmm6HKCTEji%6Mc|$yl$BqIeSV7(!CMxH-XaBx_-j?*FTijGm{D|EiAAJk*A$C% z;Hk&j!nn_Usj$XUr1>wXKZ}}60sj8mu$tIFtcpA`6>=Ro!R43^zPk*ZI;{j!(3Q%! zrDA9c@WTtivVcO=%ql*RafGI;e_#Oo;82W?i$$CS<)%*G)KL2MaZhc5yK4@KYMyEc zrD*)z%LE3iudz=NbVc!o6u=Tba})W?DH}yJ3kCA|dY9_(+6R|`?;Uhl0B!!o-)m_N z0Q}GbaN>6zoV5+N76ug8xmQF|CEOJ+(`YX#J7J z@EJ}(xj-ZmRpVu3rwYFkD1g3{ey% zoGU;=OkFO-A>50V=z6-4P@3_(9+i`Dm>Y2cC$dVPaRbsyABaj;nM|7s%Ff5;M?&Dg z|MDvE^9O(*TnINnyMO~OC`=U#Chw0a-|Mkr*M|^Fw@`?l{)An;e;CeFa{PCE0A$i| z$VpU!KfVb3_Z{HhY=-w(-&vLe49W#KSHQ))Zf!_mdIAn{$7&>*3}}WmQq(bP7J~TO z+3R)zQ}Zu4b^751XMGq!mr^uD6v+DruK2K;-ZKa_gdbQ4kCrcszkF>3{L8B$n0zB5 zd1+NM=c8g|;3w(mgJ@#6sS&DY;HOuB|F{|cp%$#2ItqX6fj_+j{MnU&C8XJaUJ*@+ zD6V)1B8r71M&)bNzBYyK6_j4av^F)_?0VbE06E`Mn}4sWrS1k5V4deNu>#2}1p+t` zN+91~F>r1I{J$!og!jaBsWe8mtPMi6|I#EV!@J66;1gMXU#x}%29=S`vmArJQFI^g zE`dLP5cm(9AzgKxBak0j0Y0=8s&a)I1|{!2IR_#aU*oV5MO9%u8NoA8Gm%=&8q_}% zYz_x(QRq7IbEJL{aJpdyp1m#w_{?D(XJAzae_q^qsliDJlKJw;mB1N+S{2zs7ttON zo%~q=;71q3kfm4Z&?#gpqUu7D5jI6&<^X`&2jr}damhOh;4_B<8n_Vyuq6ta#v%oa zRZzPS)Xp|MYF~%Urmirl#u$4a>JBNk@cHBv&2CEB$Uy>z4D3=fO|&&X5&7sHrhM|6 zzz|MfmjbZpH=8zoa!v<_h-6(ndAa(N64XZ5i?xEuD6(+;jGtHvT{p9=QCIP%j7VQ< z$=Zp+xDLm_5dIjU69W{y3JQeFM#AO(DAX zFS&z+Mfm8Br1jBod2OYFK`y61brBm6U6%qdJ}Bq*)xzHtob&e6%}E!;(GsM*y`*Nv z%V^cArge>ldrujPHhon)Qr1bkiUk7LH2}@7Z*JbzI+$HO1yo1e1?4dc$D37ERW@Bb z6`)w)7jhtkoRppzNQK}8Ca@?$$dFAk0vR>Y!=^6q4~GUL{Q5i{A_6L#xnH7s%=e&7MbR{>H_AN?4}?{L;NxOa5P$ za1)G6aY*7))JUgVzdI3RmPJr#Px@~G3*?>FPtOYS%bwMLyw%i5 zc`0=ib60Sq1bX$Rwk1Sd9j=)dlvY$1yviMb3#kqpAa9^#v^o9Fjf?p?7zG0ICdbx6 zoxAKxatifhv8vOKARE3Ro2JEb*@yddXin&nRerCp-Scdk95J5ws~2YX3C>giY1*wB zKGUd}+ioG9bSbO{#Q>2hPg|T}0j6mTw_lStrBo)_8HA0ZC^0ODD4c`$Aw6Sm_8l5f zHx6M1u2KoAxZ1DzhI5$q3rZEi-`)X!X1SYX)F(`b9P~*pxaRI)h{7h7xPAp-yqBr% zgQck-Qa<8UD?z3p)S!dOXBWbCbj|u9Maq=@0tHmBJ++%l3BYi$h^2)kltmeWwR(a{ zRl#%B;xFj$)QUug5+s(8lKz!*B~0v(Im!u&nA7wBFsOs4{P zZn}ZZSv`iy*YScbAIms_I1k>4ZOxaEYhS6;y6D1{p)gYp;#RSMXOBr;q4xEZ*m@&M zuoKCqbu|68Nav(P4#%;0|6@0l!!Oq1{J(P$M&;b=`UT0V@FwG)YEM38j~2iJZ>Dj9 z$__}y1k;f*++fqrATDYIuxsT@Q<&YLj`p0g9DrPK6rLI0*O*Mk7>##x7h@uugyC=j zjvU65-LSERQi7D%r%tF;QM4LXR^s)1a}pr%^q%KN;WOSPL?f z42KK2XJr-6Ic)D-!{+w2mL(XAjUmSo>C=QxLa29qWhWm(sgb;k74WaG0S_zzKe9Ai z$(_(vhxvOJ_pSg6<;$Xf%5PpRYTHoEA&0zu+#%m3MCZtSgG%6;QP(xbG=ZZEzOFE? zM(|4bT}sewKSI;VqS_ryxT)BURO4v+%vbBMxx_$V3YG#StpChTfUECc>|WXF-qq=| z+WigZ_D2EOhI+|x3$iz$;@n(IB+J|)PWJxC8&YRvIFj> zydL00B*^=!05hs>axw^s5@~w9=5{U*v9e{ad##2krRE40(XLh;%uoW)4CcBu5NaMJ zsNu1>bFH%pBVq7~xYBR|n<)M3AzV-nA=PvN^1KkD*gxZeIG^f}R!gx@#d2s?u3A`HAoXsi{u7(u%p%CPa3m&U#W{jmJ+~15JgIrWVGd*RBFkEa_dGN+`*q*4EVZs z2fRnb5Xu5&NSpXkyX~K0?20Ww)g^M6jK!RYsCPm3+P)_5cIvVH5*a*X``en-srFF z0zbJdEQz6%QVCwIn~|{Zi1Un~fUH{Z6?L2gBP|}p0B{f)yp^yRTR!XnvNni~Fbe3B zi=1b0=OOpIIBm%%26$r&$4{pRMW_QU5}c5XBkZ2 zr8E=Q0MRWoR6rPwL?h;VT(P3CBtbHX<}mDS%mUWwf#;vJSXNZ`~Yj*Cr$ zBqw5}eya*r?JwOEW+y&B3O_gE7cNrM2KLEA!Gc__n|miyJ`xL0?#U?5={NUH0X*<5 z0qaf$cbc5QD!9`^V(X?F*?>Oob)jRZrlu)^gxRa(3R-dDVG&Za0vs*!@oJqEG&T3f znh7MYZGpmhE{O#o_YZuf3R%oM$~ezR71aLs82A@gLcsgZvdtP!TuO-;)=~+=W8)L& z_uB#p3?HK9n|p#k3oYwQ^`h8bHdPpFG^1YLKLGyE2>5|vFrWIIFb6Vd z4VWe^XuT1I0*}%}FquA&k~I=R;meZ{E3CMDPV#EJmKP@>K$YL+1(+sXR>dvc;>mqw z1R(~2mIj)NA}V~6j$Hv@-wZ(*bhrZ&O%OGOOyGfK;Mwh99t#2ZEIHt(63dv|K`d9PG1X? zL1(3TdwQMQyNh_`Qqs^ShY$(>;ke-jysZd-f4K@oOe;E-u(!AAeOQ2# zdQTcSmA07~q8a@%Zp)=UP^3kAp(uYw;P}tR@D3w+pMNAFH zVrJ3=?ST+L9t*VQ`3RTmtrR?5?~~WN`e!Qu<1DCY5pP|v5}vM0d&)auB{77low~6= z3}vkV2#A`Vmg!VCk4NbJujI{@+qD@1pi}2&?Jj0b9%YlOmEXSw3iqJmKwN=qU|SEP z2LcVpPd2`?Di(>KXHTBTqqu=%mIZhgjCHd!)1qfXVFs#6Bn#AxkuzQi&XK*th_iTg z(eg}-No1s*GMA?OoYME!=G60?(SEM*#it8&XoKBsI^K{f3^%xNYoWczry$axg zvy#upI(Jfyp}M%@j9fn(<035q=eWMyq*8A#NxHbi4KbreyJw-Vp#^F+x@HeP6RVJa zGvi7{-jG8f3)qDy4Zg7s@;IN3oP>Ys!roxtJu3h>1cF`+ahC9?^rKxkfOZGmX9<*R zAVp1sN-?uO1i_DMZ6v9L?p5poRiJUy#sONcuBWujiU12EHKiWmcLmPE4Lo-8!u6$n zb7uhn@LOBhVBoAS{&<6h;(H=|76lt`6@l3PAK!5kbWOs-^Zg#O5^eJJ^bbooUFYqM z>)qne9P&ym4QD|d8?_bg-dBMcPn^7PV}5^r3lP5a41nWM+&I0jUKcFP9dUvFyJj45 z4{Y4(Jm!35_mNKZ>eoml?0Bvl@$A792w~5lD`HbCQ~~8=b(30!G(!m(IJI9Ze=Z9U z&+Rw$D$Y#1u`0T(fJe_tRx83=sZU24de)92=4$8mO7;e$iDppcx;~5J%DNd0sQnD7TrbHK*1gSM{8At{~HA9cV*Y`_Q(l@f0-a2kxq9=ve< zAkRDpaYrYC9C7}U6&wffT-Q8W*$!oGW~2d^tiPWWX+u1gT+>mjx1H6WohpVN?OnFz zX4Bbr^<;xFp#F^+U|hR3u`3OZNF>iigDj~srqdj1`llZ}Z}0MTy+@~<=TQIv`0xsz zBj9+S63CyKz{#F+NtCZlkWZVzjqi*E?%j*CX?8`TwQHB#iS% zPaI(g|MY|B@$s9v(!1n5|CTX~C%b%apMTXc!L+I+2n|-_LwZa)a$~*SoHa5|2WOt` z>_VqnH9`qG?J&9>Cx*%akd+a$c!f$@shsh6`eqCNhFw59erg#n5n-)!JUQ93eykZl z);4EktfVqd*U+v+kBK2`CZMnwmK*5$-Vrzb{^=a#pvXeh|Fe1o8NQ#4T0!&s(T($NHjh8RhqZGW8shxDKpLpowjgs@zDCjM)OMRVhAaEOra8Ex=1>06pns z%M#?#{w)*!zF7bO_|P(5B4CaBHYzZDt9*|JUMx#NqDDR>+lp9mfa^K0zH>_FwG&N# z!tNz&M{aRns^Cw2YN27K$fYT+6{;T$Y# zflOkhZ*rK@b-oT`UFGJKqj_T-Zu@+1LDnkIXTJ5qzabzxQ-AcfAaKs&8 zP?r)ER?r6SrRGoGXNK2T%OGE~{e26KuYA>XR2|4{yFB6yTX{Y55$G@dWV2=_!<$#lWRRT%IbZSnZQ;4Ee z0$p!_RuE&)0f(?bL<E3n<=lnp~ns$xZQmLHkN0*))!jjhRDE9Pui8b!yhpl#VXGXCS(etO{iI99h@# z1_7u3)@yt3(YqsKfc>-tvwXfTp!8K432h>&jt8tNU=|M`-|0+#zV`o7kxv6S^><&p zJxu;Bbpc8VPB`Ex0#^4^33NNwyrpJqBW39hvNEtT>0RU8GQkth5%B51cbl*JTc!X2 z@W3)w33!~6HP~ZJV3m>qdwQ2uc+ysYU|WK&^8#$XgL-`fz>@?#@eeNDo~!;%Q-E~* zv~{fH9X6SlNVO^7XzvT?CNm=bt3tiAP?){RRJ~Du5^;tr74L5l#?7 zIe8u>(7xGHfLkAfXWFqTrwYl{-lAw}k@8<0C6LPQVEQK1jg&UX%c8 z%&J2--@s%eb@3FsmEbG^XF&Lk&%gfWgE?;r1<=Pw1K;pC0c(zM9|5b8bh2hC0#txz z3ET_}^TUWCc=~dY~!sj__w42q~jM3VihzEC{rw91$SrT<5>bu|MM$%UKD@J72xji?Qyuf ox8SY<+&%6pz}@59_4xk-0A-KO%~#SV3IG5A07*qoM6N<$fYP)KLZ*U+IBfRsybQWXdwQbLP>6pAqfylh#{fb6;Z(vMMVS~$e@S=j*ftg6;Uhf59&ghTmgWD0l;*T zI709Y^p6lP1rIRMx#05C~cW=H_Aw*bJ-5DT&Z2n+x)QHX^p z00esgV8|mQcmRZ%02D^@S3L16t`O%c004NIvOKvYIYoh62rY33S640`D9%Y2D-rV&neh&#Q1i z007~1e$oCcFS8neI|hJl{-P!B1ZZ9hpmq0)X0i`JwE&>$+E?>%_LC6RbVIkUx0b+_+BaR3cnT7Zv!AJxW zizFb)h!jyGOOZ85F;a?DAXP{m@;!0_IfqH8(HlgRxt7s3}k3K`kFu>>-2Q$QMFfPW!La{h336o>X zu_CMttHv6zR;&ZNiS=X8v3CR#fknUxHUxJ0uoBa_M6WNWeqIg~6QE69c9o#eyhGvpiOA@W-aonk<7r1(?fC{oI5N*U!4 zfg=2N-7=cNnjjOr{yriy6mMFgG#l znCF=fnQv8CDz++o6_Lscl}eQ+l^ZHARH>?_s@|##Rr6KLRFA1%Q+=*RRWnoLsR`7U zt5vFIcfW3@?wFpwUVxrVZ>QdQz32KIeJ}k~{cZZE^+ya? z2D1z#2HOnI7(B%_ac?{wFUQ;QQA1tBKtrWrm0_3Rgps+?Jfqb{jYbcQX~taRB;#$y zZN{S}1|}gUOHJxc?wV3fxuz+mJ4`!F$IZ;mqRrNsHJd##*D~ju=bP7?-?v~|cv>vB zsJ6IeNwVZxrdjT`yl#bBIa#GxRa#xMMy;K#CDyyGyQdMSxlWT#tDe?p!?5wT$+oGt z8L;Kp2HUQ-ZMJ=3XJQv;x5ci*?vuTfeY$;({XGW_huIFR9a(?@3)XSs8O^N5RyOM=TTmp(3=8^+zpz2r)C z^>JO{deZfso3oq3?Wo(Y?l$ge?uXo;%ru`Vo>?<<(8I_>;8Eq#KMS9gFl*neeosSB zfoHYnBQIkwkyowPu(zdms`p{<7e4kra-ZWq<2*OsGTvEV%s0Td$hXT+!*8Bnh2KMe zBmZRodjHV?r+_5^X9J0WL4jKW`}lf%A-|44I@@LTvf1rHjG(ze6+w@Jt%Bvjts!X0 z?2xS?_ve_-kiKB_KiJlZ$9G`c^=E@oNG)mWWaNo-3TIW8)$Hg0Ub-~8?KhvJ>$ z3*&nim@mj(aCxE5!t{lw7O5^0EIO7zOo&c6l<+|iDySBWCGrz@C5{St!X3hAA}`T4 z(TLbXTq+(;@<=L8dXnssyft|w#WSTW<++3>sgS%(4NTpeI-VAqb|7ssJvzNHgOZVu zaYCvgO_R1~>SyL=cFU|~g|hy|Zi}}s9+d~lYqOB71z9Z$wnC=pR9Yz4DhIM>Wmjgu z&56o6maCpC&F##y%G;1PobR9i?GnNg;gYtchD%p19a!eQtZF&3JaKv33gZ<8D~47E ztUS1iwkmDaPpj=$m#%)jCVEY4fnLGNg2A-`YwHVD3gv};>)hAvT~AmqS>Lr``i7kw zJ{5_It`yrBmlc25DBO7E8;5VoznR>Ww5hAaxn$2~(q`%A-YuS64wkBy=9dm`4cXeX z4c}I@?e+FW+b@^RDBHV(wnMq2zdX3SWv9u`%{xC-q*U}&`cyXV(%rRT*Z6MH?i+i& z_B8C(+grT%{XWUQ+f@NoP1R=AW&26{v-dx)iK^-Nmiuj8txj!m?Z*Ss1N{dh4z}01 z)YTo*JycSU)+_5r4#yw9{+;i4Ee$peRgIj+;v;ZGdF1K$3E%e~4LaI(jC-u%2h$&R z9cLXcYC@Xwnns&bn)_Q~Te?roKGD|d-g^8;+aC{{G(1^(O7m37Y1-+6)01cN&y1aw zoqc{T`P^XJqPBbIW6s}d4{z_f5Om?vMgNQEJG?v2T=KYd^0M3I6IZxbny)%vZR&LD zJpPl@Psh8QyPB@KTx+@RdcC!KX7}kEo;S|j^u2lU7XQ}Oo;f|;z4Ll+_r>@1-xl3| zawq-H%e&ckC+@AhPrP6BKT#_XdT7&;F71j}Joy zkC~6lh7E@6o;W@^IpRNZ{ptLtL(gQ-CY~4mqW;US7Zxvm_|@yz&e53Bp_lTPlfP|z zrTyx_>lv@x#=^!PzR7qqF<$gm`|ZJZ+;<)Cqu&ot2z=0000WV@Og>004R=004l4008;_004mL004C`008P>0026e000+nl3&F} z001xNNkl6r3IrqMyUw1#vEi^qqBM4|92?iT@q7up}LTK5sD^$v; z+fK?=NvZ@1sS5EAMEt`UjpVqJij!Ck#!id}S}8lJ!X#>uI1ZqpJ0O7t4Xp_c-Fp4z zcc-&geyqLEUVEQ?-qf#KYSFjq*1hlE`|dsGthLwht#7SO%#4e-AKja|cnK~lz{T4| z1-N+oQN5LIZxGQ1ds4r93#I|g0@x4W{R~Wlu^#|@#8XE;+1fM^zQ~_dv*LN^rlh?JfB)6jg zP6Bw!J%80H#%opqe(zQsWZ*6Uv!sMf6ohR^gd9$ZB2{4K$Ond zcYg@LkylzFUULfYd$-~s0iOn8#wdX|9+Q<1A`lfIBDbm;U<+m&3DyhSDrKk@!OHV$ z^UB~A;&V}lML|HP0J;X))d40;fXIk=iR#sFSro>b3!^NDwg7FGAg2(U(1m#bM*w{0Tw8?; zS^*w-Gwvba(}qOY^{P)+e!l`vt;u6yfRcdH039QbV+F9Ql)q!YAc`}x;d`|USyurV z7;)1ou(KxB=B>ivbEyayqyqfc+c86K)%(?43kX3042e))SOHdsLHJ(qUI{t|m?%XN zqKgBdHx$8nmyyO0S^+8shE@b$DJ5W)Id~=UuWeEh<^kMy@C5Gpkx_sz-iG}yXMY<> zKsQ_X)lEPFz!)cJV?abOurT0S5r}~00r29gNUStKhho9|d)ENn6#ZaeZ6t#AtKT^Z z7zzTdthkAh1%_S;Y$kJ1d8SVxeT?7($4$fthYp^=vDc&m{H_FY9|3THfN7tq8Mpch z_1v#;V+>4D!VrPDg5gmx|0Je=q3?XY$qTki9Ba0RR1f2!2q>XL^-e z^){IM$ed98{XVGlN-(mUjuAd_@C5FCO(?*Bxee0*4g$EFfEk^U7fvW%;E@IJ&rJbS zlwtw60`V})0A5-HmWM$B^osXEp#L4eswn}3hEAZ~sub=6y$TqNfF&0v^s8XrwSXz} zy{T?^S5ny!J8Tpi96W(T7qkNW=i6|P6a2Imyk7A|B5lXEP;Nb;Na79MQr2p3DU&jOfxm(fXOm(jU=KJ#HUf|s#D1uR@oYn7Zi;zOY zy-F0|Ob-}Xd2X#c4-;b$I&+ADr#O>f1u)f0usLgRR!VT*72vmT#b*ilczrS4*J%^4 zFJ5-#Yb8(@*{Dpw3lapZ4#kXnH{dORcP(p`tTwMaC4~SpJ>8L&z;doHf?pkpkVu_F zBNbK0g$xRrODDZ67}?;0&V>@3HwE~@t(YO;OK=4lN=&|7C?kS{jUxHTLYSrn@Cs7u z)tg`f{^Am;fX~$eR)*obi^Tn;x8)(QH~3!xRDRR5=M6-!2Ox+el*O5Gw$oq7oxZ z7*!R9Rke{zmU- zEEn7>RE^|1kVU7GV1Sk4Xsc2mi!$3pu?y%8#pnAxe`Le4`}>otz?bJFI5ZRoknh|J z+}SG*%puBW<@5Z- zliXP_R3e6D8%M&_jI7h@o?byd2RCZvR;-jmS)hV|$wF2=B^ISndB1Vr({~a75Bsre zG6ej|9Ps-uNlY6=sRoUaETZCO=Pkpiw-JuV9_BPVi%RU zWNx#E--rV{A-l7-0EchE3h4jk|zn*MMhxz=y8_W+oFizyNU-u0i1f8Ffr8!Qp3JA?d7cXB7k7 zFVw3CNe6uHLKtOoecA=JVvUJSs-b3pRi}MM`CS#cH!=r^fYX4Hk|2!|u!fT8|4biv zVO7w@fvYP1-$me07v%Yv0VW6-b17%(6u{R6`tH7FHq52^o6$Wci(#nFjWHob52%$mqZc9ofRO+Zw*+aYa!O4V}MWHD1S!^ z?*daY;oO>p#RNrc#sr^sRmAfj1N^6(G0VWmb9_4E1kA3y>MLd5HCP6o>BSd66%0`` zfQp`brQv4W;A9Y?aQ^iuzEHxbzmJmdcQ2JrxP@CaB?U$3W}cVMLiMfl`xN4VLRBf# zze^*y!!t|3^D8c$ZI20N4!;qzuZRM$M4}CZ%Xo0Zt%9M-X>|eQ@g*^jL>qwTSl?vl zgr@8G-V!haRFq&NcDSK*+*Cxp*bD&+qZsxr(2OB8TB%XbwAfWB7geg~Pb~r8o0sfj zVF0|e8gm*-YFw_n&$|NrhnsN^12ZX+k|>l(eQ?IAhOVRXJssdr&orgl(1rCBq)jPO zSeF1M0~BLGXA&^oD3weVr)y%tvkPV~?SvDK7{r-^kAA&0`2ts}49i2{^jb`D^Z)NH zj#mVAjt36EF=SuoTmk<5&6sAVb)4LNtsE+l)hkiU^7?V$;RWEOeu&4kCRGp>KgdehK)>%P!S){(Hot@YWro|9hlT(#yKRO0*%H z-VMC461y`4VBfC5Z737hp>7Ayp9NrioE6yP@r} zwzo{AKo(?&z-SGq`tesQYhc_en{>>f@ArT&z68vVfS=wcN-<)I2l@>3tVH{37U;3u z2TBp{xFT3RlhiRx;tIM&Y>BRz0H(*9F+#@#x8ZJgoi`kSfxAfM=1`^{3h*(M2sRPo zSRqRAVjuX%Jn*hdl<-Z9E^uBMc$2OHwgPk2{0@!-zHSkyV^?>9k6kT?^tvf=UBCS- zV5~&$79wn&1`gc)+6myVUmci6CSfsiLLRwgI$X~yCWOB@s$CesCg390xM0@;%-DbU zjhNXEpKwbS;NRYa1GVqx82-$)SMdfCxqd<(zd8pj3^$Odx)9OFHi!>s9fjc*>oQ&j z3vl&>C3-#}GO%KSRST>+E3mf<+!;tn>EToauq4LoM@blLLPp<*D?}-~!3suYT z*U2OWD{7&Z`Fe_X1=d-CQaxwFEU+~y`BoI*Z9uciW_{7eo2Q(qRT%$Q=YsG(r0NyG zBxPSH1@O7ISGaGSkwEQduZiP;Y%oe0_oIH}@j2kT^Wnw$UQp(-A|QNA14#q>R@?!l zt!eJ>+ol|z;LfL1T}qmOqS;FkdYHL>^{j& zlAi7D0@LFXANXuxtdP%jRg~T>5`t=$m@nj6@( z0$5-+YI@+9Vr@C@iqTYPe^P&P+L=Km#7Ge`F+fi6g~H)K|8xLx{Ew!VAWd6!fZ7{1 zIe~Ax0?{xCatPs`F<`0-Ts96|F%DchCW^7!DZ*qKQpj=tyd#~-og$Q`k#Ywe>Nr`( zu|dk5&Qa)-`-}nZ|NM=chla~7SOCBz5q<&%yJp*(*`v|8@2>(Yl_O9nvtLpy*t%|? zn15dqW{TUb&J2KK^T0c%V}*=Hza;p9KBcLS1be4@vQpoAIdI*S%WPawrs0C|LheH= z0``he%JosoXVBJ2Sx9!JZGXPw&SKPXI>+^tfa55UO%{5<(lEH0T^+e=0;&JaN*(9O*B{)uBLSBDb*x-~ zSqL)t*@GwWi5*dZfAxmEN#T|%n7$YV39IF~eyF|I3ZP7R?Z+~p3{+-el~phfEO~M{ zTtv<(fr?MGOX#z-h4);3zc`2sF}krt`}cxc1g^*`tn&PYzNC!{gJAAEh13x$7I@h! zoQvk`W|uX0d;=S-ns&FW*i=QZ0vHiKe)x@e;NS@y-C0gx26^+(2MnAZ0P{mJ_j5zJ z_iga;Q3D0V%3xXyPvHdb1zwXl-2LT2_=9bne&%8U3rXF2m8|xDvv4Z|A(c-J9Q6%6-%+`dJ;TM%%r5*q+m*nyBW#D-?sUyeyY4p`?Q0>dj`)NGtK#!ZXdGAt| zT*Jo;tH8^Bm&=brIotRA>y~a`>K#-uKX1JNv$DW5%Yt&2%8Ka6(gb|NyOPDB@DWd~ z$@8^J(a3fDrHHdRmq5ZEp54(Pu(7J#L0mTh+yLPAsi1)`4&?o%5%9G$IIA0N=6y;= zz9m5;SXTbRK>GcbhoMqen)tJsnSnK4Z&X?B`oR1klzP3;$BN(vI*IZx4MgyB zJyAA)Y-wMDQQ9BH1-g~vA02Aq1IQ?WHtlQyTO_b}q6DkMfFq>B*D-~sd97B$ zNS^D7?{74mW&k7qx(DHEH{fCd%Qa(Y{%p&^N4X7cO9C(?si7fYPZ@W{axz`Zw$uuBS(q&x*@3zpj7_Ql~Cnmo)irK#rfRy=;DBaDJ!E^3lXq~XN@QYX>d`tjG37hMQ zJF=WfzA`aD9YdLXucG_^13TdYPUiSnhQd$ zOd|Y|`;1M7G5P<$Ww&bT$Z!&vT$DeQU~J6=eH{wu-^o?rTg#ywJy`;8-z)Y1^@>ZJ z7)EUgJgLMFs7hmijtRmXSg{zZBT<}^nwhs=^+w|ks#aii|3r|-``b#zTfqU2>kDcS z7k{XQ6X4smZ=C|ZwWtK{gsxAFRgSL}!1M1$swSWn;vJXxp2K$k->>B2u2liY_vztR zUIrdrjA>SufyWnt2Tuc^x*6DOVlaskch?vR!-5*Fi~`H3Yn1;_DBhz=j%{t!ES^!q zZ8UAoEglOT*B0e>uA7iF_4tzX^^GZpji+`!-vj>H zcY$AdQ#0*dk6*&hid;4>LiLQFn$_#mK5o`5G%YT*0-*M$m^u?M0aS9$vir}v7Qnz= zX&v3KB7f11Y1Z7WtFxB`{PgRbAXRELVqoZab?JSeo@?QIWvCeV+cQDLIkP-5pTjh_4}qN;60Z* z;j0zxbL=4kp>oio1VbhK_gpTP1rXn!u6kC;+0d%vCSd<=;62l#m}BIWfPg6@_gy4> zK3|Y}WPW1{kbB>o|H+PkNF9@JNo&ijC_`J!bxo&i<8-9XSt&p*e9jbqk^?LfEZkGZ zf4C+W`=_n}-g!yz>1``M_xDgK&3i5fe)08ka*IP%G|5EoxshyzYhv-BNyjOI|GR6X z6z$^zPy6Bx?jda^fC|6}*P9arHOE6NjcQ8a44)!N2|+EuTE-fjRSaMmA0cW6S6+kI zl}m><&I-JXU=r5v+yK}&AxxfKCGgNGiCTT5s6m#o9Yy>V1ApZz;OB0T&o7Na&diwr z(0{k*=4t%gtVb{BJj1v~8987h+TzLQO28CgG9WO(BcK}Pn?9Xl_;T<>M-;QwB4mUf z1&Ext2HUm(zdYm2KR3;*O`?9ITA9*`+YI3872uRByMFXq;2+!s?Cs?J|4_REXDK=c z_$RjkcikYXa>*%G&g^qCwAl}i@~vK$fy+9fgUA1#|GS^Ko0BWR*ApdmwE17>?pL1|yiu;e2ZmlS zCzpXI7vx%;Z?`tir{fh&MNdLH=o?@OUe&jJo+zZAiftbQh10+-dw^>ufp=XB{Me=WX<=~uzhC)t2_|3c2?+#B@i;S4#B$6l@ZCO>Wf=54 zvcTWE7WmDl#lKVv2k=&)$H0fK1`b^>G;d!X_FTN$^n0IAg|dnaa0O=D%otQ{ABsD8 z$(S2RMH1NN1W&owI4ruTTUx&R*x6WsS#9RDS=FnoUhx#3ca-1N!hi#ao>%}LdJ#CW zBtj*G4p@ID0&d+6ylJ=m-`D2cya6yPgOG$pk%jgfbBXBhWm{GY|#4AH_T`O(^sh>T(rec}hUEs#(1JX%Eo&p$j&l*7`uukGCm{(Bab6mLNmW z7+T<|72uhbCYJ4|h!q6<8UbW{y?@1xetm9L5W*YAfw$~-n7SJ* zxiXY<(ZE*WN4iAOyam|`j0yzCu(Ifl7}gD(TC2hU4R4*&!i}b#70zOfmvZd}NgA5M zsq{~ zUU!n_4pz7@0azJ`nO_>Xs-qQU&{aHAJ$*&8;>g6HR)GLm8OnD%wT;jr;OI|&bDNyN ze|QaM7?_THts809b5ZJeA*qYe(YL!GwN`WJwykWSH%Guyf@I}}Lu<{}3PQ?kdSTbm zxw1%{0QkC0J9M2sUNMacD|Ac|LwzB~P^`fIyO&2oGF=#iz|Qv>vg+U|BPwwd7}8`G zKhrScU2HHAL0!x3vw|7euYn#vCVf~1_G+(^z{(4rl(J}Z=8-|~ODp9{(q2HI-NdKl zM=f|z=%uewN)s%RX|ycM|L^KJlWODa#whSeci%+B7o`NNPWW^Ez%aJ%y1g_In{0Lf7XVdOFz2x{ zbgFm@;FZ88TXPg}*BgQ^@CeBucwg zEUYL+)X%eys%RfOAvBKykr>D26m^N|=Up5xQac>Li~M~HSD7@=?CSzwbK~az;$GkfZr;GnQ@|D7FfON!gc?OK>&z+K zlJqxl0W&r!DsV#MCT#%_R)0;sI__kruKt{cM9k{mS-Pg8!|J9-B%)Fm*mv zIShXUQ}t@tY+WTNIzV?y6lk<6_rwzPMqx6lZ!gQy!k%0O{`;vgS-j9}UUv>ptpfL+ z0Dk5g;DcAT^9{MBq?`tjJ7EE0zn=IspCW1uz#~)MUwhttw8d*?H!$nitfg)QRm!j} zC4g*5VJb(2doRxmSl1sk{XS8MlRIMpI9}bHVW!pb8Zbu0iB5=3EXx(pUN+aWozf(@H=DoLCJ5Fwz-FrTR^+48G~* z|GX>;0F7rTUSiaS*31eX+7TC^X98L!BtH;}tg5*qZc}D|(58tAM3p{Oz0)vfrLcKY z+rboyJzKF%&FUcUCeEc24DJA3$?#MN9`~Il?wZL@**N}w-%pMh^I3T17%0!}+BSBH`&PHJ{OLBGc_nS(e6fAoaaRvv|XQ zfTka5m=|GZ5JRz_@+VVS@ogHuolxyikrGf~w2U12!T-K*Zg_lIno1%oqQIhx#Uh=p zJMgA;q$`suef6K$xX73R-nCaU0bgKRs({~oW@|ZlwgJ`W{V4+~VL)@-6?JlFVt~Zw z>)h50&?|wSdTDKJ5&SINq1$~kGW*Kf__FNKt?oiGisuHv4|~$j7ZFF45?IAY*p3p6 zSPi>ODvwr=cU21ST~ZV)GH~s>$Q3B#H8%WpIO=1b*xeSUGA}2pK%};7h=r*GL^dB8MVx0iIt0e(3h(xpoS;Znshb#o250 z8>I9%6`XYp&?n&yj=6L2_{7ps=@n2$dkZD| z4E3G6>lDBzZx-I7XA;}YZ*%^-&%gJPt+@cRZY@9wtKyiA%4jxUa7GC{9UJMvqoKL= z|6JY$t{#gwXY^gV9#ty=JbVWDvpL|q%kli6oDyUUDN30u-r#(a*#rKwT{kJxhR~ zn0vZ`Wa^2d6$3w55)1Q>ZUTPkR^Z*2$!B|3?taU-z6E~y&A=rc;DuhOEZU4kO^;V~ zLOrlm1z0Zzc*p{?y4KH#_qaFQoUNxh_^Jd``#)%a332S8FZPvV(lIo2=Fta2b;JxY zk-Ix`*Fmez)Cl%X0#{GQqiih4d;L&LufaMgm*4=d6Kb+_Df1{~6ctNX^x{ymm%DFl zat;4%4)~|v1|FM}G`G$`sEPCI>uTeLI{&^$w{8J827**AppIe{0|?w?{Ak2X&;QZe z%2DzfDWMH4aNRB;PV_4Qct)Ot;b`d-CGh6G;s)M%32^mzI8NQOzftwDF$%6lsoRvn z2fO2?Iwt^wk?MbNLE-8m@Qe|K)y1tVOX+$(zUc4+iib^e%U(y?>H+IFfNaMC9MkEb zrhG*eLTau)Js4u7Hj(a_P$h0I#1^<5tzm ztbCDWD@wr4Xun?R9Mj*K;{Pd0<_b@B0)pwce%BfD$PKGZ_XGIoHNXQe#KE4fspyS2 z(tyypgu^?k0G2UdbN@K3`l#_x5k)ld(<-Y_N6RkH_d8u7B|9Qay{@eE?Vaiacg@J- ze|ui$0p7e@He`I>kubIJ4Pp$SQiYZEl%TC6$tL6A>;F;5u6c~(h4}Ja9iVT-75L`Z zTnCS~DB}jWb6<1Lp)sM{9!*S-gTKS?e{}1cMy?wK{_z5irctNOJX++_!A3BaN%@$Y z0i=gk$<6+G?2HK77>Nrk%fQK{VFLiEh3{9IpA6Qo!fLeXv2n8m-kJp@aX{ld5C%bx z7t-e4EhMEISHYo4Hk0=8z(g5C&_oF?L2=&iVvKnPK7(!EHtG(Zw~T2h(+>p<8MRVK zVe_>mu)*B>6VG+=)*VP{dl{pw$C&{zVMK^$-0)>RyI2z>e9b}6DJmTC)GJ7-IfqI7 zflR<>DN}_@_>r38Ubse+ffZ_DWy3LBHn{w90A0_n4EiTJAHv1^JFAvFjF?QN@zLmd}I-nLNwCBmYPFB&50L9LM7Khqffa8RjAVGW2m`{y55dhk77A;O@|4>|_ zwbUe2M5!Mq&ncchl6DIhs{6+zftmkfP{q7NjaBHWCV!E#M$I{ z^_H~yG8k&^PzE%oj7R8R3nFV7hwgZEYq0NjVt}K1>o=VOY3g_@ab39uz1npIoy*;| ztEkJ-I%-Y$2~fV@52Mg#o07s+>V|YyV2~L}&vE90!~zh<8%Jn&LK!k=x_g*bf=qe0 zfwnT^Gj}|?y|i!BSpWe1k0s1A|d5lQfsn>);zT1Zr)P2ldu0dQhbVBsNW#@=)Lxn;)W-+Q)xf72Ggxq+jG zvEQ!%!!Z(Qk_)0YKJvR<=g>i$Sc3XBHzh;U#?pXDyAr>AYFb!2Nt2s%^HM)<6zRoi z%9k2uWmA;Xvzrokm~O27%#v(Rqb>h+Q+a+r&>VD`R67st)XLwK1#k!UfXxLX87zQ# z;{sA+2N0WI^;Pm6Rc3dQ#4N_uy!9+VX0@fh7ic!FMgR_FFo8Hg!;;&fM1wn{-1#Cd zwP!5BNe14&)571B0z9;gqn0smGd2E=0HMZ3=8fG)V@sKwlC-!8pv6UPU}ke}%O+dL zrZ8;IH>clwYOM)0T{>Q;aM`=(Ca7TVGYq`_jz`Wu;M!NkYMVWT7X9T(s0MCEgks`Ljyz6G_!O_1>%91`hQFU^whNug(sLaMhuymVYxzLuNB z8e#R3g4+Z=OD%!M;cb$?>)f1@b~lrt zkzVk_Dztp-xkP?r=Z+dBmwq?r6hOPa_!JI*;Ni1J^v<~j0DyN-;s+#q)MGtMV9=cR zXW*(}`r@NG`6IO^9Rutx-TpTTM4Zmc)hkyAZ|UkUlGU#fM}ph1c@zdcm5%xANuRzc zwchkGH@025mwDq?sr_n;o=}M6D~;a!b^mBXg$dV8zME zR2v_Q$&8vwXYo~>IR`h@b6Jgi$sH4`h<(HfW18bMHtPDZ(dW*a@OR7t0KmH@@B>3K zK&s6W_|>j0f`82@JU-e%yu}hsy3H5cVu@U=L7R9jJ9h}eK3X2i-=(5@>(#GcOLyj= z6yVAM|AfPT_0jVy{IiY$)bSs(j0X)8d|a1^RsA3x1U*V|c;qp8U0L(pIIPEbrhELV zB8*An1H_G;i-REKy(zSo1a)5=1i|^Ko}P?aaeH$M=a5M6 zPHeM*rsBrm_kQTHSC8sSIHW)Q_wDw>&q;b!>F$?E5X z@Zqx!zjtv17EV}CzMk*>d8N97xvh^fJU?{c_|8MQ=iLGTz{5SvGjL~$!*A9SFxIyO zzMIGgQ+l=Qnt*?O?bE*>9d39DgT*z_U^Srv&#K;NaORL7^jSl`%x4!_i;Es=e>-<2v=Pe6JZ;$kF z=$(RjAB4is*NX}C1=kelsP1mjAkpV2SSINqv@P|A##lOpWAWcjt~=KgOH(#crO-Z| zftcjG3Ap#?9^ZJgh6^?b%-lZVDqNdZ0%*QoZu|+Qn=*=0a8f$}n#CngDgkHU*jyz} z6@Lg)fC8F50zM`IVpy7k@aKte=-?Au@6o%U72uH`=7FtSf(`2hnqbNCwl4F{H7Ko+iZ4CD|uA_fQ}Gw=og-Nb(s9~5(MUMe_6$xYM2odi4_2*yvf`3gafWQ5XOEFEr0RrA{fc-?W z-EHa)2sma4#|U_c2uFV7g$pl=Kko`~@%E!}GZ!zxMFqHcyQlycZ$GNH|33hG7~HDZ SV(}{g0000S^!lMyo6j7CaGfW;GQa$v<`ETQhcE=~w5iH;q6 z*bXRhT@9pj`sSL;%S&ZoiJ=^u0A@rY|?t{f2 zZ?Cs{elfuLOyG);yRH6-zp7TYSpVAOctDca6aX4NNPq&8IV(-9kZ#^F<3YU;zit8GvdgvaCkq-9 z%sy;;+V|yL@=39f5rEk$e|84|Q#l4Mov|j#VKe}cD}=K(NK^jpBjZ4zQ1v0N^-u4D`$3$zWK+s65PBYeHpMA}1TD+040rN>RT-Xxc}nxZ!a1>$c;(b;JE-X#kt@oL5D(CR8tU%vGK zi$obKbS8_90DPg3k==^CsqjY4w?DC3WIHN_D8dzrF=wp3c(W5p3Ug*WnknAK3l<&B zRNLdOBudB*^B@k%Q27U(c({hX%X}5)Ku@t6|4LVbRXs$}pjU&`6?1Jh{nZyj0GCIg z3qpKlXf0kzD?wGEYD-F$v{Vdl@K?}<(2>G5`iO-kXiEaMnRQ0=obhQ z3AynCqGbn!7zkoy`ItMBz{+1sb>;}>6y{vC=#MzQj@*~5K2x=v{6`%5unvz9@9)fmEZi(tT_{^CTOe`r7)F{(8dDl2 z8@JAvs`9FhDooug-Ep17FQ(c-bqc!t+B;v+f2LRKR^@5@)~3|9`yy5uRb^M{sv}t% zZ15C=V(?w{ySi+tX5m+}o$eu8Oe^vxKaSUq*wvBVaDf4)uanDxK5Si?Pt;v;Z>zo( ziOBM+@as2eU8UMeqV8n6-{pF#p&zhRWLyQuZV;Wb{$iypf1}#LYh&zKm7b9ftyZem ztXBN}O|b5?BCq_Le3!uk97lRsh1r-{(JpZcIqyJwS$n+#qk`o9ThZ$}t}4ee%Azhg z-(HuBv&{S+Q&_&LYsJRLZwLRVg1Db_o}B+xTq|NhQJSzAP*$;~$ixQ)++D?~xrbN( zXv&&=my#{BNVCY;4o~iw6)%}r_@sav?=WP%!?5E#D~L|_h;E!?>ov_ z%f(d1REH-gCW|K*vIKJ8@-FfnXE_ zL3IsHniOjDY8e;0YP%}%D>~Ft)T;9r?7lbrX&r6-(nj8}w}i4<*XrCFWMOAXYS%Vc z_x&v8TS`!8(5I)jsMt}#gq8r&$xo46=gMZVHxb2|Rc+*S#JFSG{ ztOE{t+BrWI?MUr9Jj1S{<6_>0j&o&5aOF@At&e=$Rq?uZH`(@|yUxpL%IQC?T&+J7 zJaagUS}T}%Q^1;U!0$QpeMELkb8l7>vmlMfakC~^T~-}#*K$D5ZN;6eU%S}QR_0rE zYjI90aUq

Znm?NSh^dlt`+@hfrv%DDszO!qxo||(2clpNx+HJF%(=0TO6-cgBgvDFE>IQ48ko?b=$%KL@66F{2DJ!0bav1qFQZ$t&j z7cK%0(R3-*Xf@%~3u!#IN|JcSOG0191dNaU)ctmJ+_QqS(Mz(%Y_HTVmDt| z7Wl|8$X~{>*AdSAC8=8#TXj80G@m5fht`?zt>`!2u+Pa!?lM)c->0P*#6vF7Wqz}lN!4Jt>%MBqqzIWRg4{CWcElslp68&*j6^@dG+d3{fxTc zZ%qF09pR>ZW1)R5AjjXBx)^&ALBH1)PfgUJ+yXhpI)%m9*cs94*VzGGVGJ8fD(0%jfWPa7C`}Rpt;7ZP--dw>bL7>*Nd7tAA22(Kd1aqAMVQS%C74$ zcI-Iw|JD*QMjC ztDaFmeqPhRdJm_4zH7eJ=OvrC>brroAuKQU_g}BIXDS|2$Wu~YAV`^4k5>GgtN-y$ zS}P^3_Wu0k;1pwf^P?nR{@mo0wa!4{6 z_TKRQw{dIRC%6T6Ddt%t)%+zDtM_hS34af&raIF&08N#XBGC1y$+Q-6f21e=oEGhI z(x^O8x1=)0R7S9)#gHM*m~1m92-3vl)EvMo9gwF*cS8n&$;?~Z)>fG%J0EV2dY)d{ zq9D29yUbVL?oSz=iv*>g2OhlP^ctr05gC?D<)|}qFI$p4gUdXjDDg~0%MtnWaj58%X`7+cuv9E}Di-4tT}6TjV9p2{BSBGh3zcu&DQ5`v(^Yz(2e(w}>Uv-oL1^*?F2bQD|-hje7Mh%1m z!mS@t1~EVxLy?LtoI!3UteMLS8p2>9{VPy|pbXyYnobJEPAzl{C$uAxU#)qZs?kkV z%VhfehB?*G6$8$Y;jDwSDF%GXRc$!u?ca zn~=73;j$f_wq>IUd#D=}2DKrPrLmYe&uhP}%D|A?O+~OPQPC4Q7kZBbDwF{-=pz_C zCm4H#1vH!sQg^kow)3RUR-G~5rHIgJV@t?n*`$-?Q|Z!Y6xGoaI>3)xhHEN_Yq)o* zQv2-Ymo09MXkp~|)M7Er)QFFD+CT=1DC6vkExJLe2E&9%yp(9uP$Lm1A;a<9vt)y+ zH>2B_DXTQD_$Htam7cw!TehiQ_1Sr-+Ys&&)PoBC@@1kM=E)u@fb ztn-D1?+|QMHricifVAGBL{Zw0G)O|B3>X(|%H~j_csLkb{HtkG&rAuK4I3Ul6m)ykyfP)ebLrR*w-wHx( zSczEU(JM46J|RgHIDDP04E!d+AiMtT*`ovB_*T$Q#((y@9}Uw?<;)YgzkGbom~t>p z*Nue&U+TuP$;77SZ) zz$^q$mY}>Hi0Mj+qZ;!*$Ak&jxN2$g67JjuSS|y+%4d2xzg}&x(o9QRY0(d0BY>!H#|l_6XOgUJZ=h*cnIFw z)h%jtVC=Y}9`{`qL>!U_4T zokhbR?_V{hyViz{1*+&VNB>L~=aMy#1|G-c5tq_iby4xlG|d=1xmmr$AV$jV5@2ki zJxl?q{SUpKpSuP$dvk)TD|+^OyQP7CD5W#8`|NPBLElR|XlJ6mCsb(L(^w0vk>+LGVJ+csot<}8GjVwTp(og;VrFu6Lih^mU za9rqn(v^Uh9|+^c7u=t+R{>}d53K0NyJohqMkXjWtd<-@OCSvvQF6O3NgAr3b^UT# zy{|WtWilTtm&7)sNX!aaCb-%4L_C{F*$qKTems=)>*;;xs1w`AxHxrmBji`GNqg5M zq-|rtmCuoe()|vshl{is%wVxn2BVjDt8ZZNK+>g_#Ir@2ii8D_VlR8RI7m{BvAHn4|#FWrUMw9j~@Y1^sezl}hK+x|?nlZA7 zXWNC)55Wqw>iTmPp>(^ll53Ue>Fhj3>NHi*JcnAG5Tl3Gd9tY;ph@3SCoDn~%#?

~sljPw*DQJ!P7qH^5hf)8U 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 NWqCEZIvMlO{{u#2^`-y- diff --git a/02-particle-system/assets/Asteroids_128x128_005.png b/02-particle-system/assets/Asteroids_128x128_005.png deleted file mode 100644 index 5babd25298b89940db3d1624b325e1a6ed1808f4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 17904 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 diff --git a/02-particle-system/assets/Asteroids_128x128_006.png b/02-particle-system/assets/Asteroids_128x128_006.png deleted file mode 100644 index e1e989211b46c849045c4eaecdd648522833b467..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 15040 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 diff --git a/02-particle-system/assets/Asteroids_128x128_007.png b/02-particle-system/assets/Asteroids_128x128_007.png deleted file mode 100644 index 4efbb54fcdc9bf540d00ff46139ccfa9d1846eff..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 15697 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 JPDHLkV1mwX?(+Zu diff --git a/02-particle-system/assets/Asteroids_256x256_002.png b/02-particle-system/assets/Asteroids_256x256_002.png deleted file mode 100644 index 03d0a2d0f97f020b07c87167ddab2a9029aed457..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 36264 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

dsy9=_uJ_i-ks1h+Nfxvr&_i0ib-QGV)d4l+` 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 FV1gK~#u5Mk diff --git a/02-particle-system/assets/Asteroids_256x256_005.png b/02-particle-system/assets/Asteroids_256x256_005.png deleted file mode 100644 index 56261dd3624457d37ad5d164dcddf15db2204d22..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 51001 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 A$^ZZW diff --git a/02-particle-system/assets/Asteroids_256x256_007.png b/02-particle-system/assets/Asteroids_256x256_007.png deleted file mode 100644 index b4d1da908a1815c2d76e4c25aa0e2c897ecbb4ae..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 44044 zcmV)KLZ*U+IBfRsybQWXdwQbLP>6pAqfylh#{fb6;Z(vMMVS~$e@S=j*ftg6;Uhf59&ghTmgWD0l;*T zI709Y^p6lP1rIRMx#05C~cW=H_Aw*bJ-5DT&Z2n+x)QHX^p z00esgV8|mQcmRZ%02D^@S3L16t`O%c004NIvOKvYIYoh62rY33S640`D9%Y2D-rV&neh&#Q1i z007~1e$oCcFS8neI|hJl{-P!B1ZZ9hpmq0)X0i`JwE&>$+E?>%_LC6RbVIkUx0b+_+BaR3cnT7Zv!AJxW zizFb)h!jyGOOZ85F;a?DAXP{m@;!0_IfqH8(HlgRxt7s3}k3K`kFu>>-2Q$QMFfPW!La{h336o>X zu_CMttHv6zR;&ZNiS=X8v3CR#fknUxHUxJ0uoBa_M6WNWeqIg~6QE69c9o#eyhGvpiOA@W-aonk<7r1(?fC{oI5N*U!4 zfg=2N-7=cNnjjOr{yriy6mMFgG#l znCF=fnQv8CDz++o6_Lscl}eQ+l^ZHARH>?_s@|##Rr6KLRFA1%Q+=*RRWnoLsR`7U zt5vFIcfW3@?wFpwUVxrVZ>QdQz32KIeJ}k~{cZZE^+ya? z2D1z#2HOnI7(B%_ac?{wFUQ;QQA1tBKtrWrm0_3Rgps+?Jfqb{jYbcQX~taRB;#$y zZN{S}1|}gUOHJxc?wV3fxuz+mJ4`!F$IZ;mqRrNsHJd##*D~ju=bP7?-?v~|cv>vB zsJ6IeNwVZxrdjT`yl#bBIa#GxRa#xMMy;K#CDyyGyQdMSxlWT#tDe?p!?5wT$+oGt z8L;Kp2HUQ-ZMJ=3XJQv;x5ci*?vuTfeY$;({XGW_huIFR9a(?@3)XSs8O^N5RyOM=TTmp(3=8^+zpz2r)C z^>JO{deZfso3oq3?Wo(Y?l$ge?uXo;%ru`Vo>?<<(8I_>;8Eq#KMS9gFl*neeosSB zfoHYnBQIkwkyowPu(zdms`p{<7e4kra-ZWq<2*OsGTvEV%s0Td$hXT+!*8Bnh2KMe zBmZRodjHV?r+_5^X9J0WL4jKW`}lf%A-|44I@@LTvf1rHjG(ze6+w@Jt%Bvjts!X0 z?2xS?_ve_-kiKB_KiJlZ$9G`c^=E@oNG)mWWaNo-3TIW8)$Hg0Ub-~8?KhvJ>$ z3*&nim@mj(aCxE5!t{lw7O5^0EIO7zOo&c6l<+|iDySBWCGrz@C5{St!X3hAA}`T4 z(TLbXTq+(;@<=L8dXnssyft|w#WSTW<++3>sgS%(4NTpeI-VAqb|7ssJvzNHgOZVu zaYCvgO_R1~>SyL=cFU|~g|hy|Zi}}s9+d~lYqOB71z9Z$wnC=pR9Yz4DhIM>Wmjgu z&56o6maCpC&F##y%G;1PobR9i?GnNg;gYtchD%p19a!eQtZF&3JaKv33gZ<8D~47E ztUS1iwkmDaPpj=$m#%)jCVEY4fnLGNg2A-`YwHVD3gv};>)hAvT~AmqS>Lr``i7kw zJ{5_It`yrBmlc25DBO7E8;5VoznR>Ww5hAaxn$2~(q`%A-YuS64wkBy=9dm`4cXeX z4c}I@?e+FW+b@^RDBHV(wnMq2zdX3SWv9u`%{xC-q*U}&`cyXV(%rRT*Z6MH?i+i& z_B8C(+grT%{XWUQ+f@NoP1R=AW&26{v-dx)iK^-Nmiuj8txj!m?Z*Ss1N{dh4z}01 z)YTo*JycSU)+_5r4#yw9{+;i4Ee$peRgIj+;v;ZGdF1K$3E%e~4LaI(jC-u%2h$&R z9cLXcYC@Xwnns&bn)_Q~Te?roKGD|d-g^8;+aC{{G(1^(O7m37Y1-+6)01cN&y1aw zoqc{T`P^XJqPBbIW6s}d4{z_f5Om?vMgNQEJG?v2T=KYd^0M3I6IZxbny)%vZR&LD zJpPl@Psh8QyPB@KTx+@RdcC!KX7}kEo;S|j^u2lU7XQ}Oo;f|;z4Ll+_r>@1-xl3| zawq-H%e&ckC+@AhPrP6BKT#_XdT7&;F71j}Joy zkC~6lh7E@6o;W@^IpRNZ{ptLtL(gQ-CY~4mqW;US7Zxvm_|@yz&e53Bp_lTPlfP|z zrTyx_>lv@x#=^!PzR7qqF<$gm`|ZJZ+;<)Cqu&ot2z=0000WV@Og>004R=004l4008;_004mL004C`008P>0026e000+nl3&F} z005ykNkl~DU*_chj9wvX*&`?xfZV*36@GU*Y%X#33vJpV)Q;+YaCbIo`{^I^=5C!|tYA-M@3kmn>kgM=dOUj=z57 zxqeOW<5P!&e;xv}7#Y?(@@A%)p>+|~J{H`ge%;4D!_Oa!ALS?cH;Wc~uf^Wp7&*ew zZPpQl-!CX5_{er?ug@LD!qZxVbcjbjRgQLy~9NjkeZ3i%^;U6~e z0gJg)Ubu$yaRRl0H%1;h02ACxx&_4V5x&LzOu| z>J)79pLV-+2IW@DgeBmP&-1|}+a|y50NM=yPT)f>#daoRI6o&48@Unx)sI_5zq7&L zBK{v6vow06Ivs+?)6G1MFy^>zI}_M;0JY&C0zOtZ^m0k^Bu>CY z>3tR3wK~5LDZY&HX@4NC?ZZb*djKV+Gm28=6E=CxHtI>_$^hG1Fj(dN%UOTph_n)5 z+!R1Y_`EYHDJRVemYfsV?g?DV4&c4~tB(SA>&8C06EKRw=hA*M^}mUnfi&}?wc%&I zk(56ArA0x$4>8ui=f^D^mgz8g_4Sn*Sv;gi(+^1h{79>@&92Ir%GjO6tn1KzMb z9Y`HO_Yz3=4*~a*fuh=s6L9l;Y|_XplE`lSziY!Ql1OjPD+6eLE-5J)QBt-#i>BXT zmG+>?H0bPH^K#Z_NetgRwa9Od=QK$Zh2(H~bD zgtteI;3J>sgCF0{04@Os@LqoPUf|Bj=Hamu2ow22iSi~f{3hzf*?>`W73vrOs)tV^q915dB} zwag&*ee(L>ctdUqghHw74KQNFkdk2(hdYr$ThYaj`~OCX`Y4@)@Rri|9!j4X)Y*Xv z9DxZ;+88JbL(wr{-0j9<3}7v`l;whPt^-l~o4^4W?_Mk=h5PhM|8L_QfpL#!u#}4y z`!V3I?d1Pum;pHBe?YJI&DhA6kM`|`uQvgUr0XuT1d~MF5d&|`CTjfE-%I+z{frX5 zjZz@wz(ji5Z_!+*Y>N_A^tjBR2(m-%>JU z#6UO>i4H6o(4%xEfl1Qu(3FcHikHc>J#6NomML)=6aK7qNt#Eqj2KZ;P`KU!-f0+P z{S3pF7E>7EEW+lWmiFVDf?-x*d_xe|9IYQo%LsyI;oaL=z{@BDsEj|1{ANt0pGN&c zF?ucS*Gq%;^xq`WxoM4!7$5;RCWx+<5j}Sw6euxK!?14tl_En(%a3?s5XOF^U=R@J zNoF@z#CrnwQ_yLgM`1Bt*#xXEKtnl%azqvutf2y%_ZvI8GLsRAQQ?xs-tgP}mzP{G z;ANQsSopLNX@6VYZzIDlf{VLx2qe)jG<=l%=_o*w`a6u4!>C(sd=wkeXGl+JAWEYz z{ghx7wGy>vV~Q#?YUyCm*NhqfPVEYe>p76L7_EPO1s#knpma^Z+WlEeSz2sqyaO_% zy#Nvy5IUJ^4WrHK*|!s zxJZxRBM6(1&YtlVHBFbbM82#W<1j5m$I29&<>2bPZexyDeq zX6uKx9l%Sx1o#Q=yA!xq;^y^~zrLV{^ck>DhiPWn?b6gq>;EE1hl%bBi2KCGT}AmJ zJ)fS($@hSDMvT-bY%q)%dR#!5!s}7pWX?lc1~plTw!4tqAV`aZ=D&^r@`UX|Fc{OV z^HJi>LK8Rvn`|9QWZ-~JmUw~@0~XlF9E;J^AjSkV&A`g@m_0c@hV2sI;y3<7ROqhY zV#~*UC@9?}1BMX;N=EGBzywjh7*pSm`(C}qVNlD5Mp`nW&stQ0hoiv}1A0myLu=l} z^LP`q>Wr8j80ACUFj0jxZS@Dg1jYpwVPjm+=#LTs9D+3!2|| z-0wrsPu-^}lGNV_Sg@tfx_AW}oMVO^K{GJy5!7XXaEiBX_W)j+iOk*FxG!`9DD{1Z zDRIGe=sKe-#QeT7h$7S6%a8x!?^WdQsVRA%RhQ1EF?L9wA^ofYH}P?#P8hUx;S3{D zw4zM5pOEGz<1>lI(8I?J`vav%7D^xy9&+7e0Ht>xRmDH$KvUJD&a)Ue4&$c*;W;Zr zf1o_H-2-@u^#Fc?dk+B*=2KTAy8CrXUw8O7Sz$<@f`U2r&}F8j2N19H7Uz-n_k?NJ z$!VXp$oP$K@D14vmVQ#sfN+5(zfYjW=|b5@NS#MJK}qZ!torwHBi1O;Vfp(`;KnWK zGE)i{-eiSSdMBt+FX7djRp~poQB$#qCEf)gHi0(E&VwAm}tom%nHM_Y?}U zPpkix?tc+v0oGKbEl?dm-K2_Z{*ny+PfVMiU@d<>EpkA`F*pGjT+ds1H04{O| z@E-oO4Z4;hLFeun$+-0lHfq|ra@ z{HM6}LIL#@{t`h2{piiV!~t|FqpwQ#H~ULnqB z1EM!@pT&OUQ{1t%T>@Mb#{a(`0zM7q;P`sK5DljWqh5-L*I~+e|8B6~u8;hRt}6kI zap%XS)}_IY42-JVMhqGG&V2)F>9OL$JK<=s&l)MF-?;mhE$Mx{+FN8se|m$kt$dJu z0;AUddA`EjM8HHGMH-GEoB|+5c+xc>`UDooE#RQVjA0ViK|+!@z}@Cbg4>U7JAfD8 z_#eQt`k0BDeKjB@WYm$aqoB(S9j2IKjtrkoBs(jdnn zjJF-9fZ`NP79(J?o&T7pFx@dI#6YhdR!q`Eku1aR@e51QaZaE%smR!?V zOf$_Kv+QD;`D7|U&rJD5k8Z8MC(f8jUQYfyG)m z1sE}4NZ+qmmkfP?u%htj(xK~i8ocwk&r-hR`vNZs2T&P*-SCTnBz04-@bI4c=hE%N zHy_T12)_UuY?JVznfz*y|bsW}=>ehBU}=3*>}TOw_N@oNW=&tJ+|+7c@dmFhnd0Oi@snqMF>8IxyIP zKQT=8JAQ;%1Um~A9qYhd3nMpL>|ij548?=*e|iXbpwhj!N{2ax-5M3MUqqmu z)Yy&RLhA&#*NZ!SQIF?#^DATTi~Crh&xSCb>bCX7z(xt1?_`G=>l*amYvdz2hZ0xr zu{+2=gHb*=)Y3!C>QEbwDRR^IeQe>Hut87Axciub!WdEJHP=BWFlfyo)Y(Ak%LIaJ zr=VCgm=C_NW32|vFx~Q{lY2Za<!BaJB8=%T2#RMD@adz`1?^Nj6}TJ@W9fEnV&2 zr2d9pkmlEh8Y5JHmEtg*h2`Ploo|K4o}uw~=_CwBsO zhQm7DsME_O9YYmr%3ow}D93^>SukGH?*!F!dh<@ZT`?FI)HvZA(s& za|O1w8qb?{8)jdR?0OSXr#vSc?c2E&3YCUkUK7dI=BU69s=W+5G}uvr9o6MPWz3z{ zdO!SL_@Cn*kx@%W?*#6ADLR4fi)j3A+!yoL7oy=8kCO7^x!jn`MpI=;GZp^c1Rp*s zAx4AN3oqvi0xX|@z(!=CHh=_&zscd^KuUL+7L!ML-0B`1oTbOvsZ5!8MmqI1?x$q14)0+vq&n zXsa-coMjYAOUgUn$NhYY+waaOad83kAZ={VXVu~kjaW(`sw_?_e%oaIqgd4{um zckE{|$6j`E4VUpsuHf~|vu{kRP`|~hH9nwxOHyXp~GL_2rUp z-UxNsdPY3u7KCy=_y)#X9eo$+!#G|?f61UfQhM!nOnq<1IEd=@B_87$9^@q76htJG z92=ZrgEKtKSNR6N&MvOuM&8L49CEN|GHJfexP{5I3DVCjq&Y7j;y^IM3FxJZR7;cy z2Aenl{B!6TLTDsYL6dk=C-7-L#T^&D6L`U)z(2zOdOMg;%M{KeAf1p=HYV{%`@#h% zf*oOcZxu*zxH1ZcF4Igg&om2yEVQZpQ;fhGr$xhU5vyHZa=*L z5|43=BP?+&(*els+^6Ry?mJ8|&yBp38+jMgEMyvTMAMi&pFsNvQ7FZhkX@Y}Ziv{EBAe(4OQBe;dX#Pz&2Ys4ut5MyN0Q|Dk6bfV6L zWW|)j2&b0zbu>Nz=>Tf5Pq;_Yh_6)F#k5}xYSzprb^>>OiaYMRSRKF%T>|*+zHq#U z5)Wh}tQf;so7R&dI>0K8Koh9URbAmJrkJJ3oRUTcOY-a-c3c%)PE0 zxQ~nQc)>D&ck}-~OhxP=#yW*q%rQzNG9nEtyrPUz)`5!_LQ5_6HGcD}!?c?d7r|dQ z(};STEKEt)I3=F1-v19Td&vg?F{4jP+<~e+2=FkUI+D3CGfe)Ibpz?oD<#adgYX?q01~NRwy<>U*W6# zYgTzyDV1X9S4@xr04kqeZ2V=!NL)FAH}W^Ritihn>QBN?z!)~-GMLmrUW}Zm6o^ZJ zCP&lK_E93MF82^)!`GaEBprzzKuNh|DR28U?>l-iIe-@g2=s3L@kfD!Da^OIgqr>A zGMZ#tC#5~0&zj@c8$<)491vB5f>ta*RccrB0v3vcFj0Ch>(P;b_|~t#jABullpoqs zO}r5pUgSf1Jmic&d>`RLQ|-h;bX$mgGjzpQA<%FV9cPrsZ*UP+N$@B9V;<)Z$ZZ6s z!^w2f$ExQ$bq0lSkhGu!Q@n^q^Ik;fu)Zd$@$WQUX6Q2QCP5v>F;E#5L>3}UJ(y_G zU>>-GUq5&;l>pDX19%soIB2mSO2xZG=(Ca}rl?K;b*bhX{2FV{_~lZIG}Ok}I|0>o z^K(dm8ae`f9aj62hWHTwh9w?vMGWXdqB5fAw4F#)nQ}_RZ4Jq`mEZoCIt``N`c?BW`BbA3X`eTHxIO+J-G{+t8Q6pnN!pqAhFpVx4h|1sFp94A{g`PeX&S+maJ66B3mg;iPQy_Oj@AzD<0bd5n& zW?}2kOR4k)!t+)(=kep8=4W1TjKB-p1pHw>_5hf}&AdM)@@#pj(S<7A!8G&CvB%SS z>pFjJo$9y~AO5?DX8UV|Y`uNf15W>{*%vwl<0!!DhTuA9IK~%P=T!FHE^s-!xsF|2 z#~i!)8vkF0^hC)rnG?_^0-AHRik4n{@s7mzrb|8&PWuq==Vsm$e72GnJT>&9bvmFq zFYB7AO-@*w>GLAYcix40_l=>A6^y6t*1W1ay&6%?Z>$SG41mNKA+yu@Icg63b}GVsHC2 zKXdfOasba~6Y%bo?=HszTPV~IG5oiPRz(Z7#l%E4f76*i$#+=dNtSqmlRTW`3Xk`GjX^sQj$}Rk5_Hg3_#-Eax%5~?C=xC=6!LI)1G;#nuF;i zj;5Xre4SrcyZia}s!_h@t`Ss1(mXez#&XogG(<}VS)kFAkz9+_Z$=E+WQBFku*ykR zIKeW{u)+y8S;8_31K}c=d+*@aUbLp*^U?%-C;!jG7JImT$p`Xu(lQe;g2KCSv9TMp za)6el+Oz>yi*l|q@I)R}YTsj-8FmXd5YL;-ps`f_dm!3CP1G>K^Htxc*~u&U3C{8; zkMsLpFjRMnxi76Gh#f|I24I3_msJplS~g|^muG|e9NK|#@Hzy>|m7_#ZWW;0AP@1Vco-xm?BTgX#fc(78B z4K_K)Cad&WV?^KS4~zio^e5(-XAfOw>L%eKTj^iCD2qeI^B4W)2X7U`m-Oekd8*bt ztj9Kma1%}Cna&c@;ad$xik(eYJVLy~Ukb3N?2I?BLdT_ruW1iA@Ou6lSMkPdw997! zT0fu@MfWfRkl8?y+_x?AcNBKsLha-H1;5#9@No}9i_z&6M^`dJL4IhA#WABp-LF~Z zX-;#DGaTbAPjHg&aDs1gl7~6RaS!QE$w*LpEkk0*vE8!~ByjpQIJ44f+`K9OO0*@c|b(i3~q~F7nxcMs3vz06^Uc zB-ByLh$5Q*7b-R*&fFg5OSDmy6XY7>N`mx0+TMs(0>tCUPz8BJk7ZUk!78WdvC4o= z25i!2opqKt%M+a95zg?qhknPngcz$(6@@)7`qE%7DvUw%z2lf8SJ-6P?G@C^aD40z ze(lgpx&*k5|K*Uy-mNk8n3lP)iE3XxTGVa3j$7L4sFA)9e^+Gs0?jJUB3HA>HR5?q z@<=vVI}L#>I;W3~G7+n!rA45jx4;1oaVKBqpE}@>QP!V}Osb!63dZZqY5H&6ze2N2 zc@&IagsB%?O21YUP6Gz4@g#rBHM}Xx{w!@gghr5x)UP7eHjIlgqkImC_aL9!IwL>l z47=kRzBU4Q4cK4_OG$?gi(DIAYem8bQ8Pr>0wQ%2IX~5^a3vK!WCzpCyLVeGTFQHY zH@xIBfW!RHcOK?{c@TII>|qJy)sk~9FGw3Uh2UYUPHvYOKl{%?KyvUCJ*ub8r*PU( zmjK~XN$vyI|JByiYQFbbrYEok>3VZ}Zy;X|Nc3Mf)A-YR3aQ?L_Ikpzd6I9me#*J7 z3=;u}^j=P$xKtBovF&8E=l9SZ{MtufG8w>O{?Q>SUcbYk2iJSB8i$XCET??jyDfqg)-awK&m^rYlkv+% z_5w^VztABV-y^W-^j$IbER0xk38;eA=JxBgj&yE9&`CBdHRG|Fre70jOUH-T%)?C( z0juAo&A=0UU0D;(rTXKVwpKw%nn;R8Zz>X<@tVuA<5zpz9ds@3+GCY@_5@+9h(JiS zV!%{1xYlqNafm5>lQGD$?!JRxyZ_Vt?9q$b0lb5McqiD8g}i>Tr>-H9n%~Zwu*rDb zB1+SBl1!7702+@R6TFVLC~pH(DU}KPC~*ijN>{50+?h`zQx#$yRH$)P0kPM2F^9 z>9!8NymLt85W+2o5%#)KhBbl#C%8xo=uBHW)0Sc?M$5Ik0urjq0?AJ&?`H%o7RN1k z0x~?u`gc7`nAG^=5=(;+>mxWrPQ;`>`m8JKz*;J-)%K<(JT#VHJ8RRa90BN(CnjJT zu50{uCom;$ulr3#)hw(_)7qe?DT2q5y@0w0Fy-mzraTFa27cr2+xZXA`&3{{CBWPH z2e(`7$K)nk4ARiYKP2NIGbT!eBoHGHS82w31L2nm7L1^9iEFJk({%~$h!Hj*{|I{F z1}F>|D6GXA6IgEe`U}zZ*RTY##Awcvp5)d-qnlA$p5LWsY*gOLQJ=dqO7X+*WWJlE z7hjhF*Yaj1K{u^~;dZs+AnF@;FXOJ1!eGjp72GCF4x!MC*;27rGR15F4<{%Cntni4 z=63uhAQ34^n)yJ7DW;hBTZ07KiA~>S^fBPJiy{MfJO9&S#pRzOtiy|2kLZ&%*y4+% z+OZn=G0TWPLpB-F4@ew`F3Jy_LeCKEqJ8}pW(|m~w;)Peux0gC2D~0dydLOygAX+Y z^d^snPSBK(+oU+Of90|PGf`tL_X(H@(r(kzogXh^+V;2Y>P0fdd-qpVyDP>GO>_i- z@eZI9P|JmxKqturrs*=pG&`7KXV7?-!sgO}b{qnrnJ#oh>ObWHY*WlJ$8M&W9mhLx z_;&uoofk_9@Ucq0*D6UbiJG1rW8`EDh>*9f@4gQhvKgfP0}s3iYkeE=z16qZ&I4Z% z3<=i8Q3Z?~qJGsoKnb^sWcfdKMCau&R<6MfF z$m!eUyHRd88lJ>x8cv!MDEyv8>;$^P2~-9=#Vm8|VwT-rv#_lU2ph2BIIt^9fr@x` zmYqzq!<83Biwvp(_}EYL?-yUx65wsza}eyEafj7L(p4tu>K0>kZ}i(k0*-2Pu1<;u z(d>ETQ}RME+lFJtI^rAOp|yT|*A>E1*5V|ktco5mg03r^XcR$z!2}f2@gOiBQ|ZQK z(d9we@@-o=Y~sZ9Bz7y$X^5HoX?dr4$6`|ag$X7-?gU%$xyRR7;n#>$=4YG4#ezBJ z+3UnnOtj*x1DO$Iw;e29EY{JA5-<==duCywb{y=x7%yOE7cHZ^f#-!gV8RT*-kn|& z8p)N7a9UPOZ*xtv@btV=ppv`;S{KBs|4OM+CYd<2nZC}cpBjgq&;gkV9E}~@_)Q+iIcWb$ z*{XJ{%eOG}=@v$V^USh~8Fu(( zBQ4@-X&|hd>bV(@nFsEW<{k zPy_`=2Se%c*w#Z|GV9*6W`H)EDoYwG+bT8M?gH!t z-^n_i@C@(apc4IUOY;w9DkK|>!eP|W-Ws9$7B*btJkunFL>*;2t}9=~{VFzBWkCoV zZ~nUQp(=eR4Ru&2=sj4mG+v6$Rv99TAg>l#0G82%KgGZOgk|*c{~!Ow(hHUWyp_8T zTkK+6a+trYVt0|&dErLg$VKF#6W45-eWj21sQm&P{jA4Rl*HbE&jcj*AY#4|K3az< zaj$snr}qR97>0PIWd~Pe&1(_^MQLnKX8NTdz0iz)yaSTQG&{EBg6u>M;-*QA%4EW4Rux5MWbQ6Mv8CNpGYX;Nr4kcs}SS->LImhGcI z!LNS!1uOw-n6J%Lh~vyZm!QW3m!UWQdS5%_T8oXo{rS`TXngV^&n@D`L zBN8d=F9bVg6ck3I+5u=^?Z#h9oHql#)ZNV=sdF*n7C|!5`ya z9(vv#fW_WwlX_oYl+^}aI(tX@GF@k41( z3I3Be{jvooF$qc}Y|+}WjmPoS?jf9>P=?(_rp=7ysnEoIrOn z2Vf#2%27PU8*nI$JtpzMaih;huwN6g^9|{9hVO8ihgs*ecqO~IhRb**2e^eP$L(FH7%`^OGSJD%WAc$Tm6W`2=t95lGy4cH``BwJFMgh<3D zsEg(^t`Mc0!pKdgQ(-gnhcu%#$+aHx3fG*4Mz9h|wxS*@JkD1r88Xd0S8|Imd?~0S zF$41Px$|B83ZLhLcRi;Lz$TaO_@pf!@5PP5=F#fG$Ph`bRT8f9hMxBs9^?eypk(M! zS2H3~tnf6;JjE0I5!dlHuHgrg=%20++awQ&sU%}&o33*JO$IQX@a|N^52fl*t4Orz zRCTKNb~)d}!+b6Y=@1iq-@s}ROC_C8W^Z@dGfwU)3j_u0yS>yNlpSgxN@fQAD zX4o+XKVU?#prxUy1smCLv@TWeD>zjn8qhVQeB{7pRfblgF%ZRRdCk9ovV|b^BBj_# zbv=L6U-y01ILFg0a*fC!>TAIWMxv0Aw0{24mYu+aB|yrzuC;Vzq|M)_`Txipei_Is zYYjgGJkB5Tj8oa^Fh|#YO)*c`f6dWhh7m))%NKZ<&#An)aam)ch>-%E53B>e$R{DwQ<#jkwyxdZ}zsTu{w zX#XbGhY{Z@tbRF|P8sR9ukaLSd6Zce*}(x8IN;yl#`JNZFA#1fA>rrk$5&36PhK-C-g zhg{2>`9VG$WCI#Zj6hT)1mI{e>Bd0&tTUkJ)8p`H8h4wKVHavjuL0NMY(Pfpy0{Ml(GSFN2 z?{5e5X+$!t%Y5m|srsfl8{YGhP;6fu!kFbgRWT)3BejM-<$N{o2-hyZY5W~CO+T|&I+`D=`@X{Mnc0Z zJHsw^uwOKYzQu3w7=IY>`Ndp+IuR%efCNPwP&xr^tf*xcWso^YWuR#mxSfCI06<0H z;HnH~iN`q0F_t*SS&s26f6g=uyp@k|9Y2^vu@JXU6cNjac&@pY2J~191Wxf~W{)+e zC~eV}p2F(Abj{fir*D!$p;4}X6!28Y|IoZA8%dL`a*|D!*~#T}nU18y${;g~Gqs_Z zp4I<$#}aVE=lS4LjGx$&18`2@Y)$vXmkUcsa6?`#B2Kqr#ta@cjUhh{r6C{3b-%s2b`BQ zn1%b>25s%P+syPoOj^sN>R(_#H}hWh@`^y`e#%Av8OP`{>-zxpm&_8HGGUV?R(VF* zO-n08qu>IphX99sZXJJHeg7^qqPz%!L;7+LtaDam98=8mdj4uQHJ40C;a4;ED}&Kr z94TycL8Xy>Gyz_qLH$+6A2u6DK^?6XRhC6=m z;aSJ%8`FOG>9N8(XW3-cm2Bmhv80J=^mvM3lD>cxFKtl%RgYm5IU{_tFy$K1vJM?n zVA6%@JKx2x9KKK>5WqdL`I;7hZyq*m1p>fiw$SQH`V@0+bE@!^)(yeJG#zH?Fy}IZ zIrr}wPsCsXfd(*~wW{O_rTJRTIgt z;8t$nu$qSJUqjWX%V7R*MRRbd-~-YWU;B<%XkOqQ{9lQw%xd~=y#;Ku+_|#5RH}%M z=FtYMb0*ShELr6gYn+PMo2#s9gR}Hl4yHFcf<-F(O4;vHXhUQ;3P5mA5Sekk?V67G ztY{D#HT!8}gDSKR+}#)K0RDu3cns`)HVd#R9a?HrjpkYeu$ftc6?poB4bCQn3!x(j zrN4{7@MZm6dCpayCR8klD#&<1{^1gsfYbY1E~_z>&Wp+FsHU`TC zLX3CN8d%9>cMsYXuoW7X!);l>Rv3ZqG1w)mi~)PBcqrv&Aa-dJ7Mw7eLffiqEucUa z8KrtVubLY=2K>mSC%Vb$GOJZ0l{Dq9P=2XyonayB5f{OjFr zZXD__bQ)bRRVK55xX@_GC3Qsm21{&mPB^$37I-Uvn=3gaj6XKm$uodaCIgU8#3tQ- z-S|UbOJ$goMtz&f{qnmbmGQ5NM&BBz*knoEx5p}LzB~xi@`@X>s?kTnR896-HRX!& zROD9WehkNek|-z55XNyc>iYy42XOnl_?3efngLMh0OX-UVYF*o#nl0wX`xWX(Ot->>$0&xZq1Bse$fAxxYa5?Yhm)XmWqGNA?P0qEJf9(V( zDJ~?w2LQ=HHouNcwhdWmS~dssZeR?HQB=2+ z^f4l&pH$hpw~rx~a(QONfDT<2 zxlTz*hYsx1bI7Z3{MUEClNY|l@)&=}WBj2=XY-_6R$-}Wnt^r154-w12jX&Aw8;a(i)J7O(djO?y6mrAuTHeHa_yl{o zkyweh&x%L5G1mC=eIZ0W9p+&}kzLe~@4A_19S&fXlZl-B&@o9{g%GCQXmh_ctS<@eo8dFa+?3r6lS3WgC5VBj3VKwR|ojQ$(k&v72)wcNoxdjofrIw_Oj z&70HOW!7O78hFVpJK1pQX#Mvy>_RetLn*6`9h2xoj&L#**O0T%>b`x}m|+Lk@B_}E zYjj@?@Y!&C+Tqux`+YBP1S4+dJ-maz$7{Kr9US1>{5HpVP`o~E1Q#TD|G&T(#c5pdwLT7?S#)*QI2Ab08q|1l7Vq=FGj7VT!BKuSFn*I{Na>>#kO;Sz2{JK`=0@EX(8q!qUdY4eodLXwzk4{` zxH1aabs-|YP2#^5dr*}Tm5eAT82JcL`g*R%IZCeJdfv)uzRfzPM21kfjld>Wlu;H? zIe^_<&1-nCyKo8)aEmvlkornu1mXo#S=bnt_VF`Q0de`EPX!{!eCvgj00&c=PZKoAjGFdqzF#g; z6kcY#pzA;IIwqgvNiOHrypEse&-iDI*z~j6QegOr)PgGG-^JCujlYed!y2ce+TJGU z1QQ9KrR9JT@1x__f}0O-mYr;JP9(ckd2o(+siQ-e5yPl|EV+bNc$yw7?BkVg0;X_-_C>$u~H`H+Yt>v&1nErOq`T_izJyxse0h!U0~#4h|^LSA-GvI2SYl$;zUq z&R?7Kr22vN^$=2v4d}U2!1yS?&KdD|12$bTRAe!Isf?XvGO6_Hjj`)6F#hdv>y3BHxV~iO12AoX0OTqe6 zBpHAa3<2RqT`g}6MG9K?L>khM>cf~}Cq0&<7HB0lRt79G+R--u3m+?w;CSt3cOPiDfb?3(>jb{_siBU*U;%J}t z18fq+&(i@|>^qDAyxIs-Ym%0R7V$}%fc3{-E2VUu0#H*~u5tpf9N-q-&VR=f{4tO4 z1OVgRQ{oZ)Vux z>+EJHpm3y_>*6`;MUs)zKuAe08e==l<1F(uySbX(T;p~fa$~FN|5xz37UR|(fbouJ zgLO{3#iSxB{aUV zckT;B(8R{d+LslLwf7`wQp)p%pm8*ftidkk3T+k6gyc`jp~%QAVwWMxG?8ww%N z^6#t3KuRl?M*sZwq<(B61K^-ZntG^4PL#N$P9UzO>($nguZgSLdMNk+`)u$GU*k02 zWj9x`i>tVt@8K%m;OfF^UVMh{vc_p2^&3YLrdMT#WFn6GBL-|bme>u)0z33`aznv7 zXIWsc0|OPorh1ndcCzU@*^LvJVcPKt$S7QiNrhBnMD!)$nJgKy!ZWOJf@x-1V87!} zSPbN_bq5gNUcJXv$8oR{trcqquN8hN<73Rn2qg4!@j7*LRTQjo!aMAekw;2ak2hjS zpR;_I6^?t}!Q5-Quo9s8_gDE>9`amu|HnO!hAND?1?#{w3d-xa`De3D$~5X{8-ZJQ z0N>9?4yDa9lk`~QKEF}O870|gNWj<-Aa*bg2sGtj#gcGgz#6A{gfl#v;UNgWQWTnv zNG0_2wWf}$jlUNl51aa`VT0|lz&@`gYl3m#EIZg_Rit_K7;xY-fsk)-CfF8h>#ZZ2 zWaoH_a~yYTQL{`j$CTTYGzna_pzm<<)hMrs$S6@hKa=f@=zVOX0%PT@Lvj`NS$D6l z0vL@v|3XE!BKiI*4vDMy0UqXlmUxt#`AKHj9lZWxjA~(u4QMNJ&hTxXDo7_9!)@eM%Z zQr&?g-y8+^P6aniORXduj&jk*DEfwB?5eQiJXZU=9&$#MlTH5WRqoA3dl*w6tj$+LkZu1 zhbd;*;VG*^qo~PD!fiIIG%fSMn^fxDW~TPzcH!ERe3Ri;Hra(5E6#mrV6{`)WH~4S z>*!B_672^&Ck1ot<2rtb$N7C8;deO8BfNqi_p90CQv5ZZrN=UBoQN_d!yJq3PYRq)oR9BR#DhZrl1dX^olEXy<3>DcGmI zVOXF0u*9j+ef96c=wD3*Mq=cr^t3e4-GaWOG1*Wo{)>F1m&`~- zc(F<0*npsmHZ?}`Il~c@El*~-*PQ)=Q`fz?{|`~^8|lFpVi}P?!$^6wOgR(*x zf148kDG4^k3+1mqwlZ~{YO2=OetJXKX(`_Hh$HNN_4 z%&pwqH0fHg)|=O+^?L4unpva>5Y%~oI>D|omrjOoBh*`Hj(VTpfY@y)-P9%4U5wq+ zUS7eKypd;l$g?SLaK_25#Z>AVrB+&}OD9nJ&d(;x{2BinH}P(-J&{Krm@#9*wn;%4 z)vIwK%Fxe>i9mt~{L=ZB00&KG>MzqIBbtPJ`MZQbRls3$E1+LC=O`WuDeMtgMQLC$)w!O(T*$@rSSmP-p|%?6HQy*khR zmSLMbuH^?=H2%l$zC2r-fj2XYh0WrQMymE>b z&cWF9!%}#p>{tMB^n5db$e2x}vTK44d^|)dlc+EfIB*RXQuzDS-QJq%7k9~2!XO>d z6Ntaph&|N!WrJ1LIF`jM@*T04r8$Axq^Fs8tiZC*(Q(Yg4LL>g@z1c!OHRjSl5z0i zT05ciyW)D!U-If}W)kxs#N|POPC`)#B)T>nwA3mE9j~jP4F(JM*~tcAb)SBK`l~;` z+7XWg)tp{y8y_}ixQTc3b$%_-Qs@YB*<1!-l3b~oJ{aGJNgK|``7#E$mA@Kgkka7e z@g50Tef&3iW-4_f+i;BjbsX8U19$@;Je1q+LaF`JPI^f6+*}By7~iFFrf~&@+Yji2 z0|#}P#?p7-+3Ca#)0uQE2!)S8Q@+Uus7|0@-qrVVLQ?4(%+O;s zDi;Wfh6O(Yt7XdKyemcc7pgf+$BEKINkv8V+|N3r?g+zAEB!j>nM#0NwNvX*hz@_q z_g@B?B9KuI4(nvY62~Ir*E4~(GQbG%SUe9(o$*tA8Gu9l7YWW!GyNPjx@|23tm^jU zPw`}oBb7?ff4wyaV6lt3kz1vM*<946Ff7>vD3wJKZ7bYjTqZDd?X|9}3x|$)W10b* zPA#aTfN5qR0ogS1ZR3 zf43^JX(b#o<>{se5sg%AdO5eIw~E?}hIo;yc4}Qv8iDxMuJIx*aTlU=j;t;hsxrw$ z66!V~_(U~>=F?c^DUS0MPZ2L8f4&qzZD=<2e>EBo)BlmbHFN@3@OrM~^%G46G)DnM zy_s=n4M{;3b3qu)XD$E-Kz7ET3T#^6)G8xbP#HCoQh2DwB;WY4IwkBf<#xYEOfk!V z9#hQt?s)yG=Gg6)aZ0tGUEnfd##X!+9eZ8FHI0XB)cL`*>+YMR6K<6O-8A!zJVUKa z0=vx6VcKggqzd&lWV+6VY{c$EBxX(~9gmF~C2q^sV8`ndc2qD=>}aZmsVQ}futr-J zuHGN|ai8_XBaQaoC=05^cY*Mw!=oI@7=El5(IJ*CBPklg=AT63rGVn<>mmLR_VG%l z99c-*^`9gYh|>2A1elh-fGAP!J5L8tp#al*2nG3v-&!hz$S1)qW#X;Ijj?RR88=`= z$5U#ROf%1bz5~{F{A(+iVh`7Hj^kc@v@R=lbG3u)#{KW6%WIU;Sx94s*MsZ0?4&?n zcG4IW@O_MdZw|@~sKWBkIY-b-2CpHfLeptC5gRgr_Fs;RLR zp6I&IC|v++%Brp~icvu5*+hJcB+Ilaq&SS=&+;_}thwkPi^}9P0gX(f2?$N+UrYT% z2T(UNzs{#P#QR$sq3vd$*8Dc<@T2wt;>kmC-|z9amd?uoG$nvhfT*bySjb}1jtkp* zhq{jB6@^&eIfZHZtTW95LwZaxD|!N5rn!t8d^fo=tXY?iS|u4a!rKErb4jNaO=4dw z023(t$iKc22;$ta$q)jw3?z@ded}@Z4(01bh?nvS4#oV7)3h^ zO(V*yUnry``hpPE$%vYK~P}rf=J7Ox>t*`EJOmdC5tK#I|-#ym)5D+ z2%Hlb`MPbBuG<~x1OgnnwwDdyrB)SYl+T^^21qXP7*14k4~+cZ){9Pc2_c(ym4TP8 z-%+A1;Z{JQDPV`22n;_HQOeXIgqNPC)bI%AV@M|=sGDE*h7KOJvbCrDXg$@@$(>-qq5 zlnh*SDiUWk645gD=oN!Lo}@8GXXk)NWi*3DG@hE(-tf$n4jWPW`^5c$DaVn}NTH=p zAatZ%*LZ8*TNxBKWmE!{ZoFEEWtbwFl^d14S04j6!mg5W$&PUXvXLl3KV?f!&EdLOxQqPs56jkE7b z96*E=x5>z?Nqu5+!yKd(MOPq4B55;DAjBh;en8)}7 z=Gen7N9MYZ*RaTSeoUx40o1{v-UL;58FpW=10b0yTbB$K0@s&g`mwa}&B#u=RVMCv zC(tD9rBetfUGt}&1~gg&!-!O|0VP%4_hA$@a@v3+*P$jd8WS)ENwyXn88Z6!6&;!Fkc0K%T(U z2t(iG90S%^;~B?YxEe&}Zs1rui6Woo1hlpCNnJo_@FF0p8=l+ zV4i&}ay^S&$39-oZmwgR`NZ@miTnz_;Lvm608nVYV&t5LGcyW^lq|b!96OB|y5x4= zZIFOl&l6jEEcsAO62kUWU0Wj%?qN%2lqmsB1eq;^8nMQ$58dU}3HB9Ic<{*S7Z%PD zm;fJFdK2qpoocgCQ)dvR2L;8VCb7s_3{bU-j!?=>+>{FqJzC>PLy55vJy~@TrW_2o zo6!@HM>P@I@jO+6@mEh*6n5|E-&Pmod z#Uj^n9d8RV1Dnmt+q(agzN_x!#!oW%Lz!z^bx#aslCIN;TM=1DkxGxoC5Qm#)<)P+ zMokN2s9Iw~(JW~On?td+Scqt$IXSEBFoZ@{!=4M*{qF?Gv&Qi1`o75sj88E~-iUIU zl?|e72T1^7h2Sd5$WyNE${mc3H(=TOAez*SToyG5oPbpNtFoCXH^!Wy!;IJ&(1lB@ z;{dO79gs~YA~RrhI=y_Va25 z%H6!qGAV~lWO+F%vgd>r+$s}htqwK{jU;1d$hl-wD*nVw!$c}6Qf0R8hF9rwgHUYH zfQ113)RJQOu}&<~l-8{AOd+L6lg+If^kRHf--+a&@VNe}jxKyrPzFSqc_)B^x(k_Z zQqc$v;h6r;C?Mk6^aqZ!VBkeqt2L!&E`&-_kwp+7B+QyR+6G;Mx|h+=XH~DX@QA#vH~}q{&zDpArmJ*l()fq| z{iMUz(z|5iG#f1=W*9Neg4ctv4g)cCh|Ova8*<}UI&P*mHLvuK2{Ch6SUXv@!R z$?UD7=1j&JSSsb9n|ODIYalJo*uog}!d%!EGJsS)Cv9+P2sc{F0kTu-kO!|DDCpW~ zEuv6-UfqbQMlrRjOlTw{Cm^b!->kCT zP-$HZPQbc^eCV2|rNZ}MeO$*m%GwDG3F)sJ=A`BX2p)7arQL|wY|-Lp~ifE zP^;10EW3j`HdwhdHJSN`f1^Ei`nK;@I?qSxKIqWbTwWj}O{%33 zjwNeq)CRy*x_(AC;31ei6BsezN&YkIoTWpT>v^+dEZ%x1U_D-uz=oH5z(DZ}SqOzeAHy9Q<=>9%T(L)2xeT^dH zmIfUEKK|03K=X6h<)1v;(Chz6Ck@Y23D6{_w5D2`fu_xo_`-|dsu_C&1(&hx>=N@=Evh#5QrO1G`;soN- zpzd>&L4T)8{ilNrU^ci=b@Gv+8~4_5-hJGh7-9IG$lx0ymAd>J`Rk+l-OzuRjv((4 zY~T>~@hTSBFR&t8cK~+Gfb;yvnXL}s)%@i}i#;@1?Hkv;x#*u>Y(_Pllz>Dx{J4u6 z?)VKvgs-E19ARy%gPO!SSki_hT{|2}TuD)#~Zcsg$DLw{8{Mh@L>9zUF!Ma*(&M z$_b{KXE#@8#N8~$1g_K?WrNbTP;wT2dXjE*6b{c&1VnMos&v7O?;T79Q6D!NtjR$; zbX9JE0qe}L1A}2NH?YWcEb&C3+E~qgv{rMR;p7Bp;|5?_I;7b^b?)C5h?)$x1Tl)6 z!nCjhYU4$FAsN8U{M;gxAGQ;9!S&?0J(A`C6$At$a)fB2Ix3WFl9T6AQtgjKCXjX? zY!rQSGhMCQZ!_6I+oT|V9xY|hWe`nTJIS=gGRsc(aTB|_N}Ud1ET#*^l%+FWeK#Hb zJOL`HNInxtCjs%ke%Smoj#|Aw!k=RZa{a0*0@c!&0ypx`Y}79k!yN|c|1c^AhN48+ zS_x3{T5cE1NzFv39aPj7{m112c8ggS8F%cJ%Mlp7>;9o| z5V1qh`UuUnH)21p;vhfd-)AFGlZ*LQ8H8IU8-c$x3usH(Wpt0TfH*UVGlnuT{_5v0vwT0l5J0_4MbWr@24*ukfl=GhdZuvRW58GN zzS}E3K&wPFE9A3v1Gm}X;8p-aHro+xj9YrZGIAB8v5#xjnp^L(>w`j+R$kuGXk$S= z(#IGvt4vLriOgi@Q*i>OGV-t-sIH#syD{lGGnrlcNiqRB8f@5xyUYr(^o tsuhl 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 Ux!V}+E&u=k07*qoM6N<$f*2fUwg3PC diff --git a/02-particle-system/assets/Asteroids_32x32_004.png b/02-particle-system/assets/Asteroids_32x32_004.png deleted file mode 100644 index fac3012425cb8044c0c0730931d76a4aafed9632..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4583 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 Rx9tD`002ovPDHLkV1lpUZ(jfa diff --git a/02-particle-system/assets/Asteroids_32x32_005.png b/02-particle-system/assets/Asteroids_32x32_005.png deleted file mode 100644 index 35238dbc360ca9ecdcde88b0343a201d587097d2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4822 zcmV;{5-IJ8P)KLZ*U+IBfRsybQWXdwQbLP>6pAqfylh#{fb6;Z(vMMVS~$e@S=j*ftg6;Uhf59&ghTmgWD0l;*T zI709Y^p6lP1rIRMx#05C~cW=H_Aw*bJ-5DT&Z2n+x)QHX^p z00esgV8|mQcmRZ%02D^@S3L16t`O%c004NIvOKvYIYoh62rY33S640`D9%Y2D-rV&neh&#Q1i z007~1e$oCcFS8neI|hJl{-P!B1ZZ9hpmq0)X0i`JwE&>$+E?>%_LC6RbVIkUx0b+_+BaR3cnT7Zv!AJxW zizFb)h!jyGOOZ85F;a?DAXP{m@;!0_IfqH8(HlgRxt7s3}k3K`kFu>>-2Q$QMFfPW!La{h336o>X zu_CMttHv6zR;&ZNiS=X8v3CR#fknUxHUxJ0uoBa_M6WNWeqIg~6QE69c9o#eyhGvpiOA@W-aonk<7r1(?fC{oI5N*U!4 zfg=2N-7=cNnjjOr{yriy6mMFgG#l znCF=fnQv8CDz++o6_Lscl}eQ+l^ZHARH>?_s@|##Rr6KLRFA1%Q+=*RRWnoLsR`7U zt5vFIcfW3@?wFpwUVxrVZ>QdQz32KIeJ}k~{cZZE^+ya? z2D1z#2HOnI7(B%_ac?{wFUQ;QQA1tBKtrWrm0_3Rgps+?Jfqb{jYbcQX~taRB;#$y zZN{S}1|}gUOHJxc?wV3fxuz+mJ4`!F$IZ;mqRrNsHJd##*D~ju=bP7?-?v~|cv>vB zsJ6IeNwVZxrdjT`yl#bBIa#GxRa#xMMy;K#CDyyGyQdMSxlWT#tDe?p!?5wT$+oGt z8L;Kp2HUQ-ZMJ=3XJQv;x5ci*?vuTfeY$;({XGW_huIFR9a(?@3)XSs8O^N5RyOM=TTmp(3=8^+zpz2r)C z^>JO{deZfso3oq3?Wo(Y?l$ge?uXo;%ru`Vo>?<<(8I_>;8Eq#KMS9gFl*neeosSB zfoHYnBQIkwkyowPu(zdms`p{<7e4kra-ZWq<2*OsGTvEV%s0Td$hXT+!*8Bnh2KMe zBmZRodjHV?r+_5^X9J0WL4jKW`}lf%A-|44I@@LTvf1rHjG(ze6+w@Jt%Bvjts!X0 z?2xS?_ve_-kiKB_KiJlZ$9G`c^=E@oNG)mWWaNo-3TIW8)$Hg0Ub-~8?KhvJ>$ z3*&nim@mj(aCxE5!t{lw7O5^0EIO7zOo&c6l<+|iDySBWCGrz@C5{St!X3hAA}`T4 z(TLbXTq+(;@<=L8dXnssyft|w#WSTW<++3>sgS%(4NTpeI-VAqb|7ssJvzNHgOZVu zaYCvgO_R1~>SyL=cFU|~g|hy|Zi}}s9+d~lYqOB71z9Z$wnC=pR9Yz4DhIM>Wmjgu z&56o6maCpC&F##y%G;1PobR9i?GnNg;gYtchD%p19a!eQtZF&3JaKv33gZ<8D~47E ztUS1iwkmDaPpj=$m#%)jCVEY4fnLGNg2A-`YwHVD3gv};>)hAvT~AmqS>Lr``i7kw zJ{5_It`yrBmlc25DBO7E8;5VoznR>Ww5hAaxn$2~(q`%A-YuS64wkBy=9dm`4cXeX z4c}I@?e+FW+b@^RDBHV(wnMq2zdX3SWv9u`%{xC-q*U}&`cyXV(%rRT*Z6MH?i+i& z_B8C(+grT%{XWUQ+f@NoP1R=AW&26{v-dx)iK^-Nmiuj8txj!m?Z*Ss1N{dh4z}01 z)YTo*JycSU)+_5r4#yw9{+;i4Ee$peRgIj+;v;ZGdF1K$3E%e~4LaI(jC-u%2h$&R z9cLXcYC@Xwnns&bn)_Q~Te?roKGD|d-g^8;+aC{{G(1^(O7m37Y1-+6)01cN&y1aw zoqc{T`P^XJqPBbIW6s}d4{z_f5Om?vMgNQEJG?v2T=KYd^0M3I6IZxbny)%vZR&LD zJpPl@Psh8QyPB@KTx+@RdcC!KX7}kEo;S|j^u2lU7XQ}Oo;f|;z4Ll+_r>@1-xl3| zawq-H%e&ckC+@AhPrP6BKT#_XdT7&;F71j}Joy zkC~6lh7E@6o;W@^IpRNZ{ptLtL(gQ-CY~4mqW;US7Zxvm_|@yz&e53Bp_lTPlfP|z zrTyx_>lv@x#=^!PzR7qqF<$gm`|ZJZ+;<)Cqu&ot2z=0000WV@Og>004R=004l4008;_004mL004C`008P>0026e000+nl3&F} z000O9Nkl&R%|Kq=Ot)AOzOxQ{e)^5K*1&kn^?wIb7C&U944y~sSN3KLSr_i zc_5`Rn=U^7(){_azIeEQD<}3LaPk+k&sSMk)Tp$NG>Cbmb4Qcb!IW}PkzFsShJm@` z(_A{gMzJ2*c)h@;paJF|=`s62n}ZK^kWvVlP>sTJH40~|aa{h>w{LEK7y-X?^QE87 z{2&&x7<0k5Ea{ZT&84`8MT62h*r0oRi&zM;i1a?2FnGJdcfhqkO2}^n=1=voslkUf z!AC|qIxbOP3Au3cms97$M9#kU!_lrI7T}9N>Gw70)5aN^+YnZxNHq*pqflRuB2o$I zw8u3plWUQDEo|dh|6212HZ{1^qAs#=WsBiTMmeZ327JdY8fRWP@zZX9p92Vs66vF$ z3Lz7Q?-odV) z4X(VrMeA^aF@}&uu3sEd+zj0OM}aZ$nbUm^JlH~236r=8oc+LopvO_gCI-}?iDFa3 z<(CFj!^reKO^!a^XX-9jqoL3_(xfqykgt`*Lb>ya8PcAk*=;gf8`GRKtS<-B=^E#a zHzpiD)kQ@~I&psrG-%zs0aTR9^}yQSGNg+54va46y!o3|^0f+y3R0(Pcxl4m(uC=| z+H~(|l1?SGTnFED__m{cTT*{BK(QXlZv=eH;X7_W6-xluG=xl$QrUbn$E9_38xI;G zX2QlB6WT{oBq}DrBUB}G*U2Ni*{(K7waQkCDY{L?Zh;KPg z{d#5*IOlf}2&U%rQqfRjV;t;ozOfJsL4qQcVl3SD@ErMO!Ehxb={S<91dR$<=DsjZ zI+akYm$;_GcPz#l*8V%dp@lZC>06HXfz~DA}agaRiiTe_k_W_8RZ~g9Q4gWjIB{H z-moJB>J&ttiIpyTS2Id>y=4B89%-+SRLXlVZF1;jk8&&EI}S+{l~}i?vS)L45x_vw z^&~w{ER+pdr8$={c-N5jJk0~?{#kI(cRS~O%P!c|Vr-prn;Lx6q7hun(ms;ZAMHBU zUmuY4Jl&&BBr0jwk@gdkuEV-I!twh##YRWef#u$tN2}+}%;+pky>kO_{|L3jWUg6M*KE}c5@`R-8NTxj2 zTY?c>VyTLVv0V6oih;MD9dAk@OFJ{5u5^R-7VGQWHE5%yC1erf3{@5xypu7ynlo7~ zDF=c1hi7TbCTzW(A)zKMlL7INJ(Mo@7WFW96;0IOIF!3ZH#Ox8>C zwGx+FT89#hH3Tmh7fGiRVit%K!FTKUG%Cerg%pBo+HJw2>_Y$`7IGovx-B&7c^)Q_ zFp5-JAj`*Os|ERu66*~&{+cnmQq}|(bh|?Y)ouPz15yvSkO>l%FcD%NQPGu;ARwhK z14JX3?fk1M(Fv*^6{Xk+#7e0~!eq7L%F87P9DQPj!(Z;AL9vM?=_W{&x+_#ssdHhS zp_&L_{`e6D-g~j!luDOku^)w4>_H@p0Ia>1VG||kf$zeV-)&HhBeAT>sC}eS2N1!! zTE@AC+a@wye)XyKb00xqdo(|TvJhRZ2Yt(eSZpGw7|JanyIv6s!S|@;nAB{UU90eI zS93ty(>c&yG5;fF02`hrGXz)*Jq7L4rZSjw%) zZI4ZJ{m%o+K|lqLo$eF!8YLGM94N9PqAOCx%~9a+wfQYmuww@v;+Xa3X`7k_*RXxtG}y%8TXw}Y>@k-b wY-+HHS+=S9(LaAYSo*Xl diff --git a/02-particle-system/assets/Asteroids_32x32_006.png b/02-particle-system/assets/Asteroids_32x32_006.png deleted file mode 100644 index bdbb052d4e6c2fdf3bc5ef7f5957dea63cbaab63..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4492 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 DGdw{* diff --git a/02-particle-system/assets/Asteroids_64x64_002.png b/02-particle-system/assets/Asteroids_64x64_002.png deleted file mode 100644 index 4556616f52bda4974a6d817d7dba8f5db624b9bc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7159 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 diff --git a/02-particle-system/assets/Asteroids_64x64_003.png b/02-particle-system/assets/Asteroids_64x64_003.png deleted file mode 100644 index 9223f22616dfc2c2c7759078b763554e0f760195..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7517 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 diff --git a/02-particle-system/assets/Asteroids_64x64_004.png b/02-particle-system/assets/Asteroids_64x64_004.png deleted file mode 100644 index 5dc63019b4a082042e089b4f8e392ef84a486079..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7736 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

{xDLLUW^ZkmaX(iztYA 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 D?J#E< diff --git a/02-particle-system/assets/Asteroids_64x64_006.png b/02-particle-system/assets/Asteroids_64x64_006.png deleted file mode 100644 index 0cf8b589996cbc0c5456d5f8b90211d614730847..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7456 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 U#_{peZ~y=R07*qoM6N<$g2ZlJT>t<8 diff --git a/02-particle-system/assets/Asteroids_128x128_008.png b/02-particle-system/assets/asteroid-128.png similarity index 100% rename from 02-particle-system/assets/Asteroids_128x128_008.png rename to 02-particle-system/assets/asteroid-128.png diff --git a/02-particle-system/assets/Asteroids_256x256_008.png b/02-particle-system/assets/asteroid-256.png similarity index 100% rename from 02-particle-system/assets/Asteroids_256x256_008.png rename to 02-particle-system/assets/asteroid-256.png diff --git a/02-particle-system/assets/Asteroids_32x32_008.png b/02-particle-system/assets/asteroid-32.png similarity index 100% rename from 02-particle-system/assets/Asteroids_32x32_008.png rename to 02-particle-system/assets/asteroid-32.png diff --git a/02-particle-system/assets/Asteroids_64x64_008.png b/02-particle-system/assets/asteroid-64.png similarity index 100% rename from 02-particle-system/assets/Asteroids_64x64_008.png rename to 02-particle-system/assets/asteroid-64.png diff --git a/02-particle-system/assets/bullet.png b/02-particle-system/assets/bullet.png new file mode 100644 index 0000000000000000000000000000000000000000..9a46ab5272bfefc6e9bb6e758b0d57765da92fed GIT binary patch literal 536 zcmV+z0_XjSP)1DYb%Cm*kqXLXw6{iWFDD#i8IJ zy7)EtALuH$DhPrih`9I<__auh?=^)MY45naKc3w4a`znI&*;ps`;vfRIy{$7Nvnl5 zY2Y0pnn6S{E;HL&$YwL>Ies4D6ZIh>diCDdbqp3&n*qKc@hr2rLp)EM*>Wtwd&I-6 zEEkDSh~u0NNPH`F#p5@@C6B)Z^L%a*@Qa>Ose_dcW@T;=PZ7rqy~bjp3z`#DxsJrg(sp~e*fWQlIZMOXt%4zPK^m<#19Rraa;PR%e zDF?vSE->-|NVEFeu@jnQFXhskN arUw8{y&aLZ`8M$Y0000" @@ -45,24 +47,61 @@ def rect(self): def draw(self, screen): screen.blit(self.rotated_sprite, self.rect) + # Corners + w, h = SIZE + tl = 0, 0 + tr = w, 0 + br = w, h + bl = 0, h + + for a, b, offset in [ + (tl, tr, (0, h)), + (bl, br, (0, -h)), + (tl, bl, (w, 0)), + (tr, br, (-w, 0)), + ]: + # For each side of the screen that it overlaps + if self.rect.clipline(a, b): + # Draw the spaceship at the other edge too. + screen.blit( + self.rotated_sprite, + self.rotated_sprite.get_rect(center=self.center + offset), + ) + def logic(self, **kwargs): # self.vel = clamp_vector(self.vel, self.MAX_VEL) self.center += self.vel + self.center.x %= SIZE[0] + self.center.y %= SIZE[1] + class Player(Object): - ACCELERATION = 0.4 + ACCELERATION = 0.2 FRICTION = 0.96 ROTATION_ACCELERATION = 2 INITIAL_ROTATION = 90 + FIRE_COOLDOWN = 10 # frames def __init__(self, pos, vel): super().__init__(pos, vel, load_image("player", 3)) self.speed = 0 + self.fire_cooldown = -1 - def logic(self, **kwargs): + def logic(self, events, objects, new_objects, **kwargs): pressed = pygame.key.get_pressed() + + # Fire + self.fire_cooldown -= 1 + for event in events: + if event.type == pygame.KEYDOWN: + if event.key == pygame.K_SPACE: + self.fire(new_objects) + if pressed[pygame.K_SPACE]: + self.fire(new_objects) + + # Motion rotation_acc = pressed[pygame.K_LEFT] - pressed[pygame.K_RIGHT] raw_acceleration = pressed[pygame.K_DOWN] - pressed[pygame.K_UP] @@ -75,32 +114,63 @@ def logic(self, **kwargs): self.vel.from_polar((self.speed, self.INITIAL_ROTATION - self.rotation)) - # self.acceleration = pygame.Vector2(direction_x, direction_y) * self.ACCELERATION super().logic(**kwargs) - self.center.x %= SIZE[0] - self.center.y %= SIZE[1] - def draw(self, screen): super().draw(screen) - # Corners - w, h = SIZE - tl = 0, 0 - tr = w, 0 - br = w, h - bl = 0, h + def fire(self, objects: set): + if self.fire_cooldown >= 0: + return - for a, b, offset in [ - (tl, tr, (0, h)), - (bl, br, (0, -h)), - (tl, bl, (w, 0)), - (tr, br, (-w, 0)), - ]: - # For each side of the screen that it overlaps - if self.rect.clipline(a, b): - # Draw the spaceship at the other edge too. - screen.blit( - self.rotated_sprite, - self.rotated_sprite.get_rect(center=self.center + offset), - ) + self.fire_cooldown = self.FIRE_COOLDOWN + bullet = Bullet(self.center, 270 - self.rotation) + objects.add(bullet) + + +class Bullet(Object): + SPEED = 10 + TIME_TO_LIVE = 60 * 2 + + def __init__(self, pos, angle): + super().__init__(pos, from_polar(self.SPEED, angle), load_image("bullet", 2)) + self.rotation = 90 - angle + self.time_to_live = self.TIME_TO_LIVE + + def logic(self, **kwargs): + super().logic(**kwargs) + + self.time_to_live -= 1 + + if self.time_to_live <= 0: + self.alive = False + + +class Asteroid(Object): + AVG_SPEED = 1 + + def __init__(self, pos, vel, size=4, color=None): + assert 1 <= size <= 4 + # We copy to change the color + sprite = load_image(f"asteroid-{16*2**size}").copy() + sprite.fill(color or self.random_color(), special_flags=pygame.BLEND_RGB_MULT) + + super().__init__(pos, vel, sprite) + + def random_color(self): + r, g, b = hsv_to_rgb(uniform(0, 1), 1, 1) + return int(r * 255), int(g * 255), int(b * 255) + + @classmethod + def generate_many(cls, nb=8): + objects = set() + for _ in range(nb): + angle = uniform(0, 360) + pos = SCREEN.center + from_polar(gauss(SIZE[1] / 2, SIZE[1] / 12), angle) + vel = from_polar( + gauss(cls.AVG_SPEED, cls.AVG_SPEED / 6), gauss(180 + angle, 30) + ) + size = choices([1, 2, 3, 4], [4, 3, 2, 1])[0] + objects.add(cls(pos, vel, size)) + + return objects From 93f744243a1cf2699f0c2aaa0e9a55b09ace70fd Mon Sep 17 00:00:00 2001 From: ddorn Date: Sun, 10 Oct 2021 18:56:47 +0200 Subject: [PATCH 14/80] 02: fix no wrapping screen in corners --- 02-particle-system/base/objects.py | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/02-particle-system/base/objects.py b/02-particle-system/base/objects.py index e93bb75..c1a0e46 100644 --- a/02-particle-system/base/objects.py +++ b/02-particle-system/base/objects.py @@ -47,13 +47,14 @@ def rect(self): def draw(self, screen): screen.blit(self.rotated_sprite, self.rect) - # Corners + # Goal: wrap around the screen. w, h = SIZE tl = 0, 0 tr = w, 0 br = w, h bl = 0, h + shifts = [] for a, b, offset in [ (tl, tr, (0, h)), (bl, br, (0, -h)), @@ -62,12 +63,26 @@ def draw(self, screen): ]: # For each side of the screen that it overlaps if self.rect.clipline(a, b): + shifts.append(offset) # Draw the spaceship at the other edge too. screen.blit( self.rotated_sprite, self.rotated_sprite.get_rect(center=self.center + offset), ) + # Take care of the corners of the screen. + # Here I assume that no object can touch two sides of the screen + # at the same time. If so, the code wouldn't be correct, but still + # produce the expected result -.-' + assert len(shifts) <= 2 + if len(shifts) == 2: + screen.blit( + self.rotated_sprite, + self.rotated_sprite.get_rect( + center=self.center + shifts[0] + shifts[1] + ), + ) + def logic(self, **kwargs): # self.vel = clamp_vector(self.vel, self.MAX_VEL) self.center += self.vel From 17b48338af1a9d9dc2fea4eb5263121ea3f5b967 Mon Sep 17 00:00:00 2001 From: ddorn Date: Sun, 10 Oct 2021 19:17:21 +0200 Subject: [PATCH 15/80] 02: asteroids break --- 02-particle-system/base/objects.py | 49 ++++++++++++++++++++++++++++-- 1 file changed, 47 insertions(+), 2 deletions(-) diff --git a/02-particle-system/base/objects.py b/02-particle-system/base/objects.py index c1a0e46..518d4ca 100644 --- a/02-particle-system/base/objects.py +++ b/02-particle-system/base/objects.py @@ -163,14 +163,59 @@ def logic(self, **kwargs): class Asteroid(Object): AVG_SPEED = 1 + EXPLOSION_SPEED_BOOST = 1.8 def __init__(self, pos, vel, size=4, color=None): assert 1 <= size <= 4 + self.level = size # We copy to change the color + self.color = color or self.random_color() + + super().__init__(pos, vel, self.colored_image(size, self.color)) + + @staticmethod + @lru_cache(100) + def colored_image(size, color): sprite = load_image(f"asteroid-{16*2**size}").copy() - sprite.fill(color or self.random_color(), special_flags=pygame.BLEND_RGB_MULT) + sprite.fill(color, special_flags=pygame.BLEND_RGB_MULT) + return sprite + + def logic(self, **kwargs): + super().logic(**kwargs) - super().__init__(pos, vel, sprite) + objects = kwargs.get("objects", set()) + new_objects = kwargs["new_objects"] + + for obj in objects: + if not obj.alive: + continue + + if isinstance(obj, Bullet): + # Detect if the bullet and asteroid collide. + if obj.center.distance_to(self.center) < self.radius: + obj.alive = False + self.explode(obj, new_objects) + break + + def explode(self, bullet, new_objects: set): + self.alive = False + if self.level > 1: + # We spawn two smaller asteroids in the direction perpendicular to the collision. + perp_velocity = pygame.Vector2(bullet.vel.y, -bullet.vel.x) + perp_velocity.scale_to_length( + self.vel.length() * self.EXPLOSION_SPEED_BOOST + ) + for mult in (-1, 1): + new_objects.add( + Asteroid( + self.center, perp_velocity * mult, self.level - 1, self.color + ) + ) + + @property + def radius(self): + # The 1.2 is to be nicer to the player + return self.sprite.get_width() / 2 * 1.2 def random_color(self): r, g, b = hsv_to_rgb(uniform(0, 1), 1, 1) From 1535c7383520e402f6ffa4127437744d0010bd35 Mon Sep 17 00:00:00 2001 From: ddorn Date: Sun, 10 Oct 2021 21:02:13 +0200 Subject: [PATCH 16/80] use a state class + player collision + fps counter --- 02-particle-system/base/main.py | 28 ++--- 02-particle-system/base/objects.py | 181 ++++++++++++++++++++++------- 2 files changed, 152 insertions(+), 57 deletions(-) diff --git a/02-particle-system/base/main.py b/02-particle-system/base/main.py index 03843a6..2684644 100644 --- a/02-particle-system/base/main.py +++ b/02-particle-system/base/main.py @@ -34,36 +34,30 @@ # otherwise your project will not be compatible with the showcase. from .objects import * -BACKGROUND = 0x66856C +BACKGROUND = 0x0F1012 def mainloop(): - player = Player((100, 100), (0, 0)) + pygame.init() - objects = {player} | Asteroid.generate_many() + player = Player((100, 100), (0, 0)) + state = State(player, FpsCounter(60), *Asteroid.generate_many()) - clock = pygame.time.Clock() while True: screen, events = yield for event in events: if event.type == pygame.QUIT: return + else: + state.handle_event(event) - dead = set() - new_objects = set() - for obj in objects: - obj.logic(events=events, objects=objects, new_objects=new_objects) - if not obj.alive: - dead.add(obj) - objects.difference_update(dead) - objects.update(new_objects) + # Note: the logic for collisions is in the Asteroids class. + # This may seem arbitrary, but the only collisions that we consider + # are with asteroids. + state.logic() screen.fill(BACKGROUND) - # for object in sorted(objects, key=attrgetter("rect.bottom")): - for obj in objects: - obj.draw(screen) - - clock.tick(60) + state.draw(screen) if __name__ == "__main__": diff --git a/02-particle-system/base/objects.py b/02-particle-system/base/objects.py index 518d4ca..b32050c 100644 --- a/02-particle-system/base/objects.py +++ b/02-particle-system/base/objects.py @@ -7,30 +7,84 @@ goes with it too. Feel free to modify everything in this file to your liking. """ +import time +from collections import deque from colorsys import hsv_to_rgb +from operator import attrgetter from random import choice, gauss, choices import pygame from wclib import SIZE +from wclib.showcase import text from .utils import * SCREEN = pygame.Rect(0, 0, *SIZE) +class State: + def __init__(self, *initial_objects: "Object"): + self.objects = set() + self.objects_to_add = set() + + for obj in initial_objects: + self.add(obj) + + def add(self, obj: "Object"): + # We don't add objects immediately, + # as it could invalidate iterations. + self.objects_to_add.add(obj) + obj.state = self + return obj + + def logic(self): + to_remove = set() + for obj in self.objects: + obj.logic() + if not obj.alive: + to_remove.add(obj) + self.objects.difference_update(to_remove) + self.objects.update(self.objects_to_add) + self.objects_to_add.clear() + + def draw(self, screen): + for obj in sorted(self.objects, key=attrgetter("Z")): + obj.draw(screen) + + def handle_event(self, event): + for obj in self.objects: + if obj.handle_event(event): + break + + class Object: """The base class for all objects of the game.""" + Z = 0 + + # All the objects are considered circles, + # Their hitbox is scaled by the given amount, to the advantage of the player. + HIT_BOX_SCALE = 1.2 + def __init__(self, pos, vel, sprite: pygame.Surface): + self.state: "State" = None self.center = pygame.Vector2(pos) self.vel = pygame.Vector2(vel) - self.size = pygame.Vector2(sprite.get_size()) self.sprite = sprite self.rotation = 0.0 # for the sprite self.alive = True def __str__(self): - return f"<{self.__class__.__name__}(center={self.center}, vel={self.vel}, rotation={int(self.rotation)} size={self.size})>" + return f"<{self.__class__.__name__}(center={self.center}, vel={self.vel}, rotation={int(self.rotation)})>" + + @property + def radius(self): + # The 1.2 is to be nicer to the player + return self.sprite.get_width() / 2 * self.HIT_BOX_SCALE + + def collide(self, other: "Object") -> bool: + """Whether two objects collide.""" + return self.center.distance_to(other.center) <= self.radius + other.radius @property def rotated_sprite(self): @@ -44,6 +98,9 @@ def rotated_sprite(self): def rect(self): return self.rotated_sprite.get_rect(center=self.center) + def handle_event(self, event): + pass + def draw(self, screen): screen.blit(self.rotated_sprite, self.rect) @@ -92,11 +149,13 @@ def logic(self, **kwargs): class Player(Object): - ACCELERATION = 0.2 - FRICTION = 0.96 - ROTATION_ACCELERATION = 2 + Z = 10 + HIT_BOX_SCALE = 0.7 # harder to touch the player + ACCELERATION = 0.7 + FRICTION = 0.9 + ROTATION_ACCELERATION = 3 INITIAL_ROTATION = 90 - FIRE_COOLDOWN = 10 # frames + FIRE_COOLDOWN = 15 # frames def __init__(self, pos, vel): super().__init__(pos, vel, load_image("player", 3)) @@ -104,46 +163,51 @@ def __init__(self, pos, vel): self.speed = 0 self.fire_cooldown = -1 - def logic(self, events, objects, new_objects, **kwargs): - pressed = pygame.key.get_pressed() + def handle_event(self, event): + if event.type == pygame.KEYDOWN: + if event.key == pygame.K_SPACE: + self.fire() - # Fire + def logic(self): self.fire_cooldown -= 1 - for event in events: - if event.type == pygame.KEYDOWN: - if event.key == pygame.K_SPACE: - self.fire(new_objects) - if pressed[pygame.K_SPACE]: - self.fire(new_objects) + + # For continuous shooting: + # if pressed[pygame.K_SPACE]: + # self.fire(new_objects) # Motion + pressed = pygame.key.get_pressed() rotation_acc = pressed[pygame.K_LEFT] - pressed[pygame.K_RIGHT] - raw_acceleration = pressed[pygame.K_DOWN] - pressed[pygame.K_UP] + raw_acceleration = 0.5 * pressed[pygame.K_DOWN] - pressed[pygame.K_UP] self.speed += raw_acceleration * self.ACCELERATION self.speed *= self.FRICTION # friction self.rotation += ( - rotation_acc * self.ROTATION_ACCELERATION * min(1, 0.4 + abs(self.speed)) + rotation_acc * self.ROTATION_ACCELERATION * min(1.0, 0.4 + abs(self.speed)) ) self.vel.from_polar((self.speed, self.INITIAL_ROTATION - self.rotation)) - super().logic(**kwargs) + super().logic() - def draw(self, screen): - super().draw(screen) - - def fire(self, objects: set): + def fire(self): if self.fire_cooldown >= 0: return self.fire_cooldown = self.FIRE_COOLDOWN bullet = Bullet(self.center, 270 - self.rotation) - objects.add(bullet) + self.state.add(bullet) + + def on_asteroid_collision(self, asteroid: "Asteroid"): + asteroid.explode(Bullet(self.center, self.rotation)) + + # Add particles here (and maybe damage the ship or something...) + ... class Bullet(Object): + Z = 1 SPEED = 10 TIME_TO_LIVE = 60 * 2 @@ -180,24 +244,24 @@ def colored_image(size, color): sprite.fill(color, special_flags=pygame.BLEND_RGB_MULT) return sprite - def logic(self, **kwargs): - super().logic(**kwargs) - - objects = kwargs.get("objects", set()) - new_objects = kwargs["new_objects"] + def logic(self): + super().logic() - for obj in objects: + for obj in self.state.objects: if not obj.alive: continue if isinstance(obj, Bullet): # Detect if the bullet and asteroid collide. - if obj.center.distance_to(self.center) < self.radius: - obj.alive = False - self.explode(obj, new_objects) + if self.collide(obj): + self.explode(obj) break + elif isinstance(obj, Player): + if self.collide(obj): + obj.on_asteroid_collision(self) - def explode(self, bullet, new_objects: set): + def explode(self, bullet): + bullet.alive = False self.alive = False if self.level > 1: # We spawn two smaller asteroids in the direction perpendicular to the collision. @@ -206,23 +270,20 @@ def explode(self, bullet, new_objects: set): self.vel.length() * self.EXPLOSION_SPEED_BOOST ) for mult in (-1, 1): - new_objects.add( + self.state.add( Asteroid( self.center, perp_velocity * mult, self.level - 1, self.color ) ) - @property - def radius(self): - # The 1.2 is to be nicer to the player - return self.sprite.get_width() / 2 * 1.2 + # Add particles here. def random_color(self): - r, g, b = hsv_to_rgb(uniform(0, 1), 1, 1) + r, g, b = hsv_to_rgb(uniform(0, 1), 0.8, 0.8) return int(r * 255), int(g * 255), int(b * 255) @classmethod - def generate_many(cls, nb=8): + def generate_many(cls, nb=10): objects = set() for _ in range(nb): angle = uniform(0, 360) @@ -234,3 +295,43 @@ def generate_many(cls, nb=8): objects.add(cls(pos, vel, size)) return objects + + +class FpsCounter(Object): + Z = 1000 + + def __init__(self, fps): + self.target_fps = fps + self.clock = pygame.time.Clock() + self.last_frames = deque([time.time()], maxlen=10) + self.last_sleeps = deque([0.0], maxlen=9) + + dummy_surface = pygame.Surface((1, 1)) + super().__init__((4, 8), (0, 0), dummy_surface) + + def logic(self, **kwargs): + self.last_frames.append(time.time()) + self.clock.tick(self.target_fps) + end_sleep = time.time() + self.last_sleeps.append(end_sleep - self.last_frames[-1]) + + @property + def current_fps(self): + if len(self.last_frames) <= 1: + return 0 + seconds = self.last_frames[-1] - self.last_frames[0] + return int((len(self.last_frames) - 1) / seconds) + + @property + def theoretical_fps(self): + if len(self.last_frames) <= 1: + return 0 + seconds = self.last_frames[-1] - self.last_frames[0] - sum(self.last_sleeps) + return int((len(self.last_frames) - 1) / seconds) + + def draw(self, screen): + color = "#89C4F4" + t = text(f"FPS: {self.current_fps}", color) + r = screen.blit(t, self.center) + t = text(f"Theoretical: {self.theoretical_fps}", color) + screen.blit(t, r.bottomleft) From dd3bef18c7877f28f4f46b99efa2a5be1cd6e577 Mon Sep 17 00:00:00 2001 From: ddorn Date: Mon, 11 Oct 2021 13:26:06 +0200 Subject: [PATCH 17/80] wip: readmes --- 02-particle-system/base/objects.py | 10 ++- 02-particle-system/readme.md | 104 ++++++----------------------- general_instructions.md | 82 +++++++++++++++++++++++ readme.md | 2 +- 4 files changed, 111 insertions(+), 87 deletions(-) create mode 100644 general_instructions.md diff --git a/02-particle-system/base/objects.py b/02-particle-system/base/objects.py index b32050c..c0e8b89 100644 --- a/02-particle-system/base/objects.py +++ b/02-particle-system/base/objects.py @@ -84,7 +84,12 @@ def radius(self): def collide(self, other: "Object") -> bool: """Whether two objects collide.""" - return self.center.distance_to(other.center) <= self.radius + other.radius + # The distance must be modified because everything wraps + dx = (self.center.x - other.center.x) % SIZE[0] + dx = min(dx, SIZE[0] - dx) + dy = (self.center.y - other.center.y) % SIZE[1] + dy = min(dy, SIZE[1] - dy) + return (dx ** 2 + dy ** 2) <= (self.radius + other.radius) ** 2 @property def rotated_sprite(self): @@ -140,6 +145,9 @@ def draw(self, screen): ), ) + # To see the exact size of the hitboxes + # pygame.draw.circle(screen, "red", self.center, self.radius, width=1) + def logic(self, **kwargs): # self.vel = clamp_vector(self.vel, self.MAX_VEL) self.center += self.vel diff --git a/02-particle-system/readme.md b/02-particle-system/readme.md index 1a1eeb1..fc8b515 100644 --- a/02-particle-system/readme.md +++ b/02-particle-system/readme.md @@ -1,105 +1,39 @@ -# 01 - Fog of War +# 02 — Particle System -The goal of this challenge is to implement a Fog of War mechanic -similar to Age of empires. +The goal of this challenge is to implement general and reusable particle system for your games. -### Achievements +Particles are a very good way to add feedback and interactivity to a game, +so it is very handy to have a system already implemented for when a game jam comes. -There are different stages of success for the challenge. -Succeeding in the casual stage is enough to complete the challenge, -however, in order to provide more challenge for the most adventurous -and ambitious of you, we provide two more puzzles. -The harder they are, the less point the reward, -as it is more important to always improve a bit that spend hours and hours -stuck on the same thing. +### Achievements -Here a more detailed description of the different levels and the amount of + Description of the different levels and the amount of `C`hallenger `P`oints they provide: -- Casual `+3 CP`: The world around the player is visible but the rest of the map - is hidden in complete darkness. -- Ambitious `+2 CP`: The world is visible around the player and softly fades to dark, as if the player had a light. - In the distance, everything is black. -- Adventurous `+1 CP`: Like in Age of Empires the map starts all dark. The world around the player is visible, - the parts already explored are darker and the unexplored parts are totally dark. - Additionally, in the explored parts the player sees only the static objects (Trees, Houses…) - but not the moving ghosts. +- Casual `+3 CP`: Have 3 different particle effects of your choice in the game + (for instance: asteroid explosion, ship damage, thrusters, stars, asteroids clear fireworks, bullets, warning as approaching asteroids...) +- Ambitious `+2 CP`: Have 6 different particles effects and handle 1000 particles at 60 FPS +- Adventurous `+1 CP`: Have 9 effects + +In any case, your particle system should be: +- independent of the rest of your code (for instance, in it own file) + so that you can copy/paste it in your other projects +- run at 60 FPS, at least, so that there is still processing power for the rest of a real game +- Generic, so that you can create new particle effect without too much effort. ### Setup The setup code in [`base/`](./base) consists of a simple top down game with trees and ghosts moving around. -To get started, duplicate the whole `base` folder and rename the copy with your username +To get started, duplicate the whole `base` folder and rename the copy with your username (will call it `yourname/` from now on). All your modifications should be inside the `yourname/` folder, otherwise it would be impossible to have a showcase of all the submissions. -In this `yourname/` folder, you'll find a `main.py` file. This is the entry point of your submission and where -most of your code will go. -In this file, you will find a `mainloop` function, which is the only thing that is required so that the submission -appears in the showcase. The showcase needs to have the control of the events and the display, so they are -passed down to `mainloop` in a surprising way: the `send` mechanism of generators. -Don't be afraid if that looks like black magic to you, -you can participate without understanding it. -You may be used to a main loop that looks like this: - -```python -import pygame -def mainloop(): - screen = pygame.display.set_mode((800, 500)) - # More setup... - while True: - for event in pygame.event.get(): - ... # Event handling - - # Logic and rendering of your game... - screen.blit(...) - pygame.display.update() -``` - -But now it will look like this: -```python -def mainloop(): - # Setup, but without setting up the screen - while True: - screen, events = yield - for event in events: - ... # Event handling - # Logic and rendering of your game, on the screen variable - screen.blit(...) - # No need to call pygame.display.update() it is done by the showcase. -``` - -If you are used to classes, you can also have all your code in a class, for instance `App`, -then you only need a statement like `mainloop = App.run` if the `run()` method is your main loop, -to have your submission discovered. - -### Submitting your entry - -Before the deadline, make sure that your entry is runnable both via the showcase, -when you run the top level [`main.py`](../main.py) and when you run it individually -from you own `yourname/main.py`. - -There are two ways to submit an entry: - - send a zip of your code in the discord - - make a pull request directly on this repository - -In either case, you need to post a screenshot of your entry in `#challenge-submission` -with your files if you don't do a PR, and with some comment if you want. -Sharing your code will help others learn, and you may receive good advice too! - Have fun ! -### Tips - -##### Use relative imports - -You can structure your code the way you like, but if you use multiple files, -it is very recommended that you use *relative imports*, as it is the simplest way to -make the import system work both in the showcase and when run directly. - ### Credits - - Tileset: [GameBoy Style Dark Forest Tileset by Cluly](https://cluly.itch.io/gameboy-style-dark-forest-tileset) - - Ghosts: [Free 16x16 Pixel Art 8-Directional Characters by Maytch](https://maytch.itch.io/free-16x16-pixel-art-8-directional-characters) + - Asteroids: [Asteroids 02 by GameArtForge](https://opengameart.org/content/asteroids-set-02) + - Other sprites: [Flyre by CozyFractal](https://gitlab.com/ddorn/flyre) - Setup code: [CozyFractal](https://cozyfractal.com) ### Legal stuff diff --git a/general_instructions.md b/general_instructions.md new file mode 100644 index 0000000..f49b787 --- /dev/null +++ b/general_instructions.md @@ -0,0 +1,82 @@ +# General Instructions + +### Achievements + +In each challenge, there are different stages of success, *Casual*, *Ambitious* +and *Adventurous* +Succeeding in the casual stage is enough to complete the challenge, +however, in order to provide more challenge for the most adventurous +and ambitious of you, we provide two more puzzles. +The harder they are, the less point the reward, +as it is more important to always improve a bit that spend hours and hours +stuck on the same thing. + +### Setup Code + +The setup code in [`base/`](./base) consists of a simple top down game with trees and ghosts moving around. +To get started, duplicate the whole `base` folder and rename the copy with your username +(will call it `yourname/` from now on). All your modifications should be inside the `yourname/` folder, +otherwise it would be impossible to have a showcase of all the submissions. + +In this `yourname/` folder, you'll find a `main.py` file. This is the entry point of your submission and where +most of your code will go. +In this file, you will find a `mainloop` function, which is the only thing that is required so that the submission +appears in the showcase. The showcase needs to have the control of the events and the display, so they are +passed down to `mainloop` in a surprising way: the `send` mechanism of generators. +Don't be afraid if that looks like black magic to you, +you can participate without understanding it. +You may be used to a main loop that looks like this: + +```python +import pygame +def mainloop(): + screen = pygame.display.set_mode((800, 500)) + # More setup... + while True: + for event in pygame.event.get(): + ... # Event handling + + # Logic and rendering of your game... + screen.blit(...) + pygame.display.update() +``` + +But now it will look like this: +```python +def mainloop(): + # Setup, but without setting up the screen + while True: + screen, events = yield + for event in events: + ... # Event handling + # Logic and rendering of your game, on the screen variable + screen.blit(...) + # No need to call pygame.display.update() it is done by the showcase. +``` + +If you are used to classes, you can also have all your code in a class, for instance `App`, +then you only need a statement like `mainloop = App.run` if the `run()` method is your main loop, +to have your submission discovered. + +### Submitting your entry + +Before the deadline, make sure that your entry is runnable both via the showcase, +when you run the top level [`main.py`](../main.py) and when you run it individually +from you own `yourname/main.py`. + +There are two ways to submit an entry: +- send a zip of your code in the discord +- make a pull request directly on this repository + +In either case, you need to post a screenshot of your entry in `#challenge-submission` +with your files if you don't do a PR, and with some comment if you want. +Sharing your code will help others learn, and you may receive good advice too! + +### Tips + +##### Use relative imports + +You can structure your code the way you like, but if you use multiple files, +it is very recommended that you use *relative imports*, as it is the simplest way to +make the import system work both in the showcase and when run directly. + diff --git a/readme.md b/readme.md index be14846..3f8c998 100644 --- a/readme.md +++ b/readme.md @@ -14,7 +14,7 @@ The first season started on the 26th of September 2021 and will last about 3 mon ### List of challenges 1. [Fog of War](./01-fog-of-war) - 28 Sep → 10 oct 2021 -2. **[current]** [Particle System](./02-particle-system) - 11 oct 2021 → 17 oct 2021 +2. **[current]** [Particle System](./02-particle-system) - 11 oct 2021 → 25 oct 2021 --- From b2b9dbc1c9c1c2065ca2617cf99fa7ce6aea9795 Mon Sep 17 00:00:00 2001 From: Emc235 <63981925+Emc2356@users.noreply.github.com> Date: Mon, 11 Oct 2021 14:29:30 +0300 Subject: [PATCH 18/80] Emc2356 entry * completed for-of-war challenge in casual, ambitious and adventurous * now completed the ambitious with the fading light --- 01-fog-of-war/Emc235#2196/main.py | 74 +++++++++++ 01-fog-of-war/Emc235#2196/objects.py | 176 +++++++++++++++++++++++++++ 01-fog-of-war/Emc235#2196/utils.py | 39 ++++++ 3 files changed, 289 insertions(+) create mode 100644 01-fog-of-war/Emc235#2196/main.py create mode 100644 01-fog-of-war/Emc235#2196/objects.py create mode 100644 01-fog-of-war/Emc235#2196/utils.py diff --git a/01-fog-of-war/Emc235#2196/main.py b/01-fog-of-war/Emc235#2196/main.py new file mode 100644 index 0000000..855d785 --- /dev/null +++ b/01-fog-of-war/Emc235#2196/main.py @@ -0,0 +1,74 @@ +import sys +from pathlib import Path + +try: + import wclib +except ImportError: + # wclib may not be in the path because of the architecture + # of all the challenges and the fact that there are many + # way to run them (through the showcase, or on their own) + + ROOT_FOLDER = Path(__file__).parent.parent.parent + sys.path.append(str(ROOT_FOLDER)) + import wclib + +# This line tells python how to handle the relative imports +# when you run this file directly. +__package__ = "01-fog-of-war." + Path(__file__).parent.name + +# ---- Recommended: don't modify anything above this line ---- # + +# Metadata about your submission +__author__ = "Emc235#2196" +__achievements__ = [ # Uncomment the ones you've done + "Casual", + "Ambitious", + "Adventurous" +] + + +from operator import attrgetter +import pygame +import time + +# To import the modules in yourname/, you need to use relative imports, +# otherwise your project will not be compatible with the showcase. +from .objects import Ghost, Player, SolidObject, LayeredVisibility + +BACKGROUND = 0x66856C + + +def mainloop(): + player = Player((100, 100)) + trees = SolidObject.generate_many(36) + ghosts = [Ghost(player) for _ in range(16)] + visibility = LayeredVisibility(player) + + all_objects = trees + [player] + ghosts + + clock = pygame.time.Clock() + FPS: int = 60 + + last_time: float = time.time() + + while True: + clock.tick(FPS) + dt = time.time() - last_time + dt *= 60 + last_time = time.time() + WIN, events = yield + for event in events: + if event.type == pygame.QUIT: + return + + for obj in all_objects: + obj.logic(objects=all_objects, dt=dt) + + WIN.fill(BACKGROUND) + for obj in sorted(all_objects, key=attrgetter("rect.bottom")): + obj.draw(WIN) + visibility.draw(WIN) + + +if __name__ == "__main__": + wclib.run(mainloop()) diff --git a/01-fog-of-war/Emc235#2196/objects.py b/01-fog-of-war/Emc235#2196/objects.py new file mode 100644 index 0000000..e611a5f --- /dev/null +++ b/01-fog-of-war/Emc235#2196/objects.py @@ -0,0 +1,176 @@ +""" +This file provides objects that can be used to make up +a basic playground for the challenges. + +This code is provided so that you can focus on implementing +a fog of war, without needed +Feel free to modify everything in this file to your liking. +""" +from random import choice, gauss + +import pygame + +from wclib import SIZE +from .utils import clamp, from_polar, load_image, random_in_rect + + +SCREEN = pygame.Rect(0, 0, *SIZE) + + +class Object: + """The base class for all objects of the game.""" + + def __init__(self, pos, sprite: pygame.Surface): + self.pos = pygame.math.Vector2(pos) + self.size = pygame.math.Vector2(sprite.get_size()) + self.sprite = sprite + + def __str__(self): + return f"<{self.__class__.__name__}(pos={self.pos}, size={self.size})>" + + @property + def rect(self): + return pygame.Rect(self.pos, self.size) + + def draw(self, screen): + screen.blit(self.sprite, self.pos) + + def logic(self, **kwargs): + pass + + +class Object8Directional(Object): + SCALE = 3 + SIZE = 16 + SHEET = "blue_ghost" + + ACCELERATION = 0.5 + DAMPING = 0.85 + + # Asymptotic velocity will be solution of + # x = x * DAMPING + ACCELERATION + # That is, + # x = ACCELERATION / (1 - DAMPING) + + def __init__(self, pos): + self.velocity = pygame.Vector2() + self.acceleration = pygame.Vector2() + + super().__init__(pos, self.get_image()) + + def get_image(self): + angle = self.velocity.as_polar()[1] + idx = int((-angle + 90 + 45 / 2) % 360 / 360 * 8) + sheet = load_image(self.SHEET, self.SCALE) + unit = self.SIZE * self.SCALE + return sheet.subsurface(idx * unit, 0, unit, unit) + + def logic(self, **kwargs): + self.velocity *= self.DAMPING + self.velocity += self.acceleration + self.pos += self.velocity + self.sprite = self.get_image() + self.pos.x = clamp(self.pos.x, 0, SIZE[0]-self.sprite.get_width()) + self.pos.y = clamp(self.pos.y, 0, SIZE[1]-self.sprite.get_height()) + + +class Player(Object8Directional): + def __init__(self, pos) -> None: + super().__init__(pos) + self.radius = self.sprite.get_height()*2 + self.sprite.get_height() + + def logic(self, **kwargs): + pressed = pygame.key.get_pressed() + direction_x = (pressed[pygame.K_RIGHT] - pressed[pygame.K_LEFT]) * kwargs.get("dt", 1) + direction_y = (pressed[pygame.K_DOWN] - pressed[pygame.K_UP]) * kwargs.get("dt", 1) + + self.acceleration = pygame.Vector2(direction_x, direction_y) * self.ACCELERATION + super().logic(**kwargs) + + +class Ghost(Object8Directional): + SHEET = "pink_ghost" + ACCELERATION = 0.2 + DAMPING = 0.9 + + def __init__(self, player, pos=None): + if pos is None: + pos = random_in_rect(SCREEN) + super().__init__(pos) + self.player = player + self.goal = self.new_goal() + + def new_goal(self): + direction = from_polar(60, gauss(self.velocity.as_polar()[1], 30)) + return self.rect.center + direction + + def logic(self, **kwargs): + middle_area = SCREEN.inflate(-30, -30) + while self.rect.collidepoint(self.goal) or not middle_area.collidepoint(self.goal): + self.goal = self.new_goal() + + self.acceleration = ( + self.goal - self.rect.center + ).normalize() * self.ACCELERATION * kwargs.get("dt", 1) + super().logic(**kwargs) + + def draw(self, screen): + if self.pos.distance_to(self.player.rect.center) < self.player.radius or\ + pygame.math.Vector2(self.rect.topright).distance_to(self.player.rect.center) < self.player.radius or\ + pygame.math.Vector2(self.rect.bottomright).distance_to(self.player.rect.center) < self.player.radius or\ + pygame.math.Vector2(self.rect.bottomleft).distance_to(self.player.rect.center) < self.player.radius: + screen.blit(self.sprite, self.pos) + + +class SolidObject(Object): + SHEET_RECT = [ + (0, 0, 24, 31), + (24, 0, 24, 24), + (48, 0, 24, 24), + (72, 0, 16, 24), + (88, 0, 48, 43), + (136, 0, 16, 16), + ] + SCALE = 3 + + def __init__(self, pos): + sheet = load_image("tileset", self.SCALE) + sheet.set_colorkey(0xFFFFFF) + rect = choice(self.SHEET_RECT) + rect = [x * self.SCALE for x in rect] + super().__init__(pos, sheet.subsurface(rect)) + + @classmethod + def generate_many(cls, nb=16, max_tries=1000): + objects = [] + tries = 0 # avoids infinite loop + while len(objects) < nb and tries < max_tries: + pos = random_in_rect(SCREEN) + obj = cls(pos) + if not any(obj.rect.colliderect(other.rect) for other in objects): + objects.append(obj) + return objects + + +class LayeredVisibility: + def __init__(self, player: Player) -> None: + self.player: Player = player + + self.surf: pygame.surface.Surface = pygame.surface.Surface(SIZE) + self.surf.set_colorkey((255, 255, 255)) + self.old_surf: pygame.surface.Surface = pygame.surface.Surface(self.surf.get_size()) + self.old_surf.set_alpha(200) + self.old_surf.set_colorkey((255, 255, 255)) + + def draw(self, WIN: pygame.surface.Surface) -> None: + pygame.draw.circle(self.surf, (255, 255, 255), self.player.rect.center, self.player.radius) + + pygame.draw.circle(self.old_surf, (30, 30, 30), self.player.rect.center, self.player.radius) + old_surf_copy = self.old_surf.copy() + pygame.draw.circle(old_surf_copy, (255, 255, 255), self.player.rect.center, self.player.radius) + for i in range(0, 100, 1): + pygame.draw.circle(old_surf_copy, (30+i, 30+i, 30+i), self.player.rect.center, self.player.radius-i) + + WIN.blit(self.old_surf, (0, 0)) + WIN.blit(old_surf_copy, (0, 0)) + WIN.blit(self.surf, (0, 0)) diff --git a/01-fog-of-war/Emc235#2196/utils.py b/01-fog-of-war/Emc235#2196/utils.py new file mode 100644 index 0000000..749019c --- /dev/null +++ b/01-fog-of-war/Emc235#2196/utils.py @@ -0,0 +1,39 @@ +from functools import lru_cache +from pathlib import Path +from random import uniform +from typing import Union, List, Tuple + +import pygame + +SUBMISSION_DIR = Path(__file__).parent +ASSETS = SUBMISSION_DIR.parent / "assets" + +number_type = Union[int, float] +rect_type = Union[pygame.Rect, List[int], Tuple[int, int, int, int]] + + +@lru_cache() +def load_image(name: str, scale=1): + image = pygame.image.load(ASSETS / f"{name}.png") + if scale != 1: + new_size = image.get_width() * scale, image.get_height() * scale + image = pygame.transform.scale(image, new_size) + return image.convert_alpha() + + +def clamp(value: number_type, mini: number_type, maxi: number_type) -> number_type: + """Clamp value between mini and maxi""" + return mini if value < mini else value if value < maxi else maxi + + +def random_in_rect(rect: rect_type) -> pygame.math.Vector2: + """Return a random point uniformly in a rectangle.""" + rect = pygame.Rect(rect) + return pygame.Vector2(uniform(rect.left, rect.right), uniform(rect.top, rect.bottom)) + + +def from_polar(rho: float, theta: float) -> pygame.math.Vector2: + """Create a Vector2 from its polar representation.""" + v = pygame.math.Vector2() + v.from_polar((rho, theta)) + return v From e32196602a19e001d07d01b75e3636764569bd49 Mon Sep 17 00:00:00 2001 From: David Pendergast Date: Mon, 11 Oct 2021 07:30:16 -0400 Subject: [PATCH 19/80] ghast entry * completed challege (ghast) * final cleanup (ghast) * switched over to numpy * added color tinting to scenery sprites * improve janky blurring logic, and add some translucency to ghosts as they get further away --- 01-fog-of-war/ghast/main.py | 329 +++++++++++++++++++++++++++++++++ 01-fog-of-war/ghast/objects.py | 153 +++++++++++++++ 01-fog-of-war/ghast/utils.py | 40 ++++ 3 files changed, 522 insertions(+) create mode 100644 01-fog-of-war/ghast/main.py create mode 100644 01-fog-of-war/ghast/objects.py create mode 100644 01-fog-of-war/ghast/utils.py diff --git a/01-fog-of-war/ghast/main.py b/01-fog-of-war/ghast/main.py new file mode 100644 index 0000000..0d55430 --- /dev/null +++ b/01-fog-of-war/ghast/main.py @@ -0,0 +1,329 @@ +import sys +from pathlib import Path + +try: + import wclib +except ImportError: + # wclib may not be in the path because of the architecture + # of all the challenges and the fact that there are many + # way to run them (through the showcase, or on their own) + + ROOT_FOLDER = Path(__file__).parent.parent.parent + sys.path.append(str(ROOT_FOLDER)) + import wclib + +# This line tells python how to handle the relative imports +# when you run this file directly. +__package__ = "01-fog-of-war." + Path(__file__).parent.name + +# ---- Recommended: don't modify anything above this line ---- # + +# Metadata about your submission +__author__ = "Ghast#4475" +__achievements__ = [ + "Casual", + "Ambitious", + "Adventurous", +] + + +from operator import attrgetter + +import pygame +import math +import numpy + +# To import the modules in yourname/, you need to use relative imports, +# otherwise your project will not be compatible with the showcase. +from .objects import Ghost, Player, SolidObject + + +def luminance(rgb): + # yoinked from some website + r, g, b = rgb + return 0.2126 * r + 0.7152 * g + 0.0722 * b + + +def blend(rgbs): + if len(rgbs) == 0: + return 0, 0, 0 + else: + total_sum = [0, 0, 0] + max_luminosiy = 0 + for rgb in rgbs: + max_luminosiy = max(max_luminosiy, luminance(rgb)) + for i in range(3): + total_sum[i] += rgb[i] + + if max_luminosiy == 0: + return 0, 0, 0 + else: + avg_color = mult(total_sum, 1 / len(rgbs)) + avg_luminosity = luminance(avg_color) + + # scale it up to the correct brightness + return mult(avg_color, max_luminosiy / avg_luminosity) + + +def blend_arrays(arr1, arr2): + lumin1 = arr1[:, :, 0] * 0.2126 + arr1[:, :, 1] * 0.7152 + arr1[:, :, 2] * 0.0722 + lumin1 = numpy.repeat(lumin1[:, :, numpy.newaxis], 3, axis=2) + + lumin2 = arr2[:, :, 0] * 0.2126 + arr2[:, :, 1] * 0.7152 + arr2[:, :, 2] * 0.0722 + lumin2 = numpy.repeat(lumin2[:, :, numpy.newaxis], 3, axis=2) + + return (arr1 * lumin1 + arr2 * lumin2) / (lumin1 + lumin2) + + +def bound(v, lower, upper): + return min(max(v, lower), upper) + + +def intify(rgb): + return tuple(bound(int(255 * rgb[i]), 0, 255) for i in range(3)) + + +def floatify(int_rgb): + return tuple(bound(int_rgb[i] / 255, 0, 1) for i in range(3)) + + +def hexify(int_rgb): + return 0xFF000000 + 0x010000 * int_rgb[0] + 0x000100 * int_rgb[1] + 0x000001 * int_rgb[2] + + +def mult(rgb, v): + return tuple(rgb[i] * v for i in range(3)) + + +BG = (0.4, 0.5, 0.42) # 0x66856C +RV_BG = mult(BG, 0.5) +UNRV_BG = mult(BG, 0.3) + +REVEAL_THRESH = 0.1 +GHOST_VIS_THRESH = REVEAL_THRESH / 8 + +RV_BG_AS_INTS = intify(RV_BG) +UNRV_BG_AS_INTS = intify(UNRV_BG) + +LIGHTING_GRID_DIMS = 64, 48 +LIGHT_RADIUS = int(min(LIGHTING_GRID_DIMS) / 2) - 1 +GAUSSIAN_STD_DEV = 0.12 + +PLAYER_DIM = 0.9 +GHOST_DIM = 0.55 + +TINT_RESOLUTION = 16 +COLORS_TO_TINT = ((102, 133, 108), (70, 102, 85)) + + +def get_1d_gaussian_kernel(n_points, std_dev=GAUSSIAN_STD_DEV, _cache={}): + key = (n_points, std_dev) + if key not in _cache: + raw_values = [] + for i in range(n_points): + x = ((i + 0.5) - n_points / 2) / (n_points / 2) + y = 1 / math.sqrt(2 * math.pi * std_dev) * math.exp(-0.5 * x**2 / std_dev) + raw_values.append(y) + total_sum = sum(raw_values) + normalized_values = [y / total_sum for y in raw_values] + + _cache[key] = numpy.array(normalized_values) + + return _cache[key] + + +def blur_array(array, radius: int): + kernel = get_1d_gaussian_kernel(radius * 2 + 1) + + # XXX these calls are dreadfully slow on large surfaces + # yoinked from https://stackoverflow.com/a/65804973 + array = numpy.apply_along_axis(lambda x: numpy.convolve(x, kernel, mode='same'), 0, array) + array = numpy.apply_along_axis(lambda x: numpy.convolve(x, kernel, mode='same'), 1, array) + + return array + + +def blur_surface(surface: pygame.Surface, radius: int, dest=None) -> pygame.Surface: + """Applies a Gaussian blur to the surface and returns the result. + """ + array = pygame.surfarray.pixels3d(surface) + array = blur_array(array, radius) + + if dest is None: + dest = surface.copy() + + pygame.surfarray.blit_array(dest, array) + + return dest + + +class LightGrid: + + def __init__(self, dims): + self.surf = pygame.Surface(dims) + + self.grass = numpy.zeros([dims[0], dims[1], 3], dtype=numpy.float) + for i in range(3): + self.grass[:, :, i] = UNRV_BG[i] + + self.lighting = numpy.zeros([dims[0], dims[1], 3], dtype=numpy.float) + + self.luminance = numpy.zeros([dims[0], dims[1]], dtype=numpy.float) + self.revealed = self.lighting[:, :, 0] > REVEAL_THRESH + self.visible = self.lighting[:, :, 0] > REVEAL_THRESH + + def dims(self): + return self.surf.get_size() + + def get_grid_cell(self, screen_size, xy, force_inside=False): + x = int(xy[0] / screen_size[0] * self.dims()[0]) + y = int(xy[1] / screen_size[1] * self.dims()[1]) + if not force_inside: + return x, y + else: + dims = self.dims() + return bound(x, 0, dims[0] - 1), bound(y, 0, dims[1] - 1) + + def is_revealed_at(self, screen_size, xy): + cell_xy = self.get_grid_cell(screen_size, xy, force_inside=True) + return self.revealed[cell_xy[0], cell_xy[1]] + + def is_visible_at(self, screen_size, xy): + cell_xy = self.get_grid_cell(screen_size, xy, force_inside=True) + return self.visible[cell_xy[0], cell_xy[1]] + + def get_luminance_at(self, screen_size, xy): + cell_xy = self.get_grid_cell(screen_size, xy, force_inside=True) + return self.luminance[cell_xy[0], cell_xy[1]] + + def get_color_at(self, screen_size, xy): + cell_x, cell_y = self.get_grid_cell(screen_size, xy, force_inside=True) + return tuple(self.lighting[cell_x, cell_y, i] for i in range(3)) + + def compute_lighting(self, screen_size, light_sources): + self.lighting[...] = 0 + self.luminance[...] = 0 + + max_kernel_val_pow2 = max(get_1d_gaussian_kernel(LIGHT_RADIUS * 2 + 1)) ** 2 + + for o in light_sources: + is_player = isinstance(o, Player) + + obj_color = o.get_light_color() + + xy = self.get_grid_cell(screen_size, o.rect.midbottom, force_inside=True) + + if is_player: + obj_color = mult(obj_color, PLAYER_DIM) + self.luminance[xy] = luminance(obj_color) / max_kernel_val_pow2 + else: + obj_color = mult(obj_color, GHOST_DIM) + pass + + for i in range(3): + self.lighting[xy[0]][xy[1]][i] += obj_color[i] / max_kernel_val_pow2 + + self.lighting = blur_array(self.lighting, LIGHT_RADIUS) + self.lighting[self.lighting > 1] = 1.0 + self.lighting[self.lighting < 0] = 0.0 + + self.luminance = blur_array(self.luminance, LIGHT_RADIUS) + self.luminance[self.luminance > 1] = 1.0 + self.luminance[self.luminance < 0] = 0.0 + + dimming = self.luminance * 0.3 + 0.7 + + for i in range(3): + self.lighting[:, :, i] *= dimming + + self.visible = self.luminance > REVEAL_THRESH + self.revealed |= self.luminance > REVEAL_THRESH + + for i in range(3): + self.lighting[:, :, i][self.revealed == False] = 0 + self.grass[:, :, i][self.revealed] = RV_BG[i] + + def draw_bg(self, surface): + res = blend_arrays(self.lighting, self.grass) + + pygame.surfarray.blit_array(self.surf, res * 255) + pygame.transform.scale(self.surf, surface.get_size(), surface) + + +def tint_image(base_img, img_key, color, colors_to_tint, _cache={}): + int_color = intify(color) + tint_color = floatify([round(int_color[i] / TINT_RESOLUTION) * TINT_RESOLUTION for i in range(3)]) + + key = (tint_color, img_key, colors_to_tint) + + if key not in _cache: + res = base_img.copy() + array = pygame.surfarray.pixels2d(res) + for c in colors_to_tint: + orig_color_as_hex = hexify(c) + tinted_color_as_hex = hexify(intify(blend([floatify(c), tint_color]))) + array[array == orig_color_as_hex] = tinted_color_as_hex + + _cache[key] = res + + return _cache[key] + + +def mainloop(): + player = Player((100, 100)) + trees = SolidObject.generate_many(36) + ghosts = [Ghost() for _ in range(16)] + + all_objects = [player] + trees + ghosts + objects_that_emit_light = [o for o in all_objects if o.get_light_color() is not None] + + light_grid = LightGrid(LIGHTING_GRID_DIMS) + + clock = pygame.time.Clock() + + while True: + screen, events = yield + for event in events: + if event.type == pygame.QUIT: + return + + for obj in all_objects: + obj.logic(objects=all_objects) + + light_grid.compute_lighting(screen.get_size(), objects_that_emit_light) + + light_grid.draw_bg(screen) + + for obj in sorted(all_objects, key=attrgetter("rect.bottom")): + is_visible = light_grid.is_visible_at(screen.get_size(), obj.rect.midbottom) + is_revealed = light_grid.is_revealed_at(screen.get_size(), obj.rect.midbottom) + + force_showing = False + force_image = None + if isinstance(obj, Ghost) or isinstance(obj, Player): + if is_visible: + obj.sprite.set_alpha(255) + elif is_revealed: + lumin = light_grid.get_luminance_at(screen.get_size(), obj.rect.midbottom) + if lumin >= REVEAL_THRESH: + obj.sprite.set_alpha(255) + elif lumin <= GHOST_VIS_THRESH: + obj.sprite.set_alpha(0) + else: + a = (lumin - GHOST_VIS_THRESH) / (REVEAL_THRESH - GHOST_VIS_THRESH) + obj.sprite.set_alpha(int(a * 255)) + force_showing = True + elif isinstance(obj, SolidObject) and is_revealed: + force_showing = True + tint_color = light_grid.get_color_at(screen.get_size(), obj.rect.midbottom) + tint_color = mult(tint_color, 0.8) + force_image = tint_image(obj.sprite, obj.my_sheet_rect, tint_color, COLORS_TO_TINT) + + if is_visible or force_showing: + obj.draw(screen, with_sprite=force_image) + + clock.tick(60) + + +if __name__ == "__main__": + wclib.run(mainloop()) diff --git a/01-fog-of-war/ghast/objects.py b/01-fog-of-war/ghast/objects.py new file mode 100644 index 0000000..7b785bc --- /dev/null +++ b/01-fog-of-war/ghast/objects.py @@ -0,0 +1,153 @@ +""" +This file provides objects that can be used to make up +a basic playground for the challenges. + +This code is provided so that you can focus on implementing +a fog of war, without needed +Feel free to modify everything in this file to your liking. +""" +from random import choice, gauss + +import pygame + +from wclib import SIZE +from .utils import clamp, from_polar, load_image, random_in_rect + +SCREEN = pygame.Rect(0, 0, *SIZE) + + +class Object: + """The base class for all objects of the game.""" + + def __init__(self, pos, sprite: pygame.Surface): + self.pos = pygame.Vector2(pos) + self.size = pygame.Vector2(sprite.get_size()) + self.sprite = sprite + + def __str__(self): + return f"<{self.__class__.__name__}(pos={self.pos}, size={self.size})>" + + @property + def rect(self): + return pygame.Rect(self.pos, self.size) + + def draw(self, screen, with_sprite=None): + screen.blit(self.sprite if with_sprite is None else with_sprite, self.pos) + + def logic(self, **kwargs): + pass + + def get_light_color(self): + return None + + +class Object8Directional(Object): + SCALE = 3 + SIZE = 16 + SHEET = "blue_ghost" + + ACCELERATION = 0.5 + DAMPING = 0.85 + + # Asymptotic velocity will be solution of + # x = x * DAMPING + ACCELERATION + # That is, + # x = ACCELERATION / (1 - DAMPING) + + def __init__(self, pos): + self.velocity = pygame.Vector2() + self.acceleration = pygame.Vector2() + + super().__init__(pos, self.get_image()) + + def get_image(self): + angle = self.velocity.as_polar()[1] + idx = int((-angle + 90 + 45 / 2) % 360 / 360 * 8) + sheet = load_image(self.SHEET, self.SCALE) + unit = self.SIZE * self.SCALE + return sheet.subsurface(idx * unit, 0, unit, unit) + + def logic(self, **kwargs): + self.velocity *= self.DAMPING + self.velocity += self.acceleration + self.pos += self.velocity + self.sprite = self.get_image() + + self.pos.x = clamp(self.pos.x, 0, SIZE[0]) + self.pos.y = clamp(self.pos.y, 0, SIZE[1]) + + +class Player(Object8Directional): + + def logic(self, **kwargs): + pressed = pygame.key.get_pressed() + direction_x = pressed[pygame.K_RIGHT] - pressed[pygame.K_LEFT] + direction_y = pressed[pygame.K_DOWN] - pressed[pygame.K_UP] + + self.acceleration = pygame.Vector2(direction_x, direction_y) * self.ACCELERATION + super().logic(**kwargs) + + def get_light_color(self): + return (0.55, 0.75, 0.95) + + +class Ghost(Object8Directional): + SHEET = "pink_ghost" + ACCELERATION = 0.2 + DAMPING = 0.9 + + def __init__(self, pos=None): + if pos is None: + pos = random_in_rect(SCREEN) + super().__init__(pos) + self.goal = self.new_goal() + + def new_goal(self): + direction = from_polar(60, gauss(self.velocity.as_polar()[1], 30)) + return self.rect.center + direction + + def logic(self, **kwargs): + middle_area = SCREEN.inflate(-30, -30) + while self.rect.collidepoint(self.goal) or not middle_area.collidepoint( + self.goal + ): + self.goal = self.new_goal() + + self.acceleration = ( + self.goal - self.rect.center + ).normalize() * self.ACCELERATION + + super().logic(**kwargs) + + def get_light_color(self): + return (0.65, 0.35, 0.65) + + +class SolidObject(Object): + SHEET_RECT = [ + (0, 0, 24, 31), + (24, 0, 24, 24), + (48, 0, 24, 24), + (72, 0, 16, 24), + (88, 0, 48, 43), + (136, 0, 16, 16), + ] + SCALE = 3 + + def __init__(self, pos): + sheet = load_image("tileset", self.SCALE) + sheet.set_colorkey(0xFFFFFF) + self.my_sheet_rect = choice(self.SHEET_RECT) + rect = [x * self.SCALE for x in self.my_sheet_rect] + super().__init__(pos, sheet.subsurface(rect)) + + @classmethod + def generate_many(cls, nb=16, max_tries=1000): + objects = [] + tries = 0 # avoids infinite loop + while len(objects) < nb and tries < max_tries: + pos = random_in_rect(SCREEN) + obj = cls(pos) + if not any(obj.rect.colliderect(other.rect) for other in objects): + objects.append(obj) + return objects diff --git a/01-fog-of-war/ghast/utils.py b/01-fog-of-war/ghast/utils.py new file mode 100644 index 0000000..28d56ff --- /dev/null +++ b/01-fog-of-war/ghast/utils.py @@ -0,0 +1,40 @@ +from functools import lru_cache +from pathlib import Path +from random import uniform + +import pygame + +SUBMISSION_DIR = Path(__file__).parent +ASSETS = SUBMISSION_DIR.parent / "assets" + + +@lru_cache() +def load_image(name: str, scale=1): + image = pygame.image.load(ASSETS / f"{name}.png") + if scale != 1: + new_size = image.get_width() * scale, image.get_height() * scale + image = pygame.transform.scale(image, new_size) + return image.convert_alpha() + + +def clamp(value, mini, maxi): + """Clamp value between mini and maxi""" + if value < mini: + return mini + elif maxi < value: + return maxi + else: + return value + + +def random_in_rect(rect): + """Return a random point uniformly in a rectangle.""" + rect = pygame.Rect(rect) + return pygame.Vector2(uniform(rect.left, rect.right), uniform(rect.top, rect.bottom)) + + +def from_polar(rho, theta): + """Create a Vector2 from its polar representation.""" + v = pygame.Vector2() + v.from_polar((rho, theta)) + return v From 5334d3fd0a7311e92456b431337afb328c7cda22 Mon Sep 17 00:00:00 2001 From: Martin Cupak Date: Mon, 11 Oct 2021 12:30:52 +0100 Subject: [PATCH 20/80] CoopERR entry * working level 2 * adventurous task working * changed name of base * added base/ --- 01-fog-of-war/CoopERR/main.py | 92 ++++++++++++++++++++ 01-fog-of-war/CoopERR/objects.py | 142 +++++++++++++++++++++++++++++++ 01-fog-of-war/CoopERR/utils.py | 40 +++++++++ 3 files changed, 274 insertions(+) create mode 100644 01-fog-of-war/CoopERR/main.py create mode 100644 01-fog-of-war/CoopERR/objects.py create mode 100644 01-fog-of-war/CoopERR/utils.py diff --git a/01-fog-of-war/CoopERR/main.py b/01-fog-of-war/CoopERR/main.py new file mode 100644 index 0000000..56c9a2d --- /dev/null +++ b/01-fog-of-war/CoopERR/main.py @@ -0,0 +1,92 @@ +import sys +from pathlib import Path + +from pygame.constants import SRCALPHA + +try: + import wclib +except ImportError: + # wclib may not be in the path because of the architecture + # of all the challenges and the fact that there are many + # way to run them (through the showcase, or on their own) + + ROOT_FOLDER = Path(__file__).parent.parent.parent + sys.path.append(str(ROOT_FOLDER)) + import wclib + +# This line tells python how to handle the relative imports +# when you run this file directly. +__package__ = "01-fog-of-war." + Path(__file__).parent.name + +# ---- Recommended: don't modify anything above this line ---- # + +# Metadata about your submission +__author__ = "CoopERR" +__achievements__ = [ # Uncomment the ones you've done + "Casual", + "Ambitious", + "Adventurous", +] + + +from operator import attrgetter +import pygame + +# To import the modules in yourname/, you need to use relative imports, +# otherwise your project will not be compatible with the showcase. +from .objects import Ghost, Player, SolidObject + +BACKGROUND = 0x66856C + + +def mainloop(): + player = Player((100, 100)) + trees = SolidObject.generate_many(36) + ghosts = [Ghost() for _ in range(16)] + + all_objects = trees + [player] + ghosts + solid_objects = trees + [player] + + fog = pygame.surface.Surface(pygame.display.get_surface().get_size(), pygame.SRCALPHA) + fog.fill((0,0,0)) + + def field_of_view(): + size = 150 + for i in range(200, 0, -1): + pygame.draw.circle(fog, (0,0,0,i), player.rect.center, size) + size -= 0.9 + + def ghost_distance(ghost): + distance_x = (player.rect.center[0]-ghost.rect.center[0]) + distance_y = (player.rect.center[1]-ghost.rect.center[1]) + + return (abs(distance_x) + abs(distance_y)) < 150 + + clock = pygame.time.Clock() + while True: + screen, events = yield + for event in events: + if event.type == pygame.QUIT: + return + + for obj in all_objects: + obj.logic(objects=all_objects) + + screen.fill(BACKGROUND) + + for ghost in sorted(ghosts, key=attrgetter("rect.bottom")): + if ghost_distance(ghost): + ghost.draw(screen) + for object in sorted(solid_objects, key=attrgetter("rect.bottom")): + object.draw(screen) + + field_of_view() + screen.blit(fog,(0,0)) + + + + clock.tick(60) + + +if __name__ == "__main__": + wclib.run(mainloop()) diff --git a/01-fog-of-war/CoopERR/objects.py b/01-fog-of-war/CoopERR/objects.py new file mode 100644 index 0000000..e507e56 --- /dev/null +++ b/01-fog-of-war/CoopERR/objects.py @@ -0,0 +1,142 @@ +""" +This file provides objects that can be used to make up +a basic playground for the challenges. + +This code is provided so that you can focus on implementing +a fog of war, without needed +Feel free to modify everything in this file to your liking. +""" +from random import choice, gauss + +import pygame + +from wclib import SIZE +from .utils import clamp, from_polar, load_image, random_in_rect + +SCREEN = pygame.Rect(0, 0, *SIZE) + + +class Object: + """The base class for all objects of the game.""" + + def __init__(self, pos, sprite: pygame.Surface): + self.pos = pygame.Vector2(pos) + self.size = pygame.Vector2(sprite.get_size()) + self.sprite = sprite + + def __str__(self): + return f"<{self.__class__.__name__}(pos={self.pos}, size={self.size})>" + + @property + def rect(self): + return pygame.Rect(self.pos, self.size) + + def draw(self, screen): + screen.blit(self.sprite, self.pos) + + def logic(self, **kwargs): + pass + + +class Object8Directional(Object): + SCALE = 3 + SIZE = 16 + SHEET = "blue_ghost" + + ACCELERATION = 0.5 + DAMPING = 0.85 + + # Asymptotic velocity will be solution of + # x = x * DAMPING + ACCELERATION + # That is, + # x = ACCELERATION / (1 - DAMPING) + + def __init__(self, pos): + self.velocity = pygame.Vector2() + self.acceleration = pygame.Vector2() + + super().__init__(pos, self.get_image()) + + def get_image(self): + angle = self.velocity.as_polar()[1] + idx = int((-angle + 90 + 45 / 2) % 360 / 360 * 8) + sheet = load_image(self.SHEET, self.SCALE) + unit = self.SIZE * self.SCALE + return sheet.subsurface(idx * unit, 0, unit, unit) + + def logic(self, **kwargs): + self.velocity *= self.DAMPING + self.velocity += self.acceleration + self.pos += self.velocity + self.sprite = self.get_image() + + self.pos.x = clamp(self.pos.x, 0, SIZE[0]) + self.pos.y = clamp(self.pos.y, 0, SIZE[1]) + + +class Player(Object8Directional): + def logic(self, **kwargs): + pressed = pygame.key.get_pressed() + direction_x = pressed[pygame.K_RIGHT] - pressed[pygame.K_LEFT] + direction_y = pressed[pygame.K_DOWN] - pressed[pygame.K_UP] + + self.acceleration = pygame.Vector2(direction_x, direction_y) * self.ACCELERATION + super().logic(**kwargs) + + +class Ghost(Object8Directional): + SHEET = "pink_ghost" + ACCELERATION = 0.2 + DAMPING = 0.9 + + def __init__(self, pos=None): + if pos is None: + pos = random_in_rect(SCREEN) + super().__init__(pos) + self.goal = self.new_goal() + + def new_goal(self): + direction = from_polar(60, gauss(self.velocity.as_polar()[1], 30)) + return self.rect.center + direction + + def logic(self, **kwargs): + middle_area = SCREEN.inflate(-30, -30) + while self.rect.collidepoint(self.goal) or not middle_area.collidepoint( + self.goal + ): + self.goal = self.new_goal() + + self.acceleration = ( + self.goal - self.rect.center + ).normalize() * self.ACCELERATION + super().logic(**kwargs) + + +class SolidObject(Object): + SHEET_RECT = [ + (0, 0, 24, 31), + (24, 0, 24, 24), + (48, 0, 24, 24), + (72, 0, 16, 24), + (88, 0, 48, 43), + (136, 0, 16, 16), + ] + SCALE = 3 + + def __init__(self, pos): + sheet = load_image("tileset", self.SCALE) + sheet.set_colorkey(0xFFFFFF) + rect = choice(self.SHEET_RECT) + rect = [x * self.SCALE for x in rect] + super().__init__(pos, sheet.subsurface(rect)) + + @classmethod + def generate_many(cls, nb=16, max_tries=1000): + objects = [] + tries = 0 # avoids infinite loop + while len(objects) < nb and tries < max_tries: + pos = random_in_rect(SCREEN) + obj = cls(pos) + if not any(obj.rect.colliderect(other.rect) for other in objects): + objects.append(obj) + return objects diff --git a/01-fog-of-war/CoopERR/utils.py b/01-fog-of-war/CoopERR/utils.py new file mode 100644 index 0000000..28d56ff --- /dev/null +++ b/01-fog-of-war/CoopERR/utils.py @@ -0,0 +1,40 @@ +from functools import lru_cache +from pathlib import Path +from random import uniform + +import pygame + +SUBMISSION_DIR = Path(__file__).parent +ASSETS = SUBMISSION_DIR.parent / "assets" + + +@lru_cache() +def load_image(name: str, scale=1): + image = pygame.image.load(ASSETS / f"{name}.png") + if scale != 1: + new_size = image.get_width() * scale, image.get_height() * scale + image = pygame.transform.scale(image, new_size) + return image.convert_alpha() + + +def clamp(value, mini, maxi): + """Clamp value between mini and maxi""" + if value < mini: + return mini + elif maxi < value: + return maxi + else: + return value + + +def random_in_rect(rect): + """Return a random point uniformly in a rectangle.""" + rect = pygame.Rect(rect) + return pygame.Vector2(uniform(rect.left, rect.right), uniform(rect.top, rect.bottom)) + + +def from_polar(rho, theta): + """Create a Vector2 from its polar representation.""" + v = pygame.Vector2() + v.from_polar((rho, theta)) + return v From 2ec4e47abbf8a5b2bcefdb6d60b97382a696e24e Mon Sep 17 00:00:00 2001 From: Baconinvader <47951383+Baconinvader@users.noreply.github.com> Date: Mon, 11 Oct 2021 12:32:23 +0100 Subject: [PATCH 21/80] Baconivader entry --- 01-fog-of-war/baconinvader/main.py | 81 ++++++ 01-fog-of-war/baconinvader/objects.py | 345 ++++++++++++++++++++++++++ 01-fog-of-war/baconinvader/utils.py | 40 +++ 3 files changed, 466 insertions(+) create mode 100644 01-fog-of-war/baconinvader/main.py create mode 100644 01-fog-of-war/baconinvader/objects.py create mode 100644 01-fog-of-war/baconinvader/utils.py diff --git a/01-fog-of-war/baconinvader/main.py b/01-fog-of-war/baconinvader/main.py new file mode 100644 index 0000000..f321590 --- /dev/null +++ b/01-fog-of-war/baconinvader/main.py @@ -0,0 +1,81 @@ +import sys +from pathlib import Path + +try: + import wclib +except ImportError: + # wclib may not be in the path because of the architecture + # of all the challenges and the fact that there are many + # way to run them (through the showcase, or on their own) + + ROOT_FOLDER = Path(__file__).parent.parent.parent + sys.path.append(str(ROOT_FOLDER)) + import wclib + +# This line tells python how to handle the relative imports +# when you run this file directly. +__package__ = "01-fog-of-war." + Path(__file__).parent.name + +# ---- Recommended: don't modify anything above this line ---- # + +# Metadata about your submission +__author__ = "Your Discord Tag Goes Here#7777" +__achievements__ = [ # Uncomment the ones you've done + # "Casual", + # "Ambitious", + # "Adventurous", +] + + +from operator import attrgetter +import pygame + +# To import the modules in yourname/, you need to use relative imports, +# otherwise your project will not be compatible with the showcase. +from .objects import Ghost, Player, SolidObject, Darkness, Light + +BACKGROUND = 0x66856C + + +def mainloop(): + darkness = Darkness() + #originally I was going to have support for multiple lights but I'm a busy man okay + light = Light(darkness, (100,100), 255, 100, 150, 150) + player = Player((100, 100)) + trees = SolidObject.generate_many(36) + ghosts = [Ghost() for _ in range(16)] + + all_objects = trees + [player] + ghosts + + + + clock = pygame.time.Clock() + while True: + screen, events = yield + for event in events: + if event.type == pygame.QUIT: + return + + for obj in all_objects: + obj.logic(objects=all_objects) + + screen.fill(BACKGROUND) + + visible_objects = light.get_visible_objects(all_objects) + for object in sorted(visible_objects, key=attrgetter("rect.bottom")): + object.draw(screen) + + #move light to player + light.pos.x = player.rect.centerx-light.radius + light.pos.y = player.rect.centery-light.radius + + light.update() + light.draw(screen, visible_objects) + darkness.draw(screen, light) + light.draw_uncovered(screen) + + clock.tick(60) + + +if __name__ == "__main__": + wclib.run(mainloop()) diff --git a/01-fog-of-war/baconinvader/objects.py b/01-fog-of-war/baconinvader/objects.py new file mode 100644 index 0000000..d303f43 --- /dev/null +++ b/01-fog-of-war/baconinvader/objects.py @@ -0,0 +1,345 @@ +""" +This file provides objects that can be used to make up +a basic playground for the challenges. + +This code is provided so that you can focus on implementing +a fog of war, without needed +Feel free to modify everything in this file to your liking. +""" +from random import choice, gauss + +import pygame + +from wclib import SIZE +from .utils import clamp, from_polar, load_image, random_in_rect + +SCREEN = pygame.Rect(0, 0, *SIZE) + + +class Object: + """The base class for all objects of the game.""" + + def __init__(self, pos, sprite: pygame.Surface): + self.pos = pygame.Vector2(pos) + self.size = pygame.Vector2(sprite.get_size()) + self.sprite = sprite + + def __str__(self): + return f"<{self.__class__.__name__}(pos={self.pos}, size={self.size})>" + + @property + def rect(self): + return pygame.Rect(self.pos, self.size) + + def draw(self, screen): + screen.blit(self.sprite, self.pos) + + def logic(self, **kwargs): + pass + + +class Object8Directional(Object): + SCALE = 3 + SIZE = 16 + SHEET = "blue_ghost" + + ACCELERATION = 0.5 + DAMPING = 0.85 + + # Asymptotic velocity will be solution of + # x = x * DAMPING + ACCELERATION + # That is, + # x = ACCELERATION / (1 - DAMPING) + + def __init__(self, pos): + self.velocity = pygame.Vector2() + self.acceleration = pygame.Vector2() + + super().__init__(pos, self.get_image()) + + def get_image(self): + angle = self.velocity.as_polar()[1] + idx = int((-angle + 90 + 45 / 2) % 360 / 360 * 8) + sheet = load_image(self.SHEET, self.SCALE) + unit = self.SIZE * self.SCALE + return sheet.subsurface(idx * unit, 0, unit, unit) + + def logic(self, **kwargs): + self.velocity *= self.DAMPING + self.velocity += self.acceleration + self.pos += self.velocity + self.sprite = self.get_image() + + self.pos.x = clamp(self.pos.x, 0, SIZE[0]) + self.pos.y = clamp(self.pos.y, 0, SIZE[1]) + + +class Player(Object8Directional): + def logic(self, **kwargs): + pressed = pygame.key.get_pressed() + direction_x = pressed[pygame.K_RIGHT] - pressed[pygame.K_LEFT] + direction_y = pressed[pygame.K_DOWN] - pressed[pygame.K_UP] + + self.acceleration = pygame.Vector2(direction_x, direction_y) * self.ACCELERATION + super().logic(**kwargs) + + +class Ghost(Object8Directional): + SHEET = "pink_ghost" + ACCELERATION = 0.2 + DAMPING = 0.9 + + def __init__(self, pos=None): + if pos is None: + pos = random_in_rect(SCREEN) + super().__init__(pos) + self.goal = self.new_goal() + + def new_goal(self): + direction = from_polar(60, gauss(self.velocity.as_polar()[1], 30)) + return self.rect.center + direction + + def logic(self, **kwargs): + middle_area = SCREEN.inflate(-30, -30) + while self.rect.collidepoint(self.goal) or not middle_area.collidepoint( + self.goal + ): + self.goal = self.new_goal() + + self.acceleration = ( + self.goal - self.rect.center + ).normalize() * self.ACCELERATION + super().logic(**kwargs) + + +class SolidObject(Object): + SHEET_RECT = [ + (0, 0, 24, 31), + (24, 0, 24, 24), + (48, 0, 24, 24), + (72, 0, 16, 24), + (88, 0, 48, 43), + (136, 0, 16, 16), + ] + SCALE = 3 + + def __init__(self, pos): + sheet = load_image("tileset", self.SCALE) + sheet.set_colorkey(0xFFFFFF) + rect = choice(self.SHEET_RECT) + rect = [x * self.SCALE for x in rect] + super().__init__(pos, sheet.subsurface(rect)) + + @classmethod + def generate_many(cls, nb=16, max_tries=1000): + objects = [] + tries = 0 # avoids infinite loop + while len(objects) < nb and tries < max_tries: + pos = random_in_rect(SCREEN) + obj = cls(pos) + if not any(obj.rect.colliderect(other.rect) for other in objects): + objects.append(obj) + return objects + +class Darkness(): + def __init__(self, min_light=0, reveal_light=40): + self.rect = SCREEN.copy() + + self.min_light = min_light #minimum light level + self.reveal_light = reveal_light #how light an uncovered part of the map is + + self.surface = pygame.Surface((SCREEN.w, SCREEN.h), pygame.SRCALPHA) + self.surface.fill((0,0,0,255-min_light)) + + #uncovered part of the map + self.shown_surface = self.surface.copy() + + + def draw(self, screen, light): + + #draw darkness + self.surface.blit(self.shown_surface, (0,0), special_flags=pygame.BLEND_RGBA_MIN) + screen.blit(self.surface, (0,0) ) + + + #clear light + pygame.gfxdraw.box(self.surface, light.rect, (0,0,0,255-self.min_light)) + + +class Light(): + def __init__(self, darkness, pos, light, max_light_radius, min_light_radius, radius): + self.radius = radius + + #strength of the light, drops off to 0 at distance radius + self.light = light + #radius up to which the light is as bright as possible + self.max_light_radius = max_light_radius + + self.min_light_radius = min_light_radius + + self.pos = pygame.Vector2(pos) + self.rect = pygame.Rect(self.pos.x, self.pos.y, self.radius*2, self.radius*2) + + self.darkness = darkness + self.create_surface() + + #create the actual light surface + def create_surface(self): + import pygame.gfxdraw + + + self.surface = pygame.Surface((self.rect.w, self.rect.h), flags=pygame.SRCALPHA) + self.surface.fill((0,0,0,0)) + + #draw center bright point + self.max_light_surface = pygame.Surface((self.max_light_radius*2, self.max_light_radius*2), flags=pygame.SRCALPHA) + pygame.gfxdraw.filled_circle(self.max_light_surface, self.max_light_radius, self.max_light_radius, self.max_light_radius, (0,0,0, self.light )) + + self.surface.blit(self.max_light_surface, (self.radius-self.max_light_radius, self.radius-self.max_light_radius)) + + #how much dimmer the light should get per pixel + light_change_per_pixel = (self.light )/(self.radius-self.max_light_radius) + + min_light_level = self.light-(light_change_per_pixel*(self.min_light_radius-self.max_light_radius) ) + + #draw fade + #reversed to prevent gaps in the drawing + for i in reversed(range( (self.radius-(self.max_light_radius))*1 )): + + pix = i + + dist_from_center = self.max_light_radius+pix + light_level = clamp(int(self.light-(light_change_per_pixel*pix)), min_light_level, 255-self.darkness.min_light) + colour = (0,0,0, light_level) + + pygame.gfxdraw.filled_circle(self.surface, self.rect.w//2, self.rect.h//2, int(self.max_light_radius+pix), colour) + + #draw full_surface (surface that will be permanently drawn on the FOW) + self.full_surface = pygame.Surface((self.radius*2, self.radius*2), flags=pygame.SRCALPHA) + self.full_surface.fill( (0,0,0,255) ) + pygame.gfxdraw.filled_circle(self.full_surface, self.radius, self.radius, self.radius, (0,128,0,255-self.darkness.reveal_light)) + + + def get_visible_objects(self, objects): + visible_objects = [] + for obj in objects: + visible = True + + if hasattr(obj, "velocity"): #ghosts, basically + dx = obj.rect.centerx-self.rect.centerx + dy = obj.rect.centery-self.rect.centery + dist = ( (dx**2) + (dy**2) )**0.5 + + #object not within range + if dist > self.radius: + visible = False + + if visible: + visible_objects.append(obj) + + return visible_objects + + def update(self): + self.rect.x = self.pos.x + self.rect.y = self.pos.y + + def draw(self, screen, visible_objects): + + self.draw_surface = self.surface.copy() + + #get objects in range + objects_in_range = [] + dists = [] + for obj in visible_objects: + if type(obj) == Player: + continue + + dx = obj.rect.centerx-self.rect.centerx + dy = obj.rect.centery-self.rect.centery + dist = ( (dx**2) + (dy**2) )**0.5 + + #object within range + if dist <= self.radius: + objects_in_range.append(obj) + dists.append(dist) + + #create shadows + self_center_pos = pygame.Vector2(self.pos) + self_center_pos.x += self.rect.w/2 + self_center_pos.y += self.rect.h/2 + + for i,obj in enumerate(objects_in_range): + center_pos = pygame.Vector2(obj.pos) + center_pos.x += obj.rect.w/2 + center_pos.y += obj.rect.h/2 + + angle = pygame.Vector2(0,0).angle_to(center_pos-self_center_pos) + + shadow_start_length = (obj.rect.w+obj.rect.h)/2 + + dist = dists[i] + + #create the vertices of the shadow polygon + + #"start" points are closest to the object + #"side" points are the points which are at the edge of the light radius + #"end" points are points that are used to make the shadow complete and prevent gaps from being left + shadow_start_left = pygame.Vector2((-shadow_start_length/2, 0)) + shadow_start_left.rotate_ip(angle+90) + shadow_start_left += center_pos + + + shadow_side_left = (shadow_start_left-self_center_pos) + shadow_side_left.scale_to_length(self.radius) + shadow_side_left += self_center_pos + + shadow_end_left = center_pos-self_center_pos + shadow_end_left.scale_to_length(self.radius) + shadow_end_left += shadow_side_left + + shadow_start_right = pygame.Vector2((shadow_start_length/2, 0)) + shadow_start_right.rotate_ip(angle+90) + shadow_start_right += center_pos + + shadow_side_right = (shadow_start_right-self_center_pos) + shadow_side_right.scale_to_length(self.radius) + shadow_side_right += self_center_pos + + shadow_end_right = center_pos-self_center_pos + shadow_end_right.scale_to_length(self.radius) + shadow_end_right += shadow_side_right + + + + pygame.gfxdraw.filled_circle(self.draw_surface, int(center_pos.x-self.pos.x), int(center_pos.y-self.pos.y), int(shadow_start_length//2) , (0,0,0,0)) + + ##uncomment these and you can see the points in action + ##green - start, blue - side, red - end + #pygame.gfxdraw.filled_circle(screen, int(shadow_start_left.x), int(shadow_start_left.y), 5 , (0,255,0,128)) + #pygame.gfxdraw.filled_circle(screen, int(shadow_start_right.x), int(shadow_start_right.y), 5 , (0,255,0,128)) + + #pygame.gfxdraw.filled_circle(screen, int(shadow_side_left.x), int(shadow_side_left.y), 7 , (255,0,0,128)) + #pygame.gfxdraw.filled_circle(screen, int(shadow_side_right.x), int(shadow_side_right.y), 7 , (255,0,0,128)) + + #pygame.gfxdraw.filled_circle(screen, int(shadow_end_left.x), int(shadow_end_left.y), 9 , (0,0,255,128)) + #pygame.gfxdraw.filled_circle(screen, int(shadow_end_right.x), int(shadow_end_right.y), 9 , (0,0,255,128)) + + #offset so they can be relative to the draw surface + shadow_start_left -= self.pos + shadow_start_right -= self.pos + shadow_side_left -= self.pos + shadow_side_right -= self.pos + shadow_end_left -= self.pos + shadow_end_right -= self.pos + + + pygame.gfxdraw.filled_polygon(self.draw_surface, [shadow_start_left, shadow_side_left, shadow_end_left, shadow_end_right, shadow_side_right, shadow_start_right], (0,0,0,0) ) + + + self.darkness.surface.blit(self.draw_surface, self.rect, special_flags=pygame.BLEND_RGBA_SUB) + + + def draw_uncovered(self, screen): + #draw the uncovered parts of the map + self.darkness.shown_surface.blit(self.full_surface, self.rect, special_flags=pygame.BLEND_RGBA_MIN) + diff --git a/01-fog-of-war/baconinvader/utils.py b/01-fog-of-war/baconinvader/utils.py new file mode 100644 index 0000000..28d56ff --- /dev/null +++ b/01-fog-of-war/baconinvader/utils.py @@ -0,0 +1,40 @@ +from functools import lru_cache +from pathlib import Path +from random import uniform + +import pygame + +SUBMISSION_DIR = Path(__file__).parent +ASSETS = SUBMISSION_DIR.parent / "assets" + + +@lru_cache() +def load_image(name: str, scale=1): + image = pygame.image.load(ASSETS / f"{name}.png") + if scale != 1: + new_size = image.get_width() * scale, image.get_height() * scale + image = pygame.transform.scale(image, new_size) + return image.convert_alpha() + + +def clamp(value, mini, maxi): + """Clamp value between mini and maxi""" + if value < mini: + return mini + elif maxi < value: + return maxi + else: + return value + + +def random_in_rect(rect): + """Return a random point uniformly in a rectangle.""" + rect = pygame.Rect(rect) + return pygame.Vector2(uniform(rect.left, rect.right), uniform(rect.top, rect.bottom)) + + +def from_polar(rho, theta): + """Create a Vector2 from its polar representation.""" + v = pygame.Vector2() + v.from_polar((rho, theta)) + return v From 7f18f71df4dfaa1e7cfbb26e8db506a60d297465 Mon Sep 17 00:00:00 2001 From: tank king <72032294+tank-king@users.noreply.github.com> Date: Mon, 11 Oct 2021 17:03:31 +0530 Subject: [PATCH 22/80] tank-king entry * Add files via upload * Delete objects-old.py * Casual + Ambitious + Adventurous * Delete 01-fog-of-war/tank_king/__pycache__ directory --- 01-fog-of-war/tank_king/Description.txt | 1 + 01-fog-of-war/tank_king/main.py | 81 ++++++++++ 01-fog-of-war/tank_king/objects.py | 207 ++++++++++++++++++++++++ 01-fog-of-war/tank_king/utils.py | 51 ++++++ 4 files changed, 340 insertions(+) create mode 100644 01-fog-of-war/tank_king/Description.txt create mode 100644 01-fog-of-war/tank_king/main.py create mode 100644 01-fog-of-war/tank_king/objects.py create mode 100644 01-fog-of-war/tank_king/utils.py diff --git a/01-fog-of-war/tank_king/Description.txt b/01-fog-of-war/tank_king/Description.txt new file mode 100644 index 0000000..153cf1e --- /dev/null +++ b/01-fog-of-war/tank_king/Description.txt @@ -0,0 +1 @@ +This branch contains added lighting, and flickering/blinking effect of the torch of the player diff --git a/01-fog-of-war/tank_king/main.py b/01-fog-of-war/tank_king/main.py new file mode 100644 index 0000000..fb0f1ce --- /dev/null +++ b/01-fog-of-war/tank_king/main.py @@ -0,0 +1,81 @@ +import random +import sys +from pathlib import Path + +try: + import wclib +except ImportError: + # wclib may not be in the path because of the architecture + # of all the challenges and the fact that there are many + # way to run them (through the showcase, or on their own) + + ROOT_FOLDER = Path(__file__).parent.parent.parent + sys.path.append(str(ROOT_FOLDER)) + import wclib + +# This line tells python how to handle the relative imports +# when you run this file directly. +__package__ = "01-fog-of-war." + Path(__file__).parent.name + +# ---- Recommended: don't modify anything above this line ---- # + +# Metadata about your submission +__author__ = "Your Discord Tag Goes Here#7777" +__achievements__ = [ # Uncomment the ones you've done + # "Casual", + # "Ambitious", + # "Adventurous", +] + +from operator import attrgetter +import pygame + +# To import the modules in yourname/, you need to use relative imports, +# otherwise your project will not be compatible with the showcase. +from .objects import Ghost, Player, SolidObject, LightGlow, DarkOverlay +from .utils import distance, map_to_range + +BACKGROUND = 0x66856C + + +def mainloop(): + player = Player((100, 100)) + trees = SolidObject.generate_many(36) + ghosts = [Ghost() for _ in range(16)] + + all_objects = trees + [player] + ghosts + + clock = pygame.time.Clock() + darkness = DarkOverlay() + while True: + screen, events = yield + for event in events: + if event.type == pygame.QUIT: + return + + for obj in all_objects: + obj.logic(objects=all_objects) + + screen.fill(BACKGROUND) + for object in sorted(all_objects, key=attrgetter("rect.bottom")): + if type(object) == Ghost: + d = distance(object.rect.center, player.rect.center) + if d < darkness.light.radius: + object.sprite.set_alpha(255 - map_to_range(d, 0, darkness.light.radius, 0, 255)) + object.draw(screen) + if d < 50: + darkness.light.glow = random.randint(1, 5) + darkness.light.update_glow() + else: + if darkness.light.glow != 11: + darkness.light.glow = 11 + darkness.light.update_glow() + else: + object.draw(screen) + darkness.draw(screen, player.rect.center) + + clock.tick(60) + + +if __name__ == "__main__": + wclib.run(mainloop()) diff --git a/01-fog-of-war/tank_king/objects.py b/01-fog-of-war/tank_king/objects.py new file mode 100644 index 0000000..9440911 --- /dev/null +++ b/01-fog-of-war/tank_king/objects.py @@ -0,0 +1,207 @@ +""" +This file provides objects that can be used to make up +a basic playground for the challenges. + +This code is provided so that you can focus on implementing +a fog of war, without needed +Feel free to modify everything in this file to your liking. +""" +import random +import time +from random import choice, gauss + +import pygame + +from wclib import SIZE +from .utils import clamp, from_polar, load_image, random_in_rect, distance + +SCREEN = pygame.Rect(0, 0, *SIZE) + + +class Object: + """The base class for all objects of the game.""" + + def __init__(self, pos, sprite: pygame.Surface): + self.pos = pygame.Vector2(pos) + self.size = pygame.Vector2(sprite.get_size()) + self.sprite = sprite + + def __str__(self): + return f"<{self.__class__.__name__}(pos={self.pos}, size={self.size})>" + + @property + def rect(self): + return pygame.Rect(self.pos, self.size) + + def draw(self, screen): + screen.blit(self.sprite, self.pos) + + def logic(self, **kwargs): + pass + + +class Object8Directional(Object): + SCALE = 3 + SIZE = 16 + SHEET = "blue_ghost" + + ACCELERATION = 0.5 + DAMPING = 0.85 + + # Asymptotic velocity will be solution of + # x = x * DAMPING + ACCELERATION + # That is, + # x = ACCELERATION / (1 - DAMPING) + + def __init__(self, pos): + self.velocity = pygame.Vector2() + self.acceleration = pygame.Vector2() + + super().__init__(pos, self.get_image()) + + def get_image(self): + angle = self.velocity.as_polar()[1] + idx = int((-angle + 90 + 45 / 2) % 360 / 360 * 8) + sheet = load_image(self.SHEET, self.SCALE) + unit = self.SIZE * self.SCALE + return sheet.subsurface(idx * unit, 0, unit, unit) + + def logic(self, **kwargs): + self.velocity *= self.DAMPING + self.velocity += self.acceleration + self.pos += self.velocity + self.sprite = self.get_image() + + self.pos.x = clamp(self.pos.x, 0, SIZE[0]) + self.pos.y = clamp(self.pos.y, 0, SIZE[1]) + + +class Player(Object8Directional): + def logic(self, **kwargs): + pressed = pygame.key.get_pressed() + direction_x = pressed[pygame.K_RIGHT] - pressed[pygame.K_LEFT] + direction_y = pressed[pygame.K_DOWN] - pressed[pygame.K_UP] + + self.acceleration = pygame.Vector2(direction_x, direction_y) * self.ACCELERATION + super().logic(**kwargs) + + +class Ghost(Object8Directional): + SHEET = "pink_ghost" + ACCELERATION = 0.2 + DAMPING = 0.9 + + def __init__(self, pos=None): + if pos is None: + pos = random_in_rect(SCREEN) + super().__init__(pos) + self.goal = self.new_goal() + + def new_goal(self): + direction = from_polar(60, gauss(self.velocity.as_polar()[1], 30)) + return self.rect.center + direction + + def logic(self, **kwargs): + middle_area = SCREEN.inflate(-30, -30) + while self.rect.collidepoint(self.goal) or not middle_area.collidepoint( + self.goal + ): + self.goal = self.new_goal() + + self.acceleration = ( + self.goal - self.rect.center + ).normalize() * self.ACCELERATION + super().logic(**kwargs) + + +class SolidObject(Object): + SHEET_RECT = [ + (0, 0, 24, 31), + (24, 0, 24, 24), + (48, 0, 24, 24), + (72, 0, 16, 24), + (88, 0, 48, 43), + (136, 0, 16, 16), + ] + SCALE = 3 + + def __init__(self, pos): + sheet = load_image("tileset", self.SCALE) + sheet.set_colorkey(0xFFFFFF) + rect = choice(self.SHEET_RECT) + rect = [x * self.SCALE for x in rect] + super().__init__(pos, sheet.subsurface(rect)) + + @classmethod + def generate_many(cls, nb=16, max_tries=1000): + objects = [] + tries = 0 # avoids infinite loop + while len(objects) < nb and tries < max_tries: + pos = random_in_rect(SCREEN) + obj = cls(pos) + if not any(obj.rect.colliderect(other.rect) for other in objects): + objects.append(obj) + return objects + + +class LightGlow: + def __init__(self, radius=125): + self.radius = radius + self.surf = pygame.Surface((radius * 2, radius * 2), pygame.SRCALPHA) + # self.surf.fill((255, 255, 255)) + + # pygame.draw.circle(self.surf, (255, 255, 255), self.surf.get_rect().center, self.surf.get_width() // 2) + layers = 25 + self.glow = 11 + for i in range(layers): + # k = 255 - 255 // (i + 1) + 50 + k = i * self.glow + k = clamp(k, 0, 255) + pygame.draw.circle(self.surf, (k, k, k), self.surf.get_rect().center, radius - i * 5) + self.update_glow() + self.blink_timer = time.time() + self.is_blinking = False + self.blink_k = 1 + + def blink(self): + self.blink_timer = time.time() + self.is_blinking = True + + def update_glow(self): + self.glow += 1 + self.surf = pygame.Surface((self.radius * 2, self.radius * 2), pygame.SRCALPHA) + layers = 25 + self.glow = clamp(self.glow, 0, 255) + for i in range(layers): + k = i * self.glow + k = clamp(k, 0, 255) + pygame.draw.circle(self.surf, (k, k, k), self.surf.get_rect().center, self.radius - i * 3) + + +class DarkOverlay: + def __init__(self): + self.surf = pygame.Surface(SCREEN.size) + self.light = LightGlow() + self.cell_size = 16 * 2 + self.grid = [[0 * random.random() for _ in range(SCREEN.w // self.cell_size)] for _ in range(SCREEN.h // self.cell_size)] + + def draw(self, surf: pygame.Surface, pos): + # self.light.update_glow() + size = self.cell_size + for row in range(len(self.grid)): + for col in range(len(self.grid[row])): + k = self.grid[row][col] + if k > 0: + k -= 0.1 + self.grid[row][col] = clamp(k, 25, 255) + k = int(self.grid[row][col]) + center = (col * size + size // 2, row * size + size // 2) + if distance(center, pos) < self.light.radius: + color = 55 + self.grid[row][col] = color + k = color + k -= (11 - self.light.glow) * 2 + k = clamp(k, 0, 255) + pygame.draw.rect(self.surf, (k, k, k), (col * size, row * size, size, size)) + self.surf.blit(self.light.surf, self.light.surf.get_rect(center=pos), special_flags=pygame.BLEND_RGBA_MAX) + surf.blit(self.surf, (0, 0), special_flags=pygame.BLEND_RGBA_MULT) diff --git a/01-fog-of-war/tank_king/utils.py b/01-fog-of-war/tank_king/utils.py new file mode 100644 index 0000000..9172a06 --- /dev/null +++ b/01-fog-of-war/tank_king/utils.py @@ -0,0 +1,51 @@ +import math +from functools import lru_cache +from pathlib import Path +from random import uniform + +import pygame + +SUBMISSION_DIR = Path(__file__).parent +ASSETS = SUBMISSION_DIR.parent / "assets" + + +@lru_cache() +def load_image(name: str, scale=1): + image = pygame.image.load(ASSETS / f"{name}.png") + if scale != 1: + new_size = image.get_width() * scale, image.get_height() * scale + image = pygame.transform.scale(image, new_size) + return image.convert_alpha() + + +def clamp(value, mini, maxi): + """Clamp value between mini and maxi""" + if value < mini: + return mini + elif maxi < value: + return maxi + else: + return value + + +def random_in_rect(rect): + """Return a random point uniformly in a rectangle.""" + rect = pygame.Rect(rect) + return pygame.Vector2(uniform(rect.left, rect.right), uniform(rect.top, rect.bottom)) + + +def from_polar(rho, theta): + """Create a Vector2 from its polar representation.""" + v = pygame.Vector2() + v.from_polar((rho, theta)) + return v + + +def distance(p1, p2): + """Get distance between 2 points""" + return math.sqrt((p2[0] - p1[0]) ** 2 + (p2[1] - p1[1]) ** 2) + + +def map_to_range(value, from_x, from_y, to_x, to_y): + """map the value from one range to another""" + return clamp(value * (to_y - to_x) / (from_y - from_x), to_x, to_y) From aeab065c0bb8751e5e8ff93116ad831882d7eada Mon Sep 17 00:00:00 2001 From: Alley <86802813+alley-indie@users.noreply.github.com> Date: Mon, 11 Oct 2021 13:34:03 +0200 Subject: [PATCH 23/80] alley-indie entry * 01 Casual * 01 Ambitious --- 01-fog-of-war/alley-indie/main.py | 81 +++++++++++++++ 01-fog-of-war/alley-indie/objects.py | 142 +++++++++++++++++++++++++++ 01-fog-of-war/alley-indie/utils.py | 40 ++++++++ 3 files changed, 263 insertions(+) create mode 100644 01-fog-of-war/alley-indie/main.py create mode 100644 01-fog-of-war/alley-indie/objects.py create mode 100644 01-fog-of-war/alley-indie/utils.py diff --git a/01-fog-of-war/alley-indie/main.py b/01-fog-of-war/alley-indie/main.py new file mode 100644 index 0000000..e06bed4 --- /dev/null +++ b/01-fog-of-war/alley-indie/main.py @@ -0,0 +1,81 @@ +import sys +from pathlib import Path + +try: + import wclib +except ImportError: + # wclib may not be in the path because of the architecture + # of all the challenges and the fact that there are many + # way to run them (through the showcase, or on their own) + + ROOT_FOLDER = Path(__file__).parent.parent.parent + sys.path.append(str(ROOT_FOLDER)) + import wclib + +# This line tells python how to handle the relative imports +# when you run this file directly. +__package__ = "01-fog-of-war." + Path(__file__).parent.name + +# ---- Recommended: don't modify anything above this line ---- # + +# Metadata about your submission +__author__ = "Your Discord Tag Goes Here#7777" +__achievements__ = [ # Uncomment the ones you've done + # "Casual", + # "Ambitious", + # "Adventurous", +] + + +from operator import attrgetter +import pygame + +# To import the modules in yourname/, you need to use relative imports, +# otherwise your project will not be compatible with the showcase. +from .objects import Ghost, Player, SolidObject + +BACKGROUND = 0x66856C + + +def draw_circle(fog, pos, radius, fading_value): + for i in range(fading_value, -1, -1): + c = int(255 - i * (255 / fading_value)) + color = (c, c, c) + pygame.draw.circle(fog, color, pos, radius + i * 2) + + +def mainloop(): + player = Player((100, 100)) + trees = SolidObject.generate_many(36) + ghosts = [Ghost() for _ in range(16)] + + all_objects = trees + [player] + ghosts + + fog = pygame.Surface(wclib.SIZE) + fog.fill((0, 0, 0)) + + clock = pygame.time.Clock() + while True: + screen, events = yield + for event in events: + if event.type == pygame.QUIT: + return + + for obj in all_objects: + obj.logic(objects=all_objects) + + screen.fill(BACKGROUND) + for object in sorted(all_objects, key=attrgetter("rect.bottom")): + object.draw(screen) + fog.fill((0, 0, 0)) + pos = ( + player.pos[0] + player.size[0] // 2, + player.pos[1] + player.size[1] // 2) + draw_circle(fog, pos, player.size[0], 100) + screen.blit(fog, (0 ,0), special_flags=pygame.BLEND_RGBA_MULT) + + clock.tick(60) + + +if __name__ == "__main__": + wclib.run(mainloop()) diff --git a/01-fog-of-war/alley-indie/objects.py b/01-fog-of-war/alley-indie/objects.py new file mode 100644 index 0000000..e507e56 --- /dev/null +++ b/01-fog-of-war/alley-indie/objects.py @@ -0,0 +1,142 @@ +""" +This file provides objects that can be used to make up +a basic playground for the challenges. + +This code is provided so that you can focus on implementing +a fog of war, without needed +Feel free to modify everything in this file to your liking. +""" +from random import choice, gauss + +import pygame + +from wclib import SIZE +from .utils import clamp, from_polar, load_image, random_in_rect + +SCREEN = pygame.Rect(0, 0, *SIZE) + + +class Object: + """The base class for all objects of the game.""" + + def __init__(self, pos, sprite: pygame.Surface): + self.pos = pygame.Vector2(pos) + self.size = pygame.Vector2(sprite.get_size()) + self.sprite = sprite + + def __str__(self): + return f"<{self.__class__.__name__}(pos={self.pos}, size={self.size})>" + + @property + def rect(self): + return pygame.Rect(self.pos, self.size) + + def draw(self, screen): + screen.blit(self.sprite, self.pos) + + def logic(self, **kwargs): + pass + + +class Object8Directional(Object): + SCALE = 3 + SIZE = 16 + SHEET = "blue_ghost" + + ACCELERATION = 0.5 + DAMPING = 0.85 + + # Asymptotic velocity will be solution of + # x = x * DAMPING + ACCELERATION + # That is, + # x = ACCELERATION / (1 - DAMPING) + + def __init__(self, pos): + self.velocity = pygame.Vector2() + self.acceleration = pygame.Vector2() + + super().__init__(pos, self.get_image()) + + def get_image(self): + angle = self.velocity.as_polar()[1] + idx = int((-angle + 90 + 45 / 2) % 360 / 360 * 8) + sheet = load_image(self.SHEET, self.SCALE) + unit = self.SIZE * self.SCALE + return sheet.subsurface(idx * unit, 0, unit, unit) + + def logic(self, **kwargs): + self.velocity *= self.DAMPING + self.velocity += self.acceleration + self.pos += self.velocity + self.sprite = self.get_image() + + self.pos.x = clamp(self.pos.x, 0, SIZE[0]) + self.pos.y = clamp(self.pos.y, 0, SIZE[1]) + + +class Player(Object8Directional): + def logic(self, **kwargs): + pressed = pygame.key.get_pressed() + direction_x = pressed[pygame.K_RIGHT] - pressed[pygame.K_LEFT] + direction_y = pressed[pygame.K_DOWN] - pressed[pygame.K_UP] + + self.acceleration = pygame.Vector2(direction_x, direction_y) * self.ACCELERATION + super().logic(**kwargs) + + +class Ghost(Object8Directional): + SHEET = "pink_ghost" + ACCELERATION = 0.2 + DAMPING = 0.9 + + def __init__(self, pos=None): + if pos is None: + pos = random_in_rect(SCREEN) + super().__init__(pos) + self.goal = self.new_goal() + + def new_goal(self): + direction = from_polar(60, gauss(self.velocity.as_polar()[1], 30)) + return self.rect.center + direction + + def logic(self, **kwargs): + middle_area = SCREEN.inflate(-30, -30) + while self.rect.collidepoint(self.goal) or not middle_area.collidepoint( + self.goal + ): + self.goal = self.new_goal() + + self.acceleration = ( + self.goal - self.rect.center + ).normalize() * self.ACCELERATION + super().logic(**kwargs) + + +class SolidObject(Object): + SHEET_RECT = [ + (0, 0, 24, 31), + (24, 0, 24, 24), + (48, 0, 24, 24), + (72, 0, 16, 24), + (88, 0, 48, 43), + (136, 0, 16, 16), + ] + SCALE = 3 + + def __init__(self, pos): + sheet = load_image("tileset", self.SCALE) + sheet.set_colorkey(0xFFFFFF) + rect = choice(self.SHEET_RECT) + rect = [x * self.SCALE for x in rect] + super().__init__(pos, sheet.subsurface(rect)) + + @classmethod + def generate_many(cls, nb=16, max_tries=1000): + objects = [] + tries = 0 # avoids infinite loop + while len(objects) < nb and tries < max_tries: + pos = random_in_rect(SCREEN) + obj = cls(pos) + if not any(obj.rect.colliderect(other.rect) for other in objects): + objects.append(obj) + return objects diff --git a/01-fog-of-war/alley-indie/utils.py b/01-fog-of-war/alley-indie/utils.py new file mode 100644 index 0000000..28d56ff --- /dev/null +++ b/01-fog-of-war/alley-indie/utils.py @@ -0,0 +1,40 @@ +from functools import lru_cache +from pathlib import Path +from random import uniform + +import pygame + +SUBMISSION_DIR = Path(__file__).parent +ASSETS = SUBMISSION_DIR.parent / "assets" + + +@lru_cache() +def load_image(name: str, scale=1): + image = pygame.image.load(ASSETS / f"{name}.png") + if scale != 1: + new_size = image.get_width() * scale, image.get_height() * scale + image = pygame.transform.scale(image, new_size) + return image.convert_alpha() + + +def clamp(value, mini, maxi): + """Clamp value between mini and maxi""" + if value < mini: + return mini + elif maxi < value: + return maxi + else: + return value + + +def random_in_rect(rect): + """Return a random point uniformly in a rectangle.""" + rect = pygame.Rect(rect) + return pygame.Vector2(uniform(rect.left, rect.right), uniform(rect.top, rect.bottom)) + + +def from_polar(rho, theta): + """Create a Vector2 from its polar representation.""" + v = pygame.Vector2() + v.from_polar((rho, theta)) + return v From 5d294e7903a32953475e9980c1c9edef42cf2a6b Mon Sep 17 00:00:00 2001 From: MegaIng Date: Mon, 11 Oct 2021 13:34:42 +0200 Subject: [PATCH 24/80] MegaIng entry * Implementation of Fog of War * Improved static object rendering * Added back restriction to 60 FPS * Greatly improved performance. --- 01-fog-of-war/MegaIng/main.py | 115 +++++++++++++++++++++++++ 01-fog-of-war/MegaIng/objects.py | 142 +++++++++++++++++++++++++++++++ 01-fog-of-war/MegaIng/utils.py | 46 ++++++++++ 3 files changed, 303 insertions(+) create mode 100644 01-fog-of-war/MegaIng/main.py create mode 100644 01-fog-of-war/MegaIng/objects.py create mode 100644 01-fog-of-war/MegaIng/utils.py diff --git a/01-fog-of-war/MegaIng/main.py b/01-fog-of-war/MegaIng/main.py new file mode 100644 index 0000000..659a4b1 --- /dev/null +++ b/01-fog-of-war/MegaIng/main.py @@ -0,0 +1,115 @@ +import sys +from pathlib import Path + +from MegaIng.utils import interpolate + +try: + import wclib +except ImportError: + # wclib may not be in the path because of the architecture + # of all the challenges and the fact that there are many + # way to run them (through the showcase, or on their own) + + ROOT_FOLDER = Path(__file__).parent.parent.parent + sys.path.append(str(ROOT_FOLDER)) + import wclib + +# This line tells python how to handle the relative imports +# when you run this file directly. +__package__ = "01-fog-of-war." + Path(__file__).parent.name + +# ---- Recommended: don't modify anything above this line ---- # + +# Metadata about your submission +__author__ = "MegaIng4572#7777" +__achievements__ = [ # Uncomment the ones you've done + "Casual", + "Ambitious", + "Adventurous", +] + +from operator import attrgetter +import pygame + +# To import the modules in yourname/, you need to use relative imports, +# otherwise your project will not be compatible with the showcase. +from .objects import Ghost, Player, SolidObject + +BACKGROUND = (0x66, 0x85, 0x6C) + + +class FogOverlay: + def __init__(self, player: Player, view_radii: tuple[int, int], alpha_radii: tuple[int, int], base_alpha: int, steps: int): + self.player = player + self.view_radii = view_radii + self.alpha_radii = alpha_radii + self.base_alpha = base_alpha + self.steps = steps + self.active_overlay: pygame.Surface = pygame.Surface(wclib.SIZE, pygame.SRCALPHA) + # self.active_overlay.set_colorkey((1,1,1)) + self.passive_overlay: pygame.Surface = pygame.Surface(wclib.SIZE, pygame.SRCALPHA) + self.passive_overlay.fill((0, 0, 0, 255)) + + def update_overlays(self): + self.active_overlay.fill((0, 0, 0, 255)) # Solid black + center = self.player.pos + self.player.size / 2 # Center on player, looks slightly better than topleft + for radius, alpha in ( + (interpolate(i, 0, self.steps, *self.view_radii), + interpolate(i, 0, self.steps, *self.alpha_radii, power=2) + ) + for i in reversed(range(self.steps)) + ): + pygame.draw.circle(self.active_overlay, + (0, 0, 0, alpha), + center, + radius) + r = pygame.Rect(0, 0, self.view_radii[1] * 2, self.view_radii[1] * 2) + r.center = center + r = r.clip(self.passive_overlay.get_rect()) + self.passive_overlay.fill((0, 0, 0, self.base_alpha), r, special_flags=pygame.BLEND_RGBA_MAX) + self.passive_overlay.blit(self.active_overlay, r, r, special_flags=pygame.BLEND_RGBA_MIN) + + +def mainloop(): + player = Player((100, 100)) + fog = FogOverlay(player, + view_radii=(50, 200), + alpha_radii=(0, 250), + base_alpha=150, + steps=100) + trees = SolidObject.generate_many(36) + ghosts = [Ghost() for _ in range(16)] + + all_objects = trees + [player] + ghosts + + foreground = pygame.Surface(wclib.SIZE) + foreground.set_colorkey((0, 0, 0)) + + clock = pygame.time.Clock() + while True: + screen, events = yield + for event in events: + if event.type == pygame.QUIT: + return + + for obj in all_objects: + obj.logic(objects=all_objects) + fog.update_overlays() + + screen.fill(BACKGROUND) + for obj in sorted(trees, key=attrgetter("rect.bottom")): + obj.draw(screen) + screen.blit(fog.passive_overlay, (0, 0)) + + foreground.fill((0, 0, 0)) + for obj in sorted(ghosts + [player], key=attrgetter("rect.bottom")): + obj.draw(foreground) + screen.blit(fog.passive_overlay, (0, 0)) + foreground.blit(fog.active_overlay, (0, 0)) + screen.blit(foreground, (0, 0)) + + clock.tick(60) + + +if __name__ == "__main__": + wclib.run(mainloop()) diff --git a/01-fog-of-war/MegaIng/objects.py b/01-fog-of-war/MegaIng/objects.py new file mode 100644 index 0000000..e507e56 --- /dev/null +++ b/01-fog-of-war/MegaIng/objects.py @@ -0,0 +1,142 @@ +""" +This file provides objects that can be used to make up +a basic playground for the challenges. + +This code is provided so that you can focus on implementing +a fog of war, without needed +Feel free to modify everything in this file to your liking. +""" +from random import choice, gauss + +import pygame + +from wclib import SIZE +from .utils import clamp, from_polar, load_image, random_in_rect + +SCREEN = pygame.Rect(0, 0, *SIZE) + + +class Object: + """The base class for all objects of the game.""" + + def __init__(self, pos, sprite: pygame.Surface): + self.pos = pygame.Vector2(pos) + self.size = pygame.Vector2(sprite.get_size()) + self.sprite = sprite + + def __str__(self): + return f"<{self.__class__.__name__}(pos={self.pos}, size={self.size})>" + + @property + def rect(self): + return pygame.Rect(self.pos, self.size) + + def draw(self, screen): + screen.blit(self.sprite, self.pos) + + def logic(self, **kwargs): + pass + + +class Object8Directional(Object): + SCALE = 3 + SIZE = 16 + SHEET = "blue_ghost" + + ACCELERATION = 0.5 + DAMPING = 0.85 + + # Asymptotic velocity will be solution of + # x = x * DAMPING + ACCELERATION + # That is, + # x = ACCELERATION / (1 - DAMPING) + + def __init__(self, pos): + self.velocity = pygame.Vector2() + self.acceleration = pygame.Vector2() + + super().__init__(pos, self.get_image()) + + def get_image(self): + angle = self.velocity.as_polar()[1] + idx = int((-angle + 90 + 45 / 2) % 360 / 360 * 8) + sheet = load_image(self.SHEET, self.SCALE) + unit = self.SIZE * self.SCALE + return sheet.subsurface(idx * unit, 0, unit, unit) + + def logic(self, **kwargs): + self.velocity *= self.DAMPING + self.velocity += self.acceleration + self.pos += self.velocity + self.sprite = self.get_image() + + self.pos.x = clamp(self.pos.x, 0, SIZE[0]) + self.pos.y = clamp(self.pos.y, 0, SIZE[1]) + + +class Player(Object8Directional): + def logic(self, **kwargs): + pressed = pygame.key.get_pressed() + direction_x = pressed[pygame.K_RIGHT] - pressed[pygame.K_LEFT] + direction_y = pressed[pygame.K_DOWN] - pressed[pygame.K_UP] + + self.acceleration = pygame.Vector2(direction_x, direction_y) * self.ACCELERATION + super().logic(**kwargs) + + +class Ghost(Object8Directional): + SHEET = "pink_ghost" + ACCELERATION = 0.2 + DAMPING = 0.9 + + def __init__(self, pos=None): + if pos is None: + pos = random_in_rect(SCREEN) + super().__init__(pos) + self.goal = self.new_goal() + + def new_goal(self): + direction = from_polar(60, gauss(self.velocity.as_polar()[1], 30)) + return self.rect.center + direction + + def logic(self, **kwargs): + middle_area = SCREEN.inflate(-30, -30) + while self.rect.collidepoint(self.goal) or not middle_area.collidepoint( + self.goal + ): + self.goal = self.new_goal() + + self.acceleration = ( + self.goal - self.rect.center + ).normalize() * self.ACCELERATION + super().logic(**kwargs) + + +class SolidObject(Object): + SHEET_RECT = [ + (0, 0, 24, 31), + (24, 0, 24, 24), + (48, 0, 24, 24), + (72, 0, 16, 24), + (88, 0, 48, 43), + (136, 0, 16, 16), + ] + SCALE = 3 + + def __init__(self, pos): + sheet = load_image("tileset", self.SCALE) + sheet.set_colorkey(0xFFFFFF) + rect = choice(self.SHEET_RECT) + rect = [x * self.SCALE for x in rect] + super().__init__(pos, sheet.subsurface(rect)) + + @classmethod + def generate_many(cls, nb=16, max_tries=1000): + objects = [] + tries = 0 # avoids infinite loop + while len(objects) < nb and tries < max_tries: + pos = random_in_rect(SCREEN) + obj = cls(pos) + if not any(obj.rect.colliderect(other.rect) for other in objects): + objects.append(obj) + return objects diff --git a/01-fog-of-war/MegaIng/utils.py b/01-fog-of-war/MegaIng/utils.py new file mode 100644 index 0000000..9f69a2e --- /dev/null +++ b/01-fog-of-war/MegaIng/utils.py @@ -0,0 +1,46 @@ +from functools import lru_cache +from pathlib import Path +from random import uniform + +import pygame + +SUBMISSION_DIR = Path(__file__).parent +ASSETS = SUBMISSION_DIR.parent / "assets" + + +@lru_cache() +def load_image(name: str, scale=1): + image = pygame.image.load(ASSETS / f"{name}.png") + if scale != 1: + new_size = image.get_width() * scale, image.get_height() * scale + image = pygame.transform.scale(image, new_size) + return image.convert_alpha() + + +def clamp(value, mini, maxi): + """Clamp value between mini and maxi""" + if value < mini: + return mini + elif maxi < value: + return maxi + else: + return value + + +def interpolate(value, min_in, max_in, min_out, max_out, power=1): + in_w = max_in - min_in + out_w = max_out - min_out + return ((value - min_in) / in_w) ** power * out_w + min_out + + +def random_in_rect(rect): + """Return a random point uniformly in a rectangle.""" + rect = pygame.Rect(rect) + return pygame.Vector2(uniform(rect.left, rect.right), uniform(rect.top, rect.bottom)) + + +def from_polar(rho, theta): + """Create a Vector2 from its polar representation.""" + v = pygame.Vector2() + v.from_polar((rho, theta)) + return v From 8572eb853a0a75b037b5f0f684d9b7be0e611e9b Mon Sep 17 00:00:00 2001 From: bydariogamer <62303655+bydariogamer@users.noreply.github.com> Date: Mon, 11 Oct 2021 13:36:49 +0200 Subject: [PATCH 25/80] bydariogamer entry --- 01-fog-of-war/bydariogamer/main.py | 102 ++++++++++++++++++ 01-fog-of-war/bydariogamer/objects.py | 142 ++++++++++++++++++++++++++ 01-fog-of-war/bydariogamer/utils.py | 40 ++++++++ 3 files changed, 284 insertions(+) create mode 100644 01-fog-of-war/bydariogamer/main.py create mode 100644 01-fog-of-war/bydariogamer/objects.py create mode 100644 01-fog-of-war/bydariogamer/utils.py diff --git a/01-fog-of-war/bydariogamer/main.py b/01-fog-of-war/bydariogamer/main.py new file mode 100644 index 0000000..8009618 --- /dev/null +++ b/01-fog-of-war/bydariogamer/main.py @@ -0,0 +1,102 @@ +import sys +from pathlib import Path + +try: + import wclib +except ImportError: + # wclib may not be in the path because of the architecture + # of all the challenges and the fact that there are many + # way to run them (through the showcase, or on their own) + + ROOT_FOLDER = Path(__file__).parent.parent.parent + sys.path.append(str(ROOT_FOLDER)) + import wclib + +# This line tells python how to handle the relative imports +# when you run this file directly. +__package__ = "01-fog-of-war." + Path(__file__).parent.name + +# ---- Recommended: don't modify anything above this line ---- # + +# Metadata about your submission +__author__ = "bydariogamer#7949" +__achievements__ = [ # Uncomment the ones you've done + "Casual", + "Ambitious", + "Adventurous", +] + + +from operator import attrgetter +import pygame + +# To import the modules in yourname/, you need to use relative imports, +# otherwise your project will not be compatible with the showcase. +from .objects import Ghost, Player, SolidObject + +BACKGROUND = 0x66856C + + +def mainloop(): + player = Player((100, 100)) + trees = SolidObject.generate_many(36) + ghosts = [Ghost() for _ in range(16)] + + all_objects = trees + [player] + ghosts + + clock = pygame.time.Clock() + + # surface containing a circle with faded borders + light = pygame.Surface((200, 200), pygame.SRCALPHA) + light.fill((255, 255, 255, 0)) + for i in range(100): + pygame.draw.circle(light, 3*[0]+[i], (100, 100), 100-i) + + # how slowly we want fog to come back + fog_persistance = 4 + fog_count = 0 + + # surface containing the fog + dark = pygame.Surface(wclib.SIZE, pygame.SRCALPHA) + dark.fill((0, 0, 0, 255)) + + while True: + # yield screen and process events + screen, events = yield + for event in events: + if event.type == pygame.QUIT: + return + + # run the logic of all objects + for obj in all_objects: + obj.logic(objects=all_objects) + + # fill screen with background color + screen.fill(BACKGROUND) + + # make ghosts disappear if they are out of player view range + for ghost in ghosts: + ghost.sprite.set_alpha((120 - ghost.pos.distance_to(player.pos))*4) + + # draw all objects + for obj in sorted(all_objects, key=attrgetter("rect.bottom")): + obj.draw(screen) + + # light up player surroundings + dark.blit(light, player.pos - (76, 76), special_flags=pygame.BLEND_RGBA_SUB) + + # make fog slowly come back + fog_count += 1 + fog_count %= fog_persistance + if not fog_count: + dark.fill((0, 0, 0, 1), special_flags=pygame.BLEND_RGBA_ADD) + + # blit the fog + screen.blit(dark, (0, 0)) + if __name__ == "__main__": + pygame.display.set_caption(f"{__author__}'s fog of war - {int(clock.get_fps())}/60FPS") + clock.tick(60) + + +if __name__ == "__main__": + wclib.run(mainloop()) diff --git a/01-fog-of-war/bydariogamer/objects.py b/01-fog-of-war/bydariogamer/objects.py new file mode 100644 index 0000000..e507e56 --- /dev/null +++ b/01-fog-of-war/bydariogamer/objects.py @@ -0,0 +1,142 @@ +""" +This file provides objects that can be used to make up +a basic playground for the challenges. + +This code is provided so that you can focus on implementing +a fog of war, without needed +Feel free to modify everything in this file to your liking. +""" +from random import choice, gauss + +import pygame + +from wclib import SIZE +from .utils import clamp, from_polar, load_image, random_in_rect + +SCREEN = pygame.Rect(0, 0, *SIZE) + + +class Object: + """The base class for all objects of the game.""" + + def __init__(self, pos, sprite: pygame.Surface): + self.pos = pygame.Vector2(pos) + self.size = pygame.Vector2(sprite.get_size()) + self.sprite = sprite + + def __str__(self): + return f"<{self.__class__.__name__}(pos={self.pos}, size={self.size})>" + + @property + def rect(self): + return pygame.Rect(self.pos, self.size) + + def draw(self, screen): + screen.blit(self.sprite, self.pos) + + def logic(self, **kwargs): + pass + + +class Object8Directional(Object): + SCALE = 3 + SIZE = 16 + SHEET = "blue_ghost" + + ACCELERATION = 0.5 + DAMPING = 0.85 + + # Asymptotic velocity will be solution of + # x = x * DAMPING + ACCELERATION + # That is, + # x = ACCELERATION / (1 - DAMPING) + + def __init__(self, pos): + self.velocity = pygame.Vector2() + self.acceleration = pygame.Vector2() + + super().__init__(pos, self.get_image()) + + def get_image(self): + angle = self.velocity.as_polar()[1] + idx = int((-angle + 90 + 45 / 2) % 360 / 360 * 8) + sheet = load_image(self.SHEET, self.SCALE) + unit = self.SIZE * self.SCALE + return sheet.subsurface(idx * unit, 0, unit, unit) + + def logic(self, **kwargs): + self.velocity *= self.DAMPING + self.velocity += self.acceleration + self.pos += self.velocity + self.sprite = self.get_image() + + self.pos.x = clamp(self.pos.x, 0, SIZE[0]) + self.pos.y = clamp(self.pos.y, 0, SIZE[1]) + + +class Player(Object8Directional): + def logic(self, **kwargs): + pressed = pygame.key.get_pressed() + direction_x = pressed[pygame.K_RIGHT] - pressed[pygame.K_LEFT] + direction_y = pressed[pygame.K_DOWN] - pressed[pygame.K_UP] + + self.acceleration = pygame.Vector2(direction_x, direction_y) * self.ACCELERATION + super().logic(**kwargs) + + +class Ghost(Object8Directional): + SHEET = "pink_ghost" + ACCELERATION = 0.2 + DAMPING = 0.9 + + def __init__(self, pos=None): + if pos is None: + pos = random_in_rect(SCREEN) + super().__init__(pos) + self.goal = self.new_goal() + + def new_goal(self): + direction = from_polar(60, gauss(self.velocity.as_polar()[1], 30)) + return self.rect.center + direction + + def logic(self, **kwargs): + middle_area = SCREEN.inflate(-30, -30) + while self.rect.collidepoint(self.goal) or not middle_area.collidepoint( + self.goal + ): + self.goal = self.new_goal() + + self.acceleration = ( + self.goal - self.rect.center + ).normalize() * self.ACCELERATION + super().logic(**kwargs) + + +class SolidObject(Object): + SHEET_RECT = [ + (0, 0, 24, 31), + (24, 0, 24, 24), + (48, 0, 24, 24), + (72, 0, 16, 24), + (88, 0, 48, 43), + (136, 0, 16, 16), + ] + SCALE = 3 + + def __init__(self, pos): + sheet = load_image("tileset", self.SCALE) + sheet.set_colorkey(0xFFFFFF) + rect = choice(self.SHEET_RECT) + rect = [x * self.SCALE for x in rect] + super().__init__(pos, sheet.subsurface(rect)) + + @classmethod + def generate_many(cls, nb=16, max_tries=1000): + objects = [] + tries = 0 # avoids infinite loop + while len(objects) < nb and tries < max_tries: + pos = random_in_rect(SCREEN) + obj = cls(pos) + if not any(obj.rect.colliderect(other.rect) for other in objects): + objects.append(obj) + return objects diff --git a/01-fog-of-war/bydariogamer/utils.py b/01-fog-of-war/bydariogamer/utils.py new file mode 100644 index 0000000..28d56ff --- /dev/null +++ b/01-fog-of-war/bydariogamer/utils.py @@ -0,0 +1,40 @@ +from functools import lru_cache +from pathlib import Path +from random import uniform + +import pygame + +SUBMISSION_DIR = Path(__file__).parent +ASSETS = SUBMISSION_DIR.parent / "assets" + + +@lru_cache() +def load_image(name: str, scale=1): + image = pygame.image.load(ASSETS / f"{name}.png") + if scale != 1: + new_size = image.get_width() * scale, image.get_height() * scale + image = pygame.transform.scale(image, new_size) + return image.convert_alpha() + + +def clamp(value, mini, maxi): + """Clamp value between mini and maxi""" + if value < mini: + return mini + elif maxi < value: + return maxi + else: + return value + + +def random_in_rect(rect): + """Return a random point uniformly in a rectangle.""" + rect = pygame.Rect(rect) + return pygame.Vector2(uniform(rect.left, rect.right), uniform(rect.top, rect.bottom)) + + +def from_polar(rho, theta): + """Create a Vector2 from its polar representation.""" + v = pygame.Vector2() + v.from_polar((rho, theta)) + return v From 865dea17d19b1704050b7b2bc90ba6d33b978e53 Mon Sep 17 00:00:00 2001 From: Alec Hodgkinson Date: Mon, 11 Oct 2021 04:37:56 -0700 Subject: [PATCH 26/80] zxxv entry Co-authored-by: Alec Hodgkinson --- 01-fog-of-war/zxxv/main.py | 100 +++++++++++++++++++++ 01-fog-of-war/zxxv/objects.py | 165 ++++++++++++++++++++++++++++++++++ 01-fog-of-war/zxxv/utils.py | 40 +++++++++ 3 files changed, 305 insertions(+) create mode 100644 01-fog-of-war/zxxv/main.py create mode 100644 01-fog-of-war/zxxv/objects.py create mode 100644 01-fog-of-war/zxxv/utils.py diff --git a/01-fog-of-war/zxxv/main.py b/01-fog-of-war/zxxv/main.py new file mode 100644 index 0000000..552c3c3 --- /dev/null +++ b/01-fog-of-war/zxxv/main.py @@ -0,0 +1,100 @@ +import sys +from pathlib import Path +from functools import partial + +try: + import wclib +except ImportError: + # wclib may not be in the path because of the architecture + # of all the challenges and the fact that there are many + # way to run them (through the showcase, or on their own) + + ROOT_FOLDER = Path(__file__).parent.parent.parent + sys.path.append(str(ROOT_FOLDER)) + import wclib + +# This line tells python how to handle the relative imports +# when you run this file directly. +__package__ = "01-fog-of-war." + Path(__file__).parent.name + +# ---- Recommended: don't modify anything above this line ---- # + +# Metadata about your submission +__author__ = "zxxv#1547" +__achievements__ = [ # Uncomment the ones you've done + "Casual", + "Ambitious", + # "Adventurous", +] + + +from operator import attrgetter +import pygame + +# To import the modules in yourname/, you need to use relative imports, +# otherwise your project will not be compatible with the showcase. +from .objects import Ghost, Player, SolidObject + +BACKGROUND = 0x66856C +FOG_COLOR = (0, 0, 0, 0) + + +class Game: + ''' + Game object to control updating object initialization, logic updates, and drawing the fog. + ''' + def __init__(self): + self.players = [Player((100, 100), 200, 'arrow'), Player((400, 400), 200, 'wasd')] + self.trees = SolidObject.generate_many(36) + self.ghosts = [Ghost() for _ in range(16)] + + self.all_objects = self.ghosts + self.trees + self.players + + self.fog_surface = pygame.Surface(wclib.SIZE) + self.fog_surface.fill(FOG_COLOR) + + def update(self, screen, events): + # Logic + for obj in self.all_objects: + obj.logic(objects=self.all_objects) + + # Draw + screen.fill(BACKGROUND) + for object in sorted(self.all_objects, key=attrgetter("rect.bottom")): + object.draw(screen) + self.draw_fog(screen) + + def draw_fog(self, screen): + self.fog_surface.fill(FOG_COLOR) + k = 100 + for i in range(k): + for player in self.players: + # for i in range(k): + pygame.draw.circle(self.fog_surface, ((255//k)*i, (255//k)*i, (255//k)*i, 50), player.center_pos, player.radius - i) + for tree in self.trees: + tree.draw(self.fog_surface) + screen.blit(self.fog_surface, (0, 0), special_flags=pygame.BLEND_RGBA_MIN) + + + +def mainloop(): + # player = Player((100, 100)) + # trees = SolidObject.generate_many(36) + # ghosts = [Ghost() for _ in range(16)] + + # all_objects = trees + [player] + ghosts + game = Game() + clock = pygame.time.Clock() + while True: + screen, events = yield + for event in events: + if event.type == pygame.QUIT: + return + + game.update(screen, events) + + clock.tick(60) + + +if __name__ == "__main__": + wclib.run(mainloop()) diff --git a/01-fog-of-war/zxxv/objects.py b/01-fog-of-war/zxxv/objects.py new file mode 100644 index 0000000..be930e6 --- /dev/null +++ b/01-fog-of-war/zxxv/objects.py @@ -0,0 +1,165 @@ +""" +This file provides objects that can be used to make up +a basic playground for the challenges. + +This code is provided so that you can focus on implementing +a fog of war, without needed +Feel free to modify everything in this file to your liking. +""" +from random import choice, gauss + +import pygame + +from wclib import SIZE +from .utils import clamp, from_polar, load_image, random_in_rect + +SCREEN = pygame.Rect(0, 0, *SIZE) + + +class Object: + """The base class for all objects of the game.""" + + def __init__(self, pos, sprite: pygame.Surface): + self.pos = pygame.Vector2(pos) + self.size = pygame.Vector2(sprite.get_size()) + self.sprite = sprite + + def __str__(self): + return f"<{self.__class__.__name__}(pos={self.pos}, size={self.size})>" + + @property + def rect(self): + return pygame.Rect(self.pos, self.size) + + @property + def center_pos(self): + return self.pos + pygame.Vector2(self.size//2, self.size//2) + + def draw(self, screen): + screen.blit(self.sprite, self.pos) + + def logic(self, **kwargs): + pass + + +class Object8Directional(Object): + SCALE = 3 + SIZE = 16 + SHEET = "blue_ghost" + + ACCELERATION = 0.5 + DAMPING = 0.85 + + # Asymptotic velocity will be solution of + # x = x * DAMPING + ACCELERATION + # That is, + # x = ACCELERATION / (1 - DAMPING) + + def __init__(self, pos): + self.velocity = pygame.Vector2() + self.acceleration = pygame.Vector2() + + super().__init__(pos, self.get_image()) + + def get_image(self): + angle = self.velocity.as_polar()[1] + idx = int((-angle + 90 + 45 / 2) % 360 / 360 * 8) + sheet = load_image(self.SHEET, self.SCALE) + unit = self.SIZE * self.SCALE + return sheet.subsurface(idx * unit, 0, unit, unit) + + def logic(self, **kwargs): + self.velocity *= self.DAMPING + self.velocity += self.acceleration + self.pos += self.velocity + self.sprite = self.get_image() + + self.pos.x = clamp(self.pos.x, 0, SIZE[0]- self.size[0]) + self.pos.y = clamp(self.pos.y, 0, SIZE[1] - self.size[1]) + + + +class Player(Object8Directional): + def __init__(self, pos, radius: float, keymap='arrow'): + self.radius = radius + if keymap == 'arrow': + self.keys = { + 'up': pygame.K_UP, + 'left': pygame.K_LEFT, + 'down': pygame.K_DOWN, + 'right': pygame.K_RIGHT + } + else: + self.keys = { + 'up': pygame.K_w, + 'left': pygame.K_a, + 'down': pygame.K_s, + 'right': pygame.K_d + } + super().__init__(pos) + + def logic(self, **kwargs): + pressed = pygame.key.get_pressed() + direction_x = pressed[self.keys['right']] - pressed[self.keys['left']] + direction_y = pressed[self.keys['down']] - pressed[self.keys['up']] + + self.acceleration = pygame.Vector2(direction_x, direction_y) * self.ACCELERATION + super().logic(**kwargs) + + +class Ghost(Object8Directional): + SHEET = "pink_ghost" + ACCELERATION = 0.2 + DAMPING = 0.9 + + def __init__(self, pos=None): + if pos is None: + pos = random_in_rect(SCREEN) + super().__init__(pos) + self.goal = self.new_goal() + + def new_goal(self): + direction = from_polar(60, gauss(self.velocity.as_polar()[1], 30)) + return self.rect.center + direction + + def logic(self, **kwargs): + middle_area = SCREEN.inflate(-30, -30) + while self.rect.collidepoint(self.goal) or not middle_area.collidepoint( + self.goal + ): + self.goal = self.new_goal() + + self.acceleration = ( + self.goal - self.rect.center + ).normalize() * self.ACCELERATION + super().logic(**kwargs) + + +class SolidObject(Object): + SHEET_RECT = [ + (0, 0, 24, 31), + (24, 0, 24, 24), + (48, 0, 24, 24), + (72, 0, 16, 24), + (88, 0, 48, 43), + (136, 0, 16, 16), + ] + SCALE = 3 + + def __init__(self, pos): + sheet = load_image("tileset", self.SCALE) + sheet.set_colorkey(0xFFFFFF) + rect = choice(self.SHEET_RECT) + rect = [x * self.SCALE for x in rect] + super().__init__(pos, sheet.subsurface(rect)) + + @classmethod + def generate_many(cls, nb=16, max_tries=1000): + objects = [] + tries = 0 # avoids infinite loop + while len(objects) < nb and tries < max_tries: + pos = random_in_rect(SCREEN) + obj = cls(pos) + if not any(obj.rect.colliderect(other.rect) for other in objects): + objects.append(obj) + return objects diff --git a/01-fog-of-war/zxxv/utils.py b/01-fog-of-war/zxxv/utils.py new file mode 100644 index 0000000..28d56ff --- /dev/null +++ b/01-fog-of-war/zxxv/utils.py @@ -0,0 +1,40 @@ +from functools import lru_cache +from pathlib import Path +from random import uniform + +import pygame + +SUBMISSION_DIR = Path(__file__).parent +ASSETS = SUBMISSION_DIR.parent / "assets" + + +@lru_cache() +def load_image(name: str, scale=1): + image = pygame.image.load(ASSETS / f"{name}.png") + if scale != 1: + new_size = image.get_width() * scale, image.get_height() * scale + image = pygame.transform.scale(image, new_size) + return image.convert_alpha() + + +def clamp(value, mini, maxi): + """Clamp value between mini and maxi""" + if value < mini: + return mini + elif maxi < value: + return maxi + else: + return value + + +def random_in_rect(rect): + """Return a random point uniformly in a rectangle.""" + rect = pygame.Rect(rect) + return pygame.Vector2(uniform(rect.left, rect.right), uniform(rect.top, rect.bottom)) + + +def from_polar(rho, theta): + """Create a Vector2 from its polar representation.""" + v = pygame.Vector2() + v.from_polar((rho, theta)) + return v From 286d717373dc2f76355fc96d95df1a6c6809003f Mon Sep 17 00:00:00 2001 From: gresm <78505251+gresm@users.noreply.github.com> Date: Mon, 11 Oct 2021 13:38:28 +0200 Subject: [PATCH 27/80] gresm entry * personal folder * flood_iter.py - added * fog.py - added * fog test 1 * small fix for lib * entry end commit * small license fix * add iterations number to flood_iter.py * smooth shadows * joined fog lightening mechanic Co-authored-by: gresm <> --- 01-fog-of-war/polastyn2030/flood_iter.py | 136 ++++++++++++++++++++++ 01-fog-of-war/polastyn2030/fog.py | 115 ++++++++++++++++++ 01-fog-of-war/polastyn2030/main.py | 72 ++++++++++++ 01-fog-of-war/polastyn2030/objects.py | 142 +++++++++++++++++++++++ 01-fog-of-war/polastyn2030/utils.py | 40 +++++++ wclib/showcase.py | 4 +- 6 files changed, 507 insertions(+), 2 deletions(-) create mode 100644 01-fog-of-war/polastyn2030/flood_iter.py create mode 100644 01-fog-of-war/polastyn2030/fog.py create mode 100644 01-fog-of-war/polastyn2030/main.py create mode 100644 01-fog-of-war/polastyn2030/objects.py create mode 100644 01-fog-of-war/polastyn2030/utils.py diff --git a/01-fog-of-war/polastyn2030/flood_iter.py b/01-fog-of-war/polastyn2030/flood_iter.py new file mode 100644 index 0000000..7477e66 --- /dev/null +++ b/01-fog-of-war/polastyn2030/flood_iter.py @@ -0,0 +1,136 @@ +# Copyright <2021> - MIT LICENSE +# +# Permission is hereby granted, free of charge, +# to any person obtaining a copy of this software and associated documentation files (the "Software"), +# to deal in the Software without restriction, +# including without limitation the rights to +# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, +# and to permit persons to whom the Software is furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +# INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +# DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE + +from __future__ import annotations + + +from typing import Tuple, Set, Iterator, List + + +class Flood: + def __init__(self, start_x: int, start_y: int, max_iterations: int): + self.start_x = start_x + self.start_y = start_y + self.max_iterations = max_iterations + + def __iter__(self) -> "FloodIter": + return FloodIter(self).start() + + +class FloodIter: + iterator: Iterator[Tuple[int, int, int]] + + def __init__(self, flood_info: Flood): + self.flood_info = flood_info + self.visited_places: Set[Tuple[int, int]] = set() + self.routes: Set[Tuple[int, int]] = set() + self.asking_routes: Set[Tuple[int, int]] = set() + self.possible_movement = PossibleMovement() + self.first_time: bool = True + self.iterator = iterator((self.flood_info.start_x, self.flood_info.start_y), self.possible_movement, + self.flood_info.max_iterations) + + def start(self): + self.iterator = iterator((self.flood_info.start_x, self.flood_info.start_y), self.possible_movement, + self.flood_info.max_iterations) + return self + + def __iter__(self) -> "FloodIter": + return self.start() + + def __next__(self) -> Tuple[int, int, int, "PossibleMovement"]: + if self.first_time: + self.first_time = False + return self.flood_info.start_x, self.flood_info.start_y, 0, self.possible_movement + return next(self.iterator) + (self.possible_movement,) + + +class PossibleMovement: + def __init__(self): + self.left = False + self.up = False + self.right = False + self.down = False + + def get_movement(self, pos: Tuple[int, int]): + raw = self.raw_movement(pos) + ret: Set[Tuple[int, int]] = set() + + if self.left: + ret.add(raw[0]) + + if self.up: + ret.add(raw[1]) + + if self.right: + ret.add(raw[2]) + + if self.down: + ret.add(raw[3]) + return ret + + # noinspection PyMethodMayBeStatic + def raw_movement(self, pos: Tuple[int, int]): + ret: List[Tuple[int, int]] = [ + (pos[0] - 1, pos[1]), (pos[0], pos[1] - 1), + (pos[0] + 1, pos[1]), (pos[0], pos[1] + 1) + ] + + return ret + + def all_true(self): + self.left = True + self.up = True + self.right = True + self.down = True + + def all_false(self): + self.left = False + self.up = False + self.right = False + self.down = False + + +def iterator( + start_pos: Tuple[int, int], is_correct: PossibleMovement, max_depth: int +) -> Iterator[Tuple[int, int, int]]: + + routes: Set[Tuple[int, int]] = set() + visited: Set[Tuple[int, int]] = set() + + def get_correct_spread(check_pos: Tuple[int, int]) -> Set[Tuple[int, int]]: + return is_correct.get_movement(check_pos).difference(visited) + + routes.update(get_correct_spread(start_pos)) + cnt = 0 + + while len(routes): + if cnt >= max_depth: + break + new_routes = set() + old_routes = set() + for rout in routes: + visited.add(rout) + new_routes.update(get_correct_spread(rout)) + old_routes.add(rout) + yield rout + (cnt,) + cnt += 1 + + routes.update(new_routes) + routes.difference_update(old_routes) diff --git a/01-fog-of-war/polastyn2030/fog.py b/01-fog-of-war/polastyn2030/fog.py new file mode 100644 index 0000000..4a4dc38 --- /dev/null +++ b/01-fog-of-war/polastyn2030/fog.py @@ -0,0 +1,115 @@ +from __future__ import annotations + + +import pygame as pg + + +from .flood_iter import Flood + + +class InfiniteMap: + def __init__(self): + self.map = {} + self.default = 0 + + def get(self, pos): + if pos in self.map: + return self.map[pos] + return self.default + + def set(self, pos, value): + self.map[pos] = value + + def remove(self, pos): + if pos in self.map: + del self.map[pos] + + def clear(self): + self.map = {} + + +class FogArea: + def __init__(self, rect_w, rect_h, max_visibility): + self.rect_w = rect_w + self.rect_h = rect_h + self.discovered = InfiniteMap() + self.lighted_area = InfiniteMap() + self.more_lighted_area = InfiniteMap() + self.max_steps = max_visibility + self._smooth_trans = 60 + self._semi_trans = 100 + self._fog_of_war = 125 + self._unknown = 255 + self._trans_tile = pg.Surface((rect_w, rect_h), pg.SRCALPHA) + self._trans_tile.fill((0, 0, 0, 0)) + + self._created_tiles: dict[int, pg.Surface] = {} + + def _get_tile(self, trans): + if trans in self._created_tiles: + return self._created_tiles[trans] + + copy = self._trans_tile.copy() + copy.fill((0, 0, 0, trans)) + self._created_tiles[trans] = copy + return copy + + def pos_to_grid(self, pos): + fixed_x = pos[0] - pos[0] % self.rect_w + fixed_y = pos[1] - pos[1] % self.rect_h + grid_x = fixed_x / self.rect_w + grid_y = fixed_y / self.rect_h + return grid_x, grid_y + + def grid_to_pos(self, grid): + return grid[0] * self.rect_w, grid[1] * self.rect_h + + def get_mask(self, size: tuple[int, int]): + mask = pg.Surface(size, pg.SRCALPHA) + x_grid = (size[0] - size[0] % self.rect_w) // self.rect_w + y_grid = (size[1] - size[1] % self.rect_h) // self.rect_h + + i = 0 + while i <= x_grid: + j = 0 + while j <= y_grid: + tile_pos = (i, j) + if self.discovered.get(tile_pos): + if self.lighted_area.get(tile_pos): + if self.more_lighted_area.get(tile_pos): + by = self.more_lighted_area.get(tile_pos) + mask.blit(self._get_tile(self._smooth_trans+by*5), self.grid_to_pos(tile_pos)) + else: + mask.blit(self._get_tile(self._semi_trans), self.grid_to_pos(tile_pos)) + else: + mask.blit(self._get_tile(self._fog_of_war), self.grid_to_pos(tile_pos)) + + if self.more_lighted_area.get(tile_pos): + self.more_lighted_area.remove(tile_pos) + else: + mask.blit(self._get_tile(self._unknown), self.grid_to_pos(tile_pos)) + j += 1 + i += 1 + return mask + + def draw(self, screen: pg.Surface): + screen.blit(self.get_mask(screen.get_size()), (0, 0)) + + def logic(self, player): + self.lighted_area.clear() + + pos = self.pos_to_grid(player.pos) + pos = (pos[0] + 1, pos[1] + 1) + + for x, y, step, check in Flood(pos[0], pos[1], self.max_steps): + check.all_true() + self.lighted_area.set((x, y), 1) + self.discovered.set((x, y), 1) + # self.more_lighted_area.set((x, y), step + 1) + + for x, y, step, check in Flood(pos[0], pos[1], self.max_steps//2): + check.all_true() + self.more_lighted_area.set((x, y), step + 1) + + def lighted_up(self, pos): + return self.lighted_area.get(self.pos_to_grid(pos)) diff --git a/01-fog-of-war/polastyn2030/main.py b/01-fog-of-war/polastyn2030/main.py new file mode 100644 index 0000000..a266f0a --- /dev/null +++ b/01-fog-of-war/polastyn2030/main.py @@ -0,0 +1,72 @@ +import sys +from pathlib import Path + +try: + import wclib +except ImportError: + # wclib may not be in the path because of the architecture + # of all the challenges and the fact that there are many + # way to run them (through the showcase, or on their own) + + ROOT_FOLDER = Path(__file__).parent.parent.parent + sys.path.append(str(ROOT_FOLDER)) + import wclib + +# This line tells python how to handle the relative imports +# when you run this file directly. +__package__ = "01-fog-of-war." + Path(__file__).parent.name + +# ---- Recommended: don't modify anything above this line ---- # + +# Metadata about your submission +__author__ = "Your Discord Tag Goes Here#7777" +__achievements__ = [ # Uncomment the ones you've done + # "Casual", + # "Ambitious", + # "Adventurous", +] + + +from operator import attrgetter +import pygame + +# To import the modules in yourname/, you need to use relative imports, +# otherwise your project will not be compatible with the showcase. +from .objects import Ghost, Player, SolidObject +from .fog import FogArea + +BACKGROUND = 0x66856C + + +def mainloop(): + player = Player((100, 100)) + fog = FogArea(20, 20, 10) + trees = SolidObject.generate_many(36) + ghosts = [Ghost() for _ in range(16)] + + all_objects = trees + [player] + ghosts + + clock = pygame.time.Clock() + while True: + screen, events = yield + for event in events: + if event.type == pygame.QUIT: + return + + for obj in all_objects: + obj.logic(objects=all_objects) + + fog.logic(player) + + screen.fill(BACKGROUND) + for obj in sorted(all_objects, key=attrgetter("rect.bottom")): + if not isinstance(obj, Ghost) or fog.lighted_up(obj.rect.center): + obj.draw(screen) + + fog.draw(screen) + + clock.tick(60) + + +if __name__ == "__main__": + wclib.run(mainloop()) diff --git a/01-fog-of-war/polastyn2030/objects.py b/01-fog-of-war/polastyn2030/objects.py new file mode 100644 index 0000000..e507e56 --- /dev/null +++ b/01-fog-of-war/polastyn2030/objects.py @@ -0,0 +1,142 @@ +""" +This file provides objects that can be used to make up +a basic playground for the challenges. + +This code is provided so that you can focus on implementing +a fog of war, without needed +Feel free to modify everything in this file to your liking. +""" +from random import choice, gauss + +import pygame + +from wclib import SIZE +from .utils import clamp, from_polar, load_image, random_in_rect + +SCREEN = pygame.Rect(0, 0, *SIZE) + + +class Object: + """The base class for all objects of the game.""" + + def __init__(self, pos, sprite: pygame.Surface): + self.pos = pygame.Vector2(pos) + self.size = pygame.Vector2(sprite.get_size()) + self.sprite = sprite + + def __str__(self): + return f"<{self.__class__.__name__}(pos={self.pos}, size={self.size})>" + + @property + def rect(self): + return pygame.Rect(self.pos, self.size) + + def draw(self, screen): + screen.blit(self.sprite, self.pos) + + def logic(self, **kwargs): + pass + + +class Object8Directional(Object): + SCALE = 3 + SIZE = 16 + SHEET = "blue_ghost" + + ACCELERATION = 0.5 + DAMPING = 0.85 + + # Asymptotic velocity will be solution of + # x = x * DAMPING + ACCELERATION + # That is, + # x = ACCELERATION / (1 - DAMPING) + + def __init__(self, pos): + self.velocity = pygame.Vector2() + self.acceleration = pygame.Vector2() + + super().__init__(pos, self.get_image()) + + def get_image(self): + angle = self.velocity.as_polar()[1] + idx = int((-angle + 90 + 45 / 2) % 360 / 360 * 8) + sheet = load_image(self.SHEET, self.SCALE) + unit = self.SIZE * self.SCALE + return sheet.subsurface(idx * unit, 0, unit, unit) + + def logic(self, **kwargs): + self.velocity *= self.DAMPING + self.velocity += self.acceleration + self.pos += self.velocity + self.sprite = self.get_image() + + self.pos.x = clamp(self.pos.x, 0, SIZE[0]) + self.pos.y = clamp(self.pos.y, 0, SIZE[1]) + + +class Player(Object8Directional): + def logic(self, **kwargs): + pressed = pygame.key.get_pressed() + direction_x = pressed[pygame.K_RIGHT] - pressed[pygame.K_LEFT] + direction_y = pressed[pygame.K_DOWN] - pressed[pygame.K_UP] + + self.acceleration = pygame.Vector2(direction_x, direction_y) * self.ACCELERATION + super().logic(**kwargs) + + +class Ghost(Object8Directional): + SHEET = "pink_ghost" + ACCELERATION = 0.2 + DAMPING = 0.9 + + def __init__(self, pos=None): + if pos is None: + pos = random_in_rect(SCREEN) + super().__init__(pos) + self.goal = self.new_goal() + + def new_goal(self): + direction = from_polar(60, gauss(self.velocity.as_polar()[1], 30)) + return self.rect.center + direction + + def logic(self, **kwargs): + middle_area = SCREEN.inflate(-30, -30) + while self.rect.collidepoint(self.goal) or not middle_area.collidepoint( + self.goal + ): + self.goal = self.new_goal() + + self.acceleration = ( + self.goal - self.rect.center + ).normalize() * self.ACCELERATION + super().logic(**kwargs) + + +class SolidObject(Object): + SHEET_RECT = [ + (0, 0, 24, 31), + (24, 0, 24, 24), + (48, 0, 24, 24), + (72, 0, 16, 24), + (88, 0, 48, 43), + (136, 0, 16, 16), + ] + SCALE = 3 + + def __init__(self, pos): + sheet = load_image("tileset", self.SCALE) + sheet.set_colorkey(0xFFFFFF) + rect = choice(self.SHEET_RECT) + rect = [x * self.SCALE for x in rect] + super().__init__(pos, sheet.subsurface(rect)) + + @classmethod + def generate_many(cls, nb=16, max_tries=1000): + objects = [] + tries = 0 # avoids infinite loop + while len(objects) < nb and tries < max_tries: + pos = random_in_rect(SCREEN) + obj = cls(pos) + if not any(obj.rect.colliderect(other.rect) for other in objects): + objects.append(obj) + return objects diff --git a/01-fog-of-war/polastyn2030/utils.py b/01-fog-of-war/polastyn2030/utils.py new file mode 100644 index 0000000..28d56ff --- /dev/null +++ b/01-fog-of-war/polastyn2030/utils.py @@ -0,0 +1,40 @@ +from functools import lru_cache +from pathlib import Path +from random import uniform + +import pygame + +SUBMISSION_DIR = Path(__file__).parent +ASSETS = SUBMISSION_DIR.parent / "assets" + + +@lru_cache() +def load_image(name: str, scale=1): + image = pygame.image.load(ASSETS / f"{name}.png") + if scale != 1: + new_size = image.get_width() * scale, image.get_height() * scale + image = pygame.transform.scale(image, new_size) + return image.convert_alpha() + + +def clamp(value, mini, maxi): + """Clamp value between mini and maxi""" + if value < mini: + return mini + elif maxi < value: + return maxi + else: + return value + + +def random_in_rect(rect): + """Return a random point uniformly in a rectangle.""" + rect = pygame.Rect(rect) + return pygame.Vector2(uniform(rect.left, rect.right), uniform(rect.top, rect.bottom)) + + +def from_polar(rho, theta): + """Create a Vector2 from its polar representation.""" + v = pygame.Vector2() + v.from_polar((rho, theta)) + return v diff --git a/wclib/showcase.py b/wclib/showcase.py index 00e6525..8d8f061 100644 --- a/wclib/showcase.py +++ b/wclib/showcase.py @@ -1,7 +1,7 @@ import importlib import json import sys -from functools import lru_cache +from functools import lru_cache, partial from pathlib import Path from typing import Callable, List @@ -92,7 +92,7 @@ def __init__(self, app: "App", title, buttons): self.buttons = [ Button( *button, - lambda: self.button_click(button), + partial(self.button_click, button), self.button_position(i), ) for i, button in enumerate(buttons) From ca39ed85bc1e6f0e1962770031f088c65e285c45 Mon Sep 17 00:00:00 2001 From: ddorn Date: Mon, 11 Oct 2021 13:43:27 +0200 Subject: [PATCH 28/80] fkS#2984 entry --- 01-fog-of-war/fkS124/main.py | 91 ++++++++++++++++++++ 01-fog-of-war/fkS124/objects.py | 142 ++++++++++++++++++++++++++++++++ 01-fog-of-war/fkS124/utils.py | 42 ++++++++++ 3 files changed, 275 insertions(+) create mode 100644 01-fog-of-war/fkS124/main.py create mode 100644 01-fog-of-war/fkS124/objects.py create mode 100644 01-fog-of-war/fkS124/utils.py diff --git a/01-fog-of-war/fkS124/main.py b/01-fog-of-war/fkS124/main.py new file mode 100644 index 0000000..ef7cbf6 --- /dev/null +++ b/01-fog-of-war/fkS124/main.py @@ -0,0 +1,91 @@ +import sys +from pathlib import Path + +try: + import wclib +except ImportError: + # wclib may not be in the path because of the architecture + # of all the challenges and the fact that there are many + # way to run them (through the showcase, or on their own) + + ROOT_FOLDER = Path(__file__).parent.parent.parent + sys.path.append(str(ROOT_FOLDER)) + import wclib + +# This line tells python how to handle the relative imports +# when you run this file directly. +__package__ = "01-fog-of-war." + Path(__file__).parent.name + +# ---- Recommended: don't modify anything above this line ---- # + +# Metadata about your submission +__author__ = "fkS#2984" +__achievements__ = [ # Uncomment the ones you've done + "Casual", + "Ambitious", + "Adventurous", +] + + +from operator import attrgetter +import pygame + +# To import the modules in yourname/, you need to use relative imports, +# otherwise your project will not be compatible with the showcase. +from .objects import Ghost, Player, SolidObject + +BACKGROUND = 0x66856C + + +def draw_gradient(surf, pos, radius, dep_alpha): + for i in range(20, 0, -1): + pygame.draw.circle( + surf, (0, 0, 0, dep_alpha - (-i) * 7), pos, int(radius * i / 20) + ) + + +def mainloop(): + player = Player((100, 100)) + trees = SolidObject.generate_many(36) + ghosts = [Ghost() for _ in range(16)] + + all_objects = trees + [player] + ghosts + + clock = pygame.time.Clock() + + radius = 150 + surf = pygame.Surface((1024, 768), pygame.SRCALPHA) + surf.fill((0, 0, 0)) + second_surf = pygame.Surface((1024, 768), pygame.SRCALPHA) + second_surf.fill((0, 0, 0)) + second_surf.set_alpha(180) + while True: + screen, events = yield + for event in events: + if event.type == pygame.QUIT: + return + + for obj in all_objects: + obj.logic(objects=all_objects) + + screen.fill(BACKGROUND) + for object in sorted(all_objects, key=attrgetter("rect.bottom")): + if type(object) is Ghost: + if object.pos.distance_to(player.pos) < radius: + object.draw(screen) + else: + object.draw(screen) + + second_surf.fill((0, 0, 0)) + + pygame.draw.circle( + surf, (0, 0, 0, 0), player.pos + pygame.Vector2(20, 20), radius + ) + draw_gradient(second_surf, player.pos + pygame.Vector2(20, 20), radius, 100) + screen.blit(second_surf, (0, 0)) + screen.blit(surf, (0, 0)) + clock.tick(60) + + +if __name__ == "__main__": + wclib.run(mainloop()) diff --git a/01-fog-of-war/fkS124/objects.py b/01-fog-of-war/fkS124/objects.py new file mode 100644 index 0000000..e507e56 --- /dev/null +++ b/01-fog-of-war/fkS124/objects.py @@ -0,0 +1,142 @@ +""" +This file provides objects that can be used to make up +a basic playground for the challenges. + +This code is provided so that you can focus on implementing +a fog of war, without needed +Feel free to modify everything in this file to your liking. +""" +from random import choice, gauss + +import pygame + +from wclib import SIZE +from .utils import clamp, from_polar, load_image, random_in_rect + +SCREEN = pygame.Rect(0, 0, *SIZE) + + +class Object: + """The base class for all objects of the game.""" + + def __init__(self, pos, sprite: pygame.Surface): + self.pos = pygame.Vector2(pos) + self.size = pygame.Vector2(sprite.get_size()) + self.sprite = sprite + + def __str__(self): + return f"<{self.__class__.__name__}(pos={self.pos}, size={self.size})>" + + @property + def rect(self): + return pygame.Rect(self.pos, self.size) + + def draw(self, screen): + screen.blit(self.sprite, self.pos) + + def logic(self, **kwargs): + pass + + +class Object8Directional(Object): + SCALE = 3 + SIZE = 16 + SHEET = "blue_ghost" + + ACCELERATION = 0.5 + DAMPING = 0.85 + + # Asymptotic velocity will be solution of + # x = x * DAMPING + ACCELERATION + # That is, + # x = ACCELERATION / (1 - DAMPING) + + def __init__(self, pos): + self.velocity = pygame.Vector2() + self.acceleration = pygame.Vector2() + + super().__init__(pos, self.get_image()) + + def get_image(self): + angle = self.velocity.as_polar()[1] + idx = int((-angle + 90 + 45 / 2) % 360 / 360 * 8) + sheet = load_image(self.SHEET, self.SCALE) + unit = self.SIZE * self.SCALE + return sheet.subsurface(idx * unit, 0, unit, unit) + + def logic(self, **kwargs): + self.velocity *= self.DAMPING + self.velocity += self.acceleration + self.pos += self.velocity + self.sprite = self.get_image() + + self.pos.x = clamp(self.pos.x, 0, SIZE[0]) + self.pos.y = clamp(self.pos.y, 0, SIZE[1]) + + +class Player(Object8Directional): + def logic(self, **kwargs): + pressed = pygame.key.get_pressed() + direction_x = pressed[pygame.K_RIGHT] - pressed[pygame.K_LEFT] + direction_y = pressed[pygame.K_DOWN] - pressed[pygame.K_UP] + + self.acceleration = pygame.Vector2(direction_x, direction_y) * self.ACCELERATION + super().logic(**kwargs) + + +class Ghost(Object8Directional): + SHEET = "pink_ghost" + ACCELERATION = 0.2 + DAMPING = 0.9 + + def __init__(self, pos=None): + if pos is None: + pos = random_in_rect(SCREEN) + super().__init__(pos) + self.goal = self.new_goal() + + def new_goal(self): + direction = from_polar(60, gauss(self.velocity.as_polar()[1], 30)) + return self.rect.center + direction + + def logic(self, **kwargs): + middle_area = SCREEN.inflate(-30, -30) + while self.rect.collidepoint(self.goal) or not middle_area.collidepoint( + self.goal + ): + self.goal = self.new_goal() + + self.acceleration = ( + self.goal - self.rect.center + ).normalize() * self.ACCELERATION + super().logic(**kwargs) + + +class SolidObject(Object): + SHEET_RECT = [ + (0, 0, 24, 31), + (24, 0, 24, 24), + (48, 0, 24, 24), + (72, 0, 16, 24), + (88, 0, 48, 43), + (136, 0, 16, 16), + ] + SCALE = 3 + + def __init__(self, pos): + sheet = load_image("tileset", self.SCALE) + sheet.set_colorkey(0xFFFFFF) + rect = choice(self.SHEET_RECT) + rect = [x * self.SCALE for x in rect] + super().__init__(pos, sheet.subsurface(rect)) + + @classmethod + def generate_many(cls, nb=16, max_tries=1000): + objects = [] + tries = 0 # avoids infinite loop + while len(objects) < nb and tries < max_tries: + pos = random_in_rect(SCREEN) + obj = cls(pos) + if not any(obj.rect.colliderect(other.rect) for other in objects): + objects.append(obj) + return objects diff --git a/01-fog-of-war/fkS124/utils.py b/01-fog-of-war/fkS124/utils.py new file mode 100644 index 0000000..5669d2f --- /dev/null +++ b/01-fog-of-war/fkS124/utils.py @@ -0,0 +1,42 @@ +from functools import lru_cache +from pathlib import Path +from random import uniform + +import pygame + +SUBMISSION_DIR = Path(__file__).parent +ASSETS = SUBMISSION_DIR.parent / "assets" + + +@lru_cache() +def load_image(name: str, scale=1): + image = pygame.image.load(ASSETS / f"{name}.png") + if scale != 1: + new_size = image.get_width() * scale, image.get_height() * scale + image = pygame.transform.scale(image, new_size) + return image.convert_alpha() + + +def clamp(value, mini, maxi): + """Clamp value between mini and maxi""" + if value < mini: + return mini + elif maxi < value: + return maxi + else: + return value + + +def random_in_rect(rect): + """Return a random point uniformly in a rectangle.""" + rect = pygame.Rect(rect) + return pygame.Vector2( + uniform(rect.left, rect.right), uniform(rect.top, rect.bottom) + ) + + +def from_polar(rho, theta): + """Create a Vector2 from its polar representation.""" + v = pygame.Vector2() + v.from_polar((rho, theta)) + return v From 0ea012837a550bab791e8366bcf06020346fdfa2 Mon Sep 17 00:00:00 2001 From: Leif Theden Date: Mon, 11 Oct 2021 07:50:01 -0400 Subject: [PATCH 29/80] bitcraft entry * fix issue with entry not being loaded * add bitcraft entry Co-authored-by: ddorn --- 01-fog-of-war/bitcraft/main.py | 408 ++++++++++++++++++++++++++++++ 01-fog-of-war/bitcraft/objects.py | 153 +++++++++++ 01-fog-of-war/bitcraft/utils.py | 40 +++ wclib/showcase.py | 3 - 4 files changed, 601 insertions(+), 3 deletions(-) create mode 100644 01-fog-of-war/bitcraft/main.py create mode 100644 01-fog-of-war/bitcraft/objects.py create mode 100644 01-fog-of-war/bitcraft/utils.py diff --git a/01-fog-of-war/bitcraft/main.py b/01-fog-of-war/bitcraft/main.py new file mode 100644 index 0000000..9f0f00b --- /dev/null +++ b/01-fog-of-war/bitcraft/main.py @@ -0,0 +1,408 @@ +import sys +from pathlib import Path + +try: + import wclib +except ImportError: + # wclib may not be in the path because of the architecture + # of all the challenges and the fact that there are many + # way to run them (through the showcase, or on their own) + + ROOT_FOLDER = Path(__file__).parent.parent.parent + sys.path.append(str(ROOT_FOLDER)) + import wclib + +# This line tells python how to handle the relative imports +# when you run this file directly. +__package__ = "01-fog-of-war." + Path(__file__).parent.name + +# ---- Recommended: don't modify anything above this line ---- # + +# Metadata about your submission +# aka bitcraft +__author__ = "thecornboss#2284" +__achievements__ = [ + "Casual", + "Ambitious", + "Adventurous", +] + +""" +improvements to be made: +* smarter management of the blocked cells table +* faster mask creation +* scale the cells to a higher resolution buffer +* gaussian blur +* needs code cleanup +* faster FOV -- not suitable for large light radius +* current FOV doesn't handle arbitrary shapes +* figure out method for light bleeding besides using `circle` + +-- bitcraft, 2021 + +""" + +from functools import partial +from operator import attrgetter +from random import randint +import pygame + +# To import the modules in yourname/, you need to use relative imports, +# otherwise your project will not be compatible with the showcase. +from .objects import Ghost, Player, SolidObject + +BACKGROUND = 0x66856C + +MULT = [ + [1, 0, 0, -1, -1, 0, 0, 1], + [0, 1, -1, 0, 0, -1, 1, 0], + [0, 1, 1, 0, 0, -1, -1, 0], + [1, 0, 0, 1, -1, 0, 0, -1], +] + + +def get_visible_points(vantage_point, get_allows_light, max_distance=30): + """ + Returns a set of all points visible from the given vantage point. + + Adopted from https://raw.githubusercontent.com/irskep/clubsandwich/afc79ed/clubsandwich/line_of_sight.py + Adapted from `this RogueBasin article `_. + """ + x, y = vantage_point + los_cache = set() + los_cache.add(vantage_point) + blocked_set = set() + distance = dict() + distance[vantage_point] = 0 + for region in range(8): + _cast_light( + los_cache, + blocked_set, + distance, + get_allows_light, + x, + y, + 1, + 1.0, + 0.0, + max_distance, + MULT[0][region], + MULT[1][region], + MULT[2][region], + MULT[3][region], + ) + return los_cache, blocked_set, distance + + +def _cast_light( + los_cache, + blocked_set, + distance, + get_allows_light, + cx, + cy, + row, + start, + end, + radius, + xx, + xy, + yx, + yy, +): + if start < end: + return + + radius_squared = radius ** 2 + + for j in range(row, radius + 1): + dx, dy = -j - 1, -j + blocked = False + while dx <= 0: + dx += 1 + X, Y = cx + dx * xx + dy * xy, cy + dx * yx + dy * yy + point = X, Y + l_slope, r_slope = (dx - 0.5) / (dy + 0.5), (dx + 0.5) / (dy - 0.5) + if start < r_slope: + continue + elif end > l_slope: + break + else: + d = dx ** 2 + dy ** 2 + if d < radius_squared: + los_cache.add(point) + distance[point] = d + if blocked: + if not get_allows_light(point): + new_start = r_slope + continue + else: + blocked = False + start = new_start + else: + if not get_allows_light(point) and j < radius: + blocked = True + blocked_set.add(point) + distance[point] = d + _cast_light( + los_cache, + blocked_set, + distance, + get_allows_light, + cx, + cy, + j + 1, + start, + l_slope, + radius, + xx, + xy, + yx, + yy, + ) + new_start = r_slope + if blocked: + break + + +def mainloop(): + player = Player((100, 100)) + trees = SolidObject.generate_many(36) + ghosts = [Ghost() for _ in range(16)] + + all_objects = trees + ghosts + [player] + + ## configurable parameters + # smaller cells are slower but gives higher resolution mask + cell_size_px = 4 + # light radius in pixels + light_radius_px = 140 + # darkness of the explored areas + explored_value = 64 + # min expose radius when light touches a sprite + blocked_expose_min_px = 48 + # max expose radius when light touches a sprite + blocked_expose_max_px = 64 + # min expose radius when light doesn't touch a sprite + unblocked_expose_min_px = 8 + # max expose radius when light doesn't touch a sprite + unblocked_expose_max_px = 24 + # radius of cast light around source + cast_light_px = 32 + # values greater than 1 will result in color bands and faster/retro rendering + # setting it to 1 will result in a smooth light cast. must be changed with cell + # size and light radius, or light won't render at correct brightness. + # table for known values: + # cell value notes + # 4 400 3 color bands + # 4 17 higher values create noticeable moire pattern + # 4 3 no artifacts, some caching + light_mod_value = 400 + + light_radius = int(light_radius_px // cell_size_px) + light_radius2 = light_radius ** 2 + light_radius_px2 = light_radius_px ** 2 + + new_points = set() + cast_light = None + blocked_light_min = None + blocked_light_max = None + unblocked_light_min = None + unblocked_light_max = None + old_screen = None + work_surface = None + fog_tiles = None + fog_table = None + fog_surface = None + light_surface = None + + clock = pygame.time.Clock() + while True: + screen, events = yield + for event in events: + if event.type == pygame.QUIT: + return + + sw, sh = screen.get_size() + stw = sw // cell_size_px + sth = sh // cell_size_px + + # init fog stuff + if old_screen is not screen: + old_screen = screen + fog_size = sw // cell_size_px, sh // cell_size_px + work_surface = pygame.surface.Surface((sw, sh)) + fog_surface = pygame.surface.Surface(fog_size) + light_surface = pygame.surface.Surface(fog_size) + blocked_light_min = max(1, blocked_expose_min_px // cell_size_px) + blocked_light_max = max(1, blocked_expose_max_px // cell_size_px) + unblocked_light_min = max(1, unblocked_expose_min_px // cell_size_px) + unblocked_light_max = max(1, unblocked_expose_max_px // cell_size_px) + cast_light = max(1, cast_light_px // cell_size_px) + fog_table = dict() + fog_tiles = list() + for y in range(0, sth * cell_size_px, cell_size_px): + row = list() + fog_tiles.append(row) + for x in range(0, stw * cell_size_px, cell_size_px): + row.append(False) + + for obj in all_objects: + obj.logic(objects=all_objects) + + # clear collision mask + for row in fog_tiles: + for x in range(len(row)): + row[x] = True + + # set collision mask + for obj in all_objects: + if obj is player: + continue + # cast shadow using bbox of image + rect = obj.bbox.move(obj.rect.topleft) + left = rect.left // cell_size_px + top = rect.top // cell_size_px + right = rect.right // cell_size_px + bottom = rect.bottom // cell_size_px + for y in range(top, bottom + 1): + for x in range(left, right + 1): + try: + fog_tiles[y][x] = False + except IndexError: + pass + # cast shadow with mask - very glitchy + # rect = obj.rect + # left = rect.left // cell_size_px + # top = rect.top // cell_size_px + # for point in obj.outline: + # x, y = point + # x += left + # y += top + # try: + # fog_tiles[y][x] = False + # except IndexError: + # pass + + # smooth fade and hide ghosts + x1, y1 = player.rect.center + for ghost in ghosts: + x2, y2 = ghost.rect.center + d2 = (x1 - x2) ** 2 + (y1 - y2) ** 2 + if d2 < light_radius_px2: + opacity = 1 - (d2 / light_radius_px2) + opacity = int(out_quad(opacity) * 255) + opacity = min(255, max(0, opacity)) + ghost.hidden = False + ghost.opacity = opacity + else: + ghost.hidden = True + + # get visible and blocked cells, with the distance for them + px = player.rect.centerx // cell_size_px + py = player.rect.centery // cell_size_px + func = partial(light, fog_tiles) + visible, blocked, distance = get_visible_points((px, py), func, light_radius) + + # update the fog table, order of update is important; blocked first, then visible + new_points.clear() + for point in blocked: + if point not in fog_table: + size = randint(blocked_light_min, blocked_light_max) + fog_table[point] = size + new_points.add((point, size)) + for point in visible: + if point not in fog_table: + size = randint(unblocked_light_min, unblocked_light_max) + fog_table[point] = size + new_points.add((point, size)) + + draw_fog( + fog_surface, + light_surface, + visible, + distance, + new_points, + explored_value, + light_radius2, + cast_light, + light_mod_value, + ) + + screen.fill(BACKGROUND) + for obj in sorted(all_objects, key=attrgetter("rect.bottom")): + obj.draw(screen) + + pygame.transform.scale(light_surface, work_surface.get_size(), work_surface) + screen.blit(work_surface, (0, 0), special_flags=pygame.BLEND_RGB_MULT) + + clock.tick(60) + + +def draw_fog( + fog_surface, + light_surface, + visible, + distance, + new_points, + explored_value, + light_radius2, + cast_light_radius, + light_mod_value, +): + """ + * draw circles to expose explored map areas on fog surface + * clear light surface to black + * draw visible light on light surface: + - ordered from furthest to closest... + - calculate color value + - draw circle to expose/brighten map + + """ + explored_color = explored_value, explored_value, explored_value + white = 255, 255, 255 + circle = pygame.draw.circle + fog_surface.lock() + light_surface.lock() + # draw explored cells + for point, size in new_points: + circle(fog_surface, white, point, size) + # make list of visible cells for sorting + draw_list = list() + for point in visible: + draw_list.append((distance[point], point)) + draw_list.sort(reverse=True) + # draw cells in the light radius + # avoid too many calculations, also enable color banding + cache = dict() + light_surface.fill(explored_color) + value_range = 255 - explored_value + for d, point in draw_list: + token = d // light_mod_value + try: + color = cache[token] + except KeyError: + value0 = 1 - (d / light_radius2) + value = int(out_quad(value0) * value_range) + explored_value + value = min(255, max(0, value)) + color = value, value, value + cache[token] = color + circle(light_surface, color, point, cast_light_radius) + fog_surface.unlock() + light_surface.unlock() + light_surface.blit(fog_surface, (0, 0), special_flags=pygame.BLEND_MULT) + + +def light(fog_tiles, point): + try: + return fog_tiles[point[1]][point[0]] + except IndexError: + return False + + +def out_quad(progress): + return -1.0 * progress * (progress - 2.0) + + +if __name__ == "__main__": + wclib.run(mainloop()) diff --git a/01-fog-of-war/bitcraft/objects.py b/01-fog-of-war/bitcraft/objects.py new file mode 100644 index 0000000..a237cd2 --- /dev/null +++ b/01-fog-of-war/bitcraft/objects.py @@ -0,0 +1,153 @@ +""" +This file provides objects that can be used to make up +a basic playground for the challenges. + +This code is provided so that you can focus on implementing +a fog of war, without needed +Feel free to modify everything in this file to your liking. +""" +from random import choice, gauss + +import pygame + +from wclib import SIZE +from .utils import clamp, from_polar, load_image, random_in_rect + +SCREEN = pygame.Rect(0, 0, *SIZE) + + +class Object: + """The base class for all objects of the game.""" + + def __init__(self, pos, sprite: pygame.Surface): + self.pos = pygame.Vector2(pos) + self.size = pygame.Vector2(sprite.get_size()) + self.sprite = sprite + self.mask = pygame.mask.from_surface(self.sprite) + bounds = self.mask.get_bounding_rects() + self.bbox = bounds[0].unionall(bounds[1:]) + self.hidden = False + self.opacity = 255 + + def __str__(self): + return f"<{self.__class__.__name__}(pos={self.pos}, size={self.size})>" + + @property + def rect(self): + return pygame.Rect(self.pos, self.size) + + def draw(self, screen): + if not self.hidden: + self.sprite.set_alpha(self.opacity) + screen.blit(self.sprite, self.pos) + + def logic(self, **kwargs): + pass + + +class Object8Directional(Object): + SCALE = 3 + SIZE = 16 + SHEET = "blue_ghost" + + ACCELERATION = 0.5 + DAMPING = 0.85 + + # Asymptotic velocity will be solution of + # x = x * DAMPING + ACCELERATION + # That is, + # x = ACCELERATION / (1 - DAMPING) + + def __init__(self, pos): + self.velocity = pygame.Vector2() + self.acceleration = pygame.Vector2() + + super().__init__(pos, self.get_image()) + + def get_image(self): + angle = self.velocity.as_polar()[1] + idx = int((-angle + 90 + 45 / 2) % 360 / 360 * 8) + sheet = load_image(self.SHEET, self.SCALE) + unit = self.SIZE * self.SCALE + image = sheet.subsurface(idx * unit, 0, unit, unit) + self.mask = pygame.mask.from_surface(image) + bounds = self.mask.get_bounding_rects() + self.bbox = bounds[0].unionall(bounds[1:]) + return image + + def logic(self, **kwargs): + self.velocity *= self.DAMPING + self.velocity += self.acceleration + self.pos += self.velocity + self.sprite = self.get_image() + + self.pos.x = clamp(self.pos.x, 0, SIZE[0]) + self.pos.y = clamp(self.pos.y, 0, SIZE[1]) + + +class Player(Object8Directional): + def logic(self, **kwargs): + pressed = pygame.key.get_pressed() + direction_x = pressed[pygame.K_RIGHT] - pressed[pygame.K_LEFT] + direction_y = pressed[pygame.K_DOWN] - pressed[pygame.K_UP] + + self.acceleration = pygame.Vector2(direction_x, direction_y) * self.ACCELERATION + super().logic(**kwargs) + + +class Ghost(Object8Directional): + SHEET = "pink_ghost" + ACCELERATION = 0.2 + DAMPING = 0.9 + + def __init__(self, pos=None): + if pos is None: + pos = random_in_rect(SCREEN) + super().__init__(pos) + self.goal = self.new_goal() + + def new_goal(self): + direction = from_polar(60, gauss(self.velocity.as_polar()[1], 30)) + return self.rect.center + direction + + def logic(self, **kwargs): + middle_area = SCREEN.inflate(-30, -30) + while self.rect.collidepoint(self.goal) or not middle_area.collidepoint( + self.goal + ): + self.goal = self.new_goal() + + self.acceleration = ( + self.goal - self.rect.center + ).normalize() * self.ACCELERATION + super().logic(**kwargs) + + +class SolidObject(Object): + SHEET_RECT = [ + (0, 0, 24, 31), + (24, 0, 24, 24), + (48, 0, 24, 24), + (72, 0, 16, 24), + (88, 0, 48, 43), + (136, 0, 16, 16), + ] + SCALE = 3 + + def __init__(self, pos): + sheet = load_image("tileset", self.SCALE) + sheet.set_colorkey(0xFFFFFF) + rect = choice(self.SHEET_RECT) + rect = [x * self.SCALE for x in rect] + super().__init__(pos, sheet.subsurface(rect)) + + @classmethod + def generate_many(cls, nb=16, max_tries=1000): + objects = [] + tries = 0 # avoids infinite loop + while len(objects) < nb and tries < max_tries: + pos = random_in_rect(SCREEN) + obj = cls(pos) + if not any(obj.rect.colliderect(other.rect) for other in objects): + objects.append(obj) + return objects diff --git a/01-fog-of-war/bitcraft/utils.py b/01-fog-of-war/bitcraft/utils.py new file mode 100644 index 0000000..28d56ff --- /dev/null +++ b/01-fog-of-war/bitcraft/utils.py @@ -0,0 +1,40 @@ +from functools import lru_cache +from pathlib import Path +from random import uniform + +import pygame + +SUBMISSION_DIR = Path(__file__).parent +ASSETS = SUBMISSION_DIR.parent / "assets" + + +@lru_cache() +def load_image(name: str, scale=1): + image = pygame.image.load(ASSETS / f"{name}.png") + if scale != 1: + new_size = image.get_width() * scale, image.get_height() * scale + image = pygame.transform.scale(image, new_size) + return image.convert_alpha() + + +def clamp(value, mini, maxi): + """Clamp value between mini and maxi""" + if value < mini: + return mini + elif maxi < value: + return maxi + else: + return value + + +def random_in_rect(rect): + """Return a random point uniformly in a rectangle.""" + rect = pygame.Rect(rect) + return pygame.Vector2(uniform(rect.left, rect.right), uniform(rect.top, rect.bottom)) + + +def from_polar(rho, theta): + """Create a Vector2 from its polar representation.""" + v = pygame.Vector2() + v.from_polar((rho, theta)) + return v diff --git a/wclib/showcase.py b/wclib/showcase.py index 8d8f061..4f87535 100644 --- a/wclib/showcase.py +++ b/wclib/showcase.py @@ -9,7 +9,6 @@ from .constants import ROOT_DIR, SIZE from .core import ( - MainLoop, get_mainloop, get_challenges, get_entries, @@ -87,8 +86,6 @@ class MenuState(State): def __init__(self, app: "App", title, buttons): super().__init__(app) self.title = title - self.buttons = buttons - self.buttons = [ Button( *button, From a8fcc28778604b919e2ced627827901f42242541 Mon Sep 17 00:00:00 2001 From: Abalue <39532143+Abalue@users.noreply.github.com> Date: Mon, 11 Oct 2021 12:35:45 +0100 Subject: [PATCH 30/80] Abalue entry * Add files via upload * Delete 01-fog-of-war/Abalue/__pycache__ directory --- 01-fog-of-war/Abalue/main.py | 72 +++++++ 01-fog-of-war/Abalue/objects.py | 323 ++++++++++++++++++++++++++++++++ 01-fog-of-war/Abalue/utils.py | 40 ++++ 3 files changed, 435 insertions(+) create mode 100644 01-fog-of-war/Abalue/main.py create mode 100644 01-fog-of-war/Abalue/objects.py create mode 100644 01-fog-of-war/Abalue/utils.py diff --git a/01-fog-of-war/Abalue/main.py b/01-fog-of-war/Abalue/main.py new file mode 100644 index 0000000..87545fa --- /dev/null +++ b/01-fog-of-war/Abalue/main.py @@ -0,0 +1,72 @@ +import sys +from pathlib import Path + +try: + import wclib +except ImportError: + # wclib may not be in the path because of the architecture + # of all the challenges and the fact that there are many + # way to run them (through the showcase, or on their own) + + ROOT_FOLDER = Path(__file__).parent.parent.parent + sys.path.append(str(ROOT_FOLDER)) + import wclib + +# This line tells python how to handle the relative imports +# when you run this file directly. +__package__ = "01-fog-of-war." + Path(__file__).parent.name + +# ---- Recommended: don't modify anything above this line ---- # + +# Metadata about your submission +__author__ = "Abalue#7926" +__achievements__ = [ # Uncomment the ones you've done + "Casual", + "Ambitious", + "Adventurous", +] + + +from operator import attrgetter +import pygame + +# To import the modules in yourname/, you need to use relative imports, +# otherwise your project will not be compatible with the showcase. +from .objects import Ghost, Player, SolidObject, Fog, Menu + +BACKGROUND = 0x66856C + + +def mainloop(): + player = Player((100, 100)) + trees = SolidObject.generate_many(36) + ghosts = [Ghost() for _ in range(16)] + fog = Fog(player.rect) + menu = Menu() + + all_objects = trees + ghosts + [player, menu] + + clock = pygame.time.Clock() + while True: + screen, events = yield + for event in events: + if event.type == pygame.QUIT: + return + menu.handle_event(event) + + for obj in all_objects: + obj.logic(objects=all_objects) + fog.logic(player, menu) + menu.logic() + + #screen.fill(BACKGROUND) + #for object in sorted(all_objects, key=attrgetter("rect.bottom")): + # object.draw(screen) + fog.draw(screen, all_objects) + menu.draw(screen) + + clock.tick(60) + + +if __name__ == "__main__": + wclib.run(mainloop()) diff --git a/01-fog-of-war/Abalue/objects.py b/01-fog-of-war/Abalue/objects.py new file mode 100644 index 0000000..a261934 --- /dev/null +++ b/01-fog-of-war/Abalue/objects.py @@ -0,0 +1,323 @@ +""" +This file provides objects that can be used to make up +a basic playground for the challenges. + +This code is provided so that you can focus on implementing +a fog of war, without needed +Feel free to modify everything in this file to your liking. +""" +from random import choice, gauss +from operator import attrgetter + +import pygame + +from wclib import SIZE +from .utils import clamp, from_polar, load_image, random_in_rect + +SCREEN = pygame.Rect(0, 0, *SIZE) + + +class Renderer: + def __init__(self): + self.background_color = 0x66856C + + def handle_event(self): + pass + + def logic(self, **kwargs): + pass + + def draw(self, display, objects): + display.fill(self.background_color) + for obj in objects: + display.blit(obj.sprite, obj.pos) + + +class Object: + """The base class for all objects of the game.""" + + def __init__(self, pos, sprite: pygame.Surface): + self.pos = pygame.Vector2(pos) + self.size = pygame.Vector2(sprite.get_size()) + self.sprite = sprite + + def __str__(self): + return f"<{self.__class__.__name__}(pos={self.pos}, size={self.size})>" + + @property + def rect(self): + return pygame.Rect(self.pos, self.size) + + def draw(self, screen): + screen.blit(self.sprite, self.pos) + + def logic(self, **kwargs): + pass + + +class Object8Directional(Object): + SCALE = 3 + SIZE = 16 + SHEET = "blue_ghost" + + ACCELERATION = 0.5 + DAMPING = 0.85 + + # Asymptotic velocity will be solution of + # x = x * DAMPING + ACCELERATION + # That is, + # x = ACCELERATION / (1 - DAMPING) + + def __init__(self, pos): + self.velocity = pygame.Vector2() + self.acceleration = pygame.Vector2() + + super().__init__(pos, self.get_image()) + + def get_image(self): + angle = self.velocity.as_polar()[1] + idx = int((-angle + 90 + 45 / 2) % 360 / 360 * 8) + sheet = load_image(self.SHEET, self.SCALE) + unit = self.SIZE * self.SCALE + return sheet.subsurface(idx * unit, 0, unit, unit) + + def logic(self, **kwargs): + self.velocity *= self.DAMPING + self.velocity += self.acceleration + self.pos += self.velocity + self.sprite = self.get_image() + + self.pos.x = clamp(self.pos.x, 0, SIZE[0]) + self.pos.y = clamp(self.pos.y, 0, SIZE[1]) + + +class Player(Object8Directional): + def logic(self, **kwargs): + objects = kwargs["objects"] + for obj in objects: + if isinstance(obj, Menu): + if obj.open: + return + pressed = pygame.key.get_pressed() + direction_x = pressed[pygame.K_RIGHT] - pressed[pygame.K_LEFT] + direction_y = pressed[pygame.K_DOWN] - pressed[pygame.K_UP] + + self.acceleration = pygame.Vector2(direction_x, direction_y) * self.ACCELERATION + super().logic(**kwargs) + + +class Ghost(Object8Directional): + SHEET = "pink_ghost" + ACCELERATION = 0.2 + DAMPING = 0.9 + + def __init__(self, pos=None): + if pos is None: + pos = random_in_rect(SCREEN) + super().__init__(pos) + self.sprite.convert() + self.goal = self.new_goal() + self.dist_to_player = pygame.Vector2() + + def new_goal(self): + direction = from_polar(60, gauss(self.velocity.as_polar()[1], 30)) + return self.rect.center + direction + + def logic(self, **kwargs): + middle_area = SCREEN.inflate(-30, -30) + while self.rect.collidepoint(self.goal) or not middle_area.collidepoint( + self.goal + ): + self.goal = self.new_goal() + + self.acceleration = ( + self.goal - self.rect.center + ).normalize() * self.ACCELERATION + + for object in kwargs["objects"]: + if isinstance(object, Player): + self.dist_to_player = (self.pos - object.pos).length() + super().logic(**kwargs) + + +class SolidObject(Object): + SHEET_RECT = [ + (0, 0, 24, 31), + (24, 0, 24, 24), + (48, 0, 24, 24), + (72, 0, 16, 24), + (88, 0, 48, 43), + (136, 0, 16, 16), + ] + SCALE = 3 + + def __init__(self, pos): + sheet = load_image("tileset", self.SCALE) + sheet.set_colorkey(0xFFFFFF) + rect = choice(self.SHEET_RECT) + rect = [x * self.SCALE for x in rect] + super().__init__(pos, sheet.subsurface(rect)) + + @classmethod + def generate_many(cls, nb=16, max_tries=1000): + objects = [] + tries = 0 # avoids infinite loop + while len(objects) < nb and tries < max_tries: + pos = random_in_rect(SCREEN) + obj = cls(pos) + if not any(obj.rect.colliderect(other.rect) for other in objects): + objects.append(obj) + return objects + + +class Menu: + def __init__(self): + # Should be a subclass of object but I'm lazy + self.sprite =pygame.Surface((1, 1)) + self.pos = pygame.Vector2(-2, -2) + # + + self.BG_COLOR = pygame.Color(85, 125, 245) + self.BG_ALPHA = 220 + self.OPEN_VEL = 8 + self.FONT_SIZE = 22 + pygame.font.init() + self.FONT = pygame.font.SysFont("helvetica", self.FONT_SIZE) + self.FONT_COLOR = pygame.Color(5, 45, 165) + __achievements__ = [ # can't grab from main to avoid recursive issues :( + "Default", + "Casual", + "Ambitious", + "Adventurous", + ] + self.ACHIEVEMENTS = [self.FONT.render(a, True, self.FONT_COLOR) for a in __achievements__] + self.gaps = [20] * len(self.ACHIEVEMENTS) + self.OPEN_ME_TXT = self.FONT.render("press tab to toggle menu...", True, pygame.Color(255, 255, 255)) + + self.open = False + self.has_opened = False + self.selected = 2 + height = pygame.display.get_surface().get_height() + width = 250 + self.rect = pygame.Rect(-width, 0, width, height) + + def handle_event(self, event): + if event.type == pygame.KEYDOWN: + if event.key == pygame.K_TAB: + self.open = not self.open + self.has_opened = True + if event.key == pygame.K_UP and self.open: + self.selected -= 1 + if self.selected < 0: + self.selected = len(self.ACHIEVEMENTS) - 1 + if event.key == pygame.K_DOWN and self.open: + self.selected += 1 + if self.selected >= len(self.ACHIEVEMENTS): + self.selected = 0 + + def logic(self, *args, **kwargs): + print(self.rect.topleft) + # open and close menu + if self.open and self.rect.right < self.rect.w: + self.rect.x += self.OPEN_VEL + self.rect.x = min(0, self.rect.x) + elif not self.open and self.rect.left > -self.rect.w: + self.rect.x -= self.OPEN_VEL + self.rect.right = max(0, self.rect.right) + + def draw(self, display): + surface = pygame.Surface(self.rect.size).convert() + surface.set_alpha(self.BG_ALPHA) + surface.fill(self.BG_COLOR) + for i, a in enumerate(self.ACHIEVEMENTS): + if self.selected == i: + if self.gaps[i] < 40: + self.gaps[i] += 2 + self.gaps[i] = min(self.gaps[i], 40) + pygame.draw.rect(surface, pygame.Color(220, 220, 220), (self.rect.x, 40 + i * 50, self.rect.w, 50)) + else: + if self.gaps[i] > 20: + self.gaps[i] -= 2 + self.gaps[i] = max(self.gaps[i], 20) + surface.blit(a, (self.rect.x + self.gaps[i], 50 + i * 50)) + display.blit(surface, (self.rect.topleft)) + if not self.has_opened: + display.blit(self.OPEN_ME_TXT, (400, 700)) + + +class Fog(Renderer): + def __init__(self, player_rect): + super().__init__() + self.RADIUS = 200 + self.FADE_LEN = 150 + self.FADE_ITERS = 40 + self.COLOR = pygame.Color(0, 0, 0, 255) + + self.ALPHA_RANGE = [int((self.FADE_ITERS - i - 1) / self.FADE_ITERS * 200) for i in range(self.FADE_ITERS)] + self.RADIUS_RANGE = [self.RADIUS - self.FADE_LEN * i / self.FADE_ITERS for i in range(self.FADE_ITERS)] + + self.pos = pygame.Vector2(player_rect.center) + self.size = pygame.Vector2(pygame.display.get_window_size()) * 2 + self.mode = "ambitious" + + self.explore_surf = pygame.Surface(self.size / 2).convert_alpha() + self.explore_mask = pygame.Surface(self.size / 2).convert_alpha() + self.player_surf = pygame.Surface((self.RADIUS * 2, self.RADIUS * 2)).convert_alpha() + self.player_mask = pygame.Surface((self.RADIUS * 2, self.RADIUS * 2)).convert_alpha() + self.player_mask.fill(pygame.Color(254, 254, 254, 255)) + self.player_mask_casual = pygame.Surface((self.RADIUS * 2, self.RADIUS * 2)).convert_alpha() + self.player_mask_casual.fill(pygame.Color(254, 254, 254, 255)) + pygame.draw.circle(self.player_mask_casual, pygame.Color(0, 0, 0, 0), (self.RADIUS, self.RADIUS), self.RADIUS) + + # add player view mask + for i in range(self.FADE_ITERS): + color = pygame.Color(self.COLOR) + color.a = self.ALPHA_RANGE[i] + pygame.draw.circle(self.player_mask, color, (self.RADIUS, self.RADIUS), self.RADIUS_RANGE[i]) + + def logic(self, player, menu): + self.pos.update(player.rect.center) + pygame.draw.circle(self.explore_mask, pygame.Color(0, 0, 0, 200), self.pos, self.RADIUS) + if menu.selected == 0: + self.mode = "default" + if menu.selected == 1: + self.mode = "casual" + elif menu.selected == 2: + self.mode = "ambitious" + elif menu.selected == 3: + self.mode = "adventurous" + + def draw(self, screen, all_objects): + # fill background + if self.mode == "default": + super().draw(screen, all_objects) + return + screen.fill(0x66856C) + self.explore_surf.fill(0x66856C) + self.player_surf.fill(0x66856C) + # draw objects + for object in sorted(all_objects, key=attrgetter("rect.bottom")): + if isinstance(object, Ghost): + fade = min(self.RADIUS, self.RADIUS * 5 / 3 - object.dist_to_player * 1.4) / self.RADIUS * 255 + object.sprite.set_alpha(fade) + self.player_surf.blit(object.sprite, object.pos - self.pos + (self.RADIUS, self.RADIUS)) + else: + self.player_surf.blit(object.sprite, object.pos - self.pos + (self.RADIUS, self.RADIUS)) + if isinstance(object, Player): + player = object + if not isinstance(object, Object8Directional): + self.explore_surf.blit(object.sprite, object.pos) + + # add explore mask + if self.mode == "adventurous": + self.explore_surf.blit(self.explore_mask, (0, 0)) + else: + self.explore_surf.fill(pygame.Color(0, 0, 0, 255)) + pygame.draw.circle(self.explore_surf, pygame.Color(0, 0, 0, 0), self.pos, self.RADIUS) + if self.mode != "casual": + self.player_surf.blit(self.player_mask, (0, 0)) + else: + self.player_surf.blit(self.player_mask_casual, (0, 0)) + self.player_surf.set_colorkey(pygame.Color(254, 254, 254)) + screen.blit(self.explore_surf, (0, 0)) + screen.blit(self.player_surf, pygame.Vector2(player.rect.center) - (self.RADIUS, self.RADIUS)) diff --git a/01-fog-of-war/Abalue/utils.py b/01-fog-of-war/Abalue/utils.py new file mode 100644 index 0000000..28d56ff --- /dev/null +++ b/01-fog-of-war/Abalue/utils.py @@ -0,0 +1,40 @@ +from functools import lru_cache +from pathlib import Path +from random import uniform + +import pygame + +SUBMISSION_DIR = Path(__file__).parent +ASSETS = SUBMISSION_DIR.parent / "assets" + + +@lru_cache() +def load_image(name: str, scale=1): + image = pygame.image.load(ASSETS / f"{name}.png") + if scale != 1: + new_size = image.get_width() * scale, image.get_height() * scale + image = pygame.transform.scale(image, new_size) + return image.convert_alpha() + + +def clamp(value, mini, maxi): + """Clamp value between mini and maxi""" + if value < mini: + return mini + elif maxi < value: + return maxi + else: + return value + + +def random_in_rect(rect): + """Return a random point uniformly in a rectangle.""" + rect = pygame.Rect(rect) + return pygame.Vector2(uniform(rect.left, rect.right), uniform(rect.top, rect.bottom)) + + +def from_polar(rho, theta): + """Create a Vector2 from its polar representation.""" + v = pygame.Vector2() + v.from_polar((rho, theta)) + return v From 47d5ff773d72639fdf1dcb1fcd640f58261ddb2d Mon Sep 17 00:00:00 2001 From: ddorn Date: Mon, 11 Oct 2021 13:56:55 +0200 Subject: [PATCH 31/80] andenixa entry --- 01-fog-of-war/andenixa/fog_of_war.png | Bin 0 -> 1966 bytes 01-fog-of-war/andenixa/main.py | 533 ++++++++++++++++++++++++++ 01-fog-of-war/andenixa/objects.py | 142 +++++++ 01-fog-of-war/andenixa/utils.py | 40 ++ 4 files changed, 715 insertions(+) create mode 100644 01-fog-of-war/andenixa/fog_of_war.png create mode 100644 01-fog-of-war/andenixa/main.py create mode 100644 01-fog-of-war/andenixa/objects.py create mode 100644 01-fog-of-war/andenixa/utils.py diff --git a/01-fog-of-war/andenixa/fog_of_war.png b/01-fog-of-war/andenixa/fog_of_war.png new file mode 100644 index 0000000000000000000000000000000000000000..dcc6de02d89b4fc2953e969d4340d7a6831b5532 GIT binary patch literal 1966 zcmV;f2T}NmP)g+=`VmCB1kCvW9pxaF0?JU*032pG5chmMpO)4G{`3b00%Fkz-zS;StyZRNIY`Yv%wrw&RQ@OXP4 z&x_nl$+?YHV9N>9`iTFE$Bn1t(m~Nm>1cu~<(2dGI$?~!5Xo{dE+g&r`04JUIQ_vI z0kmAy^q{#TEPdurY!LuoIneaRxxU^$-rc|A_f@{v!yEwt#&Hm98@(-)lXZ?ECg!h% zO@UqzG)tL)MGeS#f>nZ1z5{@@G(dAf;5&M{dni^mR7pI5bpn(#1j+84d>sv5)U_06GK|f0^v1t^Gg#`jc}RUF=Q3P!uGXpTX+yCDPyi_7(X1 z;2M6L+CJd*`NdDq%jL3!8z?^FQ2bL;E!;JeH9&JE+y;>;5-1J+JRu6gO0XPq)x=E1 zbQ;?KkT_? zpJAw*{!4^dJB)&o9^TF-aDag(D0k066y!K?v(^8Eqts?)T7?^T8}SVX-zWV{&iNEY z6Gx($hPd~5U=4WtcsH1oKHwThX5>@_qJ%GLE9eAKJg~TZ@pRKrd@(`FO3hi3?ZeIx zFcbwfAnC)CnK-lf0RR_-;tx2NF`I%^#zsVB$wZJr`vU+s!3`4`N_-{$oI7o!mIIt6 z1x6Hae|B?_2t)miF*g~c1VMzSK^IG`u$cItfTTaPFvXH%Xc(AH`vU+s-U0-6GZ~+7 zlI-}0qpQ7(?c3LtLgAyPG~*tFeyfhZT%|NJUr6Gt6B~17;nki+gvF zT4S#f1rd1>wec6Fzq|(2+SXb1je^n#I|LZ77A1z)nc*-&fMw|iV-tC*2V*_~L|oxu zVOzpMT>4;vfB>hzL4wjxIs^M081e!AMgw!OicdB~fCyfnUxG!3 zaV2PR!v2=mHYDSpqWw9ZPXfufFC&u`l0;$_dosZ6G*<{f;s!3PYH6%E_wh#@1x4o zlP6t`>&U@(*YNiF+5%AGSXyR}ZscMcGR0He2cb6i;y`am)SlbxI%Rej^eg5Aa#5)= znCn4$N4gl8#uv0nAH<)K8FBV*Ew*iQGUXd0{sT{hw_}bi_-538fSNYYnny%OwMUjF zb4Nw#7j50ZXT&ru68$!j2A>>&@HEhLbb=Sou6D%yT`^ZAZ3TMG5obJ3P$)|oiugqO zwy8?Ia3**~3@6GW9=-By`p-)eK)*DHw$!xL_~#{yNFS^{CrqO`vhr~el>7nn=7bT96){w$46&FlhK~?*0Ic=~^03j?pXRG%g;Ab=nYAZ4*0*j`cached_p1_dist and pt2_distcached_p2_dist + if not is_inside and not is_outside: + if pt1_dist>cached_p1_dist: + pt1 = cached[0] + cache_dirty = True + if pt2_dist [insert, append] <--- + pts2.insert(0, p2) # that is of course not optimal for lists + + if DEBUG_DRAW: + pygame.draw.line(surf, (162,194,126), p2, colis2[0] ) + pygame.draw.rect(surf, (22,232,111), s_rect, 1) + break + if DEBUG_DRAW: + pygame.draw.line(surf, (254,222,156), colis[0], colis[1] ) + pygame.draw.line(surf, (152,184,156), player_c_pos, colis[0] ) + + else: + if DEBUG_DRAW: + pygame.draw.line(surf, (254,222,156), line[0], line[1] ) + raycast_ended_r = True + if not raycast_ended_l: + ang2 = angle - a_i + line_v = ray_v.rotate(ang2) + line = tuple(player_c_pos), player_c_pos+line_v + for s_rect in subrects2: + colis = s_rect.clipline( *line ) + if colis: + if DEBUG_DRAW: + pygame.draw.rect(surf, (22,232,111), s_rect, 1) + break + if colis: + pt1 = colis[1] + line_bk = line[1], line[0] + for s_rect in reversed(subrects1): + colis2 = s_rect.clipline( *line_bk ) + if colis2: + p2 = colis2[0] + p2_off = Vector2(shadow_len, 0).rotate(ang2) + p2 = tuple( p2 + p2_off ) + cached = rays_cache.get(ang2, None) + if cached is not None: + pt1_dist = Vector2(pt1).distance_squared_to(player_c_pos) + pt2_dist = Vector2(p2).distance_squared_to(player_c_pos) + cached_p1_dist = Vector2(cached[0]).distance_squared_to(player_c_pos) + cached_p2_dist = Vector2(cached[1]).distance_squared_to(player_c_pos) + is_inside = pt1_dist>cached_p1_dist and pt2_distcached_p2_dist + if not is_inside and not is_outside: + if pt1_dist>cached_p1_dist: + pt1 = cached[0] + cache_dirty = True + if pt2_dist2: + if DEBUG_DRAW: + pygame.draw.polygon(surf, (245,100,200), points, 1) + else: + # pts1 denote inner contour (closer to player) + # pts2 are outer contour + pygame.draw.polygon(surf, color, points) + # end of raycasting + + light_spot.x = player.rect.centerx-LIGHT_SPOT_SIZE//2 + light_spot.y = player.rect.centery-LIGHT_SPOT_SIZE//2 + light_spot.draw(fog_surface, special_flags=pygame.BLEND_MIN) + + #fake blurring + if BLUR_SHADOWS: + the_pos = player.rect.centerx-LIGHT_SPOT_SIZE//2, player.rect.centery-LIGHT_SPOT_SIZE//2 + lighto.blit(fog_surface, (0,0), (*the_pos, LIGHT_SPOT_SIZE, LIGHT_SPOT_SIZE)) + if BLUR_SHADOWS>1: + l_blurred = pygame.transform.smoothscale(lighto, (LIGHT_SPOT_SIZE//4, LIGHT_SPOT_SIZE//4)) + l_blurred = pygame.transform.smoothscale(l_blurred,(LIGHT_SPOT_SIZE//2, LIGHT_SPOT_SIZE//2)) + pygame.transform.scale(l_blurred, (LIGHT_SPOT_SIZE, LIGHT_SPOT_SIZE), lighto) + fog_surface.blit(lighto, the_pos) + + screen.blit(fog_surface, (0,0), special_flags=pygame.BLEND_MULT) + + for y in range(0, fog_t_graph.nrows*fog_size_w, fog_size_w): + c_tile_y = y//fog_size_w + for x in range(0, fog_t_graph.ncols*fog_size_w, fog_size_w): + c_tile_x = x//fog_size_w + graph = fog_t_graph[c_tile_x, c_tile_y] + fog_tile = fog_tiles[graph] + screen.blit(fog_tile, (x, y), special_flags=pygame.BLEND_MULT) + + clock.tick(60) + + +if __name__ == "__main__": + wclib.run(mainloop()) diff --git a/01-fog-of-war/andenixa/objects.py b/01-fog-of-war/andenixa/objects.py new file mode 100644 index 0000000..e76cc0e --- /dev/null +++ b/01-fog-of-war/andenixa/objects.py @@ -0,0 +1,142 @@ +""" +This file provides objects that can be used to make up +a basic playground for the challenges. + +This code is provided so that you can focus on implementing +a fog of war, without needed +Feel free to modify everything in this file to your liking. +""" +from random import choice, gauss + +import pygame + +from wclib import SIZE +from .utils import clamp, from_polar, load_image, random_in_rect + +SCREEN = pygame.Rect(0, 0, *SIZE) + + +class Object: + """The base class for all objects of the game.""" + + def __init__(self, pos, sprite: pygame.Surface): + self.pos = pygame.Vector2(pos) + self.size = pygame.Vector2(sprite.get_size()) + self.sprite = sprite + + def __str__(self): + return f"<{self.__class__.__name__}(pos={self.pos}, size={self.size})>" + + @property + def rect(self): + return pygame.Rect(self.pos, self.size) + + def draw(self, screen): + screen.blit(self.sprite, self.pos) + + def logic(self, **kwargs): + pass + + +class Object8Directional(Object): + SCALE = 3 + SIZE = 16 + SHEET = "blue_ghost" + + ACCELERATION = 0.5 + DAMPING = 0.85 + + # Asymptotic velocity will be solution of + # x = x * DAMPING + ACCELERATION + # That is, + # x = ACCELERATION / (1 - DAMPING) + + def __init__(self, pos): + self.velocity = pygame.Vector2() + self.acceleration = pygame.Vector2() + + super().__init__(pos, self.get_image()) + + def get_image(self): + angle = self.velocity.as_polar()[1] + idx = int((-angle + 90 + 45 / 2) % 360 / 360 * 8) + sheet = load_image(self.SHEET, self.SCALE) + unit = self.SIZE * self.SCALE + return sheet.subsurface(idx * unit, 0, unit, unit) + + def logic(self, **kwargs): + self.velocity *= self.DAMPING + self.velocity += self.acceleration + self.pos += self.velocity + self.sprite = self.get_image() + + self.pos.x = clamp(self.pos.x, 0, SIZE[0]) + self.pos.y = clamp(self.pos.y, 0, SIZE[1]) + + +class Player(Object8Directional): + def logic(self, **kwargs): + pressed = pygame.key.get_pressed() + direction_x = pressed[pygame.K_RIGHT] - pressed[pygame.K_LEFT] + direction_y = pressed[pygame.K_DOWN] - pressed[pygame.K_UP] + + self.acceleration = pygame.Vector2(direction_x, direction_y) * self.ACCELERATION + super().logic(**kwargs) + + +class Ghost(Object8Directional): + SHEET = "pink_ghost" + ACCELERATION = 0.2 + DAMPING = 0.9 + + def __init__(self, pos=None): + if pos is None: + pos = random_in_rect(SCREEN) + super().__init__(pos) + self.goal = self.new_goal() + + def new_goal(self): + direction = from_polar(60, gauss(self.velocity.as_polar()[1], 30)) + return self.rect.center + direction + + def logic(self, **kwargs): + middle_area = SCREEN.inflate(-30, -30) + while self.rect.collidepoint(self.goal) or not middle_area.collidepoint( + self.goal + ): + self.goal = self.new_goal() + + self.acceleration = ( + self.goal - self.rect.center + ).normalize() * self.ACCELERATION + super().logic(**kwargs) + + +class SolidObject(Object): + SHEET_RECT = [ + (0, 0, 24, 31), + (24, 0, 24, 24), + (48, 0, 24, 24), + (72, 0, 16, 24), + (88, 0, 48, 43), + (136, 0, 16, 16), + ] + SCALE = 3 + + def __init__(self, pos): + sheet = load_image("tileset", self.SCALE) + sheet.set_colorkey(0xFFFFFF) + rect = choice(self.SHEET_RECT) + rect = [x * self.SCALE for x in rect] + super().__init__(pos, sheet.subsurface(rect)) + + @classmethod + def generate_many(cls, nb=16, max_tries=1000): + objects = [] + tries = 0 # avoids infinite loop + while len(objects) < nb and tries < max_tries: + pos = random_in_rect(SCREEN) + obj = cls(pos) + if not any(obj.rect.colliderect(other.rect) for other in objects): + objects.append(obj) + return objects diff --git a/01-fog-of-war/andenixa/utils.py b/01-fog-of-war/andenixa/utils.py new file mode 100644 index 0000000..28d56ff --- /dev/null +++ b/01-fog-of-war/andenixa/utils.py @@ -0,0 +1,40 @@ +from functools import lru_cache +from pathlib import Path +from random import uniform + +import pygame + +SUBMISSION_DIR = Path(__file__).parent +ASSETS = SUBMISSION_DIR.parent / "assets" + + +@lru_cache() +def load_image(name: str, scale=1): + image = pygame.image.load(ASSETS / f"{name}.png") + if scale != 1: + new_size = image.get_width() * scale, image.get_height() * scale + image = pygame.transform.scale(image, new_size) + return image.convert_alpha() + + +def clamp(value, mini, maxi): + """Clamp value between mini and maxi""" + if value < mini: + return mini + elif maxi < value: + return maxi + else: + return value + + +def random_in_rect(rect): + """Return a random point uniformly in a rectangle.""" + rect = pygame.Rect(rect) + return pygame.Vector2(uniform(rect.left, rect.right), uniform(rect.top, rect.bottom)) + + +def from_polar(rho, theta): + """Create a Vector2 from its polar representation.""" + v = pygame.Vector2() + v.from_polar((rho, theta)) + return v From 3343a3830203216bce09745224cc0852b0bdb31b Mon Sep 17 00:00:00 2001 From: ddorn Date: Mon, 11 Oct 2021 13:58:09 +0200 Subject: [PATCH 32/80] grimmys entry --- 01-fog-of-war/grimmys/main.py | 120 ++++++++++++++++++++++++++ 01-fog-of-war/grimmys/objects.py | 144 +++++++++++++++++++++++++++++++ 01-fog-of-war/grimmys/utils.py | 40 +++++++++ 3 files changed, 304 insertions(+) create mode 100644 01-fog-of-war/grimmys/main.py create mode 100644 01-fog-of-war/grimmys/objects.py create mode 100644 01-fog-of-war/grimmys/utils.py diff --git a/01-fog-of-war/grimmys/main.py b/01-fog-of-war/grimmys/main.py new file mode 100644 index 0000000..cbcaa74 --- /dev/null +++ b/01-fog-of-war/grimmys/main.py @@ -0,0 +1,120 @@ +import math +import sys +from pathlib import Path +from typing import Sequence + +try: + import wclib +except ImportError: + # wclib may not be in the path because of the architecture + # of all the challenges and the fact that there are many + # way to run them (through the showcase, or on their own) + + ROOT_FOLDER = Path(__file__).parent.parent.parent + sys.path.append(str(ROOT_FOLDER)) + import wclib + +# This line tells python how to handle the relative imports +# when you run this file directly. +__package__ = "01-fog-of-war." + Path(__file__).parent.name + +# ---- Recommended: don't modify anything above this line ---- # + +# Metadata about your submission +__author__ = "Grimmys#0373" +__achievements__ = [ # Uncomment the ones you've done + "Casual", + "Ambitious", + "Adventurous", +] + +from operator import attrgetter +import pygame + +# To import the modules in yourname/, you need to use relative imports, +# otherwise your project will not be compatible with the showcase. +from .objects import Ghost, Player, SolidObject, Object + +BACKGROUND = 0x66856C +SCREEN_SIZE = (1024, 768) +CHUNK_SIZE = (16, 16) +NUMBER_HORIZONTAL_CHUNKS = SCREEN_SIZE[0] // CHUNK_SIZE[0] +NUMBER_VERTICAL_CHUNKS = SCREEN_SIZE[1] // CHUNK_SIZE[1] +MAX_DARKNESS_LEVEL = 210 + + +def generate_light(player): + light = pygame.Surface((SCREEN_SIZE[0] * 2.2, SCREEN_SIZE[1] * 2.2), pygame.SRCALPHA) + for opacity_level in range(0, MAX_DARKNESS_LEVEL, 5): + pygame.draw.circle(light, (0, 0, 0, opacity_level), light.get_rect().center, player.VISION_RADIUS, + int(player.VISION_RADIUS * (1 - opacity_level / MAX_DARKNESS_LEVEL))) + pygame.draw.circle(light, (0, 0, 0, MAX_DARKNESS_LEVEL), light.get_rect().center, light.get_width(), + light.get_width() - player.VISION_RADIUS) + return light + + +def update_unvisited_chunks(player, unvisited_chunks): + for chunk in set(unvisited_chunks): + chunk_rect = pygame.rect.Rect(chunk[0] * CHUNK_SIZE[0], chunk[1] * CHUNK_SIZE[1], CHUNK_SIZE[0], + CHUNK_SIZE[1]) + player_distance_with_chunk = math.sqrt((chunk_rect.center[0] - player.rect.center[0]) ** 2 + ( + chunk_rect.center[1] - player.rect.center[1]) ** 2) + if player_distance_with_chunk < player.VISION_RADIUS + chunk_rect.width // 2: + unvisited_chunks.remove(chunk) + + +def display(screen, objects, player, light, unvisited_chunks): + screen.fill(BACKGROUND) + + for element in sorted(objects, key=attrgetter("rect.bottom")): + if isinstance(element, Ghost) and element.pos.distance_to(player.pos) > player.VISION_RADIUS: + continue # Don't draw ghost if it's too far, just go to the next element + element.draw(screen) + + for chunk_position in unvisited_chunks: + # Hide unvisited blocks + screen.fill(pygame.Color("black"), + rect=pygame.rect.Rect(chunk_position[0] * CHUNK_SIZE[0], chunk_position[1] * CHUNK_SIZE[1], + CHUNK_SIZE[0], CHUNK_SIZE[1])) + + screen.blit(light, (player.rect.center[0] - light.get_width() // 2, + player.rect.center[1] - light.get_height() // 2)) + + +def mainloop(): + player = Player((100, 100)) + trees = SolidObject.generate_many(36) + ghosts = [Ghost() for _ in range(16)] + + all_objects: Sequence[Object] = trees + [player] + ghosts + + light = generate_light(player) + + unvisited_chunks = set() + for x in range(NUMBER_HORIZONTAL_CHUNKS): + for y in range(NUMBER_VERTICAL_CHUNKS): + unvisited_chunks.add((x, y)) + + player_chunk = (player.rect.center[0] // CHUNK_SIZE[0], player.rect.center[1] // CHUNK_SIZE[1]) + if player_chunk in unvisited_chunks: + unvisited_chunks.remove(player_chunk) + + clock = pygame.time.Clock() + while True: + screen, events = yield + for event in events: + if event.type == pygame.QUIT: + return + + for element in all_objects: + element.logic(objects=all_objects) + + update_unvisited_chunks(player, unvisited_chunks) + + display(screen, all_objects, player, light, unvisited_chunks) + + clock.tick(60) + + +if __name__ == "__main__": + wclib.run(mainloop()) diff --git a/01-fog-of-war/grimmys/objects.py b/01-fog-of-war/grimmys/objects.py new file mode 100644 index 0000000..7f85676 --- /dev/null +++ b/01-fog-of-war/grimmys/objects.py @@ -0,0 +1,144 @@ +""" +This file provides objects that can be used to make up +a basic playground for the challenges. + +This code is provided so that you can focus on implementing +a fog of war, without needed +Feel free to modify everything in this file to your liking. +""" +from random import choice, gauss + +import pygame + +from wclib import SIZE +from .utils import clamp, from_polar, load_image, random_in_rect + +SCREEN = pygame.Rect(0, 0, *SIZE) + + +class Object: + """The base class for all objects of the game.""" + + def __init__(self, pos, sprite: pygame.Surface): + self.pos = pygame.Vector2(pos) + self.size = pygame.Vector2(sprite.get_size()) + self.sprite = sprite + + def __str__(self): + return f"<{self.__class__.__name__}(pos={self.pos}, size={self.size})>" + + @property + def rect(self): + return pygame.Rect(self.pos, self.size) + + def draw(self, screen): + screen.blit(self.sprite, self.pos) + + def logic(self, **kwargs): + pass + + +class Object8Directional(Object): + SCALE = 3 + SIZE = 16 + SHEET = "blue_ghost" + + ACCELERATION = 0.5 + DAMPING = 0.85 + + # Asymptotic velocity will be solution of + # x = x * DAMPING + ACCELERATION + # That is, + # x = ACCELERATION / (1 - DAMPING) + + def __init__(self, pos): + self.velocity = pygame.Vector2() + self.acceleration = pygame.Vector2() + + super().__init__(pos, self.get_image()) + + def get_image(self): + angle = self.velocity.as_polar()[1] + idx = int((-angle + 90 + 45 / 2) % 360 / 360 * 8) + sheet = load_image(self.SHEET, self.SCALE) + unit = self.SIZE * self.SCALE + return sheet.subsurface(idx * unit, 0, unit, unit) + + def logic(self, **kwargs): + self.velocity *= self.DAMPING + self.velocity += self.acceleration + self.pos += self.velocity + self.sprite = self.get_image() + + self.pos.x = clamp(self.pos.x, 0, SIZE[0]) + self.pos.y = clamp(self.pos.y, 0, SIZE[1]) + + +class Player(Object8Directional): + VISION_RADIUS = 120 + + def logic(self, **kwargs): + pressed = pygame.key.get_pressed() + direction_x = pressed[pygame.K_RIGHT] - pressed[pygame.K_LEFT] + direction_y = pressed[pygame.K_DOWN] - pressed[pygame.K_UP] + + self.acceleration = pygame.Vector2(direction_x, direction_y) * self.ACCELERATION + super().logic(**kwargs) + + +class Ghost(Object8Directional): + SHEET = "pink_ghost" + ACCELERATION = 0.2 + DAMPING = 0.9 + + def __init__(self, pos=None): + if pos is None: + pos = random_in_rect(SCREEN) + super().__init__(pos) + self.goal = self.new_goal() + + def new_goal(self): + direction = from_polar(60, gauss(self.velocity.as_polar()[1], 30)) + return self.rect.center + direction + + def logic(self, **kwargs): + middle_area = SCREEN.inflate(-30, -30) + while self.rect.collidepoint(self.goal) or not middle_area.collidepoint( + self.goal + ): + self.goal = self.new_goal() + + self.acceleration = ( + self.goal - self.rect.center + ).normalize() * self.ACCELERATION + super().logic(**kwargs) + + +class SolidObject(Object): + SHEET_RECT = [ + (0, 0, 24, 31), + (24, 0, 24, 24), + (48, 0, 24, 24), + (72, 0, 16, 24), + (88, 0, 48, 43), + (136, 0, 16, 16), + ] + SCALE = 3 + + def __init__(self, pos): + sheet = load_image("tileset", self.SCALE) + sheet.set_colorkey(0xFFFFFF) + rect = choice(self.SHEET_RECT) + rect = [x * self.SCALE for x in rect] + super().__init__(pos, sheet.subsurface(rect)) + + @classmethod + def generate_many(cls, nb=16, max_tries=1000): + objects = [] + tries = 0 # avoids infinite loop + while len(objects) < nb and tries < max_tries: + pos = random_in_rect(SCREEN) + obj = cls(pos) + if not any(obj.rect.colliderect(other.rect) for other in objects): + objects.append(obj) + return objects diff --git a/01-fog-of-war/grimmys/utils.py b/01-fog-of-war/grimmys/utils.py new file mode 100644 index 0000000..0ad9826 --- /dev/null +++ b/01-fog-of-war/grimmys/utils.py @@ -0,0 +1,40 @@ +from functools import lru_cache +from pathlib import Path +from random import uniform + +import pygame + +SUBMISSION_DIR = Path(__file__).parent +ASSETS = SUBMISSION_DIR.parent / "assets" + + +@lru_cache() +def load_image(name: str, scale=1): + image = pygame.image.load(ASSETS / f"{name}.png") + if scale != 1: + new_size = image.get_width() * scale, image.get_height() * scale + image = pygame.transform.scale(image, new_size) + return image.convert_alpha() + + +def clamp(value, mini, maxi): + """Clamp value between mini and maxi""" + if value < mini: + return mini + elif maxi < value: + return maxi + else: + return value + + +def random_in_rect(rect): + """Return a random point uniformly in a rectangle.""" + rect = pygame.Rect(rect) + return pygame.Vector2(uniform(rect.left, rect.right), uniform(rect.top, rect.bottom)) + + +def from_polar(rho, theta): + """Create a Vector2 from its polar representation.""" + v = pygame.Vector2() + v.from_polar((rho, theta)) + return v From 93f533857ec901a4ce0597a8b154cc30e2643537 Mon Sep 17 00:00:00 2001 From: ddorn Date: Mon, 11 Oct 2021 14:29:04 +0200 Subject: [PATCH 33/80] arosso17 entry commit b965ce5ceb138482c4a47e9b20226ef573dd6d1a Author: ddorn Date: Mon Oct 11 14:21:52 2021 +0200 revert modification to the base code + put assets in submission's folder commit 0106a7921dd1ef28de9df628ade2040640e5286f Merge: f0a11c9 34c6aa5 Author: ddorn Date: Mon Oct 11 14:11:10 2021 +0200 Merge branch 'master' of git://github.com/arosso17/WeeklyChallenges into arosso17-master commit 34c6aa541e06b30be7ac24111ea3f59fd4c376de Author: Angelo Rosso Date: Fri Oct 1 00:00:16 2021 -0400 added base folder back in commit 8d1bd6f5aa3e613df54c0f8d533ab4ae5eb0b3bc Author: Angelo Rosso Date: Thu Sep 30 23:41:49 2021 -0400 fading ghosts commit f38fcc618a5a6f19f9eb22faabb4c99572ce5782 Author: Angelo Rosso Date: Thu Sep 30 22:45:33 2021 -0400 played with lighting houses and fog commit 9709b8aae09b883fc3af28232e437520efab2e04 Author: Angelo Rosso Date: Thu Sep 30 12:43:54 2021 -0400 completed all levels commit db3809b651714e57cf1c89ac313f5540256ec03a Author: Angelo Rosso Date: Thu Sep 30 12:36:14 2021 -0400 completed all levels --- 01-fog-of-war/arosso17/fog.png | Bin 0 -> 186688 bytes 01-fog-of-war/arosso17/main.py | 134 +++++++++++++++++++++++++ 01-fog-of-war/arosso17/objects.py | 142 +++++++++++++++++++++++++++ 01-fog-of-war/arosso17/test_stuff.py | 134 +++++++++++++++++++++++++ 01-fog-of-war/arosso17/utils.py | 40 ++++++++ 01-fog-of-war/base/main.py | 1 + 01-fog-of-war/base/objects.py | 2 +- 01-fog-of-war/base/utils.py | 1 + 8 files changed, 453 insertions(+), 1 deletion(-) create mode 100644 01-fog-of-war/arosso17/fog.png create mode 100644 01-fog-of-war/arosso17/main.py create mode 100644 01-fog-of-war/arosso17/objects.py create mode 100644 01-fog-of-war/arosso17/test_stuff.py create mode 100644 01-fog-of-war/arosso17/utils.py diff --git a/01-fog-of-war/arosso17/fog.png b/01-fog-of-war/arosso17/fog.png new file mode 100644 index 0000000000000000000000000000000000000000..50de7392ced1d71f87ff46efe1db6b6512c59fdd GIT binary patch literal 186688 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 dsi2meehRx 100: + ghost.sprite.set_alpha(355 - (355/150)*dis) + ghost.draw(screen) + + screen.blit(explored_map, (0, 0)) + for i in range(0, 150, 2): + pygame.draw.circle(fog_of_war, (0, 0, 0, i), + (player.pos[0] + player.size[0] / 2, player.pos[1] + player.size[1] / 2), i + 50, 2) + pygame.draw.circle(fog_of_war, (0, 0, 0, 0), + (player.pos[0] + player.size[0] / 2, player.pos[1] + player.size[1] / 2), 50) + pygame.draw.circle(explored_map, (0, 0, 0, 150), [player.pos[0] + player.size[0] / 2, player.pos[1] + player.size[1] / 2], 150) + clock.tick(FPS) + print(clock.get_fps()) + +if __name__ == "__main__": + wclib.run(mainloop()) diff --git a/01-fog-of-war/arosso17/objects.py b/01-fog-of-war/arosso17/objects.py new file mode 100644 index 0000000..e507e56 --- /dev/null +++ b/01-fog-of-war/arosso17/objects.py @@ -0,0 +1,142 @@ +""" +This file provides objects that can be used to make up +a basic playground for the challenges. + +This code is provided so that you can focus on implementing +a fog of war, without needed +Feel free to modify everything in this file to your liking. +""" +from random import choice, gauss + +import pygame + +from wclib import SIZE +from .utils import clamp, from_polar, load_image, random_in_rect + +SCREEN = pygame.Rect(0, 0, *SIZE) + + +class Object: + """The base class for all objects of the game.""" + + def __init__(self, pos, sprite: pygame.Surface): + self.pos = pygame.Vector2(pos) + self.size = pygame.Vector2(sprite.get_size()) + self.sprite = sprite + + def __str__(self): + return f"<{self.__class__.__name__}(pos={self.pos}, size={self.size})>" + + @property + def rect(self): + return pygame.Rect(self.pos, self.size) + + def draw(self, screen): + screen.blit(self.sprite, self.pos) + + def logic(self, **kwargs): + pass + + +class Object8Directional(Object): + SCALE = 3 + SIZE = 16 + SHEET = "blue_ghost" + + ACCELERATION = 0.5 + DAMPING = 0.85 + + # Asymptotic velocity will be solution of + # x = x * DAMPING + ACCELERATION + # That is, + # x = ACCELERATION / (1 - DAMPING) + + def __init__(self, pos): + self.velocity = pygame.Vector2() + self.acceleration = pygame.Vector2() + + super().__init__(pos, self.get_image()) + + def get_image(self): + angle = self.velocity.as_polar()[1] + idx = int((-angle + 90 + 45 / 2) % 360 / 360 * 8) + sheet = load_image(self.SHEET, self.SCALE) + unit = self.SIZE * self.SCALE + return sheet.subsurface(idx * unit, 0, unit, unit) + + def logic(self, **kwargs): + self.velocity *= self.DAMPING + self.velocity += self.acceleration + self.pos += self.velocity + self.sprite = self.get_image() + + self.pos.x = clamp(self.pos.x, 0, SIZE[0]) + self.pos.y = clamp(self.pos.y, 0, SIZE[1]) + + +class Player(Object8Directional): + def logic(self, **kwargs): + pressed = pygame.key.get_pressed() + direction_x = pressed[pygame.K_RIGHT] - pressed[pygame.K_LEFT] + direction_y = pressed[pygame.K_DOWN] - pressed[pygame.K_UP] + + self.acceleration = pygame.Vector2(direction_x, direction_y) * self.ACCELERATION + super().logic(**kwargs) + + +class Ghost(Object8Directional): + SHEET = "pink_ghost" + ACCELERATION = 0.2 + DAMPING = 0.9 + + def __init__(self, pos=None): + if pos is None: + pos = random_in_rect(SCREEN) + super().__init__(pos) + self.goal = self.new_goal() + + def new_goal(self): + direction = from_polar(60, gauss(self.velocity.as_polar()[1], 30)) + return self.rect.center + direction + + def logic(self, **kwargs): + middle_area = SCREEN.inflate(-30, -30) + while self.rect.collidepoint(self.goal) or not middle_area.collidepoint( + self.goal + ): + self.goal = self.new_goal() + + self.acceleration = ( + self.goal - self.rect.center + ).normalize() * self.ACCELERATION + super().logic(**kwargs) + + +class SolidObject(Object): + SHEET_RECT = [ + (0, 0, 24, 31), + (24, 0, 24, 24), + (48, 0, 24, 24), + (72, 0, 16, 24), + (88, 0, 48, 43), + (136, 0, 16, 16), + ] + SCALE = 3 + + def __init__(self, pos): + sheet = load_image("tileset", self.SCALE) + sheet.set_colorkey(0xFFFFFF) + rect = choice(self.SHEET_RECT) + rect = [x * self.SCALE for x in rect] + super().__init__(pos, sheet.subsurface(rect)) + + @classmethod + def generate_many(cls, nb=16, max_tries=1000): + objects = [] + tries = 0 # avoids infinite loop + while len(objects) < nb and tries < max_tries: + pos = random_in_rect(SCREEN) + obj = cls(pos) + if not any(obj.rect.colliderect(other.rect) for other in objects): + objects.append(obj) + return objects diff --git a/01-fog-of-war/arosso17/test_stuff.py b/01-fog-of-war/arosso17/test_stuff.py new file mode 100644 index 0000000..122eb49 --- /dev/null +++ b/01-fog-of-war/arosso17/test_stuff.py @@ -0,0 +1,134 @@ +import sys +from pathlib import Path +import numpy as np + +try: + import wclib +except ImportError: + # wclib may not be in the path because of the architecture + # of all the challenges and the fact that there are many + # way to run them (through the showcase, or on their own) + + ROOT_FOLDER = Path(__file__).parent.parent.parent + sys.path.append(str(ROOT_FOLDER)) + import wclib + +# This line tells python how to handle the relative imports +# when you run this file directly. +__package__ = "01-fog-of-war." + Path(__file__).parent.name + +# ---- Recommended: don't modify anything above this line ---- # + +# Metadata about your submission +__author__ = "treehuggerbear1#2361" +__achievements__ = [ # Uncomment the ones you've done + "Casual", + "Ambitious", + "Adventurous", +] + +from operator import attrgetter +import pygame + +# To import the modules in yourname/, you need to use relative imports, +# otherwise your project will not be compatible with the showcase. +from .objects import Ghost, Player, SolidObject +from .utils import load_image +import random + +BACKGROUND = 0x66856C + +def dist(pos, other): + return np.sqrt((pos[0]-other[0])**2 + (pos[1]-other[1])**2) + +def mainloop(): + player = Player((100, 100)) + trees = SolidObject.generate_many(36) + houses = [] + wells = [] + dead_trees = [] + bushes = [] + for obj in trees: + if obj.rect[2] == 144: + houses.append(obj) + elif obj.rect[2] == 48 and obj.rect[3] == 72: + wells.append(obj) + elif obj.rect[2] == 72 and (obj.rect[3] == 93 or obj.rect[3] == 72): + dead_trees.append(obj) + elif obj.rect[2] == 48 and obj.rect[3] == 48: + bushes.append(obj) + ghosts = [Ghost() for _ in range(16)] + all_objects = trees + [player] + clock = pygame.time.Clock() + first = True + FPS = 60 + # 1024 x 768 + while True: + screen, events = yield + # would put outside loop, but weird showcase stuff messes up + if first: + # for pic + fog = load_image("fog") + fog.set_alpha(25) + + lights = pygame.Surface((screen.get_width(), screen.get_height()), pygame.SRCALPHA) + fog_of_war = pygame.Surface((screen.get_width(), screen.get_height()), pygame.SRCALPHA) + explored_map = pygame.Surface((screen.get_width(), screen.get_height()), pygame.SRCALPHA) + pygame.draw.rect(explored_map, (0, 0, 0, 255), [0, 0, screen.get_width(), screen.get_height()]) + + for obj in trees: + if obj.rect[2] == 144: + pygame.draw.circle(lights, (234, 206, 9, 15), + (obj.rect[0] + 32, obj.rect[1] + 94), 45, 20) + pygame.draw.circle(lights, (234, 206, 9, 15), + (obj.rect[0] - 32 + obj.rect[2], obj.rect[1] + 94), 45, 20) + pygame.draw.circle(lights, (234, 206, 9, 40), + (obj.rect[0] + 32, obj.rect[1] + 94), 25) + pygame.draw.circle(lights, (234, 206, 9, 40), + (obj.rect[0] - 32 + obj.rect[2], obj.rect[1] + 94), 25) + pygame.draw.rect(lights, (234, 206, 9, 150), + (obj.rect[0] + 21, obj.rect[1] + 84, 21, 18)) + pygame.draw.rect(lights, (234, 206, 9, 150), + (obj.rect[0] - 45 + obj.rect[2], obj.rect[1] + 84, 21, 18)) + # for pic + explored_map.blit(fog, (0, 0)) + pygame.draw.rect(fog_of_war, (0, 0, 0, 150), [0, 0, screen.get_width(), screen.get_height()]) + first = False + for event in events: + if event.type == pygame.QUIT: + return + for obj in all_objects: + obj.logic(objects=all_objects) + screen.fill(BACKGROUND) + for object in sorted(all_objects, key=attrgetter("rect.bottom")): + object.draw(screen) + screen.blit(lights, (0, 0)) + screen.blit(fog_of_war, (0, 0)) + + # for ghost in ghosts: + # ghost.logic() + # dis = dist(ghost.pos, player.pos) + # if dis < 175: + # ghost.draw(screen) + + for ghost in ghosts: + ghost.logic() + dis = dist(ghost.pos, player.pos) + if dis < 200: + ghost.sprite.set_alpha(255) + if dis > 100: + ghost.sprite.set_alpha(355 - (355/150)*dis) + ghost.draw(screen) + + screen.blit(explored_map, (0, 0)) + for i in range(0, 150, 2): + pygame.draw.circle(fog_of_war, (0, 0, 0, i), + (player.pos[0] + player.size[0] / 2, player.pos[1] + player.size[1] / 2), i + 50, 2) + pygame.draw.circle(fog_of_war, (0, 0, 0, 0), + (player.pos[0] + player.size[0] / 2, player.pos[1] + player.size[1] / 2), 50) + pygame.draw.circle(explored_map, (0, 0, 0, 150), [player.pos[0] + player.size[0] / 2, player.pos[1] + player.size[1] / 2], 150) + clock.tick(FPS) + print(clock.get_fps()) + +if __name__ == "__main__": + wclib.run(mainloop()) diff --git a/01-fog-of-war/arosso17/utils.py b/01-fog-of-war/arosso17/utils.py new file mode 100644 index 0000000..28d56ff --- /dev/null +++ b/01-fog-of-war/arosso17/utils.py @@ -0,0 +1,40 @@ +from functools import lru_cache +from pathlib import Path +from random import uniform + +import pygame + +SUBMISSION_DIR = Path(__file__).parent +ASSETS = SUBMISSION_DIR.parent / "assets" + + +@lru_cache() +def load_image(name: str, scale=1): + image = pygame.image.load(ASSETS / f"{name}.png") + if scale != 1: + new_size = image.get_width() * scale, image.get_height() * scale + image = pygame.transform.scale(image, new_size) + return image.convert_alpha() + + +def clamp(value, mini, maxi): + """Clamp value between mini and maxi""" + if value < mini: + return mini + elif maxi < value: + return maxi + else: + return value + + +def random_in_rect(rect): + """Return a random point uniformly in a rectangle.""" + rect = pygame.Rect(rect) + return pygame.Vector2(uniform(rect.left, rect.right), uniform(rect.top, rect.bottom)) + + +def from_polar(rho, theta): + """Create a Vector2 from its polar representation.""" + v = pygame.Vector2() + v.from_polar((rho, theta)) + return v diff --git a/01-fog-of-war/base/main.py b/01-fog-of-war/base/main.py index f6eb3b8..1dfeb31 100644 --- a/01-fog-of-war/base/main.py +++ b/01-fog-of-war/base/main.py @@ -63,3 +63,4 @@ def mainloop(): if __name__ == "__main__": wclib.run(mainloop()) + diff --git a/01-fog-of-war/base/objects.py b/01-fog-of-war/base/objects.py index e507e56..7836e2e 100644 --- a/01-fog-of-war/base/objects.py +++ b/01-fog-of-war/base/objects.py @@ -1,7 +1,6 @@ """ This file provides objects that can be used to make up a basic playground for the challenges. - This code is provided so that you can focus on implementing a fog of war, without needed Feel free to modify everything in this file to your liking. @@ -140,3 +139,4 @@ def generate_many(cls, nb=16, max_tries=1000): if not any(obj.rect.colliderect(other.rect) for other in objects): objects.append(obj) return objects + diff --git a/01-fog-of-war/base/utils.py b/01-fog-of-war/base/utils.py index 28d56ff..8cd3288 100644 --- a/01-fog-of-war/base/utils.py +++ b/01-fog-of-war/base/utils.py @@ -38,3 +38,4 @@ def from_polar(rho, theta): v = pygame.Vector2() v.from_polar((rho, theta)) return v + From 6cce919bd47973441a9adc48a898c3d3a88a2919 Mon Sep 17 00:00:00 2001 From: ddorn Date: Mon, 11 Oct 2021 14:35:10 +0200 Subject: [PATCH 34/80] Blaatand29 entry --- 01-fog-of-war/Blaatand29/fog_of_war.py | 44 ++++++++ 01-fog-of-war/Blaatand29/main.py | 88 +++++++++++++++ 01-fog-of-war/Blaatand29/objects.py | 142 +++++++++++++++++++++++++ 01-fog-of-war/Blaatand29/utils.py | 40 +++++++ 4 files changed, 314 insertions(+) create mode 100644 01-fog-of-war/Blaatand29/fog_of_war.py create mode 100644 01-fog-of-war/Blaatand29/main.py create mode 100644 01-fog-of-war/Blaatand29/objects.py create mode 100644 01-fog-of-war/Blaatand29/utils.py diff --git a/01-fog-of-war/Blaatand29/fog_of_war.py b/01-fog-of-war/Blaatand29/fog_of_war.py new file mode 100644 index 0000000..d515ff7 --- /dev/null +++ b/01-fog-of-war/Blaatand29/fog_of_war.py @@ -0,0 +1,44 @@ +import pygame +import random + + +class Spot: + def __init__(self, row, col, width, total_rows): + self.row = row + self.col = col + self.x = row * width + self.y = col * width + self.pos = pygame.Vector2(self.x, self.y) + self.color = "black" + self.neighbors = [] + self.width = width + self.total_rows = total_rows + self.alpha = 128 + + def draw(self, win, player_pos): + s = pygame.Surface((self.width, self.width)) + s.set_alpha(get_dist(self.pos, player_pos) + 50) + s.fill((0, 0, 0)) + win.blit(s, self.pos) + # pygame.draw.rect(win, self.color, (self.pos, (self.width, self.width))) + + +def make_grid(rows, width): + grid = [] + gap = width // rows + for i in range(rows): + grid.append([]) + for j in range(rows): + spot = Spot(i, j, gap, rows) + grid[i].append(spot) + return grid + + +def draw(win, grid, player_pos): + for row in grid: + for spot in row: + spot.draw(win, player_pos) + + +def get_dist(pos1, pos2): + return pos1.distance_to(pos2) diff --git a/01-fog-of-war/Blaatand29/main.py b/01-fog-of-war/Blaatand29/main.py new file mode 100644 index 0000000..644263b --- /dev/null +++ b/01-fog-of-war/Blaatand29/main.py @@ -0,0 +1,88 @@ +import sys +from pathlib import Path + +try: + import wclib +except ImportError: + # wclib may not be in the path because of the architecture + # of all the challenges and the fact that there are many + # way to run them (through the showcase, or on their own) + + ROOT_FOLDER = Path(__file__).parent.parent.parent + sys.path.append(str(ROOT_FOLDER)) + import wclib + +# This line tells python how to handle the relative imports +# when you run this file directly. +__package__ = "01-fog-of-war." + Path(__file__).parent.name + +# ---- Recommended: don't modify anything above this line ---- # + +# Metadata about your submission +__author__ = "Blaatand29#0070" +__achievements__ = [ # Uncomment the ones you've done + "Casual", + "Ambitious", + "Adventurous", +] + + +from operator import attrgetter +import pygame +from random import randint + +# To import the modules in yourname/, you need to use relative imports, +# otherwise your project will not be compatible with the showcase. +from .objects import Ghost, Player, SolidObject +from .fog_of_war import make_grid, draw + +BACKGROUND = 0x66856C +rows = 25 +width = 1200 + + +def mainloop(): + player = Player((100, 100)) + trees = SolidObject.generate_many(36) + ghosts = [Ghost() for _ in range(16)] + + all_objects = trees + [player] + ghosts_obj = ghosts + + grid = make_grid(rows, width) + has_seen = [] + + clock = pygame.time.Clock() + while True: + screen, events = yield + for event in events: + if event.type == pygame.QUIT: + return + + for obj in all_objects: + obj.logic(objects=all_objects) + + for obj in ghosts_obj: + obj.logic(objects=all_objects) + + screen.fill(BACKGROUND) + + for object in sorted(ghosts_obj, key=attrgetter("rect.bottom")): + object.draw(screen) + + for object in sorted(all_objects, key=attrgetter("rect.bottom")): + object.draw(screen) + if object.pos.distance_to(player.rect.center) <= 200: + if not object in has_seen: + has_seen.append(object) + + draw(screen, grid, player.rect.center) + + for object in has_seen: + object.draw(screen) + + clock.tick(60) + + +if __name__ == "__main__": + wclib.run(mainloop()) diff --git a/01-fog-of-war/Blaatand29/objects.py b/01-fog-of-war/Blaatand29/objects.py new file mode 100644 index 0000000..e507e56 --- /dev/null +++ b/01-fog-of-war/Blaatand29/objects.py @@ -0,0 +1,142 @@ +""" +This file provides objects that can be used to make up +a basic playground for the challenges. + +This code is provided so that you can focus on implementing +a fog of war, without needed +Feel free to modify everything in this file to your liking. +""" +from random import choice, gauss + +import pygame + +from wclib import SIZE +from .utils import clamp, from_polar, load_image, random_in_rect + +SCREEN = pygame.Rect(0, 0, *SIZE) + + +class Object: + """The base class for all objects of the game.""" + + def __init__(self, pos, sprite: pygame.Surface): + self.pos = pygame.Vector2(pos) + self.size = pygame.Vector2(sprite.get_size()) + self.sprite = sprite + + def __str__(self): + return f"<{self.__class__.__name__}(pos={self.pos}, size={self.size})>" + + @property + def rect(self): + return pygame.Rect(self.pos, self.size) + + def draw(self, screen): + screen.blit(self.sprite, self.pos) + + def logic(self, **kwargs): + pass + + +class Object8Directional(Object): + SCALE = 3 + SIZE = 16 + SHEET = "blue_ghost" + + ACCELERATION = 0.5 + DAMPING = 0.85 + + # Asymptotic velocity will be solution of + # x = x * DAMPING + ACCELERATION + # That is, + # x = ACCELERATION / (1 - DAMPING) + + def __init__(self, pos): + self.velocity = pygame.Vector2() + self.acceleration = pygame.Vector2() + + super().__init__(pos, self.get_image()) + + def get_image(self): + angle = self.velocity.as_polar()[1] + idx = int((-angle + 90 + 45 / 2) % 360 / 360 * 8) + sheet = load_image(self.SHEET, self.SCALE) + unit = self.SIZE * self.SCALE + return sheet.subsurface(idx * unit, 0, unit, unit) + + def logic(self, **kwargs): + self.velocity *= self.DAMPING + self.velocity += self.acceleration + self.pos += self.velocity + self.sprite = self.get_image() + + self.pos.x = clamp(self.pos.x, 0, SIZE[0]) + self.pos.y = clamp(self.pos.y, 0, SIZE[1]) + + +class Player(Object8Directional): + def logic(self, **kwargs): + pressed = pygame.key.get_pressed() + direction_x = pressed[pygame.K_RIGHT] - pressed[pygame.K_LEFT] + direction_y = pressed[pygame.K_DOWN] - pressed[pygame.K_UP] + + self.acceleration = pygame.Vector2(direction_x, direction_y) * self.ACCELERATION + super().logic(**kwargs) + + +class Ghost(Object8Directional): + SHEET = "pink_ghost" + ACCELERATION = 0.2 + DAMPING = 0.9 + + def __init__(self, pos=None): + if pos is None: + pos = random_in_rect(SCREEN) + super().__init__(pos) + self.goal = self.new_goal() + + def new_goal(self): + direction = from_polar(60, gauss(self.velocity.as_polar()[1], 30)) + return self.rect.center + direction + + def logic(self, **kwargs): + middle_area = SCREEN.inflate(-30, -30) + while self.rect.collidepoint(self.goal) or not middle_area.collidepoint( + self.goal + ): + self.goal = self.new_goal() + + self.acceleration = ( + self.goal - self.rect.center + ).normalize() * self.ACCELERATION + super().logic(**kwargs) + + +class SolidObject(Object): + SHEET_RECT = [ + (0, 0, 24, 31), + (24, 0, 24, 24), + (48, 0, 24, 24), + (72, 0, 16, 24), + (88, 0, 48, 43), + (136, 0, 16, 16), + ] + SCALE = 3 + + def __init__(self, pos): + sheet = load_image("tileset", self.SCALE) + sheet.set_colorkey(0xFFFFFF) + rect = choice(self.SHEET_RECT) + rect = [x * self.SCALE for x in rect] + super().__init__(pos, sheet.subsurface(rect)) + + @classmethod + def generate_many(cls, nb=16, max_tries=1000): + objects = [] + tries = 0 # avoids infinite loop + while len(objects) < nb and tries < max_tries: + pos = random_in_rect(SCREEN) + obj = cls(pos) + if not any(obj.rect.colliderect(other.rect) for other in objects): + objects.append(obj) + return objects diff --git a/01-fog-of-war/Blaatand29/utils.py b/01-fog-of-war/Blaatand29/utils.py new file mode 100644 index 0000000..28d56ff --- /dev/null +++ b/01-fog-of-war/Blaatand29/utils.py @@ -0,0 +1,40 @@ +from functools import lru_cache +from pathlib import Path +from random import uniform + +import pygame + +SUBMISSION_DIR = Path(__file__).parent +ASSETS = SUBMISSION_DIR.parent / "assets" + + +@lru_cache() +def load_image(name: str, scale=1): + image = pygame.image.load(ASSETS / f"{name}.png") + if scale != 1: + new_size = image.get_width() * scale, image.get_height() * scale + image = pygame.transform.scale(image, new_size) + return image.convert_alpha() + + +def clamp(value, mini, maxi): + """Clamp value between mini and maxi""" + if value < mini: + return mini + elif maxi < value: + return maxi + else: + return value + + +def random_in_rect(rect): + """Return a random point uniformly in a rectangle.""" + rect = pygame.Rect(rect) + return pygame.Vector2(uniform(rect.left, rect.right), uniform(rect.top, rect.bottom)) + + +def from_polar(rho, theta): + """Create a Vector2 from its polar representation.""" + v = pygame.Vector2() + v.from_polar((rho, theta)) + return v From 144b473c74d51af21c3de27744b00b24491fbbce Mon Sep 17 00:00:00 2001 From: ddorn Date: Mon, 11 Oct 2021 14:37:13 +0200 Subject: [PATCH 35/80] Miku entry --- 01-fog-of-war/Miku/main.py | 108 +++++++++++++++++++++++ 01-fog-of-war/Miku/objects.py | 157 ++++++++++++++++++++++++++++++++++ 01-fog-of-war/Miku/utils.py | 41 +++++++++ 3 files changed, 306 insertions(+) create mode 100644 01-fog-of-war/Miku/main.py create mode 100644 01-fog-of-war/Miku/objects.py create mode 100644 01-fog-of-war/Miku/utils.py diff --git a/01-fog-of-war/Miku/main.py b/01-fog-of-war/Miku/main.py new file mode 100644 index 0000000..931bf78 --- /dev/null +++ b/01-fog-of-war/Miku/main.py @@ -0,0 +1,108 @@ +import sys +from pathlib import Path + +try: + import wclib +except ImportError: + # wclib may not be in the path because of the architecture + # of all the challenges and the fact that there are many + # way to run them (through the showcase, or on their own) + + ROOT_FOLDER = Path(__file__).parent.parent.parent + sys.path.append(str(ROOT_FOLDER)) + import wclib + +# This line tells python how to handle the relative imports +# when you run this file directly. +__package__ = "01-fog-of-war." + Path(__file__).parent.name + +# ---- Recommended: don't modify anything above this line ---- # + +# Metadata about your submission +__author__ = 'await ctx.send("Miku")#7006' +__achievements__ = [ # Uncomment the ones you've done + # "Casual", + # "Ambitious", + # "Adventurous", +] + + +from operator import attrgetter +import pygame + +pygame.init() + +# To import the modules in yourname/, you need to use relative imports, +# otherwise your project will not be compatible with the showcase. +from .objects import Ghost, Player, SolidObject + +BACKGROUND = 0x66856C + +fog_size = 35 +fogs = [pygame.Surface((fog_size, fog_size), pygame.SRCALPHA), pygame.Surface((1024, 768), pygame.SRCALPHA)] +fog_x, fog_y = 1024/fog_size, 768/fog_size +fps_font = pygame.font.SysFont("Bold", 50) +fogs[0].fill((20, 20, 20, 255)) +fogs[1].fill((20, 20, 20, 220)) +#first fog is completely black, second is gray + +#generates a light +def draw_light(radius, quality): + surface = pygame.Surface((radius*2, radius*2), pygame.SRCALPHA) + loop_count, color_change = 25*quality, 8/quality + for i in range(loop_count): + pygame.draw.circle(surface, (20, 20, 20, 220-i*color_change), (radius, radius), radius-i*2) + return(surface) + +def mainloop(): + player = Player((100, 100)) + last_player_position = [100, 100] + trees = SolidObject.generate_many(36) + ghosts = [Ghost() for _ in range(16)] + + light_r = 150 + light_rect = pygame.Rect(0, 0, light_r*2, light_r*2) + light = draw_light(light_r, 12) + #Dont pass a number higher than 12 + + all_objects = trees + [player] + ghosts + + clock = pygame.time.Clock() + while True: + screen, events = yield + for event in events: + if event.type == pygame.QUIT: + return + + for obj in all_objects: + obj.logic(objects=all_objects) + #creates a fog area + if last_player_position != player.rect.topleft: + light_rect.center = player.rect.center + position = (player.rect.center[0]/fog_x, player.rect.center[1]/fog_y) + pygame.draw.circle(fogs[0], (0, 0, 0, 0), position, light_r/fog_x) + last_player_position = player.rect.topleft + + screen.fill(BACKGROUND) + for object in sorted(all_objects, key=attrgetter("rect.bottom")): + if getattr(object, "SHEET", None) != "pink_ghost": + object.draw(screen) + else: + if object.rect.colliderect(light_rect): + object.draw(screen, light_rect.center, light_r) + + #draws a fog + fog = pygame.Surface.copy(fogs[1]) + fog2 = fogs[0] + fog2 = pygame.transform.smoothscale(fog2, (1024, 768)) + fog.blit(fog2, (0, 0)) + pygame.draw.circle(fog, (0, 0, 0, 0), player.rect.center, light_r) + screen.blit(fog, (0, 0)) + screen.blit(light, (player.rect.center[0]-light_r, player.rect.center[1]-light_r)) + #draws a fog + + clock.tick(60) + + +if __name__ == "__main__": + wclib.run(mainloop()) diff --git a/01-fog-of-war/Miku/objects.py b/01-fog-of-war/Miku/objects.py new file mode 100644 index 0000000..fd1cad6 --- /dev/null +++ b/01-fog-of-war/Miku/objects.py @@ -0,0 +1,157 @@ +""" +This file provides objects that can be used to make up +a basic playground for the challenges. + +This code is provided so that you can focus on implementing +a fog of war, without needed +Feel free to modify everything in this file to your liking. +""" +from random import choice, gauss + +#custom import +from math import sqrt +#custom import + +import pygame + +from wclib import SIZE +from .utils import clamp, from_polar, load_image, random_in_rect + +SCREEN = pygame.Rect(0, 0, *SIZE) + + +class Object: + """The base class for all objects of the game.""" + + def __init__(self, pos, sprite: pygame.Surface): + self.pos = pygame.Vector2(pos) + self.size = pygame.Vector2(sprite.get_size()) + self.sprite = sprite + + def __str__(self): + return f"<{self.__class__.__name__}(pos={self.pos}, size={self.size})>" + + @property + def rect(self): + return pygame.Rect(self.pos, self.size) + + def draw(self, screen): + screen.blit(self.sprite, self.pos) + + def logic(self, **kwargs): + pass + + +class Object8Directional(Object): + SCALE = 3 + SIZE = 16 + SHEET = "blue_ghost" + + ACCELERATION = 0.5 + DAMPING = 0.85 + + # Asymptotic velocity will be solution of + # x = x * DAMPING + ACCELERATION + # That is, + # x = ACCELERATION / (1 - DAMPING) + + def __init__(self, pos): + self.velocity = pygame.Vector2() + self.acceleration = pygame.Vector2() + + super().__init__(pos, self.get_image()) + + def get_image(self): + angle = self.velocity.as_polar()[1] + idx = int((-angle + 90 + 45 / 2) % 360 / 360 * 8) + sheet = load_image(self.SHEET, self.SCALE) + unit = self.SIZE * self.SCALE + return sheet.subsurface(idx * unit, 0, unit, unit) + + def logic(self, **kwargs): + self.velocity *= self.DAMPING + self.velocity += self.acceleration + self.pos += self.velocity + self.sprite = self.get_image() + + self.pos.x = clamp(self.pos.x, 0, SIZE[0]) + self.pos.y = clamp(self.pos.y, 0, SIZE[1]) + + +class Player(Object8Directional): + def logic(self, **kwargs): + pressed = pygame.key.get_pressed() + direction_x = pressed[pygame.K_RIGHT] - pressed[pygame.K_LEFT] + direction_y = pressed[pygame.K_DOWN] - pressed[pygame.K_UP] + + self.acceleration = pygame.Vector2(direction_x, direction_y) * self.ACCELERATION + super().logic(**kwargs) + + +class Ghost(Object8Directional): + SHEET = "pink_ghost" + ACCELERATION = 0.2 + DAMPING = 0.9 + + def __init__(self, pos=None): + if pos is None: + pos = random_in_rect(SCREEN) + super().__init__(pos) + self.goal = self.new_goal() + + def new_goal(self): + direction = from_polar(60, gauss(self.velocity.as_polar()[1], 30)) + return self.rect.center + direction + + def logic(self, **kwargs): + middle_area = SCREEN.inflate(-30, -30) + while self.rect.collidepoint(self.goal) or not middle_area.collidepoint( + self.goal + ): + self.goal = self.new_goal() + + self.acceleration = ( + self.goal - self.rect.center + ).normalize() * self.ACCELERATION + super().logic(**kwargs) + + #custom method + def draw(self, screen, plr_rect, light_r): + surface = pygame.Surface.copy(self.sprite) + ghost_rect = self.rect.center + distance = sqrt((plr_rect[0]-ghost_rect[0])**2 + (plr_rect[1]-ghost_rect[1])**2) + distance = distance/light_r*255 + surface.set_alpha(255-distance) + screen.blit(surface, self.pos) + #custom method + + +class SolidObject(Object): + SHEET_RECT = [ + (0, 0, 24, 31), + (24, 0, 24, 24), + (48, 0, 24, 24), + (72, 0, 16, 24), + (88, 0, 48, 43), + (136, 0, 16, 16), + ] + SCALE = 3 + + def __init__(self, pos): + sheet = load_image("tileset", self.SCALE) + sheet.set_colorkey(0xFFFFFF) + rect = choice(self.SHEET_RECT) + rect = [x * self.SCALE for x in rect] + super().__init__(pos, sheet.subsurface(rect)) + + @classmethod + def generate_many(cls, nb=16, max_tries=1000): + objects = [] + tries = 0 # avoids infinite loop + while len(objects) < nb and tries < max_tries: + pos = random_in_rect(SCREEN) + obj = cls(pos) + if not any(obj.rect.colliderect(other.rect) for other in objects): + objects.append(obj) + return objects + diff --git a/01-fog-of-war/Miku/utils.py b/01-fog-of-war/Miku/utils.py new file mode 100644 index 0000000..8cd3288 --- /dev/null +++ b/01-fog-of-war/Miku/utils.py @@ -0,0 +1,41 @@ +from functools import lru_cache +from pathlib import Path +from random import uniform + +import pygame + +SUBMISSION_DIR = Path(__file__).parent +ASSETS = SUBMISSION_DIR.parent / "assets" + + +@lru_cache() +def load_image(name: str, scale=1): + image = pygame.image.load(ASSETS / f"{name}.png") + if scale != 1: + new_size = image.get_width() * scale, image.get_height() * scale + image = pygame.transform.scale(image, new_size) + return image.convert_alpha() + + +def clamp(value, mini, maxi): + """Clamp value between mini and maxi""" + if value < mini: + return mini + elif maxi < value: + return maxi + else: + return value + + +def random_in_rect(rect): + """Return a random point uniformly in a rectangle.""" + rect = pygame.Rect(rect) + return pygame.Vector2(uniform(rect.left, rect.right), uniform(rect.top, rect.bottom)) + + +def from_polar(rho, theta): + """Create a Vector2 from its polar representation.""" + v = pygame.Vector2() + v.from_polar((rho, theta)) + return v + From a917d99db0499f7a6ecf3ca2f25b09d83deda3d4 Mon Sep 17 00:00:00 2001 From: ddorn Date: Mon, 11 Oct 2021 14:38:25 +0200 Subject: [PATCH 36/80] RoboMarchello entry --- 01-fog-of-war/RoboMarchello/main.py | 74 ++++++++++ 01-fog-of-war/RoboMarchello/objects.py | 181 +++++++++++++++++++++++++ 01-fog-of-war/RoboMarchello/utils.py | 40 ++++++ 3 files changed, 295 insertions(+) create mode 100644 01-fog-of-war/RoboMarchello/main.py create mode 100644 01-fog-of-war/RoboMarchello/objects.py create mode 100644 01-fog-of-war/RoboMarchello/utils.py diff --git a/01-fog-of-war/RoboMarchello/main.py b/01-fog-of-war/RoboMarchello/main.py new file mode 100644 index 0000000..d83920e --- /dev/null +++ b/01-fog-of-war/RoboMarchello/main.py @@ -0,0 +1,74 @@ +import sys +from pathlib import Path + +try: + import wclib +except ImportError: + # wclib may not be in the path because of the architecture + # of all the challenges and the fact that there are many + # way to run them (through the showcase, or on their own) + + ROOT_FOLDER = Path(__file__).parent.parent.parent + sys.path.append(str(ROOT_FOLDER)) + import wclib + +# This line tells python how to handle the relative imports +# when you run this file directly. +__package__ = "01-fog-of-war." + Path(__file__).parent.name + +# ---- Recommended: don't modify anything above this line ---- # + +# Metadata about your submission +__author__ = "RoboMarchello#0570" +__achievements__ = [ # Uncomment the ones you've done + "Casual", + "Ambitious", + "Adventurous", +] + + +from operator import attrgetter +import pygame + +# To import the modules in yourname/, you need to use relative imports, +# otherwise your project will not be compatible with the showcase. +from .objects import Ghost, Player, SolidObject, Fog + +BACKGROUND = 0x66856C + + +def mainloop(): + player = Player((100, 100)) + trees = SolidObject.generate_many(36) + ghosts = [Ghost() for _ in range(16)] + + fog = Fog(player) + + all_objects = trees + [player] + ghosts + + clock = pygame.time.Clock() + while True: + screen, events = yield + for event in events: + if event.type == pygame.QUIT: + return + + for obj in all_objects: + obj.logic(objects=all_objects) + + screen.fill(BACKGROUND) + + for object in sorted(all_objects, key=attrgetter("rect.bottom")): + if ghosts.count(object) >= 1: + if fog.get_dist(object) < 130: + object.draw(screen) + else: + object.draw(screen) + + fog.draw(screen) + + clock.tick(60) + + +if __name__ == "__main__": + wclib.run(mainloop()) diff --git a/01-fog-of-war/RoboMarchello/objects.py b/01-fog-of-war/RoboMarchello/objects.py new file mode 100644 index 0000000..fcce0a5 --- /dev/null +++ b/01-fog-of-war/RoboMarchello/objects.py @@ -0,0 +1,181 @@ +""" +This file provides objects that can be used to make up +a basic playground for the challenges. + +This code is provided so that you can focus on implementing +a fog of war, without needed +Feel free to modify everything in this file to your liking. +""" +from random import choice, gauss +import math +import pygame,pygame.gfxdraw + +from wclib import SIZE +from .utils import clamp, from_polar, load_image, random_in_rect + +SCREEN = pygame.Rect(0, 0, *SIZE) + +class Object: + """The base class for all objects of the game.""" + + def __init__(self, pos, sprite: pygame.Surface): + self.pos = pygame.Vector2(pos) + self.size = pygame.Vector2(sprite.get_size()) + self.sprite = sprite + + def __str__(self): + return f"<{self.__class__.__name__}(pos={self.pos}, size={self.size})>" + + @property + def rect(self): + return pygame.Rect(self.pos, self.size) + + def draw(self, screen): + screen.blit(self.sprite, self.pos) + + def logic(self, **kwargs): + pass + + +class Object8Directional(Object): + SCALE = 3 + SIZE = 16 + SHEET = "blue_ghost" + + ACCELERATION = 0.3 + DAMPING = 0.85 + + # Asymptotic velocity will be solution of + # x = x * DAMPING + ACCELERATION + # That is, + # x = ACCELERATION / (1 - DAMPING) + + def __init__(self, pos): + self.velocity = pygame.Vector2() + self.acceleration = pygame.Vector2() + + super().__init__(pos, self.get_image()) + + def get_image(self): + angle = self.velocity.as_polar()[1] + idx = int((-angle + 90 + 45 / 2) % 360 / 360 * 8) + sheet = load_image(self.SHEET, self.SCALE) + unit = self.SIZE * self.SCALE + return sheet.subsurface(idx * unit, 0, unit, unit) + + def logic(self, **kwargs): + self.velocity *= self.DAMPING + self.velocity += self.acceleration + self.pos += self.velocity + self.sprite = self.get_image() + + self.pos.x = clamp(self.pos.x, 0, SIZE[0]) + self.pos.y = clamp(self.pos.y, 0, SIZE[1]) + + +class Player(Object8Directional): + def logic(self, **kwargs): + pressed = pygame.key.get_pressed() + direction_x = pressed[pygame.K_RIGHT] - pressed[pygame.K_LEFT] + direction_y = pressed[pygame.K_DOWN] - pressed[pygame.K_UP] + + self.acceleration = pygame.Vector2(direction_x, direction_y) * self.ACCELERATION + super().logic(**kwargs) + + +class Ghost(Object8Directional): + SHEET = "pink_ghost" + ACCELERATION = 0.2 + DAMPING = 0.9 + + def __init__(self, pos=None): + if pos is None: + pos = random_in_rect(SCREEN) + super().__init__(pos) + self.goal = self.new_goal() + + def new_goal(self): + direction = from_polar(60, gauss(self.velocity.as_polar()[1], 30)) + return self.rect.center + direction + + def logic(self, **kwargs): + middle_area = SCREEN.inflate(-30, -30) + while self.rect.collidepoint(self.goal) or not middle_area.collidepoint( + self.goal + ): + self.goal = self.new_goal() + + self.acceleration = ( + self.goal - self.rect.center + ).normalize() * self.ACCELERATION + super().logic(**kwargs) + + +class SolidObject(Object): + SHEET_RECT = [ + (0, 0, 24, 31), + (24, 0, 24, 24), + (48, 0, 24, 24), + (72, 0, 16, 24), + (88, 0, 48, 43), + (136, 0, 16, 16), + ] + SCALE = 3 + + def __init__(self, pos): + sheet = load_image("tileset", self.SCALE) + sheet.set_colorkey(0xFFFFFF) + rect = choice(self.SHEET_RECT) + rect = [x * self.SCALE for x in rect] + super().__init__(pos, sheet.subsurface(rect)) + + @classmethod + def generate_many(cls, nb=16, max_tries=1000): + objects = [] + tries = 0 # avoids infinite loop + while len(objects) < nb and tries < max_tries: + pos = random_in_rect(SCREEN) + obj = cls(pos) + if not any(obj.rect.colliderect(other.rect) for other in objects): + objects.append(obj) + return objects + +class Fog(): + def __init__(self,player): + self.maskSurf = pygame.Surface(SCREEN.size,pygame.SRCALPHA) + self.maskSurf.fill((0,0,0)) + + self.player = player + + self.addRadius = 0 + self.isAdd = False + + self.rect = pygame.Rect(0,0,125*2,125*2) + + def draw(self,screen): + if self.addRadius <= 0: + self.isAdd = True + elif self.addRadius >= 10: + self.isAdd = False + + if self.isAdd == True: + self.addRadius += 0.2 + else: + self.addRadius -= 0.2 + + smoothRadius = 135#225 + + alpha = 210 + + for alp in range(200): + alpha -= 1 + pygame.draw.circle(self.maskSurf,(0,0,0,alpha),self.player.rect.center,smoothRadius) + smoothRadius -= 1 + self.rect.center = self.player.rect.center + + screen.blit(self.maskSurf,(0,0)) + + def get_dist(self,ghost): + dist = [(self.player.rect.center[0]-ghost.rect.center[0])**2,(self.player.rect.center[1]-ghost.rect.center[1])**2] + + return math.sqrt(dist[0]+dist[1]) diff --git a/01-fog-of-war/RoboMarchello/utils.py b/01-fog-of-war/RoboMarchello/utils.py new file mode 100644 index 0000000..28d56ff --- /dev/null +++ b/01-fog-of-war/RoboMarchello/utils.py @@ -0,0 +1,40 @@ +from functools import lru_cache +from pathlib import Path +from random import uniform + +import pygame + +SUBMISSION_DIR = Path(__file__).parent +ASSETS = SUBMISSION_DIR.parent / "assets" + + +@lru_cache() +def load_image(name: str, scale=1): + image = pygame.image.load(ASSETS / f"{name}.png") + if scale != 1: + new_size = image.get_width() * scale, image.get_height() * scale + image = pygame.transform.scale(image, new_size) + return image.convert_alpha() + + +def clamp(value, mini, maxi): + """Clamp value between mini and maxi""" + if value < mini: + return mini + elif maxi < value: + return maxi + else: + return value + + +def random_in_rect(rect): + """Return a random point uniformly in a rectangle.""" + rect = pygame.Rect(rect) + return pygame.Vector2(uniform(rect.left, rect.right), uniform(rect.top, rect.bottom)) + + +def from_polar(rho, theta): + """Create a Vector2 from its polar representation.""" + v = pygame.Vector2() + v.from_polar((rho, theta)) + return v From dc67db1090122a4501ac25d88c2c61eee83cd5ba Mon Sep 17 00:00:00 2001 From: ddorn Date: Mon, 11 Oct 2021 14:40:24 +0200 Subject: [PATCH 37/80] auto-format with black --- 01-fog-of-war/Abalue/main.py | 4 +- 01-fog-of-war/Abalue/objects.py | 63 ++- 01-fog-of-war/Blaatand29/fog_of_war.py | 60 +-- 01-fog-of-war/Blaatand29/objects.py | 8 +- 01-fog-of-war/CoopERR/main.py | 30 +- 01-fog-of-war/CoopERR/objects.py | 8 +- 01-fog-of-war/Emc235#2196/main.py | 2 +- 01-fog-of-war/Emc235#2196/objects.py | 34 +- 01-fog-of-war/MegaIng/main.py | 37 +- 01-fog-of-war/MegaIng/objects.py | 8 +- 01-fog-of-war/Miku/main.py | 143 ++++--- 01-fog-of-war/Miku/objects.py | 25 +- 01-fog-of-war/Miku/utils.py | 1 - 01-fog-of-war/RoboMarchello/main.py | 6 +- 01-fog-of-war/RoboMarchello/objects.py | 47 ++- 01-fog-of-war/alley-indie/main.py | 6 +- 01-fog-of-war/alley-indie/objects.py | 8 +- 01-fog-of-war/andenixa/main.py | 501 +++++++++++++---------- 01-fog-of-war/andenixa/objects.py | 10 +- 01-fog-of-war/arosso17/main.py | 101 +++-- 01-fog-of-war/arosso17/objects.py | 8 +- 01-fog-of-war/arosso17/test_stuff.py | 98 ++++- 01-fog-of-war/baconinvader/main.py | 14 +- 01-fog-of-war/baconinvader/objects.py | 245 ++++++----- 01-fog-of-war/base/main.py | 1 - 01-fog-of-war/base/objects.py | 9 +- 01-fog-of-war/base/utils.py | 1 - 01-fog-of-war/bitcraft/objects.py | 8 +- 01-fog-of-war/bydariogamer/main.py | 8 +- 01-fog-of-war/bydariogamer/objects.py | 8 +- 01-fog-of-war/fkS124/main.py | 8 +- 01-fog-of-war/fkS124/objects.py | 8 +- 01-fog-of-war/fkS124/utils.py | 4 +- 01-fog-of-war/ghast/main.py | 14 +- 01-fog-of-war/ghast/objects.py | 9 +- 01-fog-of-war/grimmys/main.py | 65 ++- 01-fog-of-war/grimmys/objects.py | 8 +- 01-fog-of-war/polastyn2030/flood_iter.py | 29 +- 01-fog-of-war/polastyn2030/fog.py | 12 +- 01-fog-of-war/polastyn2030/objects.py | 8 +- 01-fog-of-war/tank_king/objects.py | 23 +- 01-fog-of-war/zxxv/main.py | 26 +- 01-fog-of-war/zxxv/objects.py | 41 +- wclib/showcase.py | 8 +- 44 files changed, 1019 insertions(+), 746 deletions(-) diff --git a/01-fog-of-war/Abalue/main.py b/01-fog-of-war/Abalue/main.py index 87545fa..e6cc17c 100644 --- a/01-fog-of-war/Abalue/main.py +++ b/01-fog-of-war/Abalue/main.py @@ -59,8 +59,8 @@ def mainloop(): fog.logic(player, menu) menu.logic() - #screen.fill(BACKGROUND) - #for object in sorted(all_objects, key=attrgetter("rect.bottom")): + # screen.fill(BACKGROUND) + # for object in sorted(all_objects, key=attrgetter("rect.bottom")): # object.draw(screen) fog.draw(screen, all_objects) menu.draw(screen) diff --git a/01-fog-of-war/Abalue/objects.py b/01-fog-of-war/Abalue/objects.py index a261934..50c966f 100644 --- a/01-fog-of-war/Abalue/objects.py +++ b/01-fog-of-war/Abalue/objects.py @@ -125,14 +125,10 @@ def new_goal(self): def logic(self, **kwargs): middle_area = SCREEN.inflate(-30, -30) - while self.rect.collidepoint(self.goal) or not middle_area.collidepoint( - self.goal - ): + while self.rect.collidepoint(self.goal) or not middle_area.collidepoint(self.goal): self.goal = self.new_goal() - self.acceleration = ( - self.goal - self.rect.center - ).normalize() * self.ACCELERATION + self.acceleration = (self.goal - self.rect.center).normalize() * self.ACCELERATION for object in kwargs["objects"]: if isinstance(object, Player): @@ -173,7 +169,7 @@ def generate_many(cls, nb=16, max_tries=1000): class Menu: def __init__(self): # Should be a subclass of object but I'm lazy - self.sprite =pygame.Surface((1, 1)) + self.sprite = pygame.Surface((1, 1)) self.pos = pygame.Vector2(-2, -2) # @@ -184,7 +180,7 @@ def __init__(self): pygame.font.init() self.FONT = pygame.font.SysFont("helvetica", self.FONT_SIZE) self.FONT_COLOR = pygame.Color(5, 45, 165) - __achievements__ = [ # can't grab from main to avoid recursive issues :( + __achievements__ = [ # can't grab from main to avoid recursive issues :( "Default", "Casual", "Ambitious", @@ -192,7 +188,9 @@ def __init__(self): ] self.ACHIEVEMENTS = [self.FONT.render(a, True, self.FONT_COLOR) for a in __achievements__] self.gaps = [20] * len(self.ACHIEVEMENTS) - self.OPEN_ME_TXT = self.FONT.render("press tab to toggle menu...", True, pygame.Color(255, 255, 255)) + self.OPEN_ME_TXT = self.FONT.render( + "press tab to toggle menu...", True, pygame.Color(255, 255, 255) + ) self.open = False self.has_opened = False @@ -234,7 +232,11 @@ def draw(self, display): if self.gaps[i] < 40: self.gaps[i] += 2 self.gaps[i] = min(self.gaps[i], 40) - pygame.draw.rect(surface, pygame.Color(220, 220, 220), (self.rect.x, 40 + i * 50, self.rect.w, 50)) + pygame.draw.rect( + surface, + pygame.Color(220, 220, 220), + (self.rect.x, 40 + i * 50, self.rect.w, 50), + ) else: if self.gaps[i] > 20: self.gaps[i] -= 2 @@ -253,8 +255,12 @@ def __init__(self, player_rect): self.FADE_ITERS = 40 self.COLOR = pygame.Color(0, 0, 0, 255) - self.ALPHA_RANGE = [int((self.FADE_ITERS - i - 1) / self.FADE_ITERS * 200) for i in range(self.FADE_ITERS)] - self.RADIUS_RANGE = [self.RADIUS - self.FADE_LEN * i / self.FADE_ITERS for i in range(self.FADE_ITERS)] + self.ALPHA_RANGE = [ + int((self.FADE_ITERS - i - 1) / self.FADE_ITERS * 200) for i in range(self.FADE_ITERS) + ] + self.RADIUS_RANGE = [ + self.RADIUS - self.FADE_LEN * i / self.FADE_ITERS for i in range(self.FADE_ITERS) + ] self.pos = pygame.Vector2(player_rect.center) self.size = pygame.Vector2(pygame.display.get_window_size()) * 2 @@ -267,13 +273,23 @@ def __init__(self, player_rect): self.player_mask.fill(pygame.Color(254, 254, 254, 255)) self.player_mask_casual = pygame.Surface((self.RADIUS * 2, self.RADIUS * 2)).convert_alpha() self.player_mask_casual.fill(pygame.Color(254, 254, 254, 255)) - pygame.draw.circle(self.player_mask_casual, pygame.Color(0, 0, 0, 0), (self.RADIUS, self.RADIUS), self.RADIUS) + pygame.draw.circle( + self.player_mask_casual, + pygame.Color(0, 0, 0, 0), + (self.RADIUS, self.RADIUS), + self.RADIUS, + ) # add player view mask for i in range(self.FADE_ITERS): color = pygame.Color(self.COLOR) color.a = self.ALPHA_RANGE[i] - pygame.draw.circle(self.player_mask, color, (self.RADIUS, self.RADIUS), self.RADIUS_RANGE[i]) + pygame.draw.circle( + self.player_mask, + color, + (self.RADIUS, self.RADIUS), + self.RADIUS_RANGE[i], + ) def logic(self, player, menu): self.pos.update(player.rect.center) @@ -298,11 +314,19 @@ def draw(self, screen, all_objects): # draw objects for object in sorted(all_objects, key=attrgetter("rect.bottom")): if isinstance(object, Ghost): - fade = min(self.RADIUS, self.RADIUS * 5 / 3 - object.dist_to_player * 1.4) / self.RADIUS * 255 + fade = ( + min(self.RADIUS, self.RADIUS * 5 / 3 - object.dist_to_player * 1.4) + / self.RADIUS + * 255 + ) object.sprite.set_alpha(fade) - self.player_surf.blit(object.sprite, object.pos - self.pos + (self.RADIUS, self.RADIUS)) + self.player_surf.blit( + object.sprite, object.pos - self.pos + (self.RADIUS, self.RADIUS) + ) else: - self.player_surf.blit(object.sprite, object.pos - self.pos + (self.RADIUS, self.RADIUS)) + self.player_surf.blit( + object.sprite, object.pos - self.pos + (self.RADIUS, self.RADIUS) + ) if isinstance(object, Player): player = object if not isinstance(object, Object8Directional): @@ -320,4 +344,7 @@ def draw(self, screen, all_objects): self.player_surf.blit(self.player_mask_casual, (0, 0)) self.player_surf.set_colorkey(pygame.Color(254, 254, 254)) screen.blit(self.explore_surf, (0, 0)) - screen.blit(self.player_surf, pygame.Vector2(player.rect.center) - (self.RADIUS, self.RADIUS)) + screen.blit( + self.player_surf, + pygame.Vector2(player.rect.center) - (self.RADIUS, self.RADIUS), + ) diff --git a/01-fog-of-war/Blaatand29/fog_of_war.py b/01-fog-of-war/Blaatand29/fog_of_war.py index d515ff7..db0a7f5 100644 --- a/01-fog-of-war/Blaatand29/fog_of_war.py +++ b/01-fog-of-war/Blaatand29/fog_of_war.py @@ -3,42 +3,42 @@ class Spot: - def __init__(self, row, col, width, total_rows): - self.row = row - self.col = col - self.x = row * width - self.y = col * width - self.pos = pygame.Vector2(self.x, self.y) - self.color = "black" - self.neighbors = [] - self.width = width - self.total_rows = total_rows - self.alpha = 128 - - def draw(self, win, player_pos): - s = pygame.Surface((self.width, self.width)) - s.set_alpha(get_dist(self.pos, player_pos) + 50) - s.fill((0, 0, 0)) - win.blit(s, self.pos) - # pygame.draw.rect(win, self.color, (self.pos, (self.width, self.width))) + def __init__(self, row, col, width, total_rows): + self.row = row + self.col = col + self.x = row * width + self.y = col * width + self.pos = pygame.Vector2(self.x, self.y) + self.color = "black" + self.neighbors = [] + self.width = width + self.total_rows = total_rows + self.alpha = 128 + + def draw(self, win, player_pos): + s = pygame.Surface((self.width, self.width)) + s.set_alpha(get_dist(self.pos, player_pos) + 50) + s.fill((0, 0, 0)) + win.blit(s, self.pos) + # pygame.draw.rect(win, self.color, (self.pos, (self.width, self.width))) def make_grid(rows, width): - grid = [] - gap = width // rows - for i in range(rows): - grid.append([]) - for j in range(rows): - spot = Spot(i, j, gap, rows) - grid[i].append(spot) - return grid + grid = [] + gap = width // rows + for i in range(rows): + grid.append([]) + for j in range(rows): + spot = Spot(i, j, gap, rows) + grid[i].append(spot) + return grid def draw(win, grid, player_pos): - for row in grid: - for spot in row: - spot.draw(win, player_pos) + for row in grid: + for spot in row: + spot.draw(win, player_pos) def get_dist(pos1, pos2): - return pos1.distance_to(pos2) + return pos1.distance_to(pos2) diff --git a/01-fog-of-war/Blaatand29/objects.py b/01-fog-of-war/Blaatand29/objects.py index e507e56..cbc1806 100644 --- a/01-fog-of-war/Blaatand29/objects.py +++ b/01-fog-of-war/Blaatand29/objects.py @@ -101,14 +101,10 @@ def new_goal(self): def logic(self, **kwargs): middle_area = SCREEN.inflate(-30, -30) - while self.rect.collidepoint(self.goal) or not middle_area.collidepoint( - self.goal - ): + while self.rect.collidepoint(self.goal) or not middle_area.collidepoint(self.goal): self.goal = self.new_goal() - self.acceleration = ( - self.goal - self.rect.center - ).normalize() * self.ACCELERATION + self.acceleration = (self.goal - self.rect.center).normalize() * self.ACCELERATION super().logic(**kwargs) diff --git a/01-fog-of-war/CoopERR/main.py b/01-fog-of-war/CoopERR/main.py index 56c9a2d..d7e01c1 100644 --- a/01-fog-of-war/CoopERR/main.py +++ b/01-fog-of-war/CoopERR/main.py @@ -23,9 +23,9 @@ # Metadata about your submission __author__ = "CoopERR" __achievements__ = [ # Uncomment the ones you've done - "Casual", - "Ambitious", - "Adventurous", + "Casual", + "Ambitious", + "Adventurous", ] @@ -48,42 +48,40 @@ def mainloop(): solid_objects = trees + [player] fog = pygame.surface.Surface(pygame.display.get_surface().get_size(), pygame.SRCALPHA) - fog.fill((0,0,0)) + fog.fill((0, 0, 0)) def field_of_view(): size = 150 for i in range(200, 0, -1): - pygame.draw.circle(fog, (0,0,0,i), player.rect.center, size) + pygame.draw.circle(fog, (0, 0, 0, i), player.rect.center, size) size -= 0.9 def ghost_distance(ghost): - distance_x = (player.rect.center[0]-ghost.rect.center[0]) - distance_y = (player.rect.center[1]-ghost.rect.center[1]) + distance_x = player.rect.center[0] - ghost.rect.center[0] + distance_y = player.rect.center[1] - ghost.rect.center[1] - return (abs(distance_x) + abs(distance_y)) < 150 + return (abs(distance_x) + abs(distance_y)) < 150 clock = pygame.time.Clock() while True: - screen, events = yield + screen, events = yield for event in events: if event.type == pygame.QUIT: return for obj in all_objects: obj.logic(objects=all_objects) - + screen.fill(BACKGROUND) - + for ghost in sorted(ghosts, key=attrgetter("rect.bottom")): if ghost_distance(ghost): - ghost.draw(screen) + ghost.draw(screen) for object in sorted(solid_objects, key=attrgetter("rect.bottom")): object.draw(screen) - - field_of_view() - screen.blit(fog,(0,0)) - + field_of_view() + screen.blit(fog, (0, 0)) clock.tick(60) diff --git a/01-fog-of-war/CoopERR/objects.py b/01-fog-of-war/CoopERR/objects.py index e507e56..cbc1806 100644 --- a/01-fog-of-war/CoopERR/objects.py +++ b/01-fog-of-war/CoopERR/objects.py @@ -101,14 +101,10 @@ def new_goal(self): def logic(self, **kwargs): middle_area = SCREEN.inflate(-30, -30) - while self.rect.collidepoint(self.goal) or not middle_area.collidepoint( - self.goal - ): + while self.rect.collidepoint(self.goal) or not middle_area.collidepoint(self.goal): self.goal = self.new_goal() - self.acceleration = ( - self.goal - self.rect.center - ).normalize() * self.ACCELERATION + self.acceleration = (self.goal - self.rect.center).normalize() * self.ACCELERATION super().logic(**kwargs) diff --git a/01-fog-of-war/Emc235#2196/main.py b/01-fog-of-war/Emc235#2196/main.py index 855d785..081977c 100644 --- a/01-fog-of-war/Emc235#2196/main.py +++ b/01-fog-of-war/Emc235#2196/main.py @@ -23,7 +23,7 @@ __achievements__ = [ # Uncomment the ones you've done "Casual", "Ambitious", - "Adventurous" + "Adventurous", ] diff --git a/01-fog-of-war/Emc235#2196/objects.py b/01-fog-of-war/Emc235#2196/objects.py index e611a5f..6b47448 100644 --- a/01-fog-of-war/Emc235#2196/objects.py +++ b/01-fog-of-war/Emc235#2196/objects.py @@ -70,14 +70,14 @@ def logic(self, **kwargs): self.velocity += self.acceleration self.pos += self.velocity self.sprite = self.get_image() - self.pos.x = clamp(self.pos.x, 0, SIZE[0]-self.sprite.get_width()) - self.pos.y = clamp(self.pos.y, 0, SIZE[1]-self.sprite.get_height()) + self.pos.x = clamp(self.pos.x, 0, SIZE[0] - self.sprite.get_width()) + self.pos.y = clamp(self.pos.y, 0, SIZE[1] - self.sprite.get_height()) class Player(Object8Directional): def __init__(self, pos) -> None: super().__init__(pos) - self.radius = self.sprite.get_height()*2 + self.sprite.get_height() + self.radius = self.sprite.get_height() * 2 + self.sprite.get_height() def logic(self, **kwargs): pressed = pygame.key.get_pressed() @@ -110,15 +110,20 @@ def logic(self, **kwargs): self.goal = self.new_goal() self.acceleration = ( - self.goal - self.rect.center - ).normalize() * self.ACCELERATION * kwargs.get("dt", 1) + (self.goal - self.rect.center).normalize() * self.ACCELERATION * kwargs.get("dt", 1) + ) super().logic(**kwargs) def draw(self, screen): - if self.pos.distance_to(self.player.rect.center) < self.player.radius or\ - pygame.math.Vector2(self.rect.topright).distance_to(self.player.rect.center) < self.player.radius or\ - pygame.math.Vector2(self.rect.bottomright).distance_to(self.player.rect.center) < self.player.radius or\ - pygame.math.Vector2(self.rect.bottomleft).distance_to(self.player.rect.center) < self.player.radius: + if ( + self.pos.distance_to(self.player.rect.center) < self.player.radius + or pygame.math.Vector2(self.rect.topright).distance_to(self.player.rect.center) + < self.player.radius + or pygame.math.Vector2(self.rect.bottomright).distance_to(self.player.rect.center) + < self.player.radius + or pygame.math.Vector2(self.rect.bottomleft).distance_to(self.player.rect.center) + < self.player.radius + ): screen.blit(self.sprite, self.pos) @@ -167,9 +172,16 @@ def draw(self, WIN: pygame.surface.Surface) -> None: pygame.draw.circle(self.old_surf, (30, 30, 30), self.player.rect.center, self.player.radius) old_surf_copy = self.old_surf.copy() - pygame.draw.circle(old_surf_copy, (255, 255, 255), self.player.rect.center, self.player.radius) + pygame.draw.circle( + old_surf_copy, (255, 255, 255), self.player.rect.center, self.player.radius + ) for i in range(0, 100, 1): - pygame.draw.circle(old_surf_copy, (30+i, 30+i, 30+i), self.player.rect.center, self.player.radius-i) + pygame.draw.circle( + old_surf_copy, + (30 + i, 30 + i, 30 + i), + self.player.rect.center, + self.player.radius - i, + ) WIN.blit(self.old_surf, (0, 0)) WIN.blit(old_surf_copy, (0, 0)) diff --git a/01-fog-of-war/MegaIng/main.py b/01-fog-of-war/MegaIng/main.py index 659a4b1..670a519 100644 --- a/01-fog-of-war/MegaIng/main.py +++ b/01-fog-of-war/MegaIng/main.py @@ -39,7 +39,14 @@ class FogOverlay: - def __init__(self, player: Player, view_radii: tuple[int, int], alpha_radii: tuple[int, int], base_alpha: int, steps: int): + def __init__( + self, + player: Player, + view_radii: tuple[int, int], + alpha_radii: tuple[int, int], + base_alpha: int, + steps: int, + ): self.player = player self.view_radii = view_radii self.alpha_radii = alpha_radii @@ -52,31 +59,29 @@ def __init__(self, player: Player, view_radii: tuple[int, int], alpha_radii: tup def update_overlays(self): self.active_overlay.fill((0, 0, 0, 255)) # Solid black - center = self.player.pos + self.player.size / 2 # Center on player, looks slightly better than topleft + center = ( + self.player.pos + self.player.size / 2 + ) # Center on player, looks slightly better than topleft for radius, alpha in ( - (interpolate(i, 0, self.steps, *self.view_radii), - interpolate(i, 0, self.steps, *self.alpha_radii, power=2) - ) - for i in reversed(range(self.steps)) + ( + interpolate(i, 0, self.steps, *self.view_radii), + interpolate(i, 0, self.steps, *self.alpha_radii, power=2), + ) + for i in reversed(range(self.steps)) ): - pygame.draw.circle(self.active_overlay, - (0, 0, 0, alpha), - center, - radius) + pygame.draw.circle(self.active_overlay, (0, 0, 0, alpha), center, radius) r = pygame.Rect(0, 0, self.view_radii[1] * 2, self.view_radii[1] * 2) r.center = center r = r.clip(self.passive_overlay.get_rect()) - self.passive_overlay.fill((0, 0, 0, self.base_alpha), r, special_flags=pygame.BLEND_RGBA_MAX) + self.passive_overlay.fill( + (0, 0, 0, self.base_alpha), r, special_flags=pygame.BLEND_RGBA_MAX + ) self.passive_overlay.blit(self.active_overlay, r, r, special_flags=pygame.BLEND_RGBA_MIN) def mainloop(): player = Player((100, 100)) - fog = FogOverlay(player, - view_radii=(50, 200), - alpha_radii=(0, 250), - base_alpha=150, - steps=100) + fog = FogOverlay(player, view_radii=(50, 200), alpha_radii=(0, 250), base_alpha=150, steps=100) trees = SolidObject.generate_many(36) ghosts = [Ghost() for _ in range(16)] diff --git a/01-fog-of-war/MegaIng/objects.py b/01-fog-of-war/MegaIng/objects.py index e507e56..cbc1806 100644 --- a/01-fog-of-war/MegaIng/objects.py +++ b/01-fog-of-war/MegaIng/objects.py @@ -101,14 +101,10 @@ def new_goal(self): def logic(self, **kwargs): middle_area = SCREEN.inflate(-30, -30) - while self.rect.collidepoint(self.goal) or not middle_area.collidepoint( - self.goal - ): + while self.rect.collidepoint(self.goal) or not middle_area.collidepoint(self.goal): self.goal = self.new_goal() - self.acceleration = ( - self.goal - self.rect.center - ).normalize() * self.ACCELERATION + self.acceleration = (self.goal - self.rect.center).normalize() * self.ACCELERATION super().logic(**kwargs) diff --git a/01-fog-of-war/Miku/main.py b/01-fog-of-war/Miku/main.py index 931bf78..64f4d4b 100644 --- a/01-fog-of-war/Miku/main.py +++ b/01-fog-of-war/Miku/main.py @@ -2,15 +2,15 @@ from pathlib import Path try: - import wclib + import wclib except ImportError: - # wclib may not be in the path because of the architecture - # of all the challenges and the fact that there are many - # way to run them (through the showcase, or on their own) + # wclib may not be in the path because of the architecture + # of all the challenges and the fact that there are many + # way to run them (through the showcase, or on their own) - ROOT_FOLDER = Path(__file__).parent.parent.parent - sys.path.append(str(ROOT_FOLDER)) - import wclib + ROOT_FOLDER = Path(__file__).parent.parent.parent + sys.path.append(str(ROOT_FOLDER)) + import wclib # This line tells python how to handle the relative imports # when you run this file directly. @@ -21,9 +21,9 @@ # Metadata about your submission __author__ = 'await ctx.send("Miku")#7006' __achievements__ = [ # Uncomment the ones you've done - # "Casual", - # "Ambitious", - # "Adventurous", + # "Casual", + # "Ambitious", + # "Adventurous", ] @@ -39,70 +39,79 @@ BACKGROUND = 0x66856C fog_size = 35 -fogs = [pygame.Surface((fog_size, fog_size), pygame.SRCALPHA), pygame.Surface((1024, 768), pygame.SRCALPHA)] -fog_x, fog_y = 1024/fog_size, 768/fog_size +fogs = [ + pygame.Surface((fog_size, fog_size), pygame.SRCALPHA), + pygame.Surface((1024, 768), pygame.SRCALPHA), +] +fog_x, fog_y = 1024 / fog_size, 768 / fog_size fps_font = pygame.font.SysFont("Bold", 50) fogs[0].fill((20, 20, 20, 255)) fogs[1].fill((20, 20, 20, 220)) -#first fog is completely black, second is gray +# first fog is completely black, second is gray -#generates a light +# generates a light def draw_light(radius, quality): - surface = pygame.Surface((radius*2, radius*2), pygame.SRCALPHA) - loop_count, color_change = 25*quality, 8/quality - for i in range(loop_count): - pygame.draw.circle(surface, (20, 20, 20, 220-i*color_change), (radius, radius), radius-i*2) - return(surface) + surface = pygame.Surface((radius * 2, radius * 2), pygame.SRCALPHA) + loop_count, color_change = 25 * quality, 8 / quality + for i in range(loop_count): + pygame.draw.circle( + surface, + (20, 20, 20, 220 - i * color_change), + (radius, radius), + radius - i * 2, + ) + return surface + def mainloop(): - player = Player((100, 100)) - last_player_position = [100, 100] - trees = SolidObject.generate_many(36) - ghosts = [Ghost() for _ in range(16)] - - light_r = 150 - light_rect = pygame.Rect(0, 0, light_r*2, light_r*2) - light = draw_light(light_r, 12) - #Dont pass a number higher than 12 - - all_objects = trees + [player] + ghosts - - clock = pygame.time.Clock() - while True: - screen, events = yield - for event in events: - if event.type == pygame.QUIT: - return - - for obj in all_objects: - obj.logic(objects=all_objects) - #creates a fog area - if last_player_position != player.rect.topleft: - light_rect.center = player.rect.center - position = (player.rect.center[0]/fog_x, player.rect.center[1]/fog_y) - pygame.draw.circle(fogs[0], (0, 0, 0, 0), position, light_r/fog_x) - last_player_position = player.rect.topleft - - screen.fill(BACKGROUND) - for object in sorted(all_objects, key=attrgetter("rect.bottom")): - if getattr(object, "SHEET", None) != "pink_ghost": - object.draw(screen) - else: - if object.rect.colliderect(light_rect): - object.draw(screen, light_rect.center, light_r) - - #draws a fog - fog = pygame.Surface.copy(fogs[1]) - fog2 = fogs[0] - fog2 = pygame.transform.smoothscale(fog2, (1024, 768)) - fog.blit(fog2, (0, 0)) - pygame.draw.circle(fog, (0, 0, 0, 0), player.rect.center, light_r) - screen.blit(fog, (0, 0)) - screen.blit(light, (player.rect.center[0]-light_r, player.rect.center[1]-light_r)) - #draws a fog - - clock.tick(60) + player = Player((100, 100)) + last_player_position = [100, 100] + trees = SolidObject.generate_many(36) + ghosts = [Ghost() for _ in range(16)] + + light_r = 150 + light_rect = pygame.Rect(0, 0, light_r * 2, light_r * 2) + light = draw_light(light_r, 12) + # Dont pass a number higher than 12 + + all_objects = trees + [player] + ghosts + + clock = pygame.time.Clock() + while True: + screen, events = yield + for event in events: + if event.type == pygame.QUIT: + return + + for obj in all_objects: + obj.logic(objects=all_objects) + # creates a fog area + if last_player_position != player.rect.topleft: + light_rect.center = player.rect.center + position = (player.rect.center[0] / fog_x, player.rect.center[1] / fog_y) + pygame.draw.circle(fogs[0], (0, 0, 0, 0), position, light_r / fog_x) + last_player_position = player.rect.topleft + + screen.fill(BACKGROUND) + for object in sorted(all_objects, key=attrgetter("rect.bottom")): + if getattr(object, "SHEET", None) != "pink_ghost": + object.draw(screen) + else: + if object.rect.colliderect(light_rect): + object.draw(screen, light_rect.center, light_r) + + # draws a fog + fog = pygame.Surface.copy(fogs[1]) + fog2 = fogs[0] + fog2 = pygame.transform.smoothscale(fog2, (1024, 768)) + fog.blit(fog2, (0, 0)) + pygame.draw.circle(fog, (0, 0, 0, 0), player.rect.center, light_r) + screen.blit(fog, (0, 0)) + screen.blit(light, (player.rect.center[0] - light_r, player.rect.center[1] - light_r)) + # draws a fog + + clock.tick(60) if __name__ == "__main__": - wclib.run(mainloop()) + wclib.run(mainloop()) diff --git a/01-fog-of-war/Miku/objects.py b/01-fog-of-war/Miku/objects.py index fd1cad6..838e4b8 100644 --- a/01-fog-of-war/Miku/objects.py +++ b/01-fog-of-war/Miku/objects.py @@ -8,9 +8,10 @@ """ from random import choice, gauss -#custom import +# custom import from math import sqrt -#custom import + +# custom import import pygame @@ -105,25 +106,22 @@ def new_goal(self): def logic(self, **kwargs): middle_area = SCREEN.inflate(-30, -30) - while self.rect.collidepoint(self.goal) or not middle_area.collidepoint( - self.goal - ): + while self.rect.collidepoint(self.goal) or not middle_area.collidepoint(self.goal): self.goal = self.new_goal() - self.acceleration = ( - self.goal - self.rect.center - ).normalize() * self.ACCELERATION + self.acceleration = (self.goal - self.rect.center).normalize() * self.ACCELERATION super().logic(**kwargs) - #custom method + # custom method def draw(self, screen, plr_rect, light_r): surface = pygame.Surface.copy(self.sprite) ghost_rect = self.rect.center - distance = sqrt((plr_rect[0]-ghost_rect[0])**2 + (plr_rect[1]-ghost_rect[1])**2) - distance = distance/light_r*255 - surface.set_alpha(255-distance) + distance = sqrt((plr_rect[0] - ghost_rect[0]) ** 2 + (plr_rect[1] - ghost_rect[1]) ** 2) + distance = distance / light_r * 255 + surface.set_alpha(255 - distance) screen.blit(surface, self.pos) - #custom method + + # custom method class SolidObject(Object): @@ -154,4 +152,3 @@ def generate_many(cls, nb=16, max_tries=1000): if not any(obj.rect.colliderect(other.rect) for other in objects): objects.append(obj) return objects - diff --git a/01-fog-of-war/Miku/utils.py b/01-fog-of-war/Miku/utils.py index 8cd3288..28d56ff 100644 --- a/01-fog-of-war/Miku/utils.py +++ b/01-fog-of-war/Miku/utils.py @@ -38,4 +38,3 @@ def from_polar(rho, theta): v = pygame.Vector2() v.from_polar((rho, theta)) return v - diff --git a/01-fog-of-war/RoboMarchello/main.py b/01-fog-of-war/RoboMarchello/main.py index d83920e..11d9a41 100644 --- a/01-fog-of-war/RoboMarchello/main.py +++ b/01-fog-of-war/RoboMarchello/main.py @@ -22,8 +22,8 @@ __author__ = "RoboMarchello#0570" __achievements__ = [ # Uncomment the ones you've done "Casual", - "Ambitious", - "Adventurous", + "Ambitious", + "Adventurous", ] @@ -57,7 +57,7 @@ def mainloop(): obj.logic(objects=all_objects) screen.fill(BACKGROUND) - + for object in sorted(all_objects, key=attrgetter("rect.bottom")): if ghosts.count(object) >= 1: if fog.get_dist(object) < 130: diff --git a/01-fog-of-war/RoboMarchello/objects.py b/01-fog-of-war/RoboMarchello/objects.py index fcce0a5..c00173b 100644 --- a/01-fog-of-war/RoboMarchello/objects.py +++ b/01-fog-of-war/RoboMarchello/objects.py @@ -8,13 +8,14 @@ """ from random import choice, gauss import math -import pygame,pygame.gfxdraw +import pygame, pygame.gfxdraw from wclib import SIZE from .utils import clamp, from_polar, load_image, random_in_rect SCREEN = pygame.Rect(0, 0, *SIZE) + class Object: """The base class for all objects of the game.""" @@ -100,14 +101,10 @@ def new_goal(self): def logic(self, **kwargs): middle_area = SCREEN.inflate(-30, -30) - while self.rect.collidepoint(self.goal) or not middle_area.collidepoint( - self.goal - ): + while self.rect.collidepoint(self.goal) or not middle_area.collidepoint(self.goal): self.goal = self.new_goal() - self.acceleration = ( - self.goal - self.rect.center - ).normalize() * self.ACCELERATION + self.acceleration = (self.goal - self.rect.center).normalize() * self.ACCELERATION super().logic(**kwargs) @@ -140,19 +137,20 @@ def generate_many(cls, nb=16, max_tries=1000): objects.append(obj) return objects -class Fog(): - def __init__(self,player): - self.maskSurf = pygame.Surface(SCREEN.size,pygame.SRCALPHA) - self.maskSurf.fill((0,0,0)) + +class Fog: + def __init__(self, player): + self.maskSurf = pygame.Surface(SCREEN.size, pygame.SRCALPHA) + self.maskSurf.fill((0, 0, 0)) self.player = player self.addRadius = 0 self.isAdd = False - self.rect = pygame.Rect(0,0,125*2,125*2) + self.rect = pygame.Rect(0, 0, 125 * 2, 125 * 2) - def draw(self,screen): + def draw(self, screen): if self.addRadius <= 0: self.isAdd = True elif self.addRadius >= 10: @@ -162,20 +160,25 @@ def draw(self,screen): self.addRadius += 0.2 else: self.addRadius -= 0.2 - - smoothRadius = 135#225 - + + smoothRadius = 135 # 225 + alpha = 210 - + for alp in range(200): alpha -= 1 - pygame.draw.circle(self.maskSurf,(0,0,0,alpha),self.player.rect.center,smoothRadius) + pygame.draw.circle( + self.maskSurf, (0, 0, 0, alpha), self.player.rect.center, smoothRadius + ) smoothRadius -= 1 self.rect.center = self.player.rect.center - screen.blit(self.maskSurf,(0,0)) + screen.blit(self.maskSurf, (0, 0)) - def get_dist(self,ghost): - dist = [(self.player.rect.center[0]-ghost.rect.center[0])**2,(self.player.rect.center[1]-ghost.rect.center[1])**2] + def get_dist(self, ghost): + dist = [ + (self.player.rect.center[0] - ghost.rect.center[0]) ** 2, + (self.player.rect.center[1] - ghost.rect.center[1]) ** 2, + ] - return math.sqrt(dist[0]+dist[1]) + return math.sqrt(dist[0] + dist[1]) diff --git a/01-fog-of-war/alley-indie/main.py b/01-fog-of-war/alley-indie/main.py index e06bed4..60982ac 100644 --- a/01-fog-of-war/alley-indie/main.py +++ b/01-fog-of-war/alley-indie/main.py @@ -68,11 +68,9 @@ def mainloop(): for object in sorted(all_objects, key=attrgetter("rect.bottom")): object.draw(screen) fog.fill((0, 0, 0)) - pos = ( - player.pos[0] + player.size[0] // 2, - player.pos[1] + player.size[1] // 2) + pos = (player.pos[0] + player.size[0] // 2, player.pos[1] + player.size[1] // 2) draw_circle(fog, pos, player.size[0], 100) - screen.blit(fog, (0 ,0), special_flags=pygame.BLEND_RGBA_MULT) + screen.blit(fog, (0, 0), special_flags=pygame.BLEND_RGBA_MULT) clock.tick(60) diff --git a/01-fog-of-war/alley-indie/objects.py b/01-fog-of-war/alley-indie/objects.py index e507e56..cbc1806 100644 --- a/01-fog-of-war/alley-indie/objects.py +++ b/01-fog-of-war/alley-indie/objects.py @@ -101,14 +101,10 @@ def new_goal(self): def logic(self, **kwargs): middle_area = SCREEN.inflate(-30, -30) - while self.rect.collidepoint(self.goal) or not middle_area.collidepoint( - self.goal - ): + while self.rect.collidepoint(self.goal) or not middle_area.collidepoint(self.goal): self.goal = self.new_goal() - self.acceleration = ( - self.goal - self.rect.center - ).normalize() * self.ACCELERATION + self.acceleration = (self.goal - self.rect.center).normalize() * self.ACCELERATION super().logic(**kwargs) diff --git a/01-fog-of-war/andenixa/main.py b/01-fog-of-war/andenixa/main.py index cb65658..cd244e7 100644 --- a/01-fog-of-war/andenixa/main.py +++ b/01-fog-of-war/andenixa/main.py @@ -54,34 +54,36 @@ # matches (relative) positional flags to tile/sprite numbers # Note: numbers don't mean anything, they are just pic position in the sprite sheet tset_flag_to_graph = { - TILE_POS_ALL:8, - TILE_POS_W : 2, - TILE_POS_S : 7, - TILE_POS_N : 4, - TILE_POS_E : 6, - TILE_POS_SW : 1, - TILE_POS_SE : 9, - TILE_POS_NW : 3, - TILE_POS_NE : 5, - TILE_POS_NONE: 0, - TILE_POS_W | TILE_POS_S: 12, - TILE_POS_W | TILE_POS_N: 13, - TILE_POS_E | TILE_POS_N: 10, - TILE_POS_E | TILE_POS_S: 11, - TILE_POS_NE | TILE_POS_SW: 14, - TILE_POS_SE | TILE_POS_NW: 15, - } + TILE_POS_ALL: 8, + TILE_POS_W: 2, + TILE_POS_S: 7, + TILE_POS_N: 4, + TILE_POS_E: 6, + TILE_POS_SW: 1, + TILE_POS_SE: 9, + TILE_POS_NW: 3, + TILE_POS_NE: 5, + TILE_POS_NONE: 0, + TILE_POS_W | TILE_POS_S: 12, + TILE_POS_W | TILE_POS_N: 13, + TILE_POS_E | TILE_POS_N: 10, + TILE_POS_E | TILE_POS_S: 11, + TILE_POS_NE | TILE_POS_SW: 14, + TILE_POS_SE | TILE_POS_NW: 15, +} + class Grid: - """ represent a grid, to be accessed via grid[x, y] """ + """represent a grid, to be accessed via grid[x, y]""" + def __init__(self, ncols, nrows, size, value=0): - self.ncols=ncols - self.size=size - self.nrows=nrows - self._items = [ [value for n in range(ncols)] for m in range(nrows) ] + self.ncols = ncols + self.size = size + self.nrows = nrows + self._items = [[value for n in range(ncols)] for m in range(nrows)] def cell_at_pos(self, pos): - x, y = pos + x, y = pos col = x // self.size[0] row = y // self.size[1] return col, row @@ -97,21 +99,22 @@ def __getitem__(self, where): def __len__(self): return self.nrows * self.ncols + class LightSpot: - """ Prepares light spot picture - """ - def __init__(self, size, fog_color, noise_str=7, light_frames=5, fps=15): + """Prepares light spot picture""" + + def __init__(self, size, fog_color, noise_str=7, light_frames=5, fps=15): self._light_sphere = pygame.Surface(size).convert() - self._radius = radius = (size[0]//2)-8 + self._radius = radius = (size[0] // 2) - 8 self._fog_color = fog_color self._light_sphere_w = self._light_sphere.get_size()[0] self.x = 0 self.y = 0 self._light_sphere.fill(self._fog_color) - self._delay = 1000//fps + self._delay = 1000 // fps self._lights = [] - print('Generating lights bulbs ..') + print("Generating lights bulbs ..") for _ in range(light_frames): s = self._light_sphere.copy() self._draw_spot(s) @@ -120,72 +123,90 @@ def __init__(self, size, fog_color, noise_str=7, light_frames=5, fps=15): @property def light_color(self): - return self._lights[0].get_at((self._light_sphere_w//2,self._light_sphere_w//2)) - - def _draw_spot(self, surf): - pos = (self._light_sphere_w//2, self._light_sphere_w//2) + return self._lights[0].get_at((self._light_sphere_w // 2, self._light_sphere_w // 2)) + + def _draw_spot(self, surf): + pos = (self._light_sphere_w // 2, self._light_sphere_w // 2) c = 0 - for r in range(self._radius, 10, -1): + for r in range(self._radius, 10, -1): c += 1 c = max(c, 0) - c1 = min(self._fog_color[0]+c, 255) - c2 = min(self._fog_color[1]+c+25, 255) - c3 = min(self._fog_color[2]+c, 255) + c1 = min(self._fog_color[0] + c, 255) + c2 = min(self._fog_color[1] + c + 25, 255) + c3 = min(self._fog_color[2] + c, 255) pygame.draw.circle(surf, (c1, c2, c3), pos, r) - + def _render_noise(self, surf, severity): r = 3 for x in range(r, self._light_sphere_w, r): for y in range(r, self._light_sphere_w, r): - color = surf.get_at((x,y)) + color = surf.get_at((x, y)) c1 = color.r c2 = color.g c3 = color.b - if (c1, c2, c3)==self._fog_color: + if (c1, c2, c3) == self._fog_color: continue - noise_add = random.randint(0, severity) - noise_c = (min(c1+noise_add, 255), min(c2+noise_add, 255), min(c3+noise_add, 255)) + noise_add = random.randint(0, severity) + noise_c = ( + min(c1 + noise_add, 255), + min(c2 + noise_add, 255), + min(c3 + noise_add, 255), + ) radius = random.randint(1, r) - pygame.draw.circle(surf, noise_c, (x-radius, y-radius), radius ) + pygame.draw.circle(surf, noise_c, (x - radius, y - radius), radius) # pixel noise doesn't work with soft shadows - #surf.set_at((x,y), ) - # + # surf.set_at((x,y), ) + # + def draw(self, surf, special_flags=0): - surf.blit(self._lights[(pygame.time.get_ticks()//self._delay) % len(self._lights)], (self.x, self.y), special_flags=special_flags) + surf.blit( + self._lights[(pygame.time.get_ticks() // self._delay) % len(self._lights)], + (self.x, self.y), + special_flags=special_flags, + ) + def in_circle(c_x, c_y, radius, x, y): - """ check if point x, y is inside circle c_x, c_y with specified radius - """ - dx = x-c_x - dy = y-c_y - return (dx*dx + dy*dy) <= radius*radius + """check if point x, y is inside circle c_x, c_y with specified radius""" + dx = x - c_x + dy = y - c_y + return (dx * dx + dy * dy) <= radius * radius -def tile_paint( graph_grid, flag_grid, pos, paint_flag=TILE_POS_ALL ): - """ tile drawing - used to find adjucent edges for seamless tile coverage (like a map editor) + +def tile_paint(graph_grid, flag_grid, pos, paint_flag=TILE_POS_ALL): + """tile drawing + used to find adjucent edges for seamless tile coverage (like a map editor) """ res = False col, row = pos pos_idx = 0 - pbrush = [TILE_POS_SE, TILE_POS_S, TILE_POS_SW, - TILE_POS_E, paint_flag, TILE_POS_W, - TILE_POS_NE, TILE_POS_N, TILE_POS_NW] - - for y in range(row-1, row+2): - for x in range(col-1, col+2): - if x<-1 or y<-1: # the edge is till a little glitchty + pbrush = [ + TILE_POS_SE, + TILE_POS_S, + TILE_POS_SW, + TILE_POS_E, + paint_flag, + TILE_POS_W, + TILE_POS_NE, + TILE_POS_N, + TILE_POS_NW, + ] + + for y in range(row - 1, row + 2): + for x in range(col - 1, col + 2): + if x < -1 or y < -1: # the edge is till a little glitchty continue - pb_flag = pbrush[pos_idx] + pb_flag = pbrush[pos_idx] try: if paint_flag != TILE_POS_NONE: - tile_flag = flag_grid[x, y] | pb_flag + tile_flag = flag_grid[x, y] | pb_flag else: tile_flag = flag_grid[x, y] & ~pb_flag - except IndexError: #takes care of the edge if a map ;( - continue - sprite_no = tset_flag_to_graph[ tile_flag ] + except IndexError: # takes care of the edge if a map ;( + continue + sprite_no = tset_flag_to_graph[tile_flag] old_sprite = graph_grid[x, y] - if old_sprite!=sprite_no: + if old_sprite != sprite_no: res = True graph_grid[x, y] = sprite_no flag_grid[x, y] = tile_flag @@ -193,32 +214,35 @@ def tile_paint( graph_grid, flag_grid, pos, paint_flag=TILE_POS_ALL ): pos_idx += 1 return res + def rect_dist(r1, r2): - return max(abs(r1.centerx-r2.centerx), abs(r1.centery-r2.centery)) + return max(abs(r1.centerx - r2.centerx), abs(r1.centery - r2.centery)) + def measure_angle_vec(vec2, vec1): return (vec2 - vec1).as_polar()[1] + def load_tiles(fn, size, colorkey=None, scale=None, verbose=True): - """ load all sprites of size in image file fn - return: subsurfaces of all sprites + """load all sprites of size in image file fn + return: subsurfaces of all sprites """ if verbose: - print('Loading:', fn) + print("Loading:", fn) sheet = pygame.image.load(fn).convert() if colorkey is not None: - sheet.set_colorkey( colorkey ) + sheet.set_colorkey(colorkey) tiles = [] for row in range(0, sheet.get_size()[1], size[1]): for col in range(0, sheet.get_size()[0], size[0]): - tile = sheet.subsurface( (col, row, *size) ) + tile = sheet.subsurface((col, row, *size)) if scale is not None: - tile = pygame.transform.scale(tile, (int(size[0]*scale), int(size[1]*scale))) - tiles.append( tile ) + tile = pygame.transform.scale(tile, (int(size[0] * scale), int(size[1] * scale))) + tiles.append(tile) return tiles -def mainloop(): +def mainloop(): screen, events = yield width, height = screen.get_size() @@ -226,45 +250,45 @@ def mainloop(): BLUR_SHADOWS = 2 LIGHT_SPOT_SIZE = 320 FOG_TILE_WIDTH = 64 - FOG_GRID_SIZE = (width//FOG_TILE_WIDTH + 2, height//FOG_TILE_WIDTH + 2) + FOG_GRID_SIZE = (width // FOG_TILE_WIDTH + 2, height // FOG_TILE_WIDTH + 2) COLOR_MAGENTA = (114, 89, 151) - DISCOVERY_TILES_RADIUS = (LIGHT_SPOT_SIZE//FOG_TILE_WIDTH)//2 - angle_step = 3 # for raycasting + DISCOVERY_TILES_RADIUS = (LIGHT_SPOT_SIZE // FOG_TILE_WIDTH) // 2 + angle_step = 3 # for raycasting shadow_divider = 6 - Vector2 = pygame.Vector2 + Vector2 = pygame.Vector2 discovery_tile_offsets = [] - for y in range(-DISCOVERY_TILES_RADIUS, DISCOVERY_TILES_RADIUS+1): - for x in range(-DISCOVERY_TILES_RADIUS, DISCOVERY_TILES_RADIUS+1): - if in_circle(0,0, DISCOVERY_TILES_RADIUS, x, y): - discovery_tile_offsets.append((x, y)) - - #discovery_tile_offsets = ((0,0), (-1,0), (0,-1), (1,0), (0,1),(-1,1),(1,1),(0,2)) + for y in range(-DISCOVERY_TILES_RADIUS, DISCOVERY_TILES_RADIUS + 1): + for x in range(-DISCOVERY_TILES_RADIUS, DISCOVERY_TILES_RADIUS + 1): + if in_circle(0, 0, DISCOVERY_TILES_RADIUS, x, y): + discovery_tile_offsets.append((x, y)) + + # discovery_tile_offsets = ((0,0), (-1,0), (0,-1), (1,0), (0,1),(-1,1),(1,1),(0,2)) tile_scale = None - if FOG_TILE_WIDTH!=32: - tile_scale = FOG_TILE_WIDTH/32 - fog_tiles = load_tiles('fog_of_war.png', (32,32), scale=tile_scale) + if FOG_TILE_WIDTH != 32: + tile_scale = FOG_TILE_WIDTH / 32 + fog_tiles = load_tiles("fog_of_war.png", (32, 32), scale=tile_scale) t_size = fog_tiles[0].get_size() fog_t_graph = Grid(*FOG_GRID_SIZE, t_size, tset_flag_to_graph[TILE_POS_NONE]) fog_t_flags = Grid(*FOG_GRID_SIZE, t_size, TILE_POS_NONE) fog_t_visited = Grid(*FOG_GRID_SIZE, t_size, False) - - fog_size_w, fog_size_h = fog_tiles[0].get_size() + + fog_size_w, fog_size_h = fog_tiles[0].get_size() fog_color = COLOR_MAGENTA - + light_spot = LightSpot((LIGHT_SPOT_SIZE, LIGHT_SPOT_SIZE), fog_color) - fog_surface = pygame.Surface(screen.get_size()) - screen.blit(fog_surface, (0,0), special_flags=pygame.BLEND_MULT) + fog_surface = pygame.Surface(screen.get_size()) + screen.blit(fog_surface, (0, 0), special_flags=pygame.BLEND_MULT) - light_color = screen.get_at((0,0)) + light_color = screen.get_at((0, 0)) lighto = pygame.Surface((LIGHT_SPOT_SIZE, LIGHT_SPOT_SIZE)) - obj_rects = {} # object rects cache (in case I want to alter those) - obj_srects = {} # objects subrect/"texels" cache + obj_rects = {} # object rects cache (in case I want to alter those) + obj_srects = {} # objects subrect/"texels" cache - cull_distance = light_spot._light_sphere_w//2 # for sahdow generation - ray_length = light_spot._radius+15 # raycasting ray length + cull_distance = light_spot._light_sphere_w // 2 # for sahdow generation + ray_length = light_spot._radius + 15 # raycasting ray length player = Player((100, 100)) trees = SolidObject.generate_many(36) @@ -279,56 +303,82 @@ def mainloop(): for event in events: if event.type == pygame.QUIT: return - + for obj in all_objects: obj.logic(objects=all_objects) - tile_col, tile_row = fog_t_graph.cell_at_pos( (player.rect.centerx, player.rect.centery) ) + tile_col, tile_row = fog_t_graph.cell_at_pos((player.rect.centerx, player.rect.centery)) - if (tile_col != old_tile_col or tile_row != old_tile_row) and not fog_t_visited[tile_col, tile_row]: + if (tile_col != old_tile_col or tile_row != old_tile_row) and not fog_t_visited[ + tile_col, tile_row + ]: for xoff, yoff in discovery_tile_offsets: col = tile_col + xoff row = tile_row + yoff tile_paint(fog_t_graph, fog_t_flags, (col, row)) fog_t_visited[tile_col, tile_row] = True - old_tile_col, old_tile_row = fog_t_graph.cell_at_pos( (player.rect.centerx, player.rect.centery) ) + old_tile_col, old_tile_row = fog_t_graph.cell_at_pos( + (player.rect.centerx, player.rect.centery) + ) screen.fill(BACKGROUND) radius = light_spot._radius - for object in tuple(sorted(all_objects, key=attrgetter("rect.bottom"))): + for object in tuple(sorted(all_objects, key=attrgetter("rect.bottom"))): if isinstance(object, Ghost): - if not in_circle(object.rect.x, object.rect.y, radius, player.rect.x, player.rect.y): + if not in_circle( + object.rect.x, object.rect.y, radius, player.rect.x, player.rect.y + ): continue object.draw(screen) fog_surface.fill(light_spot._fog_color) - - pygame.draw.rect(fog_surface, light_spot.light_color, (player.rect.centerx-LIGHT_SPOT_SIZE//2, player.rect.centery-LIGHT_SPOT_SIZE//2, LIGHT_SPOT_SIZE, LIGHT_SPOT_SIZE)) + + pygame.draw.rect( + fog_surface, + light_spot.light_color, + ( + player.rect.centerx - LIGHT_SPOT_SIZE // 2, + player.rect.centery - LIGHT_SPOT_SIZE // 2, + LIGHT_SPOT_SIZE, + LIGHT_SPOT_SIZE, + ), + ) p_rect = player.rect - - all_objects_filtered = sorted( (obj for obj in all_objects if not obj is player and - not obj.rect.colliderect(p_rect) and rect_dist(player.rect, obj.rect)cached_p1_dist and pt2_distcached_p2_dist + cached_p1_dist = Vector2(cached[0]).distance_squared_to( + player_c_pos + ) + cached_p2_dist = Vector2(cached[1]).distance_squared_to( + player_c_pos + ) + is_inside = ( + pt1_dist > cached_p1_dist and pt2_dist < cached_p2_dist + ) + is_outside = ( + pt2_dist < cached_p1_dist or pt1_dist > cached_p2_dist + ) if not is_inside and not is_outside: - if pt1_dist>cached_p1_dist: - pt1 = cached[0] + if pt1_dist > cached_p1_dist: + pt1 = cached[0] + cache_dirty = True + if pt2_dist < cached_p2_dist: + p2 = cached[1] cache_dirty = True - if pt2_dist [insert, append] <--- - pts2.insert(0, p2) # that is of course not optimal for lists + # insert points rather then append for proper + # polygon drawing ---> [insert, append] <--- + pts2.insert(0, p2) # that is of course not optimal for lists if DEBUG_DRAW: - pygame.draw.line(surf, (162,194,126), p2, colis2[0] ) - pygame.draw.rect(surf, (22,232,111), s_rect, 1) - break + pygame.draw.line(surf, (162, 194, 126), p2, colis2[0]) + pygame.draw.rect(surf, (22, 232, 111), s_rect, 1) + break if DEBUG_DRAW: - pygame.draw.line(surf, (254,222,156), colis[0], colis[1] ) - pygame.draw.line(surf, (152,184,156), player_c_pos, colis[0] ) - + pygame.draw.line(surf, (254, 222, 156), colis[0], colis[1]) + pygame.draw.line(surf, (152, 184, 156), player_c_pos, colis[0]) + else: if DEBUG_DRAW: - pygame.draw.line(surf, (254,222,156), line[0], line[1] ) + pygame.draw.line(surf, (254, 222, 156), line[0], line[1]) raycast_ended_r = True if not raycast_ended_l: ang2 = angle - a_i line_v = ray_v.rotate(ang2) - line = tuple(player_c_pos), player_c_pos+line_v + line = tuple(player_c_pos), player_c_pos + line_v for s_rect in subrects2: - colis = s_rect.clipline( *line ) + colis = s_rect.clipline(*line) if colis: if DEBUG_DRAW: - pygame.draw.rect(surf, (22,232,111), s_rect, 1) - break - if colis: - pt1 = colis[1] + pygame.draw.rect(surf, (22, 232, 111), s_rect, 1) + break + if colis: + pt1 = colis[1] line_bk = line[1], line[0] for s_rect in reversed(subrects1): - colis2 = s_rect.clipline( *line_bk ) + colis2 = s_rect.clipline(*line_bk) if colis2: p2 = colis2[0] p2_off = Vector2(shadow_len, 0).rotate(ang2) - p2 = tuple( p2 + p2_off ) - cached = rays_cache.get(ang2, None) + p2 = tuple(p2 + p2_off) + cached = rays_cache.get(ang2, None) if cached is not None: pt1_dist = Vector2(pt1).distance_squared_to(player_c_pos) pt2_dist = Vector2(p2).distance_squared_to(player_c_pos) - cached_p1_dist = Vector2(cached[0]).distance_squared_to(player_c_pos) - cached_p2_dist = Vector2(cached[1]).distance_squared_to(player_c_pos) - is_inside = pt1_dist>cached_p1_dist and pt2_distcached_p2_dist + cached_p1_dist = Vector2(cached[0]).distance_squared_to( + player_c_pos + ) + cached_p2_dist = Vector2(cached[1]).distance_squared_to( + player_c_pos + ) + is_inside = ( + pt1_dist > cached_p1_dist and pt2_dist < cached_p2_dist + ) + is_outside = ( + pt2_dist < cached_p1_dist or pt1_dist > cached_p2_dist + ) if not is_inside and not is_outside: - if pt1_dist>cached_p1_dist: - pt1 = cached[0] + if pt1_dist > cached_p1_dist: + pt1 = cached[0] + cache_dirty = True + if pt2_dist < cached_p2_dist: + p2 = cached[1] cache_dirty = True - if pt2_dist2: + + points = pts1 + pts2 + if len(points) > 2: if DEBUG_DRAW: - pygame.draw.polygon(surf, (245,100,200), points, 1) + pygame.draw.polygon(surf, (245, 100, 200), points, 1) else: # pts1 denote inner contour (closer to player) # pts2 are outer contour pygame.draw.polygon(surf, color, points) # end of raycasting - light_spot.x = player.rect.centerx-LIGHT_SPOT_SIZE//2 - light_spot.y = player.rect.centery-LIGHT_SPOT_SIZE//2 - light_spot.draw(fog_surface, special_flags=pygame.BLEND_MIN) + light_spot.x = player.rect.centerx - LIGHT_SPOT_SIZE // 2 + light_spot.y = player.rect.centery - LIGHT_SPOT_SIZE // 2 + light_spot.draw(fog_surface, special_flags=pygame.BLEND_MIN) - #fake blurring + # fake blurring if BLUR_SHADOWS: - the_pos = player.rect.centerx-LIGHT_SPOT_SIZE//2, player.rect.centery-LIGHT_SPOT_SIZE//2 - lighto.blit(fog_surface, (0,0), (*the_pos, LIGHT_SPOT_SIZE, LIGHT_SPOT_SIZE)) - if BLUR_SHADOWS>1: - l_blurred = pygame.transform.smoothscale(lighto, (LIGHT_SPOT_SIZE//4, LIGHT_SPOT_SIZE//4)) - l_blurred = pygame.transform.smoothscale(l_blurred,(LIGHT_SPOT_SIZE//2, LIGHT_SPOT_SIZE//2)) + the_pos = ( + player.rect.centerx - LIGHT_SPOT_SIZE // 2, + player.rect.centery - LIGHT_SPOT_SIZE // 2, + ) + lighto.blit(fog_surface, (0, 0), (*the_pos, LIGHT_SPOT_SIZE, LIGHT_SPOT_SIZE)) + if BLUR_SHADOWS > 1: + l_blurred = pygame.transform.smoothscale( + lighto, (LIGHT_SPOT_SIZE // 4, LIGHT_SPOT_SIZE // 4) + ) + l_blurred = pygame.transform.smoothscale( + l_blurred, (LIGHT_SPOT_SIZE // 2, LIGHT_SPOT_SIZE // 2) + ) pygame.transform.scale(l_blurred, (LIGHT_SPOT_SIZE, LIGHT_SPOT_SIZE), lighto) - fog_surface.blit(lighto, the_pos) + fog_surface.blit(lighto, the_pos) - screen.blit(fog_surface, (0,0), special_flags=pygame.BLEND_MULT) + screen.blit(fog_surface, (0, 0), special_flags=pygame.BLEND_MULT) - for y in range(0, fog_t_graph.nrows*fog_size_w, fog_size_w): - c_tile_y = y//fog_size_w - for x in range(0, fog_t_graph.ncols*fog_size_w, fog_size_w): - c_tile_x = x//fog_size_w + for y in range(0, fog_t_graph.nrows * fog_size_w, fog_size_w): + c_tile_y = y // fog_size_w + for x in range(0, fog_t_graph.ncols * fog_size_w, fog_size_w): + c_tile_x = x // fog_size_w graph = fog_t_graph[c_tile_x, c_tile_y] fog_tile = fog_tiles[graph] screen.blit(fog_tile, (x, y), special_flags=pygame.BLEND_MULT) - + clock.tick(60) diff --git a/01-fog-of-war/andenixa/objects.py b/01-fog-of-war/andenixa/objects.py index e76cc0e..cbc1806 100644 --- a/01-fog-of-war/andenixa/objects.py +++ b/01-fog-of-war/andenixa/objects.py @@ -101,14 +101,10 @@ def new_goal(self): def logic(self, **kwargs): middle_area = SCREEN.inflate(-30, -30) - while self.rect.collidepoint(self.goal) or not middle_area.collidepoint( - self.goal - ): + while self.rect.collidepoint(self.goal) or not middle_area.collidepoint(self.goal): self.goal = self.new_goal() - self.acceleration = ( - self.goal - self.rect.center - ).normalize() * self.ACCELERATION + self.acceleration = (self.goal - self.rect.center).normalize() * self.ACCELERATION super().logic(**kwargs) @@ -134,7 +130,7 @@ def __init__(self, pos): def generate_many(cls, nb=16, max_tries=1000): objects = [] tries = 0 # avoids infinite loop - while len(objects) < nb and tries < max_tries: + while len(objects) < nb and tries < max_tries: pos = random_in_rect(SCREEN) obj = cls(pos) if not any(obj.rect.colliderect(other.rect) for other in objects): diff --git a/01-fog-of-war/arosso17/main.py b/01-fog-of-war/arosso17/main.py index a32640a..8f9312e 100644 --- a/01-fog-of-war/arosso17/main.py +++ b/01-fog-of-war/arosso17/main.py @@ -2,6 +2,8 @@ from pathlib import Path import numpy as np +ROOT_FOLDER = Path(__file__).parent.parent.parent + try: import wclib except ImportError: @@ -9,7 +11,6 @@ # of all the challenges and the fact that there are many # way to run them (through the showcase, or on their own) - ROOT_FOLDER = Path(__file__).parent.parent.parent sys.path.append(str(ROOT_FOLDER)) import wclib @@ -38,8 +39,10 @@ BACKGROUND = 0x66856C + def dist(pos, other): - return np.sqrt((pos[0]-other[0])**2 + (pos[1]-other[1])**2) + return np.sqrt((pos[0] - other[0]) ** 2 + (pos[1] - other[1]) ** 2) + def mainloop(): player = Player((100, 100)) @@ -73,26 +76,60 @@ def mainloop(): lights = pygame.Surface((screen.get_width(), screen.get_height()), pygame.SRCALPHA) fog_of_war = pygame.Surface((screen.get_width(), screen.get_height()), pygame.SRCALPHA) - explored_map = pygame.Surface((screen.get_width(), screen.get_height()), pygame.SRCALPHA) - pygame.draw.rect(explored_map, (0, 0, 0, 255), [0, 0, screen.get_width(), screen.get_height()]) + explored_map = pygame.Surface( + (screen.get_width(), screen.get_height()), pygame.SRCALPHA + ) + pygame.draw.rect( + explored_map, + (0, 0, 0, 255), + [0, 0, screen.get_width(), screen.get_height()], + ) for obj in trees: if obj.rect[2] == 144: - pygame.draw.circle(lights, (234, 206, 9, 15), - (obj.rect[0] + 32, obj.rect[1] + 94), 45, 20) - pygame.draw.circle(lights, (234, 206, 9, 15), - (obj.rect[0] - 32 + obj.rect[2], obj.rect[1] + 94), 45, 20) - pygame.draw.circle(lights, (234, 206, 9, 40), - (obj.rect[0] + 32, obj.rect[1] + 94), 25) - pygame.draw.circle(lights, (234, 206, 9, 40), - (obj.rect[0] - 32 + obj.rect[2], obj.rect[1] + 94), 25) - pygame.draw.rect(lights, (234, 206, 9, 150), - (obj.rect[0] + 21, obj.rect[1] + 84, 21, 18)) - pygame.draw.rect(lights, (234, 206, 9, 150), - (obj.rect[0] - 45 + obj.rect[2], obj.rect[1] + 84, 21, 18)) + pygame.draw.circle( + lights, + (234, 206, 9, 15), + (obj.rect[0] + 32, obj.rect[1] + 94), + 45, + 20, + ) + pygame.draw.circle( + lights, + (234, 206, 9, 15), + (obj.rect[0] - 32 + obj.rect[2], obj.rect[1] + 94), + 45, + 20, + ) + pygame.draw.circle( + lights, + (234, 206, 9, 40), + (obj.rect[0] + 32, obj.rect[1] + 94), + 25, + ) + pygame.draw.circle( + lights, + (234, 206, 9, 40), + (obj.rect[0] - 32 + obj.rect[2], obj.rect[1] + 94), + 25, + ) + pygame.draw.rect( + lights, + (234, 206, 9, 150), + (obj.rect[0] + 21, obj.rect[1] + 84, 21, 18), + ) + pygame.draw.rect( + lights, + (234, 206, 9, 150), + (obj.rect[0] - 45 + obj.rect[2], obj.rect[1] + 84, 21, 18), + ) # for pic explored_map.blit(fog, (0, 0)) - pygame.draw.rect(fog_of_war, (0, 0, 0, 150), [0, 0, screen.get_width(), screen.get_height()]) + pygame.draw.rect( + fog_of_war, + (0, 0, 0, 150), + [0, 0, screen.get_width(), screen.get_height()], + ) first = False for event in events: if event.type == pygame.QUIT: @@ -117,18 +154,36 @@ def mainloop(): if dis < 200: ghost.sprite.set_alpha(255) if dis > 100: - ghost.sprite.set_alpha(355 - (355/150)*dis) + ghost.sprite.set_alpha(355 - (355 / 150) * dis) ghost.draw(screen) screen.blit(explored_map, (0, 0)) for i in range(0, 150, 2): - pygame.draw.circle(fog_of_war, (0, 0, 0, i), - (player.pos[0] + player.size[0] / 2, player.pos[1] + player.size[1] / 2), i + 50, 2) - pygame.draw.circle(fog_of_war, (0, 0, 0, 0), - (player.pos[0] + player.size[0] / 2, player.pos[1] + player.size[1] / 2), 50) - pygame.draw.circle(explored_map, (0, 0, 0, 150), [player.pos[0] + player.size[0] / 2, player.pos[1] + player.size[1] / 2], 150) + pygame.draw.circle( + fog_of_war, + (0, 0, 0, i), + ( + player.pos[0] + player.size[0] / 2, + player.pos[1] + player.size[1] / 2, + ), + i + 50, + 2, + ) + pygame.draw.circle( + fog_of_war, + (0, 0, 0, 0), + (player.pos[0] + player.size[0] / 2, player.pos[1] + player.size[1] / 2), + 50, + ) + pygame.draw.circle( + explored_map, + (0, 0, 0, 150), + [player.pos[0] + player.size[0] / 2, player.pos[1] + player.size[1] / 2], + 150, + ) clock.tick(FPS) print(clock.get_fps()) + if __name__ == "__main__": wclib.run(mainloop()) diff --git a/01-fog-of-war/arosso17/objects.py b/01-fog-of-war/arosso17/objects.py index e507e56..cbc1806 100644 --- a/01-fog-of-war/arosso17/objects.py +++ b/01-fog-of-war/arosso17/objects.py @@ -101,14 +101,10 @@ def new_goal(self): def logic(self, **kwargs): middle_area = SCREEN.inflate(-30, -30) - while self.rect.collidepoint(self.goal) or not middle_area.collidepoint( - self.goal - ): + while self.rect.collidepoint(self.goal) or not middle_area.collidepoint(self.goal): self.goal = self.new_goal() - self.acceleration = ( - self.goal - self.rect.center - ).normalize() * self.ACCELERATION + self.acceleration = (self.goal - self.rect.center).normalize() * self.ACCELERATION super().logic(**kwargs) diff --git a/01-fog-of-war/arosso17/test_stuff.py b/01-fog-of-war/arosso17/test_stuff.py index 122eb49..467eb7d 100644 --- a/01-fog-of-war/arosso17/test_stuff.py +++ b/01-fog-of-war/arosso17/test_stuff.py @@ -38,8 +38,10 @@ BACKGROUND = 0x66856C + def dist(pos, other): - return np.sqrt((pos[0]-other[0])**2 + (pos[1]-other[1])**2) + return np.sqrt((pos[0] - other[0]) ** 2 + (pos[1] - other[1]) ** 2) + def mainloop(): player = Player((100, 100)) @@ -73,26 +75,60 @@ def mainloop(): lights = pygame.Surface((screen.get_width(), screen.get_height()), pygame.SRCALPHA) fog_of_war = pygame.Surface((screen.get_width(), screen.get_height()), pygame.SRCALPHA) - explored_map = pygame.Surface((screen.get_width(), screen.get_height()), pygame.SRCALPHA) - pygame.draw.rect(explored_map, (0, 0, 0, 255), [0, 0, screen.get_width(), screen.get_height()]) + explored_map = pygame.Surface( + (screen.get_width(), screen.get_height()), pygame.SRCALPHA + ) + pygame.draw.rect( + explored_map, + (0, 0, 0, 255), + [0, 0, screen.get_width(), screen.get_height()], + ) for obj in trees: if obj.rect[2] == 144: - pygame.draw.circle(lights, (234, 206, 9, 15), - (obj.rect[0] + 32, obj.rect[1] + 94), 45, 20) - pygame.draw.circle(lights, (234, 206, 9, 15), - (obj.rect[0] - 32 + obj.rect[2], obj.rect[1] + 94), 45, 20) - pygame.draw.circle(lights, (234, 206, 9, 40), - (obj.rect[0] + 32, obj.rect[1] + 94), 25) - pygame.draw.circle(lights, (234, 206, 9, 40), - (obj.rect[0] - 32 + obj.rect[2], obj.rect[1] + 94), 25) - pygame.draw.rect(lights, (234, 206, 9, 150), - (obj.rect[0] + 21, obj.rect[1] + 84, 21, 18)) - pygame.draw.rect(lights, (234, 206, 9, 150), - (obj.rect[0] - 45 + obj.rect[2], obj.rect[1] + 84, 21, 18)) + pygame.draw.circle( + lights, + (234, 206, 9, 15), + (obj.rect[0] + 32, obj.rect[1] + 94), + 45, + 20, + ) + pygame.draw.circle( + lights, + (234, 206, 9, 15), + (obj.rect[0] - 32 + obj.rect[2], obj.rect[1] + 94), + 45, + 20, + ) + pygame.draw.circle( + lights, + (234, 206, 9, 40), + (obj.rect[0] + 32, obj.rect[1] + 94), + 25, + ) + pygame.draw.circle( + lights, + (234, 206, 9, 40), + (obj.rect[0] - 32 + obj.rect[2], obj.rect[1] + 94), + 25, + ) + pygame.draw.rect( + lights, + (234, 206, 9, 150), + (obj.rect[0] + 21, obj.rect[1] + 84, 21, 18), + ) + pygame.draw.rect( + lights, + (234, 206, 9, 150), + (obj.rect[0] - 45 + obj.rect[2], obj.rect[1] + 84, 21, 18), + ) # for pic explored_map.blit(fog, (0, 0)) - pygame.draw.rect(fog_of_war, (0, 0, 0, 150), [0, 0, screen.get_width(), screen.get_height()]) + pygame.draw.rect( + fog_of_war, + (0, 0, 0, 150), + [0, 0, screen.get_width(), screen.get_height()], + ) first = False for event in events: if event.type == pygame.QUIT: @@ -117,18 +153,36 @@ def mainloop(): if dis < 200: ghost.sprite.set_alpha(255) if dis > 100: - ghost.sprite.set_alpha(355 - (355/150)*dis) + ghost.sprite.set_alpha(355 - (355 / 150) * dis) ghost.draw(screen) screen.blit(explored_map, (0, 0)) for i in range(0, 150, 2): - pygame.draw.circle(fog_of_war, (0, 0, 0, i), - (player.pos[0] + player.size[0] / 2, player.pos[1] + player.size[1] / 2), i + 50, 2) - pygame.draw.circle(fog_of_war, (0, 0, 0, 0), - (player.pos[0] + player.size[0] / 2, player.pos[1] + player.size[1] / 2), 50) - pygame.draw.circle(explored_map, (0, 0, 0, 150), [player.pos[0] + player.size[0] / 2, player.pos[1] + player.size[1] / 2], 150) + pygame.draw.circle( + fog_of_war, + (0, 0, 0, i), + ( + player.pos[0] + player.size[0] / 2, + player.pos[1] + player.size[1] / 2, + ), + i + 50, + 2, + ) + pygame.draw.circle( + fog_of_war, + (0, 0, 0, 0), + (player.pos[0] + player.size[0] / 2, player.pos[1] + player.size[1] / 2), + 50, + ) + pygame.draw.circle( + explored_map, + (0, 0, 0, 150), + [player.pos[0] + player.size[0] / 2, player.pos[1] + player.size[1] / 2], + 150, + ) clock.tick(FPS) print(clock.get_fps()) + if __name__ == "__main__": wclib.run(mainloop()) diff --git a/01-fog-of-war/baconinvader/main.py b/01-fog-of-war/baconinvader/main.py index f321590..43ba87c 100644 --- a/01-fog-of-war/baconinvader/main.py +++ b/01-fog-of-war/baconinvader/main.py @@ -39,16 +39,14 @@ def mainloop(): darkness = Darkness() - #originally I was going to have support for multiple lights but I'm a busy man okay - light = Light(darkness, (100,100), 255, 100, 150, 150) + # originally I was going to have support for multiple lights but I'm a busy man okay + light = Light(darkness, (100, 100), 255, 100, 150, 150) player = Player((100, 100)) trees = SolidObject.generate_many(36) ghosts = [Ghost() for _ in range(16)] all_objects = trees + [player] + ghosts - - clock = pygame.time.Clock() while True: screen, events = yield @@ -65,10 +63,10 @@ def mainloop(): for object in sorted(visible_objects, key=attrgetter("rect.bottom")): object.draw(screen) - #move light to player - light.pos.x = player.rect.centerx-light.radius - light.pos.y = player.rect.centery-light.radius - + # move light to player + light.pos.x = player.rect.centerx - light.radius + light.pos.y = player.rect.centery - light.radius + light.update() light.draw(screen, visible_objects) darkness.draw(screen, light) diff --git a/01-fog-of-war/baconinvader/objects.py b/01-fog-of-war/baconinvader/objects.py index d303f43..73b78a7 100644 --- a/01-fog-of-war/baconinvader/objects.py +++ b/01-fog-of-war/baconinvader/objects.py @@ -101,14 +101,10 @@ def new_goal(self): def logic(self, **kwargs): middle_area = SCREEN.inflate(-30, -30) - while self.rect.collidepoint(self.goal) or not middle_area.collidepoint( - self.goal - ): + while self.rect.collidepoint(self.goal) or not middle_area.collidepoint(self.goal): self.goal = self.new_goal() - self.acceleration = ( - self.goal - self.rect.center - ).normalize() * self.ACCELERATION + self.acceleration = (self.goal - self.rect.center).normalize() * self.ACCELERATION super().logic(**kwargs) @@ -141,96 +137,125 @@ def generate_many(cls, nb=16, max_tries=1000): objects.append(obj) return objects -class Darkness(): + +class Darkness: def __init__(self, min_light=0, reveal_light=40): self.rect = SCREEN.copy() - self.min_light = min_light #minimum light level - self.reveal_light = reveal_light #how light an uncovered part of the map is + self.min_light = min_light # minimum light level + self.reveal_light = reveal_light # how light an uncovered part of the map is self.surface = pygame.Surface((SCREEN.w, SCREEN.h), pygame.SRCALPHA) - self.surface.fill((0,0,0,255-min_light)) + self.surface.fill((0, 0, 0, 255 - min_light)) - #uncovered part of the map + # uncovered part of the map self.shown_surface = self.surface.copy() - def draw(self, screen, light): - #draw darkness - self.surface.blit(self.shown_surface, (0,0), special_flags=pygame.BLEND_RGBA_MIN) - screen.blit(self.surface, (0,0) ) - + # draw darkness + self.surface.blit(self.shown_surface, (0, 0), special_flags=pygame.BLEND_RGBA_MIN) + screen.blit(self.surface, (0, 0)) - #clear light - pygame.gfxdraw.box(self.surface, light.rect, (0,0,0,255-self.min_light)) + # clear light + pygame.gfxdraw.box(self.surface, light.rect, (0, 0, 0, 255 - self.min_light)) -class Light(): +class Light: def __init__(self, darkness, pos, light, max_light_radius, min_light_radius, radius): self.radius = radius - #strength of the light, drops off to 0 at distance radius + # strength of the light, drops off to 0 at distance radius self.light = light - #radius up to which the light is as bright as possible + # radius up to which the light is as bright as possible self.max_light_radius = max_light_radius self.min_light_radius = min_light_radius self.pos = pygame.Vector2(pos) - self.rect = pygame.Rect(self.pos.x, self.pos.y, self.radius*2, self.radius*2) + self.rect = pygame.Rect(self.pos.x, self.pos.y, self.radius * 2, self.radius * 2) self.darkness = darkness self.create_surface() - #create the actual light surface + # create the actual light surface def create_surface(self): import pygame.gfxdraw - self.surface = pygame.Surface((self.rect.w, self.rect.h), flags=pygame.SRCALPHA) - self.surface.fill((0,0,0,0)) - - #draw center bright point - self.max_light_surface = pygame.Surface((self.max_light_radius*2, self.max_light_radius*2), flags=pygame.SRCALPHA) - pygame.gfxdraw.filled_circle(self.max_light_surface, self.max_light_radius, self.max_light_radius, self.max_light_radius, (0,0,0, self.light )) - - self.surface.blit(self.max_light_surface, (self.radius-self.max_light_radius, self.radius-self.max_light_radius)) + self.surface.fill((0, 0, 0, 0)) + + # draw center bright point + self.max_light_surface = pygame.Surface( + (self.max_light_radius * 2, self.max_light_radius * 2), + flags=pygame.SRCALPHA, + ) + pygame.gfxdraw.filled_circle( + self.max_light_surface, + self.max_light_radius, + self.max_light_radius, + self.max_light_radius, + (0, 0, 0, self.light), + ) + + self.surface.blit( + self.max_light_surface, + (self.radius - self.max_light_radius, self.radius - self.max_light_radius), + ) + + # how much dimmer the light should get per pixel + light_change_per_pixel = (self.light) / (self.radius - self.max_light_radius) + + min_light_level = self.light - ( + light_change_per_pixel * (self.min_light_radius - self.max_light_radius) + ) + + # draw fade + # reversed to prevent gaps in the drawing + for i in reversed(range((self.radius - (self.max_light_radius)) * 1)): - #how much dimmer the light should get per pixel - light_change_per_pixel = (self.light )/(self.radius-self.max_light_radius) - - min_light_level = self.light-(light_change_per_pixel*(self.min_light_radius-self.max_light_radius) ) - - #draw fade - #reversed to prevent gaps in the drawing - for i in reversed(range( (self.radius-(self.max_light_radius))*1 )): - pix = i - - dist_from_center = self.max_light_radius+pix - light_level = clamp(int(self.light-(light_change_per_pixel*pix)), min_light_level, 255-self.darkness.min_light) - colour = (0,0,0, light_level) - - pygame.gfxdraw.filled_circle(self.surface, self.rect.w//2, self.rect.h//2, int(self.max_light_radius+pix), colour) - - #draw full_surface (surface that will be permanently drawn on the FOW) - self.full_surface = pygame.Surface((self.radius*2, self.radius*2), flags=pygame.SRCALPHA) - self.full_surface.fill( (0,0,0,255) ) - pygame.gfxdraw.filled_circle(self.full_surface, self.radius, self.radius, self.radius, (0,128,0,255-self.darkness.reveal_light)) + dist_from_center = self.max_light_radius + pix + light_level = clamp( + int(self.light - (light_change_per_pixel * pix)), + min_light_level, + 255 - self.darkness.min_light, + ) + colour = (0, 0, 0, light_level) + + pygame.gfxdraw.filled_circle( + self.surface, + self.rect.w // 2, + self.rect.h // 2, + int(self.max_light_radius + pix), + colour, + ) + + # draw full_surface (surface that will be permanently drawn on the FOW) + self.full_surface = pygame.Surface( + (self.radius * 2, self.radius * 2), flags=pygame.SRCALPHA + ) + self.full_surface.fill((0, 0, 0, 255)) + pygame.gfxdraw.filled_circle( + self.full_surface, + self.radius, + self.radius, + self.radius, + (0, 128, 0, 255 - self.darkness.reveal_light), + ) def get_visible_objects(self, objects): visible_objects = [] for obj in objects: visible = True - if hasattr(obj, "velocity"): #ghosts, basically - dx = obj.rect.centerx-self.rect.centerx - dy = obj.rect.centery-self.rect.centery - dist = ( (dx**2) + (dy**2) )**0.5 + if hasattr(obj, "velocity"): # ghosts, basically + dx = obj.rect.centerx - self.rect.centerx + dy = obj.rect.centery - self.rect.centery + dist = ((dx ** 2) + (dy ** 2)) ** 0.5 - #object not within range + # object not within range if dist > self.radius: visible = False @@ -247,99 +272,113 @@ def draw(self, screen, visible_objects): self.draw_surface = self.surface.copy() - #get objects in range + # get objects in range objects_in_range = [] dists = [] for obj in visible_objects: if type(obj) == Player: continue - - dx = obj.rect.centerx-self.rect.centerx - dy = obj.rect.centery-self.rect.centery - dist = ( (dx**2) + (dy**2) )**0.5 - #object within range + dx = obj.rect.centerx - self.rect.centerx + dy = obj.rect.centery - self.rect.centery + dist = ((dx ** 2) + (dy ** 2)) ** 0.5 + + # object within range if dist <= self.radius: objects_in_range.append(obj) dists.append(dist) - #create shadows + # create shadows self_center_pos = pygame.Vector2(self.pos) - self_center_pos.x += self.rect.w/2 - self_center_pos.y += self.rect.h/2 - - for i,obj in enumerate(objects_in_range): + self_center_pos.x += self.rect.w / 2 + self_center_pos.y += self.rect.h / 2 + + for i, obj in enumerate(objects_in_range): center_pos = pygame.Vector2(obj.pos) - center_pos.x += obj.rect.w/2 - center_pos.y += obj.rect.h/2 + center_pos.x += obj.rect.w / 2 + center_pos.y += obj.rect.h / 2 - angle = pygame.Vector2(0,0).angle_to(center_pos-self_center_pos) + angle = pygame.Vector2(0, 0).angle_to(center_pos - self_center_pos) - shadow_start_length = (obj.rect.w+obj.rect.h)/2 + shadow_start_length = (obj.rect.w + obj.rect.h) / 2 dist = dists[i] - #create the vertices of the shadow polygon + # create the vertices of the shadow polygon - #"start" points are closest to the object - #"side" points are the points which are at the edge of the light radius - #"end" points are points that are used to make the shadow complete and prevent gaps from being left - shadow_start_left = pygame.Vector2((-shadow_start_length/2, 0)) - shadow_start_left.rotate_ip(angle+90) + # "start" points are closest to the object + # "side" points are the points which are at the edge of the light radius + # "end" points are points that are used to make the shadow complete and prevent gaps from being left + shadow_start_left = pygame.Vector2((-shadow_start_length / 2, 0)) + shadow_start_left.rotate_ip(angle + 90) shadow_start_left += center_pos - - shadow_side_left = (shadow_start_left-self_center_pos) + shadow_side_left = shadow_start_left - self_center_pos shadow_side_left.scale_to_length(self.radius) shadow_side_left += self_center_pos - shadow_end_left = center_pos-self_center_pos + shadow_end_left = center_pos - self_center_pos shadow_end_left.scale_to_length(self.radius) shadow_end_left += shadow_side_left - shadow_start_right = pygame.Vector2((shadow_start_length/2, 0)) - shadow_start_right.rotate_ip(angle+90) + shadow_start_right = pygame.Vector2((shadow_start_length / 2, 0)) + shadow_start_right.rotate_ip(angle + 90) shadow_start_right += center_pos - shadow_side_right = (shadow_start_right-self_center_pos) + shadow_side_right = shadow_start_right - self_center_pos shadow_side_right.scale_to_length(self.radius) shadow_side_right += self_center_pos - shadow_end_right = center_pos-self_center_pos + shadow_end_right = center_pos - self_center_pos shadow_end_right.scale_to_length(self.radius) shadow_end_right += shadow_side_right - - - pygame.gfxdraw.filled_circle(self.draw_surface, int(center_pos.x-self.pos.x), int(center_pos.y-self.pos.y), int(shadow_start_length//2) , (0,0,0,0)) + pygame.gfxdraw.filled_circle( + self.draw_surface, + int(center_pos.x - self.pos.x), + int(center_pos.y - self.pos.y), + int(shadow_start_length // 2), + (0, 0, 0, 0), + ) ##uncomment these and you can see the points in action ##green - start, blue - side, red - end - #pygame.gfxdraw.filled_circle(screen, int(shadow_start_left.x), int(shadow_start_left.y), 5 , (0,255,0,128)) - #pygame.gfxdraw.filled_circle(screen, int(shadow_start_right.x), int(shadow_start_right.y), 5 , (0,255,0,128)) + # pygame.gfxdraw.filled_circle(screen, int(shadow_start_left.x), int(shadow_start_left.y), 5 , (0,255,0,128)) + # pygame.gfxdraw.filled_circle(screen, int(shadow_start_right.x), int(shadow_start_right.y), 5 , (0,255,0,128)) - #pygame.gfxdraw.filled_circle(screen, int(shadow_side_left.x), int(shadow_side_left.y), 7 , (255,0,0,128)) - #pygame.gfxdraw.filled_circle(screen, int(shadow_side_right.x), int(shadow_side_right.y), 7 , (255,0,0,128)) + # pygame.gfxdraw.filled_circle(screen, int(shadow_side_left.x), int(shadow_side_left.y), 7 , (255,0,0,128)) + # pygame.gfxdraw.filled_circle(screen, int(shadow_side_right.x), int(shadow_side_right.y), 7 , (255,0,0,128)) - #pygame.gfxdraw.filled_circle(screen, int(shadow_end_left.x), int(shadow_end_left.y), 9 , (0,0,255,128)) - #pygame.gfxdraw.filled_circle(screen, int(shadow_end_right.x), int(shadow_end_right.y), 9 , (0,0,255,128)) + # pygame.gfxdraw.filled_circle(screen, int(shadow_end_left.x), int(shadow_end_left.y), 9 , (0,0,255,128)) + # pygame.gfxdraw.filled_circle(screen, int(shadow_end_right.x), int(shadow_end_right.y), 9 , (0,0,255,128)) - #offset so they can be relative to the draw surface + # offset so they can be relative to the draw surface shadow_start_left -= self.pos shadow_start_right -= self.pos shadow_side_left -= self.pos shadow_side_right -= self.pos shadow_end_left -= self.pos shadow_end_right -= self.pos - - - pygame.gfxdraw.filled_polygon(self.draw_surface, [shadow_start_left, shadow_side_left, shadow_end_left, shadow_end_right, shadow_side_right, shadow_start_right], (0,0,0,0) ) - - - self.darkness.surface.blit(self.draw_surface, self.rect, special_flags=pygame.BLEND_RGBA_SUB) + pygame.gfxdraw.filled_polygon( + self.draw_surface, + [ + shadow_start_left, + shadow_side_left, + shadow_end_left, + shadow_end_right, + shadow_side_right, + shadow_start_right, + ], + (0, 0, 0, 0), + ) + + self.darkness.surface.blit( + self.draw_surface, self.rect, special_flags=pygame.BLEND_RGBA_SUB + ) def draw_uncovered(self, screen): - #draw the uncovered parts of the map - self.darkness.shown_surface.blit(self.full_surface, self.rect, special_flags=pygame.BLEND_RGBA_MIN) - + # draw the uncovered parts of the map + self.darkness.shown_surface.blit( + self.full_surface, self.rect, special_flags=pygame.BLEND_RGBA_MIN + ) diff --git a/01-fog-of-war/base/main.py b/01-fog-of-war/base/main.py index 1dfeb31..f6eb3b8 100644 --- a/01-fog-of-war/base/main.py +++ b/01-fog-of-war/base/main.py @@ -63,4 +63,3 @@ def mainloop(): if __name__ == "__main__": wclib.run(mainloop()) - diff --git a/01-fog-of-war/base/objects.py b/01-fog-of-war/base/objects.py index 7836e2e..8fc0638 100644 --- a/01-fog-of-war/base/objects.py +++ b/01-fog-of-war/base/objects.py @@ -100,14 +100,10 @@ def new_goal(self): def logic(self, **kwargs): middle_area = SCREEN.inflate(-30, -30) - while self.rect.collidepoint(self.goal) or not middle_area.collidepoint( - self.goal - ): + while self.rect.collidepoint(self.goal) or not middle_area.collidepoint(self.goal): self.goal = self.new_goal() - self.acceleration = ( - self.goal - self.rect.center - ).normalize() * self.ACCELERATION + self.acceleration = (self.goal - self.rect.center).normalize() * self.ACCELERATION super().logic(**kwargs) @@ -139,4 +135,3 @@ def generate_many(cls, nb=16, max_tries=1000): if not any(obj.rect.colliderect(other.rect) for other in objects): objects.append(obj) return objects - diff --git a/01-fog-of-war/base/utils.py b/01-fog-of-war/base/utils.py index 8cd3288..28d56ff 100644 --- a/01-fog-of-war/base/utils.py +++ b/01-fog-of-war/base/utils.py @@ -38,4 +38,3 @@ def from_polar(rho, theta): v = pygame.Vector2() v.from_polar((rho, theta)) return v - diff --git a/01-fog-of-war/bitcraft/objects.py b/01-fog-of-war/bitcraft/objects.py index a237cd2..baf2e0b 100644 --- a/01-fog-of-war/bitcraft/objects.py +++ b/01-fog-of-war/bitcraft/objects.py @@ -112,14 +112,10 @@ def new_goal(self): def logic(self, **kwargs): middle_area = SCREEN.inflate(-30, -30) - while self.rect.collidepoint(self.goal) or not middle_area.collidepoint( - self.goal - ): + while self.rect.collidepoint(self.goal) or not middle_area.collidepoint(self.goal): self.goal = self.new_goal() - self.acceleration = ( - self.goal - self.rect.center - ).normalize() * self.ACCELERATION + self.acceleration = (self.goal - self.rect.center).normalize() * self.ACCELERATION super().logic(**kwargs) diff --git a/01-fog-of-war/bydariogamer/main.py b/01-fog-of-war/bydariogamer/main.py index 8009618..d8feda7 100644 --- a/01-fog-of-war/bydariogamer/main.py +++ b/01-fog-of-war/bydariogamer/main.py @@ -50,7 +50,7 @@ def mainloop(): light = pygame.Surface((200, 200), pygame.SRCALPHA) light.fill((255, 255, 255, 0)) for i in range(100): - pygame.draw.circle(light, 3*[0]+[i], (100, 100), 100-i) + pygame.draw.circle(light, 3 * [0] + [i], (100, 100), 100 - i) # how slowly we want fog to come back fog_persistance = 4 @@ -76,7 +76,7 @@ def mainloop(): # make ghosts disappear if they are out of player view range for ghost in ghosts: - ghost.sprite.set_alpha((120 - ghost.pos.distance_to(player.pos))*4) + ghost.sprite.set_alpha((120 - ghost.pos.distance_to(player.pos)) * 4) # draw all objects for obj in sorted(all_objects, key=attrgetter("rect.bottom")): @@ -94,7 +94,9 @@ def mainloop(): # blit the fog screen.blit(dark, (0, 0)) if __name__ == "__main__": - pygame.display.set_caption(f"{__author__}'s fog of war - {int(clock.get_fps())}/60FPS") + pygame.display.set_caption( + f"{__author__}'s fog of war - {int(clock.get_fps())}/60FPS" + ) clock.tick(60) diff --git a/01-fog-of-war/bydariogamer/objects.py b/01-fog-of-war/bydariogamer/objects.py index e507e56..cbc1806 100644 --- a/01-fog-of-war/bydariogamer/objects.py +++ b/01-fog-of-war/bydariogamer/objects.py @@ -101,14 +101,10 @@ def new_goal(self): def logic(self, **kwargs): middle_area = SCREEN.inflate(-30, -30) - while self.rect.collidepoint(self.goal) or not middle_area.collidepoint( - self.goal - ): + while self.rect.collidepoint(self.goal) or not middle_area.collidepoint(self.goal): self.goal = self.new_goal() - self.acceleration = ( - self.goal - self.rect.center - ).normalize() * self.ACCELERATION + self.acceleration = (self.goal - self.rect.center).normalize() * self.ACCELERATION super().logic(**kwargs) diff --git a/01-fog-of-war/fkS124/main.py b/01-fog-of-war/fkS124/main.py index ef7cbf6..db5b5dc 100644 --- a/01-fog-of-war/fkS124/main.py +++ b/01-fog-of-war/fkS124/main.py @@ -39,9 +39,7 @@ def draw_gradient(surf, pos, radius, dep_alpha): for i in range(20, 0, -1): - pygame.draw.circle( - surf, (0, 0, 0, dep_alpha - (-i) * 7), pos, int(radius * i / 20) - ) + pygame.draw.circle(surf, (0, 0, 0, dep_alpha - (-i) * 7), pos, int(radius * i / 20)) def mainloop(): @@ -78,9 +76,7 @@ def mainloop(): second_surf.fill((0, 0, 0)) - pygame.draw.circle( - surf, (0, 0, 0, 0), player.pos + pygame.Vector2(20, 20), radius - ) + pygame.draw.circle(surf, (0, 0, 0, 0), player.pos + pygame.Vector2(20, 20), radius) draw_gradient(second_surf, player.pos + pygame.Vector2(20, 20), radius, 100) screen.blit(second_surf, (0, 0)) screen.blit(surf, (0, 0)) diff --git a/01-fog-of-war/fkS124/objects.py b/01-fog-of-war/fkS124/objects.py index e507e56..cbc1806 100644 --- a/01-fog-of-war/fkS124/objects.py +++ b/01-fog-of-war/fkS124/objects.py @@ -101,14 +101,10 @@ def new_goal(self): def logic(self, **kwargs): middle_area = SCREEN.inflate(-30, -30) - while self.rect.collidepoint(self.goal) or not middle_area.collidepoint( - self.goal - ): + while self.rect.collidepoint(self.goal) or not middle_area.collidepoint(self.goal): self.goal = self.new_goal() - self.acceleration = ( - self.goal - self.rect.center - ).normalize() * self.ACCELERATION + self.acceleration = (self.goal - self.rect.center).normalize() * self.ACCELERATION super().logic(**kwargs) diff --git a/01-fog-of-war/fkS124/utils.py b/01-fog-of-war/fkS124/utils.py index 5669d2f..28d56ff 100644 --- a/01-fog-of-war/fkS124/utils.py +++ b/01-fog-of-war/fkS124/utils.py @@ -30,9 +30,7 @@ def clamp(value, mini, maxi): def random_in_rect(rect): """Return a random point uniformly in a rectangle.""" rect = pygame.Rect(rect) - return pygame.Vector2( - uniform(rect.left, rect.right), uniform(rect.top, rect.bottom) - ) + return pygame.Vector2(uniform(rect.left, rect.right), uniform(rect.top, rect.bottom)) def from_polar(rho, theta): diff --git a/01-fog-of-war/ghast/main.py b/01-fog-of-war/ghast/main.py index 0d55430..9168a0e 100644 --- a/01-fog-of-war/ghast/main.py +++ b/01-fog-of-war/ghast/main.py @@ -122,7 +122,7 @@ def get_1d_gaussian_kernel(n_points, std_dev=GAUSSIAN_STD_DEV, _cache={}): raw_values = [] for i in range(n_points): x = ((i + 0.5) - n_points / 2) / (n_points / 2) - y = 1 / math.sqrt(2 * math.pi * std_dev) * math.exp(-0.5 * x**2 / std_dev) + y = 1 / math.sqrt(2 * math.pi * std_dev) * math.exp(-0.5 * x ** 2 / std_dev) raw_values.append(y) total_sum = sum(raw_values) normalized_values = [y / total_sum for y in raw_values] @@ -137,15 +137,14 @@ def blur_array(array, radius: int): # XXX these calls are dreadfully slow on large surfaces # yoinked from https://stackoverflow.com/a/65804973 - array = numpy.apply_along_axis(lambda x: numpy.convolve(x, kernel, mode='same'), 0, array) - array = numpy.apply_along_axis(lambda x: numpy.convolve(x, kernel, mode='same'), 1, array) + array = numpy.apply_along_axis(lambda x: numpy.convolve(x, kernel, mode="same"), 0, array) + array = numpy.apply_along_axis(lambda x: numpy.convolve(x, kernel, mode="same"), 1, array) return array def blur_surface(surface: pygame.Surface, radius: int, dest=None) -> pygame.Surface: - """Applies a Gaussian blur to the surface and returns the result. - """ + """Applies a Gaussian blur to the surface and returns the result.""" array = pygame.surfarray.pixels3d(surface) array = blur_array(array, radius) @@ -158,7 +157,6 @@ def blur_surface(surface: pygame.Surface, radius: int, dest=None) -> pygame.Surf class LightGrid: - def __init__(self, dims): self.surf = pygame.Surface(dims) @@ -252,7 +250,9 @@ def draw_bg(self, surface): def tint_image(base_img, img_key, color, colors_to_tint, _cache={}): int_color = intify(color) - tint_color = floatify([round(int_color[i] / TINT_RESOLUTION) * TINT_RESOLUTION for i in range(3)]) + tint_color = floatify( + [round(int_color[i] / TINT_RESOLUTION) * TINT_RESOLUTION for i in range(3)] + ) key = (tint_color, img_key, colors_to_tint) diff --git a/01-fog-of-war/ghast/objects.py b/01-fog-of-war/ghast/objects.py index 7b785bc..55b8271 100644 --- a/01-fog-of-war/ghast/objects.py +++ b/01-fog-of-war/ghast/objects.py @@ -78,7 +78,6 @@ def logic(self, **kwargs): class Player(Object8Directional): - def logic(self, **kwargs): pressed = pygame.key.get_pressed() direction_x = pressed[pygame.K_RIGHT] - pressed[pygame.K_LEFT] @@ -108,14 +107,10 @@ def new_goal(self): def logic(self, **kwargs): middle_area = SCREEN.inflate(-30, -30) - while self.rect.collidepoint(self.goal) or not middle_area.collidepoint( - self.goal - ): + while self.rect.collidepoint(self.goal) or not middle_area.collidepoint(self.goal): self.goal = self.new_goal() - self.acceleration = ( - self.goal - self.rect.center - ).normalize() * self.ACCELERATION + self.acceleration = (self.goal - self.rect.center).normalize() * self.ACCELERATION super().logic(**kwargs) diff --git a/01-fog-of-war/grimmys/main.py b/01-fog-of-war/grimmys/main.py index cbcaa74..264d444 100644 --- a/01-fog-of-war/grimmys/main.py +++ b/01-fog-of-war/grimmys/main.py @@ -46,19 +46,35 @@ def generate_light(player): light = pygame.Surface((SCREEN_SIZE[0] * 2.2, SCREEN_SIZE[1] * 2.2), pygame.SRCALPHA) for opacity_level in range(0, MAX_DARKNESS_LEVEL, 5): - pygame.draw.circle(light, (0, 0, 0, opacity_level), light.get_rect().center, player.VISION_RADIUS, - int(player.VISION_RADIUS * (1 - opacity_level / MAX_DARKNESS_LEVEL))) - pygame.draw.circle(light, (0, 0, 0, MAX_DARKNESS_LEVEL), light.get_rect().center, light.get_width(), - light.get_width() - player.VISION_RADIUS) + pygame.draw.circle( + light, + (0, 0, 0, opacity_level), + light.get_rect().center, + player.VISION_RADIUS, + int(player.VISION_RADIUS * (1 - opacity_level / MAX_DARKNESS_LEVEL)), + ) + pygame.draw.circle( + light, + (0, 0, 0, MAX_DARKNESS_LEVEL), + light.get_rect().center, + light.get_width(), + light.get_width() - player.VISION_RADIUS, + ) return light def update_unvisited_chunks(player, unvisited_chunks): for chunk in set(unvisited_chunks): - chunk_rect = pygame.rect.Rect(chunk[0] * CHUNK_SIZE[0], chunk[1] * CHUNK_SIZE[1], CHUNK_SIZE[0], - CHUNK_SIZE[1]) - player_distance_with_chunk = math.sqrt((chunk_rect.center[0] - player.rect.center[0]) ** 2 + ( - chunk_rect.center[1] - player.rect.center[1]) ** 2) + chunk_rect = pygame.rect.Rect( + chunk[0] * CHUNK_SIZE[0], + chunk[1] * CHUNK_SIZE[1], + CHUNK_SIZE[0], + CHUNK_SIZE[1], + ) + player_distance_with_chunk = math.sqrt( + (chunk_rect.center[0] - player.rect.center[0]) ** 2 + + (chunk_rect.center[1] - player.rect.center[1]) ** 2 + ) if player_distance_with_chunk < player.VISION_RADIUS + chunk_rect.width // 2: unvisited_chunks.remove(chunk) @@ -67,18 +83,32 @@ def display(screen, objects, player, light, unvisited_chunks): screen.fill(BACKGROUND) for element in sorted(objects, key=attrgetter("rect.bottom")): - if isinstance(element, Ghost) and element.pos.distance_to(player.pos) > player.VISION_RADIUS: + if ( + isinstance(element, Ghost) + and element.pos.distance_to(player.pos) > player.VISION_RADIUS + ): continue # Don't draw ghost if it's too far, just go to the next element element.draw(screen) for chunk_position in unvisited_chunks: # Hide unvisited blocks - screen.fill(pygame.Color("black"), - rect=pygame.rect.Rect(chunk_position[0] * CHUNK_SIZE[0], chunk_position[1] * CHUNK_SIZE[1], - CHUNK_SIZE[0], CHUNK_SIZE[1])) - - screen.blit(light, (player.rect.center[0] - light.get_width() // 2, - player.rect.center[1] - light.get_height() // 2)) + screen.fill( + pygame.Color("black"), + rect=pygame.rect.Rect( + chunk_position[0] * CHUNK_SIZE[0], + chunk_position[1] * CHUNK_SIZE[1], + CHUNK_SIZE[0], + CHUNK_SIZE[1], + ), + ) + + screen.blit( + light, + ( + player.rect.center[0] - light.get_width() // 2, + player.rect.center[1] - light.get_height() // 2, + ), + ) def mainloop(): @@ -95,7 +125,10 @@ def mainloop(): for y in range(NUMBER_VERTICAL_CHUNKS): unvisited_chunks.add((x, y)) - player_chunk = (player.rect.center[0] // CHUNK_SIZE[0], player.rect.center[1] // CHUNK_SIZE[1]) + player_chunk = ( + player.rect.center[0] // CHUNK_SIZE[0], + player.rect.center[1] // CHUNK_SIZE[1], + ) if player_chunk in unvisited_chunks: unvisited_chunks.remove(player_chunk) diff --git a/01-fog-of-war/grimmys/objects.py b/01-fog-of-war/grimmys/objects.py index 7f85676..abaa11a 100644 --- a/01-fog-of-war/grimmys/objects.py +++ b/01-fog-of-war/grimmys/objects.py @@ -103,14 +103,10 @@ def new_goal(self): def logic(self, **kwargs): middle_area = SCREEN.inflate(-30, -30) - while self.rect.collidepoint(self.goal) or not middle_area.collidepoint( - self.goal - ): + while self.rect.collidepoint(self.goal) or not middle_area.collidepoint(self.goal): self.goal = self.new_goal() - self.acceleration = ( - self.goal - self.rect.center - ).normalize() * self.ACCELERATION + self.acceleration = (self.goal - self.rect.center).normalize() * self.ACCELERATION super().logic(**kwargs) diff --git a/01-fog-of-war/polastyn2030/flood_iter.py b/01-fog-of-war/polastyn2030/flood_iter.py index 7477e66..d6cfeac 100644 --- a/01-fog-of-war/polastyn2030/flood_iter.py +++ b/01-fog-of-war/polastyn2030/flood_iter.py @@ -43,12 +43,18 @@ def __init__(self, flood_info: Flood): self.asking_routes: Set[Tuple[int, int]] = set() self.possible_movement = PossibleMovement() self.first_time: bool = True - self.iterator = iterator((self.flood_info.start_x, self.flood_info.start_y), self.possible_movement, - self.flood_info.max_iterations) + self.iterator = iterator( + (self.flood_info.start_x, self.flood_info.start_y), + self.possible_movement, + self.flood_info.max_iterations, + ) def start(self): - self.iterator = iterator((self.flood_info.start_x, self.flood_info.start_y), self.possible_movement, - self.flood_info.max_iterations) + self.iterator = iterator( + (self.flood_info.start_x, self.flood_info.start_y), + self.possible_movement, + self.flood_info.max_iterations, + ) return self def __iter__(self) -> "FloodIter": @@ -57,7 +63,12 @@ def __iter__(self) -> "FloodIter": def __next__(self) -> Tuple[int, int, int, "PossibleMovement"]: if self.first_time: self.first_time = False - return self.flood_info.start_x, self.flood_info.start_y, 0, self.possible_movement + return ( + self.flood_info.start_x, + self.flood_info.start_y, + 0, + self.possible_movement, + ) return next(self.iterator) + (self.possible_movement,) @@ -88,8 +99,10 @@ def get_movement(self, pos: Tuple[int, int]): # noinspection PyMethodMayBeStatic def raw_movement(self, pos: Tuple[int, int]): ret: List[Tuple[int, int]] = [ - (pos[0] - 1, pos[1]), (pos[0], pos[1] - 1), - (pos[0] + 1, pos[1]), (pos[0], pos[1] + 1) + (pos[0] - 1, pos[1]), + (pos[0], pos[1] - 1), + (pos[0] + 1, pos[1]), + (pos[0], pos[1] + 1), ] return ret @@ -108,7 +121,7 @@ def all_false(self): def iterator( - start_pos: Tuple[int, int], is_correct: PossibleMovement, max_depth: int + start_pos: Tuple[int, int], is_correct: PossibleMovement, max_depth: int ) -> Iterator[Tuple[int, int, int]]: routes: Set[Tuple[int, int]] = set() diff --git a/01-fog-of-war/polastyn2030/fog.py b/01-fog-of-war/polastyn2030/fog.py index 4a4dc38..e824c37 100644 --- a/01-fog-of-war/polastyn2030/fog.py +++ b/01-fog-of-war/polastyn2030/fog.py @@ -78,9 +78,15 @@ def get_mask(self, size: tuple[int, int]): if self.lighted_area.get(tile_pos): if self.more_lighted_area.get(tile_pos): by = self.more_lighted_area.get(tile_pos) - mask.blit(self._get_tile(self._smooth_trans+by*5), self.grid_to_pos(tile_pos)) + mask.blit( + self._get_tile(self._smooth_trans + by * 5), + self.grid_to_pos(tile_pos), + ) else: - mask.blit(self._get_tile(self._semi_trans), self.grid_to_pos(tile_pos)) + mask.blit( + self._get_tile(self._semi_trans), + self.grid_to_pos(tile_pos), + ) else: mask.blit(self._get_tile(self._fog_of_war), self.grid_to_pos(tile_pos)) @@ -107,7 +113,7 @@ def logic(self, player): self.discovered.set((x, y), 1) # self.more_lighted_area.set((x, y), step + 1) - for x, y, step, check in Flood(pos[0], pos[1], self.max_steps//2): + for x, y, step, check in Flood(pos[0], pos[1], self.max_steps // 2): check.all_true() self.more_lighted_area.set((x, y), step + 1) diff --git a/01-fog-of-war/polastyn2030/objects.py b/01-fog-of-war/polastyn2030/objects.py index e507e56..cbc1806 100644 --- a/01-fog-of-war/polastyn2030/objects.py +++ b/01-fog-of-war/polastyn2030/objects.py @@ -101,14 +101,10 @@ def new_goal(self): def logic(self, **kwargs): middle_area = SCREEN.inflate(-30, -30) - while self.rect.collidepoint(self.goal) or not middle_area.collidepoint( - self.goal - ): + while self.rect.collidepoint(self.goal) or not middle_area.collidepoint(self.goal): self.goal = self.new_goal() - self.acceleration = ( - self.goal - self.rect.center - ).normalize() * self.ACCELERATION + self.acceleration = (self.goal - self.rect.center).normalize() * self.ACCELERATION super().logic(**kwargs) diff --git a/01-fog-of-war/tank_king/objects.py b/01-fog-of-war/tank_king/objects.py index 9440911..96f06eb 100644 --- a/01-fog-of-war/tank_king/objects.py +++ b/01-fog-of-war/tank_king/objects.py @@ -103,14 +103,10 @@ def new_goal(self): def logic(self, **kwargs): middle_area = SCREEN.inflate(-30, -30) - while self.rect.collidepoint(self.goal) or not middle_area.collidepoint( - self.goal - ): + while self.rect.collidepoint(self.goal) or not middle_area.collidepoint(self.goal): self.goal = self.new_goal() - self.acceleration = ( - self.goal - self.rect.center - ).normalize() * self.ACCELERATION + self.acceleration = (self.goal - self.rect.center).normalize() * self.ACCELERATION super().logic(**kwargs) @@ -175,7 +171,9 @@ def update_glow(self): for i in range(layers): k = i * self.glow k = clamp(k, 0, 255) - pygame.draw.circle(self.surf, (k, k, k), self.surf.get_rect().center, self.radius - i * 3) + pygame.draw.circle( + self.surf, (k, k, k), self.surf.get_rect().center, self.radius - i * 3 + ) class DarkOverlay: @@ -183,7 +181,10 @@ def __init__(self): self.surf = pygame.Surface(SCREEN.size) self.light = LightGlow() self.cell_size = 16 * 2 - self.grid = [[0 * random.random() for _ in range(SCREEN.w // self.cell_size)] for _ in range(SCREEN.h // self.cell_size)] + self.grid = [ + [0 * random.random() for _ in range(SCREEN.w // self.cell_size)] + for _ in range(SCREEN.h // self.cell_size) + ] def draw(self, surf: pygame.Surface, pos): # self.light.update_glow() @@ -203,5 +204,9 @@ def draw(self, surf: pygame.Surface, pos): k -= (11 - self.light.glow) * 2 k = clamp(k, 0, 255) pygame.draw.rect(self.surf, (k, k, k), (col * size, row * size, size, size)) - self.surf.blit(self.light.surf, self.light.surf.get_rect(center=pos), special_flags=pygame.BLEND_RGBA_MAX) + self.surf.blit( + self.light.surf, + self.light.surf.get_rect(center=pos), + special_flags=pygame.BLEND_RGBA_MAX, + ) surf.blit(self.surf, (0, 0), special_flags=pygame.BLEND_RGBA_MULT) diff --git a/01-fog-of-war/zxxv/main.py b/01-fog-of-war/zxxv/main.py index 552c3c3..4147230 100644 --- a/01-fog-of-war/zxxv/main.py +++ b/01-fog-of-war/zxxv/main.py @@ -40,24 +40,28 @@ class Game: - ''' + """ Game object to control updating object initialization, logic updates, and drawing the fog. - ''' + """ + def __init__(self): - self.players = [Player((100, 100), 200, 'arrow'), Player((400, 400), 200, 'wasd')] + self.players = [ + Player((100, 100), 200, "arrow"), + Player((400, 400), 200, "wasd"), + ] self.trees = SolidObject.generate_many(36) self.ghosts = [Ghost() for _ in range(16)] - self.all_objects = self.ghosts + self.trees + self.players + self.all_objects = self.ghosts + self.trees + self.players self.fog_surface = pygame.Surface(wclib.SIZE) self.fog_surface.fill(FOG_COLOR) - + def update(self, screen, events): # Logic for obj in self.all_objects: obj.logic(objects=self.all_objects) - + # Draw screen.fill(BACKGROUND) for object in sorted(self.all_objects, key=attrgetter("rect.bottom")): @@ -69,13 +73,17 @@ def draw_fog(self, screen): k = 100 for i in range(k): for player in self.players: - # for i in range(k): - pygame.draw.circle(self.fog_surface, ((255//k)*i, (255//k)*i, (255//k)*i, 50), player.center_pos, player.radius - i) + # for i in range(k): + pygame.draw.circle( + self.fog_surface, + ((255 // k) * i, (255 // k) * i, (255 // k) * i, 50), + player.center_pos, + player.radius - i, + ) for tree in self.trees: tree.draw(self.fog_surface) screen.blit(self.fog_surface, (0, 0), special_flags=pygame.BLEND_RGBA_MIN) - def mainloop(): # player = Player((100, 100)) diff --git a/01-fog-of-war/zxxv/objects.py b/01-fog-of-war/zxxv/objects.py index be930e6..6c41ab0 100644 --- a/01-fog-of-war/zxxv/objects.py +++ b/01-fog-of-war/zxxv/objects.py @@ -30,10 +30,10 @@ def __str__(self): @property def rect(self): return pygame.Rect(self.pos, self.size) - + @property def center_pos(self): - return self.pos + pygame.Vector2(self.size//2, self.size//2) + return self.pos + pygame.Vector2(self.size // 2, self.size // 2) def draw(self, screen): screen.blit(self.sprite, self.pos) @@ -74,38 +74,37 @@ def logic(self, **kwargs): self.pos += self.velocity self.sprite = self.get_image() - self.pos.x = clamp(self.pos.x, 0, SIZE[0]- self.size[0]) + self.pos.x = clamp(self.pos.x, 0, SIZE[0] - self.size[0]) self.pos.y = clamp(self.pos.y, 0, SIZE[1] - self.size[1]) - class Player(Object8Directional): - def __init__(self, pos, radius: float, keymap='arrow'): + def __init__(self, pos, radius: float, keymap="arrow"): self.radius = radius - if keymap == 'arrow': + if keymap == "arrow": self.keys = { - 'up': pygame.K_UP, - 'left': pygame.K_LEFT, - 'down': pygame.K_DOWN, - 'right': pygame.K_RIGHT + "up": pygame.K_UP, + "left": pygame.K_LEFT, + "down": pygame.K_DOWN, + "right": pygame.K_RIGHT, } else: self.keys = { - 'up': pygame.K_w, - 'left': pygame.K_a, - 'down': pygame.K_s, - 'right': pygame.K_d + "up": pygame.K_w, + "left": pygame.K_a, + "down": pygame.K_s, + "right": pygame.K_d, } super().__init__(pos) def logic(self, **kwargs): pressed = pygame.key.get_pressed() - direction_x = pressed[self.keys['right']] - pressed[self.keys['left']] - direction_y = pressed[self.keys['down']] - pressed[self.keys['up']] + direction_x = pressed[self.keys["right"]] - pressed[self.keys["left"]] + direction_y = pressed[self.keys["down"]] - pressed[self.keys["up"]] self.acceleration = pygame.Vector2(direction_x, direction_y) * self.ACCELERATION super().logic(**kwargs) - + class Ghost(Object8Directional): SHEET = "pink_ghost" @@ -124,14 +123,10 @@ def new_goal(self): def logic(self, **kwargs): middle_area = SCREEN.inflate(-30, -30) - while self.rect.collidepoint(self.goal) or not middle_area.collidepoint( - self.goal - ): + while self.rect.collidepoint(self.goal) or not middle_area.collidepoint(self.goal): self.goal = self.new_goal() - self.acceleration = ( - self.goal - self.rect.center - ).normalize() * self.ACCELERATION + self.acceleration = (self.goal - self.rect.center).normalize() * self.ACCELERATION super().logic(**kwargs) diff --git a/wclib/showcase.py b/wclib/showcase.py index 4f87535..1fba800 100644 --- a/wclib/showcase.py +++ b/wclib/showcase.py @@ -130,9 +130,7 @@ class ChallengeSelectState(MenuState): BG_COLOR = 0x151515 def __init__(self, app: "App"): - super().__init__( - app, "Weekly Challenges", [[c, None] for c in get_challenges()] - ) + super().__init__(app, "Weekly Challenges", [[c, None] for c in get_challenges()]) def button_click(self, data): challenge, none = data @@ -229,9 +227,7 @@ def handle_events(self, events): except Exception: # Or BaseException ? self.crashed = True t = text("Crashed", "red", 30) - self.virtual_screen.blit( - t, t.get_rect(center=self.virtual_screen.get_rect().center) - ) + self.virtual_screen.blit(t, t.get_rect(center=self.virtual_screen.get_rect().center)) def draw(self, screen: pygame.Surface): if self.rect.size != self.virtual_screen.get_size(): From 75845658b11b4513ae5e10606d33ccce87ea8199 Mon Sep 17 00:00:00 2001 From: ddorn Date: Mon, 11 Oct 2021 14:48:14 +0200 Subject: [PATCH 38/80] New version of the showcase + allow external modules (#17) * fix menu always selecting last * Prompt to install modules * wclib: better exception handling --- 01-fog-of-war/base/requirements.txt | 8 ++ 01-fog-of-war/cozyfractal/fog.py | 0 wclib/core.py | 46 ++++++++ wclib/showcase.py | 164 ++++++++++++++++++++++++++-- 4 files changed, 208 insertions(+), 10 deletions(-) create mode 100644 01-fog-of-war/base/requirements.txt create mode 100644 01-fog-of-war/cozyfractal/fog.py diff --git a/01-fog-of-war/base/requirements.txt b/01-fog-of-war/base/requirements.txt new file mode 100644 index 0000000..2a1e6fe --- /dev/null +++ b/01-fog-of-war/base/requirements.txt @@ -0,0 +1,8 @@ +# Add here the extra requirements for your project. +# You cannot specify version numbers (yet). +# Lines starting with a "#" are ignored. +# DO NOT list pygame here. + +# Please try to limit you dependencies as much as you can + +# numpy diff --git a/01-fog-of-war/cozyfractal/fog.py b/01-fog-of-war/cozyfractal/fog.py new file mode 100644 index 0000000..e69de29 diff --git a/wclib/core.py b/wclib/core.py index a10e9f0..f46eec7 100644 --- a/wclib/core.py +++ b/wclib/core.py @@ -1,5 +1,7 @@ import importlib import json +import subprocess +import sys from collections import namedtuple from functools import lru_cache from time import time @@ -35,6 +37,50 @@ def run( print(f"App run for {end - start:02}s at {frames / (end - start)} FPS.") +def get_requirements(challenge: str, entry: str) -> List[str]: + req_path = ROOT_DIR / challenge / entry / "requirements.txt" + + if not req_path.exists(): + return [] + + # Can't use the := operator as we want python 3.6 compat. + requirements = [] + for line in req_path.read_text().splitlines(): + line = line.strip() + if line and not line.startswith("#"): + # Common possible mistakes + assert not " " in line, f"Space in the requirements of {challenge}/{entry}." + assert ( + not "." in line + ), f"Package with '.' in the requirements of {challenge}/{entry}." + requirements.append(line) + return requirements + + +def get_missing_requirements(challenge: str, entry: str) -> List[str]: + missing = [] + for req in get_requirements(challenge, entry): + try: + importlib.import_module(req) + except ModuleNotFoundError: + missing.append(req) + return missing + + +def install_missing_requirements(challenge: str, entry: str) -> int: + missing = get_missing_requirements(challenge, entry) + command = [ + sys.executable, + "-m", + "pip", + "install", + *missing, + ] + print("Running:", command) + subprocess.check_call(command) + importlib.invalidate_caches() + + def get_mainloop(challenge: str, entry: str) -> MainLoop: """Utility to import a mainloop.""" diff --git a/wclib/showcase.py b/wclib/showcase.py index 1fba800..eb181af 100644 --- a/wclib/showcase.py +++ b/wclib/showcase.py @@ -2,7 +2,9 @@ import json import sys from functools import lru_cache, partial +import traceback from pathlib import Path +from threading import Thread from typing import Callable, List import pygame @@ -13,6 +15,8 @@ get_challenges, get_entries, get_challenge_data, + get_missing_requirements, + install_missing_requirements, ) TITLE = "title" @@ -214,25 +218,165 @@ def __init__(self, challenge, entry, rect=(0, 0, *SIZE)): self.entry = entry self.rect = pygame.Rect(rect) self.virtual_screen = pygame.Surface(SIZE) + self.missing_requirements = get_missing_requirements(challenge, entry) - self.mainloop = get_mainloop(challenge, entry) - next(self.mainloop) - self.mainloop.send((self.virtual_screen, [])) + self.mainloop = self.load_mainloop() + self.mainloop_next() - self.crashed = False - - def handle_events(self, events): + def mainloop_next(self, events=(), _first=False): try: + events = list(self.modify_events(events)) + if _first: + next(self.mainloop) self.mainloop.send((self.virtual_screen, events)) - except Exception: # Or BaseException ? - self.crashed = True - t = text("Crashed", "red", 30) - self.virtual_screen.blit(t, t.get_rect(center=self.virtual_screen.get_rect().center)) + except StopIteration: + pass + except TypeError as e: + # Yuck! + if e.args == ("can't send non-None value to a just-started generator",): + return self.mainloop_next(events, True) + else: + # Double yuck! + print("Error:", e) + print(traceback.print_exc()) + self.mainloop = self.crashed_mainloop(e) + except Exception as e: # Or BaseException ? + print("Error:", e) + print(traceback.print_exc()) + self.mainloop = self.crashed_mainloop(e) + + def load_mainloop(self): + if self.missing_requirements: + loop = self.install_mainloop() + else: + try: + loop = get_mainloop(self.challenge, self.entry) + except Exception as e: + loop = self.crashed_mainloop(e) + + return loop + + def handle_events(self, events): + if not self.mainloop: + self.mainloop = self.load_mainloop() + + self.mainloop_next(events) + + def modify_mouse_pos(self, pos): + return ( + (pos[0] - self.rect.x) * self.virtual_screen.get_width() // self.rect.w, + (pos[1] - self.rect.y) * self.virtual_screen.get_height() // self.rect.h, + ) + + def modify_mouse_rel(self, pos): + return ( + (pos[0]) * self.virtual_screen.get_width() // self.rect.width, + (pos[1]) * self.virtual_screen.get_height() // self.rect.height, + ) + + def modify_events(self, events): + for event in events: + # We don't modify events as they may be used by other EmbeddedApps. + if event.type in (pygame.MOUSEBUTTONDOWN, pygame.MOUSEBUTTONUP): + yield pygame.event.Event( + event.type, + button=event.button, + pos=self.modify_mouse_pos(event.pos), + ) + elif event.type == pygame.MOUSEMOTION: + yield pygame.event.Event( + event.type, + buttons=event.buttons, + pos=self.modify_mouse_pos(event.pos), + rel=self.modify_mouse_rel(event.rel), + ) + else: + yield event def draw(self, screen: pygame.Surface): + if not self.mainloop: + return + if self.rect.size != self.virtual_screen.get_size(): pygame.transform.smoothscale( self.virtual_screen, self.rect.size, screen.subsurface(self.rect) ) else: screen.blit(self.virtual_screen, self.rect) + + def install_mainloop(self): + w, h = SIZE + install_rect = pygame.Rect(0, 0, 600, 100) + install_rect.midbottom = (w / 2, h - 100) + mouse = (0, 0) + installing = False + install_thread = None + timer = 0 + clock = pygame.time.Clock() + + while True: + timer += 1 + clock.tick(60) + screen, events = yield + + for event in events: + if event.type == pygame.MOUSEMOTION: + mouse = event.pos + if ( + event.type == pygame.MOUSEBUTTONDOWN + and install_rect.collidepoint(mouse) + and not installing + ): + installing = True + install_thread = Thread( + target=install_missing_requirements, + args=(self.challenge, self.entry), + ) + install_thread.start() + + screen.fill("#272822") + t = text("Missing requirements:", "white", 90) + r = screen.blit(t, t.get_rect(midtop=(w / 2, 50))) + + for req in self.missing_requirements: + t = text(req, "white", 72) + r.top += 30 + r = screen.blit(t, t.get_rect(midtop=r.midbottom)) + + # install button + if install_rect.collidepoint(mouse): + color = "#6B9BAC" + else: + color = "#4B7B8C" + pygame.draw.rect(screen, color, install_rect, border_radius=10) + # Button text + txt = ( + "Install via pip" + if not installing + else "Installing" + "." * (timer // 30 % 4) + ) + t = text(txt, "white", 80) + screen.blit(t, t.get_rect(center=install_rect.center)) + + # installation finished! + if installing and not install_thread.is_alive(): + self.mainloop = None + self.missing_requirements = get_missing_requirements( + self.challenge, self.entry + ) + print("Still missing after install:", self.missing_requirements) + return + + def crashed_mainloop(self, error): + print(error) + print(traceback.print_exc()) + screen, events = yield + + t = text(f"Crashed: {error}", "red", 30) + r = screen.blit(t, t.get_rect(center=screen.get_rect().center)) + t = text("Check the console for details.", "red", 30) + screen.blit(t, t.get_rect(midtop=r.midbottom)) + + while True: + # Do nothing. + screen, events = yield From fe0c084a9ae6b2ed4b2120c0d358afa5b35c3447 Mon Sep 17 00:00:00 2001 From: ddorn Date: Mon, 11 Oct 2021 15:35:27 +0200 Subject: [PATCH 39/80] make all entries work together --- 01-fog-of-war/Abalue/objects.py | 2 +- 01-fog-of-war/MegaIng/main.py | 2 +- 01-fog-of-war/andenixa/main.py | 8 ++-- 01-fog-of-war/arosso17/main.py | 2 +- 01-fog-of-war/arosso17/requirements.txt | 8 ++++ 01-fog-of-war/arosso17/test_stuff.py | 2 +- 01-fog-of-war/ghast/requirements.txt | 8 ++++ wclib/core.py | 17 ++++++-- wclib/showcase.py | 53 ++++++++++--------------- 9 files changed, 59 insertions(+), 43 deletions(-) create mode 100644 01-fog-of-war/arosso17/requirements.txt create mode 100644 01-fog-of-war/ghast/requirements.txt diff --git a/01-fog-of-war/Abalue/objects.py b/01-fog-of-war/Abalue/objects.py index 50c966f..cfebc38 100644 --- a/01-fog-of-war/Abalue/objects.py +++ b/01-fog-of-war/Abalue/objects.py @@ -214,7 +214,7 @@ def handle_event(self, event): self.selected = 0 def logic(self, *args, **kwargs): - print(self.rect.topleft) + # print(self.rect.topleft) # open and close menu if self.open and self.rect.right < self.rect.w: self.rect.x += self.OPEN_VEL diff --git a/01-fog-of-war/MegaIng/main.py b/01-fog-of-war/MegaIng/main.py index 670a519..c53a3a1 100644 --- a/01-fog-of-war/MegaIng/main.py +++ b/01-fog-of-war/MegaIng/main.py @@ -1,7 +1,6 @@ import sys from pathlib import Path -from MegaIng.utils import interpolate try: import wclib @@ -34,6 +33,7 @@ # To import the modules in yourname/, you need to use relative imports, # otherwise your project will not be compatible with the showcase. from .objects import Ghost, Player, SolidObject +from .utils import interpolate BACKGROUND = (0x66, 0x85, 0x6C) diff --git a/01-fog-of-war/andenixa/main.py b/01-fog-of-war/andenixa/main.py index cd244e7..c557c13 100644 --- a/01-fog-of-war/andenixa/main.py +++ b/01-fog-of-war/andenixa/main.py @@ -4,6 +4,7 @@ import sys from pathlib import Path + try: import wclib except ImportError: @@ -36,6 +37,7 @@ # To import the modules in yourname/, you need to use relative imports, # otherwise your project will not be compatible with the showcase. from .objects import Ghost, Player, SolidObject +from .utils import SUBMISSION_DIR BACKGROUND = 0x66856C @@ -114,7 +116,7 @@ def __init__(self, size, fog_color, noise_str=7, light_frames=5, fps=15): self._delay = 1000 // fps self._lights = [] - print("Generating lights bulbs ..") + # print("Generating lights bulbs ..") for _ in range(light_frames): s = self._light_sphere.copy() self._draw_spot(s) @@ -223,7 +225,7 @@ def measure_angle_vec(vec2, vec1): return (vec2 - vec1).as_polar()[1] -def load_tiles(fn, size, colorkey=None, scale=None, verbose=True): +def load_tiles(fn, size, colorkey=None, scale=None, verbose=False): """load all sprites of size in image file fn return: subsurfaces of all sprites """ @@ -267,7 +269,7 @@ def mainloop(): tile_scale = None if FOG_TILE_WIDTH != 32: tile_scale = FOG_TILE_WIDTH / 32 - fog_tiles = load_tiles("fog_of_war.png", (32, 32), scale=tile_scale) + fog_tiles = load_tiles(SUBMISSION_DIR / "fog_of_war.png", (32, 32), scale=tile_scale) t_size = fog_tiles[0].get_size() fog_t_graph = Grid(*FOG_GRID_SIZE, t_size, tset_flag_to_graph[TILE_POS_NONE]) fog_t_flags = Grid(*FOG_GRID_SIZE, t_size, TILE_POS_NONE) diff --git a/01-fog-of-war/arosso17/main.py b/01-fog-of-war/arosso17/main.py index 8f9312e..0a20091 100644 --- a/01-fog-of-war/arosso17/main.py +++ b/01-fog-of-war/arosso17/main.py @@ -182,7 +182,7 @@ def mainloop(): 150, ) clock.tick(FPS) - print(clock.get_fps()) + # print(clock.get_fps()) if __name__ == "__main__": diff --git a/01-fog-of-war/arosso17/requirements.txt b/01-fog-of-war/arosso17/requirements.txt new file mode 100644 index 0000000..94f9b23 --- /dev/null +++ b/01-fog-of-war/arosso17/requirements.txt @@ -0,0 +1,8 @@ +# Add here the extra requirements for your project. +# You cannot specify version numbers (yet). +# Lines starting with a "#" are ignored. +# DO NOT list pygame here. + +# Please try to limit you dependencies as much as you can + +numpy diff --git a/01-fog-of-war/arosso17/test_stuff.py b/01-fog-of-war/arosso17/test_stuff.py index 467eb7d..e944158 100644 --- a/01-fog-of-war/arosso17/test_stuff.py +++ b/01-fog-of-war/arosso17/test_stuff.py @@ -181,7 +181,7 @@ def mainloop(): 150, ) clock.tick(FPS) - print(clock.get_fps()) + # print(clock.get_fps()) if __name__ == "__main__": diff --git a/01-fog-of-war/ghast/requirements.txt b/01-fog-of-war/ghast/requirements.txt new file mode 100644 index 0000000..94f9b23 --- /dev/null +++ b/01-fog-of-war/ghast/requirements.txt @@ -0,0 +1,8 @@ +# Add here the extra requirements for your project. +# You cannot specify version numbers (yet). +# Lines starting with a "#" are ignored. +# DO NOT list pygame here. + +# Please try to limit you dependencies as much as you can + +numpy diff --git a/wclib/core.py b/wclib/core.py index f46eec7..61481f3 100644 --- a/wclib/core.py +++ b/wclib/core.py @@ -13,6 +13,19 @@ MainLoop = Generator[None, Tuple[pygame.Surface, List[pygame.event.Event]], None] +__all__ = [ + "MainLoop", + "run", + "get_missing_requirements", + "get_requirements", + "install_missing_requirements", + "get_mainloop", + "get_challenges", + "get_entries", + "ChallengeData", + "get_challenge_data", +] + def run( mainloop: MainLoop, @@ -50,9 +63,7 @@ def get_requirements(challenge: str, entry: str) -> List[str]: if line and not line.startswith("#"): # Common possible mistakes assert not " " in line, f"Space in the requirements of {challenge}/{entry}." - assert ( - not "." in line - ), f"Package with '.' in the requirements of {challenge}/{entry}." + assert not "." in line, f"Package with '.' in the requirements of {challenge}/{entry}." requirements.append(line) return requirements diff --git a/wclib/showcase.py b/wclib/showcase.py index eb181af..a9c9061 100644 --- a/wclib/showcase.py +++ b/wclib/showcase.py @@ -4,22 +4,16 @@ from functools import lru_cache, partial import traceback from pathlib import Path +from random import shuffle from threading import Thread from typing import Callable, List import pygame from .constants import ROOT_DIR, SIZE -from .core import ( - get_mainloop, - get_challenges, - get_entries, - get_challenge_data, - get_missing_requirements, - install_missing_requirements, -) - -TITLE = "title" +from .core import * + +TITLE_FONT = "title" ACCENT = "#48929B" @@ -67,7 +61,7 @@ class App: def __init__(self, initial_state: Callable[["App"], State]): pygame.init() self.running = True - self.screen = pygame.display.set_mode(SIZE) + self.screen = pygame.display.set_mode(SIZE, pygame.SCALED) self.states = [initial_state(self)] pygame.display.set_caption(self.TITLE) @@ -107,7 +101,7 @@ def button_position(i): return ( padding + (i % cols) * col_width + (col_width - Button.TOTAL_SIZE[0]) / 2, - 120 + i // cols * (Button.TOTAL_SIZE[1] + padding), + 100 + i // cols * (Button.TOTAL_SIZE[1] + padding), ) def button_click(self, data): @@ -117,7 +111,7 @@ def draw(self, screen: pygame.Surface): super().draw(screen) screen.fill(ACCENT, (0, 0, SIZE[0], 4)) - t = text(self.title, 0xEEEEEE00, 82, TITLE) + t = text(self.title, 0xEEEEEE00, 82, TITLE_FONT) screen.blit(t, t.get_rect(midtop=(SIZE[0] / 2, 20))) for button in self.buttons: @@ -144,6 +138,7 @@ def button_click(self, data): class EntrySelectState(MenuState): def __init__(self, app: "App", challenge): buttons = [(challenge, entry) for entry in get_entries(challenge)] + shuffle(buttons) super().__init__(app, get_challenge_data(challenge).name, buttons) self.challenge = challenge @@ -171,7 +166,7 @@ def draw(self, screen): class Button: NAME_HEIGHT = 32 - SIZE = (SIZE[0] // 5, SIZE[1] // 5) + SIZE = (SIZE[0] // 6, SIZE[1] // 6) TOTAL_SIZE = (SIZE[0], SIZE[1] + NAME_HEIGHT) def __init__(self, challenge, entry, callback, position): @@ -208,7 +203,7 @@ def handle_events(self, events): self.app.handle_events(events) for event in events: - if event.type == pygame.MOUSEBUTTONDOWN: + if event.type == pygame.MOUSEBUTTONDOWN and event.button == 1: self.callback() @@ -236,13 +231,8 @@ def mainloop_next(self, events=(), _first=False): if e.args == ("can't send non-None value to a just-started generator",): return self.mainloop_next(events, True) else: - # Double yuck! - print("Error:", e) - print(traceback.print_exc()) self.mainloop = self.crashed_mainloop(e) except Exception as e: # Or BaseException ? - print("Error:", e) - print(traceback.print_exc()) self.mainloop = self.crashed_mainloop(e) def load_mainloop(self): @@ -298,9 +288,12 @@ def draw(self, screen: pygame.Surface): return if self.rect.size != self.virtual_screen.get_size(): - pygame.transform.smoothscale( - self.virtual_screen, self.rect.size, screen.subsurface(self.rect) - ) + try: + pygame.transform.smoothscale( + self.virtual_screen, self.rect.size, screen.subsurface(self.rect) + ) + except ValueError: + pass else: screen.blit(self.virtual_screen, self.rect) @@ -350,26 +343,20 @@ def install_mainloop(self): color = "#4B7B8C" pygame.draw.rect(screen, color, install_rect, border_radius=10) # Button text - txt = ( - "Install via pip" - if not installing - else "Installing" + "." * (timer // 30 % 4) - ) + txt = "Install via pip" if not installing else "Installing" + "." * (timer // 30 % 4) t = text(txt, "white", 80) screen.blit(t, t.get_rect(center=install_rect.center)) # installation finished! if installing and not install_thread.is_alive(): self.mainloop = None - self.missing_requirements = get_missing_requirements( - self.challenge, self.entry - ) + self.missing_requirements = get_missing_requirements(self.challenge, self.entry) print("Still missing after install:", self.missing_requirements) return def crashed_mainloop(self, error): - print(error) - print(traceback.print_exc()) + print("Error:", error, file=sys.stderr) + traceback.print_tb(error.__traceback__, file=sys.stderr) screen, events = yield t = text(f"Crashed: {error}", "red", 30) From a20deaf6ec329dbde56a62a89cba4a1b74634ada Mon Sep 17 00:00:00 2001 From: ddorn Date: Mon, 11 Oct 2021 15:43:29 +0200 Subject: [PATCH 40/80] CozyFractal entry commit 5f32ce6db77af4bbb4e5fbf51601adfa3b800a67 Author: ddorn Date: Mon Oct 11 15:39:15 2021 +0200 reformat commit 4629181afd8bb5dada8161268f98f52906554ea7 Author: ddorn Date: Thu Oct 7 10:10:27 2021 +0200 wclib: better exception handling commit 45bb395d2fdb6f7ae2f4d86faac6b393a92791ad Author: ddorn Date: Wed Oct 6 20:24:37 2021 +0200 use numpy faster memory simulation commit 48ff1cca3c59a319f2244de06a6a17b8015f17c7 Author: ddorn Date: Wed Oct 6 15:36:06 2021 +0200 darker memory commit c3bbcc687f94796dce6e321909cbe793c74ac333 Author: ddorn Date: Wed Oct 6 15:35:16 2021 +0200 Prompt to install modules commit 5103edd07bac41d75e826ae0ea6d4d05c221ad0b Author: ddorn Date: Sun Oct 3 22:59:33 2021 +0200 working ! --- 01-fog-of-war/cozyfractal/main.py | 68 +++++ 01-fog-of-war/cozyfractal/objects.py | 274 +++++++++++++++++++++ 01-fog-of-war/cozyfractal/requirements.txt | 8 + 01-fog-of-war/cozyfractal/utils.py | 70 ++++++ 4 files changed, 420 insertions(+) create mode 100644 01-fog-of-war/cozyfractal/main.py create mode 100644 01-fog-of-war/cozyfractal/objects.py create mode 100644 01-fog-of-war/cozyfractal/requirements.txt create mode 100644 01-fog-of-war/cozyfractal/utils.py diff --git a/01-fog-of-war/cozyfractal/main.py b/01-fog-of-war/cozyfractal/main.py new file mode 100644 index 0000000..6ede85d --- /dev/null +++ b/01-fog-of-war/cozyfractal/main.py @@ -0,0 +1,68 @@ +import sys +from pathlib import Path + +try: + import wclib +except ImportError: + # wclib may not be in the path because of the architecture + # of all the challenges and the fact that there are many + # way to run them (through the showcase, or on their own) + + ROOT_FOLDER = Path(__file__).parent.parent.parent + sys.path.append(str(ROOT_FOLDER)) + import wclib # It should work now + +# This line tells python how to handle the relative imports +# when you run this file directly. +__package__ = "01-fog-of-war." + Path(__file__).parent.name + +# ---- Recommended: don't modify anything above this line ---- # + +# Metadata about your submission +__author__ = "CozyFractal#6978" +__achievements__ = [ # Uncomment the ones you've done + # "Casual", + # "Ambitious", + # "Adventurous", +] + + +from operator import attrgetter +import pygame + +from wclib import SIZE + +# To import the modules in yourname/, you need to use relative imports, +# otherwise your project will not be compatible with the showcase. +from .objects import Ghost, Player, SolidObject, Shadow + +BACKGROUND = 0x66856C + + +def mainloop(): + player = Player((100, 100)) + trees = SolidObject.generate_many(36) + ghosts = [Ghost() for _ in range(16)] + shadow = Shadow(SIZE) + + all_objects = trees + [player] + ghosts + + clock = pygame.time.Clock() + while True: + screen, events = yield + for event in events: + if event.type == pygame.QUIT: + return + + for obj in all_objects: + obj.logic(objects=all_objects) + + shadow.logic(player, all_objects) + + screen.fill(BACKGROUND) + + shadow.draw(screen, player, all_objects) + + +if __name__ == "__main__": + wclib.run(mainloop()) diff --git a/01-fog-of-war/cozyfractal/objects.py b/01-fog-of-war/cozyfractal/objects.py new file mode 100644 index 0000000..65bae77 --- /dev/null +++ b/01-fog-of-war/cozyfractal/objects.py @@ -0,0 +1,274 @@ +""" +This file provides objects that can be used to make up +a basic playground for the challenges. + +This code is provided so that you can focus on implementing +a fog of war, without needed +Feel free to modify everything in this file to your liking. +""" +from operator import attrgetter +from random import choice, gauss +from typing import List + +import numpy as np + +from wclib import SIZE +from .utils import * + +SCREEN = pygame.Rect(0, 0, *SIZE) + + +def np_blit_rect(dest, surf, pos): + """Return the 8 coordinates to blit np array on each other, like pygame.blit, with bound checking.""" + w = dest.shape[0] + h = dest.shape[1] + + sw = surf.shape[0] + sh = surf.shape[1] + + # blit start position (on dest) + x, y = map(int, pos) + # blit end pos (on dest) + bex, bey = x + sw, y + sh + + # if the beginning of the surf is outside dest (more on the top/left) + # we take only what's inside + sx = sy = 0 + if x < 0: + sx = -x + x = 0 + if y < 0: + sy = -y + y = 0 + + # and we cut also what's on the other side + if w < bex: + bex = w + if h < bey: + bey = h + + # and finally update the end position of surf that will be blit + ex = sx + (bex - x) + ey = sy + (bey - y) + + return x, bex, y, bey, sx, ex, sy, ey + + +def np_blit(dest, surf, pos): + """Blit an surf on dest like pygame.blit.""" + x1, x2, y1, y2, a1, a2, b1, b2 = np_blit_rect(dest, surf, pos) + dest[x1:x2, y1:y2] = surf[a1:a2, b1:b2] + + +class Shadow: + + # All those values could be arguments of __init__, + # but since I know I'll only have on instance at any time + # they are more visible here. + + VISION = 150 # how many pixels we see in each direction + GRADIENT_SIZE = VISION # pixels + PITCH_BLACK = 255 + DARK = 180 # out of 255 + MEMORY_DECAY = 8 + + def __init__(self, size): + self.timer = 0 + self.size = pygame.Vector2(size) + self.memory = np.full(size, self.PITCH_BLACK, dtype=np.uint8) + self.memory_surf = pygame.Surface(size, pygame.SRCALPHA) + + self.sight = self.compute_sight_surf(self.VISION, False) + self.sight_inverted = 255 - self.sight + self.sight_surf_inverted = self.compute_sight_surf(self.VISION, True) + + def sight_rect(self, center): + r = pygame.Rect(0, 0, *self.sight.shape) + r.center = center + return r + + def logic(self, player, objects): + self.timer += 1 + player_center = player.rect.center + + np.clip(self.memory, self.DARK, 254, out=self.memory) + + if self.timer % self.MEMORY_DECAY == 0: + self.memory += 1 + + # Blit the light circle on the memory + x1, x2, y1, y2, a1, a2, b1, b2 = np_blit_rect( + self.memory, self.sight, self.sight_rect(player_center).topleft + ) + self.memory[x1:x2, y1:y2] = np.minimum( + self.memory[x1:x2, y1:y2], + self.sight[a1:a2, b1:b2], + ) + + pygame.surfarray.pixels_alpha(self.memory_surf)[:] = self.memory + + def draw(self, screen: pygame.Surface, player, objects: List["Object"]): + player_center = pygame.Vector2(int(player.rect.centerx), int(player.rect.centery)) + vision_rect = self.sight_rect(player_center) + + # Draw screen with only static objects: + for obj in sorted(objects, key=attrgetter("rect.bottom")): + if obj.STATIC: + obj.draw(screen) + + # Draw screen with moving objects too + # with_moving = pygame.Surface(screen.get_size(), pygame.SRCALPHA) + with_moving = pygame.Surface(vision_rect.size, pygame.SRCALPHA) + for obj in sorted(objects, key=attrgetter("rect.bottom")): + if obj.rect.colliderect(vision_rect): + with_moving.blit(obj.sprite, obj.pos - vision_rect.topleft) + + # Erase just outside the circle + pygame.surfarray.pixels_alpha(with_moving)[:] = self.sight_inverted + with_moving.set_colorkey(0) + screen.blit(with_moving, vision_rect) + + screen.blit(self.memory_surf, (0, 0)) + + def compute_sight_surf(self, radius, inverted): + # Draw a transparent gradient + s = pygame.Surface((radius * 2 + 1, radius * 2 + 1), pygame.SRCALPHA) + s.fill((0, 0, 0, self.PITCH_BLACK)) + start = radius - self.GRADIENT_SIZE + end = radius + for r in range(end, start - 1, -1): + alpha = chrange(r, (start, end), (0, 255), 2) + g = 255 - alpha + if inverted: + color = (255, 255, 255, 255 - alpha) + else: + color = (0, 0, 0, alpha) + pygame.draw.circle(s, color, (radius, radius), r) + return pygame.surfarray.pixels_alpha(s) + + +class Object: + """The base class for all objects of the game.""" + + STATIC = True + + def __init__(self, pos, sprite: pygame.Surface): + self.pos = pygame.Vector2(pos) + self.size = pygame.Vector2(sprite.get_size()) + self.sprite = sprite + + def __str__(self): + return f"<{self.__class__.__name__}(pos={self.pos}, size={self.size})>" + + @property + def rect(self): + return pygame.Rect(self.pos, self.size) + + def draw(self, screen): + screen.blit(self.sprite, self.pos) + + def logic(self, **kwargs): + pass + + +class Object8Directional(Object): + STATIC = False + SCALE = 3 + SIZE = 16 + SHEET = "blue_ghost" + + ACCELERATION = 0.5 + DAMPING = 0.85 + + # Asymptotic velocity will be solution of + # x = x * DAMPING + ACCELERATION + # That is, + # x = ACCELERATION / (1 - DAMPING) + + def __init__(self, pos): + self.velocity = pygame.Vector2() + self.acceleration = pygame.Vector2() + + super().__init__(pos, self.get_image()) + + def get_image(self): + angle = self.velocity.as_polar()[1] + idx = int((-angle + 90 + 45 / 2) % 360 / 360 * 8) + sheet = load_image(self.SHEET, self.SCALE) + unit = self.SIZE * self.SCALE + return sheet.subsurface(idx * unit, 0, unit, unit) + + def logic(self, **kwargs): + self.velocity *= self.DAMPING + self.velocity += self.acceleration + self.pos += self.velocity + self.sprite = self.get_image() + + self.pos.x = clamp(self.pos.x, 0, SIZE[0]) + self.pos.y = clamp(self.pos.y, 0, SIZE[1]) + + +class Player(Object8Directional): + ACCELERATION = 0.9 + + def logic(self, **kwargs): + pressed = pygame.key.get_pressed() + direction_x = pressed[pygame.K_RIGHT] - pressed[pygame.K_LEFT] + direction_y = pressed[pygame.K_DOWN] - pressed[pygame.K_UP] + + self.acceleration = pygame.Vector2(direction_x, direction_y) * self.ACCELERATION + super().logic(**kwargs) + + +class Ghost(Object8Directional): + SHEET = "pink_ghost" + ACCELERATION = 0.2 + DAMPING = 0.9 + + def __init__(self, pos=None): + if pos is None: + pos = random_in_rect(SCREEN) + super().__init__(pos) + self.goal = self.new_goal() + + def new_goal(self): + direction = from_polar(60, gauss(self.velocity.as_polar()[1], 30)) + return self.rect.center + direction + + def logic(self, **kwargs): + middle_area = SCREEN.inflate(-30, -30) + while self.rect.collidepoint(self.goal) or not middle_area.collidepoint(self.goal): + self.goal = self.new_goal() + + self.acceleration = (self.goal - self.rect.center).normalize() * self.ACCELERATION + super().logic(**kwargs) + + +class SolidObject(Object): + SHEET_RECT = [ + (0, 0, 24, 31), + (24, 0, 24, 24), + (48, 0, 24, 24), + (72, 0, 16, 24), + (88, 0, 48, 43), + (136, 0, 16, 16), + ] + SCALE = 3 + + def __init__(self, pos): + sheet = load_image("tileset", self.SCALE) + sheet.set_colorkey(0xFFFFFF) + rect = choice(self.SHEET_RECT) + rect = [x * self.SCALE for x in rect] + super().__init__(pos, sheet.subsurface(rect)) + + @classmethod + def generate_many(cls, nb=16, max_tries=1000): + objects = [] + tries = 0 # avoids infinite loop + while len(objects) < nb and tries < max_tries: + pos = random_in_rect(SCREEN) + obj = cls(pos) + if not any(obj.rect.colliderect(other.rect) for other in objects): + objects.append(obj) + return objects diff --git a/01-fog-of-war/cozyfractal/requirements.txt b/01-fog-of-war/cozyfractal/requirements.txt new file mode 100644 index 0000000..94f9b23 --- /dev/null +++ b/01-fog-of-war/cozyfractal/requirements.txt @@ -0,0 +1,8 @@ +# Add here the extra requirements for your project. +# You cannot specify version numbers (yet). +# Lines starting with a "#" are ignored. +# DO NOT list pygame here. + +# Please try to limit you dependencies as much as you can + +numpy diff --git a/01-fog-of-war/cozyfractal/utils.py b/01-fog-of-war/cozyfractal/utils.py new file mode 100644 index 0000000..306350c --- /dev/null +++ b/01-fog-of-war/cozyfractal/utils.py @@ -0,0 +1,70 @@ +from functools import lru_cache +from pathlib import Path +from random import uniform +from typing import Tuple + +import pygame + +SUBMISSION_DIR = Path(__file__).parent +ASSETS = SUBMISSION_DIR.parent / "assets" + + +@lru_cache() +def load_image(name: str, scale=1): + image = pygame.image.load(ASSETS / f"{name}.png") + if scale != 1: + new_size = image.get_width() * scale, image.get_height() * scale + image = pygame.transform.scale(image, new_size) + return image.convert_alpha() + + +def clamp(value, mini, maxi): + """Clamp value between mini and maxi""" + if value < mini: + return mini + elif maxi < value: + return maxi + else: + return value + + +def random_in_rect(rect): + """Return a random point uniformly in a rectangle.""" + rect = pygame.Rect(rect) + return pygame.Vector2(uniform(rect.left, rect.right), uniform(rect.top, rect.bottom)) + + +def from_polar(rho, theta): + """Create a Vector2 from its polar representation.""" + v = pygame.Vector2() + v.from_polar((rho, theta)) + return v + + +def chrange( + x: float, + initial_range: Tuple[float, float], + target_range: Tuple[float, float], + power=1, + flipped=False, +): + """Change the range of a number by mapping the initial_range to target_range using a linear transformation.""" + normalised = (x - initial_range[0]) / (initial_range[1] - initial_range[0]) + normalised **= power + if flipped: + normalised = 1 - normalised + return normalised * (target_range[1] - target_range[0]) + target_range[0] + + +def fill_outside_rect(surf: pygame.Surface, color, rect: pygame.Rect): + rect = surf.get_rect().clip(rect) + if rect.width == 0: + return # Rect was outside the surface + + w, h = surf.get_size() + # Two vertical bars + surf.fill(color, (0, 0, rect.left, h)) + surf.fill(color, (rect.right, 0, w - rect.right, h)) + # Two small horizontal bar + surf.fill(color, (rect.left, 0, rect.width, rect.top)) + surf.fill(color, (rect.left, rect.bottom, rect.width, h - rect.bottom)) From ef89e94e98741747899905c870d78196efbe44e8 Mon Sep 17 00:00:00 2001 From: ddorn Date: Mon, 11 Oct 2021 16:47:04 +0200 Subject: [PATCH 41/80] scroll in showcase --- wclib/showcase.py | 99 +++++++++++++++++++++++++++++++++++++---------- 1 file changed, 78 insertions(+), 21 deletions(-) diff --git a/wclib/showcase.py b/wclib/showcase.py index a9c9061..4b4646d 100644 --- a/wclib/showcase.py +++ b/wclib/showcase.py @@ -1,12 +1,11 @@ -import importlib -import json import sys -from functools import lru_cache, partial import traceback -from pathlib import Path +from _operator import attrgetter +from functools import lru_cache +from functools import partial from random import shuffle from threading import Thread -from typing import Callable, List +from typing import Callable import pygame @@ -29,6 +28,16 @@ def text(txt, color, size=20, font_name=None): return font(size, font_name).render(str(txt), True, color) +def clamp(value, mini, maxi): + """Clamp value between mini and maxi""" + if value < mini: + return mini + elif maxi < value: + return maxi + else: + return value + + class State: BG_COLOR = 0x151515 @@ -81,6 +90,9 @@ def run(self): class MenuState(State): + SCROLL_SPEED = 10 + GAPS = 20 # pixels between each button + def __init__(self, app: "App", title, buttons): super().__init__(app) self.title = title @@ -92,27 +104,45 @@ def __init__(self, app: "App", title, buttons): ) for i, button in enumerate(buttons) ] + total_height = self.buttons[-1].rect.bottom + self.GAPS * 2 + + if total_height > SIZE[1]: + self.scrollable_surf = pygame.Surface((SIZE[0], total_height)) + else: + self.scrollable_surf = None + self.scroll = 0 - @staticmethod - def button_position(i): - padding = 5 - cols = (SIZE[0] - 2 * padding) // Button.TOTAL_SIZE[0] - col_width = SIZE[0] / cols + def button_position(self, i): + gaps = self.GAPS + cols = SIZE[0] // (Button.TOTAL_SIZE[0] + gaps) + start = (SIZE[0] - cols * Button.TOTAL_SIZE[0] - (cols - 1) * gaps) / 2 return ( - padding + (i % cols) * col_width + (col_width - Button.TOTAL_SIZE[0]) / 2, - 100 + i // cols * (Button.TOTAL_SIZE[1] + padding), + start + (i % cols) * (Button.TOTAL_SIZE[0] + gaps), + 130 + i // cols * (Button.TOTAL_SIZE[1] + gaps), ) def button_click(self, data): raise NotImplemented def draw(self, screen: pygame.Surface): + if self.scrollable_surf is not None and screen is not self.scrollable_surf: + # Swap screen and self.scrollable_surf + self.draw(self.scrollable_surf) + screen.blit(self.scrollable_surf.subsurface(0, self.scroll, *SIZE), (0, 0)) + + if self.scroll <= 100: + t = text("Scroll down!", ACCENT) + t.set_alpha(int((1 - self.scroll / 100) * 255)) + screen.blit(t, t.get_rect(bottomright=SIZE - pygame.Vector2(10, 10))) + + return + super().draw(screen) screen.fill(ACCENT, (0, 0, SIZE[0], 4)) t = text(self.title, 0xEEEEEE00, 82, TITLE_FONT) - screen.blit(t, t.get_rect(midtop=(SIZE[0] / 2, 20))) + screen.blit(t, t.get_rect(midtop=(SIZE[0] / 2, self.GAPS * 1.5))) for button in self.buttons: button.draw(screen) @@ -120,9 +150,35 @@ def draw(self, screen: pygame.Surface): def handle_events(self, events): super().handle_events(events) + for event in events: + if event.type == pygame.MOUSEWHEEL and self.scrollable_surf: + self.scroll += event.y * self.SCROLL_SPEED + self.scroll = clamp(self.scroll, 0, self.scrollable_surf.get_height() - SIZE[1]) + + if self.scroll != 0: + events = [self.fix_event(e) for e in events] + print(events) + for button in self.buttons: button.handle_events(events) + def fix_event(self, event): + # We return new event to not interfere with other objects using events + if event.type in (pygame.MOUSEBUTTONDOWN, pygame.MOUSEBUTTONUP): + return pygame.event.Event( + event.type, + button=event.button, + pos=(event.pos[0], event.pos[1] + self.scroll), + ) + elif event.type == pygame.MOUSEMOTION: + return pygame.event.Event( + event.type, + buttons=event.buttons, + pos=(event.pos[0], event.pos[1] + self.scroll), + rel=event.rel, + ) + return event + class ChallengeSelectState(MenuState): BG_COLOR = 0x151515 @@ -166,7 +222,7 @@ def draw(self, screen): class Button: NAME_HEIGHT = 32 - SIZE = (SIZE[0] // 6, SIZE[1] // 6) + SIZE = (SIZE[0] // 5, SIZE[1] // 5) TOTAL_SIZE = (SIZE[0], SIZE[1] + NAME_HEIGHT) def __init__(self, challenge, entry, callback, position): @@ -196,15 +252,16 @@ def draw(self, screen): screen.blit(t, t.get_rect(center=self.rect.midbottom + offset)) def handle_events(self, events): - self.mouse_over = self.rect.collidepoint(pygame.mouse.get_pos()) - - if not self.mouse_over: - return - - self.app.handle_events(events) for event in events: if event.type == pygame.MOUSEBUTTONDOWN and event.button == 1: - self.callback() + if self.rect.collidepoint(event.pos): + self.callback() + + if event.type == pygame.MOUSEMOTION: + self.mouse_over = self.rect.collidepoint(event.pos) + + if self.mouse_over: + self.app.handle_events(events) class EmbeddedApp: From ad91df382efd44e750114b49594e302141b5e118 Mon Sep 17 00:00:00 2001 From: ddorn Date: Mon, 11 Oct 2021 17:18:19 +0200 Subject: [PATCH 42/80] small fixes --- 01-fog-of-war/cozyfractal/main.py | 1 + wclib/showcase.py | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/01-fog-of-war/cozyfractal/main.py b/01-fog-of-war/cozyfractal/main.py index 6ede85d..0e1b650 100644 --- a/01-fog-of-war/cozyfractal/main.py +++ b/01-fog-of-war/cozyfractal/main.py @@ -62,6 +62,7 @@ def mainloop(): screen.fill(BACKGROUND) shadow.draw(screen, player, all_objects) + clock.tick(60) if __name__ == "__main__": diff --git a/wclib/showcase.py b/wclib/showcase.py index 4b4646d..4ef1def 100644 --- a/wclib/showcase.py +++ b/wclib/showcase.py @@ -157,7 +157,6 @@ def handle_events(self, events): if self.scroll != 0: events = [self.fix_event(e) for e in events] - print(events) for button in self.buttons: button.handle_events(events) From 7706f5c72d2130bef675ba7d869ba3546dd78a9f Mon Sep 17 00:00:00 2001 From: ddorn Date: Mon, 11 Oct 2021 21:44:49 +0200 Subject: [PATCH 43/80] big showcase speed boost --- wclib/showcase.py | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/wclib/showcase.py b/wclib/showcase.py index 4ef1def..0f4972c 100644 --- a/wclib/showcase.py +++ b/wclib/showcase.py @@ -5,7 +5,7 @@ from functools import partial from random import shuffle from threading import Thread -from typing import Callable +from typing import Callable, Optional import pygame @@ -112,6 +112,8 @@ def __init__(self, app: "App", title, buttons): self.scrollable_surf = None self.scroll = 0 + self.clock = pygame.time.Clock() + def button_position(self, i): gaps = self.GAPS cols = SIZE[0] // (Button.TOTAL_SIZE[0] + gaps) @@ -125,6 +127,9 @@ def button_position(self, i): def button_click(self, data): raise NotImplemented + def logic(self): + self.clock.tick(60) + def draw(self, screen: pygame.Surface): if self.scrollable_surf is not None and screen is not self.scrollable_surf: # Swap screen and self.scrollable_surf @@ -271,10 +276,19 @@ def __init__(self, challenge, entry, rect=(0, 0, *SIZE)): self.virtual_screen = pygame.Surface(SIZE) self.missing_requirements = get_missing_requirements(challenge, entry) + # This one is for performance improvement. + # Most buttons are not to be redrawn nor scaled every frame, + # So we keep the scaled surface if we can. + # It is discarded every time there is a call to mainloop_next. + self.scaled_virtual_screen: Optional[pygame.Surface] = None + self.mainloop = self.load_mainloop() self.mainloop_next() def mainloop_next(self, events=(), _first=False): + # Erase the cache + self.scaled_virtual_screen = None + try: events = list(self.modify_events(events)) if _first: @@ -344,12 +358,11 @@ def draw(self, screen: pygame.Surface): return if self.rect.size != self.virtual_screen.get_size(): - try: - pygame.transform.smoothscale( - self.virtual_screen, self.rect.size, screen.subsurface(self.rect) + if self.scaled_virtual_screen is None: + self.scaled_virtual_screen = pygame.transform.smoothscale( + self.virtual_screen, self.rect.size ) - except ValueError: - pass + screen.blit(self.scaled_virtual_screen, self.rect) else: screen.blit(self.virtual_screen, self.rect) From 70b3b0fbfab9b509e5e33553c3eca2fc34999597 Mon Sep 17 00:00:00 2001 From: ddorn Date: Mon, 11 Oct 2021 22:12:43 +0200 Subject: [PATCH 44/80] showcase: smooth scroll --- wclib/showcase.py | 37 ++++++++++++++++++++++++++++++++++--- 1 file changed, 34 insertions(+), 3 deletions(-) diff --git a/wclib/showcase.py b/wclib/showcase.py index 0f4972c..8f7ea6c 100644 --- a/wclib/showcase.py +++ b/wclib/showcase.py @@ -91,6 +91,7 @@ def run(self): class MenuState(State): SCROLL_SPEED = 10 + SCROLL_FRICTION = 0.8 GAPS = 20 # pixels between each button def __init__(self, app: "App", title, buttons): @@ -110,10 +111,18 @@ def __init__(self, app: "App", title, buttons): self.scrollable_surf = pygame.Surface((SIZE[0], total_height)) else: self.scrollable_surf = None + self.scroll = 0 + self.scroll_momentum = 0 self.clock = pygame.time.Clock() + @property + def max_scroll(self): + if self.scrollable_surf is None: + return 0 + return self.scrollable_surf.get_height() - SIZE[1] + def button_position(self, i): gaps = self.GAPS cols = SIZE[0] // (Button.TOTAL_SIZE[0] + gaps) @@ -130,11 +139,33 @@ def button_click(self, data): def logic(self): self.clock.tick(60) + if self.scrollable_surf is None: + return + + self.scroll_momentum *= self.SCROLL_FRICTION + self.scroll += self.scroll_momentum + + t = 0.7 + if self.scroll <= 0: + target = 0 + elif self.scroll >= self.max_scroll: + target = self.max_scroll + else: + return + + self.scroll_momentum = self.scroll_momentum * t + (1 - t) * ((target - self.scroll) / 4) + def draw(self, screen: pygame.Surface): if self.scrollable_surf is not None and screen is not self.scrollable_surf: # Swap screen and self.scrollable_surf self.draw(self.scrollable_surf) - screen.blit(self.scrollable_surf.subsurface(0, self.scroll, *SIZE), (0, 0)) + screen.blit(self.scrollable_surf, (0, -self.scroll)) + + if self.scroll < 0: + screen.fill(ACCENT, (0, 0, SIZE[0], -self.scroll)) + elif self.scroll > self.max_scroll: + bottom_blank = self.scroll - self.max_scroll + screen.fill(self.BG_COLOR, (0, SIZE[1] - bottom_blank, SIZE[0], bottom_blank)) if self.scroll <= 100: t = text("Scroll down!", ACCENT) @@ -157,8 +188,8 @@ def handle_events(self, events): for event in events: if event.type == pygame.MOUSEWHEEL and self.scrollable_surf: - self.scroll += event.y * self.SCROLL_SPEED - self.scroll = clamp(self.scroll, 0, self.scrollable_surf.get_height() - SIZE[1]) + self.scroll_momentum += event.y * self.SCROLL_SPEED + # self.scroll = clamp(self.scroll, 0, self.scrollable_surf.get_height() - SIZE[1]) if self.scroll != 0: events = [self.fix_event(e) for e in events] From c369a88a5f7f83d459cb39156e3c6675571aeee8 Mon Sep 17 00:00:00 2001 From: ddorn Date: Mon, 11 Oct 2021 22:18:03 +0200 Subject: [PATCH 45/80] showcase: load apps one by one for smoother menu open --- wclib/showcase.py | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/wclib/showcase.py b/wclib/showcase.py index 8f7ea6c..3d61ba7 100644 --- a/wclib/showcase.py +++ b/wclib/showcase.py @@ -114,6 +114,7 @@ def __init__(self, app: "App", title, buttons): self.scroll = 0 self.scroll_momentum = 0 + self.timer = 0 self.clock = pygame.time.Clock() @@ -139,6 +140,11 @@ def button_click(self, data): def logic(self): self.clock.tick(60) + # we load one app per frame, for smoother UX + if self.timer < len(self.buttons): + self.buttons[self.timer].app.load() + self.timer += 1 + if self.scrollable_surf is None: return @@ -313,8 +319,12 @@ def __init__(self, challenge, entry, rect=(0, 0, *SIZE)): # It is discarded every time there is a call to mainloop_next. self.scaled_virtual_screen: Optional[pygame.Surface] = None - self.mainloop = self.load_mainloop() - self.mainloop_next() + self.mainloop = None + + def load(self): + if self.mainloop is None: + self.mainloop = self.load_mainloop() + self.mainloop_next() def mainloop_next(self, events=(), _first=False): # Erase the cache From 90f93460b5db8d1d7411ed4ef28b46d02c9df45b Mon Sep 17 00:00:00 2001 From: ddorn Date: Wed, 13 Oct 2021 19:03:20 +0200 Subject: [PATCH 46/80] 02: readmes --- 02-particle-system/base/objects.py | 45 ++++++++++++++++------------ 02-particle-system/base/utils.py | 11 +++---- 02-particle-system/readme.md | 47 ++++++++++++++++++++++++++---- general_instructions.md | 41 ++++++++++++++++++++++++-- readme.md | 9 ++++++ 5 files changed, 121 insertions(+), 32 deletions(-) diff --git a/02-particle-system/base/objects.py b/02-particle-system/base/objects.py index c0e8b89..47e2c29 100644 --- a/02-particle-system/base/objects.py +++ b/02-particle-system/base/objects.py @@ -73,12 +73,15 @@ def __init__(self, pos, vel, sprite: pygame.Surface): self.sprite = sprite self.rotation = 0.0 # for the sprite self.alive = True + # Cache it every frame, as it was taking 10% (!!) of the processing power. + self.rect = self.get_rect() def __str__(self): return f"<{self.__class__.__name__}(center={self.center}, vel={self.vel}, rotation={int(self.rotation)})>" @property def radius(self): + """All objects are considered circles of this radius for collisions.""" # The 1.2 is to be nicer to the player return self.sprite.get_width() / 2 * self.HIT_BOX_SCALE @@ -99,12 +102,13 @@ def rotated_sprite(self): # to floats that are equal. return rotate_image(self.sprite, int(self.rotation)) - @property - def rect(self): + def get_rect(self): return self.rotated_sprite.get_rect(center=self.center) def handle_event(self, event): - pass + """Override this method to make an object react to events. + Returns True if the event was handled and should not be given to other objects.""" + return False def draw(self, screen): screen.blit(self.rotated_sprite, self.rect) @@ -140,13 +144,12 @@ def draw(self, screen): if len(shifts) == 2: screen.blit( self.rotated_sprite, - self.rotated_sprite.get_rect( - center=self.center + shifts[0] + shifts[1] - ), + self.rotated_sprite.get_rect(center=self.center + shifts[0] + shifts[1]), ) # To see the exact size of the hitboxes - # pygame.draw.circle(screen, "red", self.center, self.radius, width=1) + if pygame.key.get_pressed()[pygame.K_d]: + pygame.draw.circle(screen, "red", self.center, self.radius, width=1) def logic(self, **kwargs): # self.vel = clamp_vector(self.vel, self.MAX_VEL) @@ -155,6 +158,8 @@ def logic(self, **kwargs): self.center.x %= SIZE[0] self.center.y %= SIZE[1] + self.rect = self.get_rect() + class Player(Object): Z = 10 @@ -191,9 +196,7 @@ def logic(self): self.speed += raw_acceleration * self.ACCELERATION self.speed *= self.FRICTION # friction - self.rotation += ( - rotation_acc * self.ROTATION_ACCELERATION * min(1.0, 0.4 + abs(self.speed)) - ) + self.rotation += rotation_acc * self.ROTATION_ACCELERATION * min(1.0, 0.4 + abs(self.speed)) self.vel.from_polar((self.speed, self.INITIAL_ROTATION - self.rotation)) @@ -208,6 +211,8 @@ def fire(self): self.state.add(bullet) def on_asteroid_collision(self, asteroid: "Asteroid"): + # For simplicity I just explode the asteroid, but depending on what you aim for, + # it might be better to just loose some life or even reset the game... asteroid.explode(Bullet(self.center, self.rotation)) # Add particles here (and maybe damage the ship or something...) @@ -274,14 +279,10 @@ def explode(self, bullet): if self.level > 1: # We spawn two smaller asteroids in the direction perpendicular to the collision. perp_velocity = pygame.Vector2(bullet.vel.y, -bullet.vel.x) - perp_velocity.scale_to_length( - self.vel.length() * self.EXPLOSION_SPEED_BOOST - ) + perp_velocity.scale_to_length(self.vel.length() * self.EXPLOSION_SPEED_BOOST) for mult in (-1, 1): self.state.add( - Asteroid( - self.center, perp_velocity * mult, self.level - 1, self.color - ) + Asteroid(self.center, perp_velocity * mult, self.level - 1, self.color) ) # Add particles here. @@ -296,9 +297,7 @@ def generate_many(cls, nb=10): for _ in range(nb): angle = uniform(0, 360) pos = SCREEN.center + from_polar(gauss(SIZE[1] / 2, SIZE[1] / 12), angle) - vel = from_polar( - gauss(cls.AVG_SPEED, cls.AVG_SPEED / 6), gauss(180 + angle, 30) - ) + vel = from_polar(gauss(cls.AVG_SPEED, cls.AVG_SPEED / 6), gauss(180 + angle, 30)) size = choices([1, 2, 3, 4], [4, 3, 2, 1])[0] objects.add(cls(pos, vel, size)) @@ -309,6 +308,7 @@ class FpsCounter(Object): Z = 1000 def __init__(self, fps): + self.hidden = False self.target_fps = fps self.clock = pygame.time.Clock() self.last_frames = deque([time.time()], maxlen=10) @@ -317,6 +317,10 @@ def __init__(self, fps): dummy_surface = pygame.Surface((1, 1)) super().__init__((4, 8), (0, 0), dummy_surface) + def handle_event(self, event): + if event.type == pygame.KEYDOWN and event.key == pygame.K_f: + self.hidden = not self.hidden + def logic(self, **kwargs): self.last_frames.append(time.time()) self.clock.tick(self.target_fps) @@ -338,6 +342,9 @@ def theoretical_fps(self): return int((len(self.last_frames) - 1) / seconds) def draw(self, screen): + if self.hidden: + return + color = "#89C4F4" t = text(f"FPS: {self.current_fps}", color) r = screen.blit(t, self.center) diff --git a/02-particle-system/base/utils.py b/02-particle-system/base/utils.py index 9978011..625b252 100644 --- a/02-particle-system/base/utils.py +++ b/02-particle-system/base/utils.py @@ -9,12 +9,15 @@ @lru_cache() -def load_image(name: str, scale=1): +def load_image(name: str, scale=1, alpha=True): image = pygame.image.load(ASSETS / f"{name}.png") if scale != 1: new_size = image.get_width() * scale, image.get_height() * scale image = pygame.transform.scale(image, new_size) - return image.convert_alpha() + if alpha: + return image.convert_alpha() + else: + return image.convert() @lru_cache() @@ -36,9 +39,7 @@ def clamp(value, mini, maxi): def random_in_rect(rect): """Return a random point uniformly in a rectangle.""" rect = pygame.Rect(rect) - return pygame.Vector2( - uniform(rect.left, rect.right), uniform(rect.top, rect.bottom) - ) + return pygame.Vector2(uniform(rect.left, rect.right), uniform(rect.top, rect.bottom)) def from_polar(rho, theta): diff --git a/02-particle-system/readme.md b/02-particle-system/readme.md index fc8b515..75d9fe8 100644 --- a/02-particle-system/readme.md +++ b/02-particle-system/readme.md @@ -11,9 +11,8 @@ so it is very handy to have a system already implemented for when a game jam com `C`hallenger `P`oints they provide: - Casual `+3 CP`: Have 3 different particle effects of your choice in the game - (for instance: asteroid explosion, ship damage, thrusters, stars, asteroids clear fireworks, bullets, warning as approaching asteroids...) - Ambitious `+2 CP`: Have 6 different particles effects and handle 1000 particles at 60 FPS -- Adventurous `+1 CP`: Have 9 effects +- Adventurous `+1 CP`: Have the asteroids break in pieces that together make up the original sprite. In any case, your particle system should be: - independent of the rest of your code (for instance, in it own file) @@ -23,13 +22,51 @@ In any case, your particle system should be: ### Setup -The setup code in [`base/`](./base) consists of a simple top down game with trees and ghosts moving around. -To get started, duplicate the whole `base` folder and rename the copy with your username -(will call it `yourname/` from now on). All your modifications should be inside the `yourname/` folder, +The setup code in [`base/`](./base) consists of a simple Asteroids clone with a ship that moves around and fires on asteroids. +The code is a bit more complex than last time, so here's an overview. + +- [`main.py`](./base/main.py) contains basic boilerplate, with every method delegated to a `State` object. +- [`objects.py](./base/objects.py) contains many things: + - The `State` class, that represent everything in the game. It is probably the place were you will + want to create your particle system / particle manager. This class contains all the `Object`s of the game, + and is accessible from any object as `obj.state`. In order to add an object to the state, use `state.add(new_object)`, + it will then be drawn and updated each frame automatically. Objects are removed from the state when `obj.alive == False`. + - The `Object` class, base class of all objects of the game (`Player`, `Asteroid`, `Bullet`). It takes care of + drawing correctly the rotated sprites, detecting collisions and moving objects according to their velocity. + You probably don't need to modify it. + - The `Player` class implements event handling and firing. It contains a `on_asteroid_collision()` + method that is called whenever the ship collides with an asteroid. It is a good place to add particles. + An other good place is `Player.logic()` to emit particles every frame. + - The `Asteroid` class dispatches the collision with other objects and manages its own explosion. + The `explode` method is a nice place to add particles. + - The `Bullet` class doesn't do much, except dying after a given time. + - The `FpsCounter` class is a wrapper around `pygame.time.Clock` so it manages the FPS but also + displays them. You can toggle the display with the `F` key. + +To get started, **duplicate** the whole `base` folder and rename the copy with your username +(we will call it `yourname/` from now on). All your modifications should be inside the `yourname/` folder, otherwise it would be impossible to have a showcase of all the submissions. +> PLEASE. Do not modify the base folder. + +Further instructions are + Have fun ! +### Tips + +**Tip 1**: If you are struggling to find places to add particles, here are a few, but there are countless others! +> asteroid explosion, ship damage, thrusters, stars, asteroids clear fireworks, bullets, warning as approaching asteroids... + +**Tip 2**: You can remove completely the code with the asteroids if you want to, it is there only to sparkle your +creativity. If you want to, you can just create a "particle showcase" with lots of nice handcrafted effects going on at the same time. +I strongly suggest this option if you have not used object-oriented programming before, as the setup code make heavy use of it. +However, this challenge is a good chance to get more familiar with OOP. + +**Tip 3**: If you have never made particles before, don't start by making something generic. +Make something specific, then think about how you could make it more reusable. +Usable comes first, reusable comes second. + ### Credits - Asteroids: [Asteroids 02 by GameArtForge](https://opengameart.org/content/asteroids-set-02) diff --git a/general_instructions.md b/general_instructions.md index f49b787..af9f96c 100644 --- a/general_instructions.md +++ b/general_instructions.md @@ -3,7 +3,8 @@ ### Achievements In each challenge, there are different stages of success, *Casual*, *Ambitious* -and *Adventurous* +and *Adventurous*. + Succeeding in the casual stage is enough to complete the challenge, however, in order to provide more challenge for the most adventurous and ambitious of you, we provide two more puzzles. @@ -13,11 +14,19 @@ stuck on the same thing. ### Setup Code -The setup code in [`base/`](./base) consists of a simple top down game with trees and ghosts moving around. -To get started, duplicate the whole `base` folder and rename the copy with your username +The setup code in the challenge `base/` folder consists of a simple game prototype. +It is meant to be used as a starting point and for inspiration. However, you can +completely remove it and start something from scratch if you want to. +If you want to, you can also use a small game that you were already developing, +but it should not have already solved the challenge: the part of the submission +that solves the challenge must be *new* work. + +To get started, **duplicate** the whole `base` folder and rename the copy with your username (will call it `yourname/` from now on). All your modifications should be inside the `yourname/` folder, otherwise it would be impossible to have a showcase of all the submissions. +> Please do NOT modify the base folder. Copy and paste it instead. + In this `yourname/` folder, you'll find a `main.py` file. This is the entry point of your submission and where most of your code will go. In this file, you will find a `mainloop` function, which is the only thing that is required so that the submission @@ -58,6 +67,19 @@ If you are used to classes, you can also have all your code in a class, for inst then you only need a statement like `mainloop = App.run` if the `run()` method is your main loop, to have your submission discovered. +### External modules + +It is possible to use modules others than pygame in your submission. +However, please try to keep it as the minimum possible. +Keep in mind also that people may have trouble installing your requirements, +and then won't be able to play your entry. + +In order to use external modules, you need to have a `requirements.txt` file +at the root of your submission. This file contains the name of the modules +that you need, one by line but without any version specified. + +Users will be prompted to install them when running your entry (without just having the game crash). + ### Submitting your entry Before the deadline, make sure that your entry is runnable both via the showcase, @@ -80,3 +102,16 @@ You can structure your code the way you like, but if you use multiple files, it is very recommended that you use *relative imports*, as it is the simplest way to make the import system work both in the showcase and when run directly. +Using relative imports means that if your folder looks like this: +``` +yourname/ +├── main.py +└── utils.py +``` +And you want to import function `foo` from `utils.py` in your `main.py`, +you use +```python +from .utils import foo +``` +Where the dot in front of `.utils` signifies that python needs to look inside the +same directory (here, the `yourname/` directory). diff --git a/readme.md b/readme.md index 3f8c998..f6f1aea 100644 --- a/readme.md +++ b/readme.md @@ -17,6 +17,15 @@ The first season started on the 26th of September 2021 and will last about 3 mon 2. **[current]** [Particle System](./02-particle-system) - 11 oct 2021 → 25 oct 2021 +### Detailed instruction + +You need to read [the detailed instructions](./general_instructions.md) +in order to participate. They contain: + - the submission process; + - what you are allowed to do; + - the utilities provided to you; + - some various tips for the challenges. + --- In case you find contradictory information, the information posted in the Discord server are always the correct ones. Also, please, if you do find such erroneous information, From 53ba39f46f77a784ba05fdce9b46639f45dc5619 Mon Sep 17 00:00:00 2001 From: ddorn Date: Thu, 14 Oct 2021 10:26:43 +0200 Subject: [PATCH 47/80] improve code quality + toggle fps cap --- 02-particle-system/base/main.py | 8 ++--- 02-particle-system/base/objects.py | 56 ++++++++++++++++-------------- 02-particle-system/base/utils.py | 41 ++++++++++++++++++++++ wclib/showcase.py | 4 ++- 4 files changed, 76 insertions(+), 33 deletions(-) diff --git a/02-particle-system/base/main.py b/02-particle-system/base/main.py index 2684644..f803c69 100644 --- a/02-particle-system/base/main.py +++ b/02-particle-system/base/main.py @@ -26,12 +26,9 @@ # "Adventurous", ] - -from operator import attrgetter -import pygame - # To import the modules in yourname/, you need to use relative imports, # otherwise your project will not be compatible with the showcase. +# noinspection PyPackages from .objects import * BACKGROUND = 0x0F1012 @@ -40,7 +37,8 @@ def mainloop(): pygame.init() - player = Player((100, 100), (0, 0)) + player = Player((SIZE[0] / 2, SIZE[1] / 2), (0, 0)) + # The state is just a collection of all the objects in the game state = State(player, FpsCounter(60), *Asteroid.generate_many()) while True: diff --git a/02-particle-system/base/objects.py b/02-particle-system/base/objects.py index 47e2c29..708d5af 100644 --- a/02-particle-system/base/objects.py +++ b/02-particle-system/base/objects.py @@ -7,20 +7,19 @@ goes with it too. Feel free to modify everything in this file to your liking. """ + import time from collections import deque from colorsys import hsv_to_rgb +from functools import lru_cache from operator import attrgetter -from random import choice, gauss, choices +from random import gauss, choices, uniform import pygame -from wclib import SIZE -from wclib.showcase import text +# noinspection PyPackages from .utils import * -SCREEN = pygame.Rect(0, 0, *SIZE) - class State: def __init__(self, *initial_objects: "Object"): @@ -305,48 +304,51 @@ def generate_many(cls, nb=10): class FpsCounter(Object): + """ + A wrapper around pygame.time.Clock that shows the FPS on screen. + + Controls: + - [F] Toggles the display of FPS + - [U] Toggles the capping of FPS + """ + Z = 1000 + REMEMBER = 30 def __init__(self, fps): self.hidden = False + self.cap_fps = True self.target_fps = fps self.clock = pygame.time.Clock() - self.last_frames = deque([time.time()], maxlen=10) - self.last_sleeps = deque([0.0], maxlen=9) + self.frame_starts = deque([time.time()], maxlen=self.REMEMBER) dummy_surface = pygame.Surface((1, 1)) super().__init__((4, 8), (0, 0), dummy_surface) def handle_event(self, event): - if event.type == pygame.KEYDOWN and event.key == pygame.K_f: - self.hidden = not self.hidden + if event.type == pygame.KEYDOWN: + if event.key == pygame.K_f: + self.hidden = not self.hidden + elif event.key == pygame.K_u: + self.cap_fps = not self.cap_fps def logic(self, **kwargs): - self.last_frames.append(time.time()) - self.clock.tick(self.target_fps) - end_sleep = time.time() - self.last_sleeps.append(end_sleep - self.last_frames[-1]) + # Passing 0 to tick() removes the cap on FPS. + self.clock.tick(self.target_fps * self.cap_fps) - @property - def current_fps(self): - if len(self.last_frames) <= 1: - return 0 - seconds = self.last_frames[-1] - self.last_frames[0] - return int((len(self.last_frames) - 1) / seconds) + self.frame_starts.append(time.time()) @property - def theoretical_fps(self): - if len(self.last_frames) <= 1: + def current_fps(self): + if len(self.frame_starts) <= 1: return 0 - seconds = self.last_frames[-1] - self.last_frames[0] - sum(self.last_sleeps) - return int((len(self.last_frames) - 1) / seconds) + seconds = self.frame_starts[-1] - self.frame_starts[0] + return (len(self.frame_starts) - 1) / seconds def draw(self, screen): if self.hidden: return color = "#89C4F4" - t = text(f"FPS: {self.current_fps}", color) - r = screen.blit(t, self.center) - t = text(f"Theoretical: {self.theoretical_fps}", color) - screen.blit(t, r.bottomleft) + t = text(f"FPS: {int(self.current_fps)}", color) + screen.blit(t, self.center) diff --git a/02-particle-system/base/utils.py b/02-particle-system/base/utils.py index 625b252..af91448 100644 --- a/02-particle-system/base/utils.py +++ b/02-particle-system/base/utils.py @@ -4,8 +4,26 @@ import pygame +from wclib.constants import SIZE, ROOT_DIR + +__all__ = [ + "SIZE", + "SUBMISSION_DIR", + "ASSETS", + "SCREEN", + "load_image", + "rotate_image", + "clamp", + "random_in_rect", + "from_polar", + "clamp_vector", + "segments", + "text", +] + SUBMISSION_DIR = Path(__file__).parent ASSETS = SUBMISSION_DIR.parent / "assets" +SCREEN = pygame.Rect(0, 0, *SIZE) @lru_cache() @@ -60,3 +78,26 @@ def segments(points): """Return all the segments made from adjacent pairs of points in the list. Also return the segment made of the last and first point.""" return zip(points, points[1:] + [points[0]]) + + +@lru_cache() +def font(size=20, name=None): + """ + Load a font from its name in the wclib/assets folder. + + If a Path object is given as the name, this path will be used instead. + Results are cached. + """ + + name = name or "regular" + if isinstance(name, Path): + path = name + else: + path = ROOT_DIR / "wclib" / "assets" / (name + ".ttf") + return pygame.font.Font(path, size) + + +@lru_cache(5000) +def text(txt, color, size=20, font_name=None): + """Render a text on a surface. Results are cached.""" + return font(size, font_name).render(str(txt), True, color) diff --git a/wclib/showcase.py b/wclib/showcase.py index c7b616f..00ee53f 100644 --- a/wclib/showcase.py +++ b/wclib/showcase.py @@ -17,13 +17,15 @@ @lru_cache() def font(size=20, name=None): + """Load a font from the wclib/assets folder. Results are cached.""" name = name or "regular" path = ROOT_DIR / "wclib" / "assets" / (name + ".ttf") return pygame.font.Font(path, size) -@lru_cache() +@lru_cache(5000) def text(txt, color, size=20, font_name=None): + """Render a text on a surface. Results are cached.""" return font(size, font_name).render(str(txt), True, color) From 243f0e8f3dfd91fb9cdf14a99eececa37383cadf Mon Sep 17 00:00:00 2001 From: ddorn Date: Thu, 14 Oct 2021 10:35:20 +0200 Subject: [PATCH 48/80] 02: improve code quality --- 02-particle-system/assets/asteroid-128.png | Bin 17344 -> 16359 bytes 02-particle-system/base/objects.py | 29 +++++++++++++++++---- 02-particle-system/base/utils.py | 10 ++----- 3 files changed, 26 insertions(+), 13 deletions(-) diff --git a/02-particle-system/assets/asteroid-128.png b/02-particle-system/assets/asteroid-128.png index fa23112b46b872569388509d7139764ef0e63a12..a017985c849598f26b8195d28b1833f94c090056 100644 GIT binary patch literal 16359 zcmVvhF6rCRuh9B-jcz76A*< z##iA#&{nWj5ClaKvGEW1YDCsMCXgV>EVK9H%$&>28Sup{J>#~FKqi}a;?ane!>J2x@%9(&cr{sCx$Da3d0?kiwnXUSBlGDVe=%uO_I)vaBoL^P7 z|_6Rb?beWgw#o zhme^e6;u>mNMWp%HAgCD=}MYbU{_F42|% zDj|kY2_f@PnQK1%KGWX&`_DO5r$Q1#|H-NU|G!~>d++CcpLf{9zcl>-zuxzu_iwN2 z@0?br9jnvy_WE4kS9h>Ub)di17k}5Wh3~7Yx7Xo4?utFDtE*r0=N!NNkN?LX1)>cB0Brv zfdkXQLx*^Nd3kBtwr$(AW$RV~xx8iBzzd`XsKJU|?MgfcRbZA71ZV)edbnxuCXj;W ze)8qi+*cf+@BcTyPykM!F4T4|6+i?M|20rWsfP|6oSuLF`RU-ngFH`dEC9D`*)kn> z{PEMa*tQu5y0K`QUd#m0QBcS{EI8q$WIrL8GBW4(vP7v=Tr9yd}RwQ$f93i+UGd2a2LWq0!FK97s*n5k?wg)@>S@tz0SAo~pw>=&hnCjg*3#5<0WDxUg?C!!wYINd0cvFd zddS+T(+1Sn4&iOn(vg~v0vBxT4FxRTUzFEN3TVZQaBQxvzQ_A^KCA&KEnFs8*2wxy zAWFM%JWkB$6oG2@mhEix8XyO{U0w#DC{rG8i(>2;K}-2evO(3V>cQ*k?@$4F@Id_? zEN83e82}zSe25_q!KASrU>pnQVF{u%T29p_UcXkL-nfbDj(W+94ydy?*VmIjQhzHg zn1G@|0|{aWaQuu8hW*>NbsMjPq{D+{r<-=4DM0t{+fNN9aCJR|AX-UHt>e-9#U4PP zi$U0t%3&rRrQ<2dcz(+N)?79iwS_{<-I;ebwRdXy;%G z;CRML7g(fxe`+P?w8H@K5CZMpySJPz0ULT{8PsBX+*JJDbz&Z&+7cI`<{|#2Gd4qh z4LaX9s4ohj@BQWLc23&S#0>}gV3rvPVhwAhG<~WUXulfl+zLS0jN>8~ixFsr_ z(4Yx9y0(5_psw{A)(Fj!54`u6uKPr_?^AVEX=O)KvEe)+5Stb1Z4^u@?th|K**Ixi z_i_OswYtj2XK3@*Z30!`Et5K7=O`3DCa0@2fy$Rw9jNQ~KEIa~OE1`AO_(F~j=hh7 zL|EjRr>&|(o~O3>*^Z})_h^UbUA*Jct1er)>zj9e@fe}#Z1h5Ie9tdkyHYj%LfyNg zQI3mL$RX`R<0#V!LrhPK{{ob#7&p&&-*-@c;oz0^oWmj#E&4o}bO%(XgRXtb|gR}~mD zL5f)sJFb?N?FS^y0ZSGsbev8?he9)-dj_5}Y$xh@cq$Q?CJR!Y|J*arDv@E0JLS|< zn2k!Ai)Bj*du9pWA((Ks4%l8Fg@O^QUURIOrL~dwQAFbBe(`-6d%T5?54dBA|H#(c zo=}qOD}a=^o9cK8Vu$*-j;+?cEwG0e`@T>m?nAH-9dCJ6bPO~S=j>rbtNEw`V(HK_ zft}H;IKwuOSC*C>ptiuSA=boSm?9eZ*dvck-}$F+Q+vnc2I_O}1?Nqdzv0RTEb8j+ zP`j;}@u*Xugf-J4>C*;w6^hlG*8FvZ3$(;QMw|Ki*O$P&1o)$8?rHa3cM}+}jXdgd#40QT@XtK;%=F;>4@_sg`poHs6HjR7;^|6!;CswW(_T7J zl}2=?s`sIeuk%_dd-}Dqr*~`?)J<#XyFd8em3rzetE)@f)z?XH%U6%BgjUAZ$VSXH z#kX3w20uTV9N*v6-5PEB66Hx_Nsp@tQ}jJvD4ZqKCy9VDEQ*+*Q&Bf%gy7j8nC|?C zJEr4LIDR^9`*wo+;P)Pw0Xb?Y>2mpSr6BiD|M1msOlO>R#`IJP#nXG9nl8EOvT6Gn zirk>J8D~X(@nT;Qzro_w$HNJg=IDK*z9O-|sn@17^j*L3USxUxxSn62sv@&aWCf*_ zv^i*qGbG&^!g0~_EIgt1b-TLgjmlHDW7D*@YbZMi7*qRDytN-*FcSE&-dN)-Ra3E_AnHpX8IkUn*-+T5-@?5Kk?|}(@7_vJiX1*AW5z*$@2O$Et)CIu`~tjs}z02ut9cl)G=7J$Bfc z^!S=RaNq9l&S)q~5iOeecY_AwyuL;Y7uvI+U<9E$@3^vuC!BBs?c!Xw1FS@(jh8kP zf%})I6HhwPPqnwco&!qDlG^EA8KeO0WJl7D^s?m-z)mCfjfqJ!`Y@noU&PULtFJ39 z9dhLBW4j@sKl}c7SDd-}k+g-elRZ#oIS{jj@}dN$I#I5wdFuAlrU&l3e|i=T@JnXX zv1^sNpp?=&gQ=p{hDfu*qJch$e5`Nl@2r$sgO9O?5CDyvB2Rp9y6cWREAG5|mK0!i zr`kMDKf#ci7)m24C!TzghwBEX&lKD8+16ZyNUcrw8(wwVDGfx87HI@&0o3c)hp`_$ zl7^PuMDk!5lYj%j2Edtc|3rCd^c#+?^G<%%$$Z*f|9Gc5v)v|6UMu|lSo1B0IyAdC zXlHCTg`loIbV%_fGBWd5Xf~d6&1^WXrm7S@!`8)3rV{Eyhs%105#8hbcnHjmfBk|+U-8M zMswZZ@i?`eu@s&y?ITGfHn8n)E=EC%=93^dCS{=TpG>9f$P!e#ca@GZH@OrXz&Mn%{V(Aus!4qY=n9> z9?RFxd|2;&-8i&ByS62reOJ8OUI^8*$1nD3XXlZHtxHZmMYM|!_{QITodN-1#}`s% zr=NMo^y+iZp3Xl19G!yW!TwR<0!w}7(*n;t4(*M1y@U(hsg0d^Z!Z9y1W=I>SUrTP zCIAH5eW=2%C#N_4@YU?}Z~Wh{P0v63TubG}mcnk9uR*HB7-~;Hy2b%D?|HrR=w92)C`T)N5mesW zsTm!}hSz_KQ!Fv$1&Twu?f8E@VS2+gZ!9`Gt1CSk6M))tJc+Eqt1f9@QF8;xF6RBZ zBF#GPxZ_E;$5qM?LJL7dk{()!#Qa(3yn1@i2d|y>l#RtGjwpMY?*7)dSzk~v(uU*6 z56kDHWDbVvRnh>H!!cLM^>iN*O4^gEvqmF$4S-EDf3*bX(CVR`8-a=AYi#H{-}kc^ z8vE7eQV&wjqybeQo#Sy%)_bsZf*m0w=iNlCN#hW%jp#`VPPpWXOTSol zv<&>(*LoT%37~j1va)f4cDf7O2UA|k##eXTckcZ5^ynjxw5-W2PisMl^fD-lG$KV- z!t>p-xo}wC_#-<+N9LzSQ|mB7Ombs8!fnv&`Ui>u5YXcV`*q2cml8xI<#8dLHwYqx ziK9eC=@~Z#i(~>C-gms^&C`>6_DpA&nV5~J*r{X45wq0#KI6jdD0imYb~yGHT8jRt zR##(}>z#d5<#D8Dbrl$`o7-IjXx(@?Rn|K9I0w76==8`uFERhd8B#jJZ%G%A-}%1Z(q9dDo8TTv4CZcf_O!=v{qYCOh8k zD!g2*i-G2zRPpoi<*1!dpJ87?xg2@fhCD9DMm0pox;t^NImLC3@uO(G*-@J%oacPu z*jJC)wzQ!Iq0L#&I4(z%l6_jZ+X*CHIRz6G&5HI;=yhP78w|(?ZF0 zWk$Oh;P}o-(!<}7(9ZpN|N7sq$1s#6SJxvz!86eEyH=^qvo5RCc|UaiAeu5Am`MmA zLBX(@Czl6&(n+?Rbquj1msvRE(dTU~K>;dWLLN4q7!zc0Aq;IHRR-We(W6fhpTwy` z*<$5@4g5-V_NU)n!^|(<+CA?DZwFu;=k7G!dH9L_8Kb06WW? z_+AN1u})DD7YdCp(&*~6w;U6AzyzV$aeJ|#qroI~QS4J=uy_gD_iV+O&?HPBIqmdH zgn8{}8+5k90wjQ@Y!E8v)F&x7(hGao6Y?@QY74#V`kzq&rrNYNA=Rka4@rK+cUXeW zL_46sjxsd+LbjCW@eaX1e0WDCIB%(9uNk{*jhFk{%U<^}*$8JlK)*kH)DR<2g#-FtwyrZooBw;~D2wHfMA|V$WKpib4Y070*|lkMl^e zVRF|QXP?R0`O5YvFC7LVR(1x_PSsoKI{uMzi&~e9axsL)p)L=u1H1}jV4E?i4D);u zrU6(|@BphAEfKawaL5gZ4g0`|*(fHDgt>ZddA!@pcDnfIb7%^KcgJ<1E|>UpLB318kq`D>T0ZPVt(!!2}Uo z1r||#kU-FR%sND@xSvZL;Ju<8W_q0cX$yg)g%$=8NLT%)W!B=B)Nn-rAkv($)d+VE z9aK`E({idF%tX1J@&xokmTr|d=523fl6E|@t*xBStcu9Nh&O>luvJ@Mr9=tGati^V(suz(0)&R*SUGzY7Jv_@idAhao^ zPyrE)ev29=A8nu^e(c^i&W(e|&lL^gJ2bRWE#pkh!s9!&LGPJ7#`K)+BA=Vi4wDp^ z(4;4;U*bC;SF1sGFVVnzIZL5W+EvuAzyviT_64X1OYk(B)wNgMo;G(-`|N%8)6UFj z*l*g*?#JD>e6Yqfa;*`JU+ z-8IqJP`3MjmCnY=<>KQc0BxRL3Lw{8g9aPC2q3+^c!`n9h3~D!CR$Oesn7L;cI|y$ z(!Y1_^G>zFaa$`@ErwoCnyk6>8%*Krfl9}xUeZX#sB=&qdwcpOQ;#rH&%$Y{wWg8#RMVoP#Gnd6@_$gMoX&?t#U@gdc$Y8T2^OG>|NpHyrtQOnP5UjbC|nu(=>OoZF1hu(@jnb=OjRNRMg=)%4Ry`0 zTTerGi^LtHe6|I= zGtaKk7qs0IxWgKvK-KwREpO0l`0`}2lC10-oD<3aG(GwFp6THSA1WuLmNwLX2=dQ4 z|J>=K8vkTFBaA_v^^-G{LP+le{USBF)y|OS@G5)Mv=kXB@hGQgLZdNqgJHTPJEWOb z8{6rYX-ehEKu!y8k=>7DnTUM^^x7_4Ps8 zPvn5_`L^=F01V@oNYx>IH~!%mHsbip|MTZj`ewm9fOD6EePmOBiPLhJ?HE1T% zfc9X5SJ%R5e3RspwbB_QNapAnnNBs(Tc9p& znXY`(RhoMP00$5gC^sMr)Bub3Ou7n)xgX!J`LQ47XdYv=jK)O7{f-VstO>gbD#a{# z2*SPJxrbmP`H>tf0WBbybgvKt=P)T8(_};$#-KeTha*Y-J6Hok3>$wu_D8bKRPNRM z=|Twy>2)BeFl{^5PtI*+m^%ds;PE-LOwrrl_0vf9?rPlar;E0fx6~lF$K?iK@ev&f zNyU^7XbEE0#dKFhbqo)hHpdzA5Lz-g00!fhXbvYqr@e!;hL^hi)D9+?fQ89vPe1vz zz)WJDTgZ7t1nsM9C4{TfMfE%>13XBl_6UTuqJ>BUUrJj%`#sYyQHE(diU@W=h=UyT zE_$@R*ya_^d*;aBW~@SItpk#Nh45|hrXA5*jD;^@Ng(BS@Pu)bnHoT%PeAnuc|q(ueN(DeA7{c}e8nX-Vsu|E zvU+4Xr-YIFM7ST#a^CF>GZQi^LE#UVM}+g$5wlmcRy&;a4Ix>+hY*qe(>St*FZstz zl4~)9QUudWF%;rWw>QcK-HKHQN>h(3&4jxd|42;Dx@YDt+F2(Vd7Jp-GGIYSB%dQt=< zCF3@5G_)OHePtW)Y=_>Lim zo-g{-a{3JBqc#A%jn3F?aQ#d97um`cbU2P}rXQMvmOgLqS*h0J%)W|!5F`i$d?bz< zag^qh?4h^*^iS4i7|UPP#H6^*&KFwUoBi=mMEzWBaxaki3%Mk=j=I-(_&UU9=-jH(@E_Q7N}qk z+z%nbv*4s~%Q*lB4J?O8ZPrGRd46UuG!3tg1jTc(oI{9W4{owd8th)Zm_`$-ldXb4 zD075?ZRDMyAnqq!EKI1aWQa0|3k)ildMuI9TG@r=O)QhqET|webb6;VeKDZBrvgQrUTN_=@w4G?ogg z<{aMoj+qD8l?BmS#0015mNklI@N@su8Z?@?LKX+|5s>U@sMVYWA?`NMIj zPR!OZ)JH0$s3Z~?FeJ&=Mgx0s%^l*)0H%Izdp4<3qi^1y$!3Fh2pPeOm!j9ee@-9^@t%0wY-Vm!g5Qu{?32>{H+A^N8k2iD^(^J_R1!T_woJUVFdD6 zc2^1QvNai^Qhy16xYV%~7&;0ag;r1&HJnZD|Fn$_)A)hfLVeOqRh-f;?3vePp49Zq z1AYeS*Pw2}X3Cs3;3=8j{!N!0YMY(8OJoFHxDm4Oh7cd2av`znb z(IWsrC$k8}RG7QUD>FS3MP~A~I9*dN37-FE9&i_C*%*19>IbUW-1$J=ylG@?Rkm6M zFnpF11yXubR;xpQUQ3n?pk^!+iFG(qT)YhX<~;%tW?@y^=n4WBin*D?DXIqVnzW~|0hj{tEknwzIleg$&-%>zJUO3 zGxp>;btKE{lA(H87^9&I8#H}`jA8mxK<&#ZVDgZ$)DPO2+39?iD;mwnBUNX2n%l!F zn68^0vjA&8ucm}@8*{EBO?C*fQhN`T_9D%>=H)Wg#<|9+*{VzDFq^)d8wwn6|LlL< zHCrRHwQgGxZ6=(s#K4{2D%y**CyWqf;o-K6`U?1b4BARan&s&6n6)$p9a;tn9h3Ia zR=%rjMGr1FWWpzcP--d(78(IaZjfw7AxNpCI#F3KQz^;F;TnYxeeGwGWqMju(^+ah zaxJAusKNvRwY+oSX{Vnyee3VPStCwoOv_cDeny|x)zsk2*@%On4gzjYTq`IGM?kqN zEjCQW02UgZ#-(F?jMYNA5AHT9iIA0S8~RnK6HU~n7Z#M6qhXPV7NKw2#Me&43F^CW z_s+*t5$tmxzIeITGVXudlI7h|dLf{4vUUak2qln!VD<;e|HSA91v4NIRtmFbvQOvN z42wNAhY3`V%`vc|4GW;U00`bF%6g7dG*=qaC{3cVR?#N{+QJarzz(;z50C%0Dnk4M;n_xQ&vR6puadI4G0rcG>ZHASWxJQRb4Q1 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 diff --git a/02-particle-system/base/objects.py b/02-particle-system/base/objects.py index 708d5af..f18e8f2 100644 --- a/02-particle-system/base/objects.py +++ b/02-particle-system/base/objects.py @@ -57,15 +57,23 @@ def handle_event(self, event): class Object: - """The base class for all objects of the game.""" + """ + The base class for all objects of the game. + Controls: + - [d] Show the hitboxes for debugging. + """ + + # Controls the order of draw. + # Objects are sorted according to Z before drawing. Z = 0 # All the objects are considered circles, - # Their hitbox is scaled by the given amount, to the advantage of the player. + # Their hit-box is scaled by the given amount, to the advantage of the player. HIT_BOX_SCALE = 1.2 def __init__(self, pos, vel, sprite: pygame.Surface): + # The state is set when the object is added to a state. self.state: "State" = None self.center = pygame.Vector2(pos) self.vel = pygame.Vector2(vel) @@ -102,6 +110,7 @@ def rotated_sprite(self): return rotate_image(self.sprite, int(self.rotation)) def get_rect(self): + """Compute the rectangle containing the object.""" return self.rotated_sprite.get_rect(center=self.center) def handle_event(self, event): @@ -126,7 +135,7 @@ def draw(self, screen): (tl, bl, (w, 0)), (tr, br, (-w, 0)), ]: - # For each side of the screen that it overlaps + # For each side [a,b] of the screen that it overlaps if self.rect.clipline(a, b): shifts.append(offset) # Draw the spaceship at the other edge too. @@ -195,6 +204,7 @@ def logic(self): self.speed += raw_acceleration * self.ACCELERATION self.speed *= self.FRICTION # friction + # The min term makes it harder to turn at slow speed. self.rotation += rotation_acc * self.ROTATION_ACCELERATION * min(1.0, 0.4 + abs(self.speed)) self.vel.from_polar((self.speed, self.INITIAL_ROTATION - self.rotation)) @@ -209,6 +219,9 @@ def fire(self): bullet = Bullet(self.center, 270 - self.rotation) self.state.add(bullet) + # You can add particles here too. + ... + def on_asteroid_collision(self, asteroid: "Asteroid"): # For simplicity I just explode the asteroid, but depending on what you aim for, # it might be better to just loose some life or even reset the game... @@ -236,6 +249,9 @@ def logic(self, **kwargs): if self.time_to_live <= 0: self.alive = False + # Maybe some trail particles here ? You can put particles EVERYWHERE. Really. + ... + class Asteroid(Object): AVG_SPEED = 1 @@ -284,7 +300,8 @@ def explode(self, bullet): Asteroid(self.center, perp_velocity * mult, self.level - 1, self.color) ) - # Add particles here. + # You'll add particles here for sure ;) + ... def random_color(self): r, g, b = hsv_to_rgb(uniform(0, 1), 0.8, 0.8) @@ -292,10 +309,12 @@ def random_color(self): @classmethod def generate_many(cls, nb=10): + """Return a set of nb Asteroids randomly generated.""" objects = set() for _ in range(nb): angle = uniform(0, 360) - pos = SCREEN.center + from_polar(gauss(SIZE[1] / 2, SIZE[1] / 12), angle) + distance_from_center = gauss(SIZE[1] / 2, SIZE[1] / 12) + pos = SCREEN.center + from_polar(distance_from_center, angle) vel = from_polar(gauss(cls.AVG_SPEED, cls.AVG_SPEED / 6), gauss(180 + angle, 30)) size = choices([1, 2, 3, 4], [4, 3, 2, 1])[0] objects.add(cls(pos, vel, size)) diff --git a/02-particle-system/base/utils.py b/02-particle-system/base/utils.py index af91448..46d50b1 100644 --- a/02-particle-system/base/utils.py +++ b/02-particle-system/base/utils.py @@ -17,7 +17,6 @@ "random_in_rect", "from_polar", "clamp_vector", - "segments", "text", ] @@ -28,6 +27,7 @@ @lru_cache() def load_image(name: str, scale=1, alpha=True): + """Load a image from the disk and caches the results.""" image = pygame.image.load(ASSETS / f"{name}.png") if scale != 1: new_size = image.get_width() * scale, image.get_height() * scale @@ -68,18 +68,12 @@ def from_polar(rho, theta): def clamp_vector(v: pygame.Vector2, max_length): - """Ensure that a vector ahs a magnitude less than max_length.""" + """Ensure that a vector has a magnitude less than max_length.""" if v.length() > max_length: return v.normalize() * max_length return v -def segments(points): - """Return all the segments made from adjacent pairs of points in the list. - Also return the segment made of the last and first point.""" - return zip(points, points[1:] + [points[0]]) - - @lru_cache() def font(size=20, name=None): """ From f6d48d8eb0e91f8d11c6594cbfed0e1d8ebd8519 Mon Sep 17 00:00:00 2001 From: ddorn Date: Thu, 14 Oct 2021 11:30:55 +0200 Subject: [PATCH 49/80] 02: final version --- 02-particle-system/readme.md | 25 +++++++++++++++++++------ readme.md | 2 +- 2 files changed, 20 insertions(+), 7 deletions(-) diff --git a/02-particle-system/readme.md b/02-particle-system/readme.md index 75d9fe8..e96be88 100644 --- a/02-particle-system/readme.md +++ b/02-particle-system/readme.md @@ -10,11 +10,20 @@ so it is very handy to have a system already implemented for when a game jam com Description of the different levels and the amount of `C`hallenger `P`oints they provide: -- Casual `+3 CP`: Have 3 different particle effects of your choice in the game -- Ambitious `+2 CP`: Have 6 different particles effects and handle 1000 particles at 60 FPS -- Adventurous `+1 CP`: Have the asteroids break in pieces that together make up the original sprite. - -In any case, your particle system should be: +- Casual `+3 CP`: Have 3 different particle effects of your choice in the game +- Ambitious `+2 CP`: Have the asteroids break in pieces that together make up the original sprite, + in a somewhat "realistic" way. +- Adventurous `+1 CP`: + Have a reusable system that can handle a thousand particles at 60 FPS + with three of the following features (you choose!): + - Transparency + - Images as well as drawn particles + - Change colors overtime with multistep gradients + - Particle physics (colliding against walls, asteroids, ...) + - Ability to spawn a burst of particles but also spawn some over time + - A cool feature of your choice (mention it in the description of your entry!) + +In any case, your particle system should strive to be: - independent of the rest of your code (for instance, in it own file) so that you can copy/paste it in your other projects - run at 60 FPS, at least, so that there is still processing power for the rest of a real game @@ -26,11 +35,12 @@ The setup code in [`base/`](./base) consists of a simple Asteroids clone with a The code is a bit more complex than last time, so here's an overview. - [`main.py`](./base/main.py) contains basic boilerplate, with every method delegated to a `State` object. -- [`objects.py](./base/objects.py) contains many things: +- [`objects.py`](./base/objects.py) contains many things: - The `State` class, that represent everything in the game. It is probably the place were you will want to create your particle system / particle manager. This class contains all the `Object`s of the game, and is accessible from any object as `obj.state`. In order to add an object to the state, use `state.add(new_object)`, it will then be drawn and updated each frame automatically. Objects are removed from the state when `obj.alive == False`. + If you do not use a particle manager, you can add your particles directly to the state as with other objects. - The `Object` class, base class of all objects of the game (`Player`, `Asteroid`, `Bullet`). It takes care of drawing correctly the rotated sprites, detecting collisions and moving objects according to their velocity. You probably don't need to modify it. @@ -67,6 +77,9 @@ However, this challenge is a good chance to get more familiar with OOP. Make something specific, then think about how you could make it more reusable. Usable comes first, reusable comes second. +**Tip 4**: If you have already made a particle system before, make a new one! +Try to make it better, or explore other concepts, the possibilities are endless ;) + ### Credits - Asteroids: [Asteroids 02 by GameArtForge](https://opengameart.org/content/asteroids-set-02) diff --git a/readme.md b/readme.md index f6f1aea..83df848 100644 --- a/readme.md +++ b/readme.md @@ -17,7 +17,7 @@ The first season started on the 26th of September 2021 and will last about 3 mon 2. **[current]** [Particle System](./02-particle-system) - 11 oct 2021 → 25 oct 2021 -### Detailed instruction +### Detailed instructions You need to read [the detailed instructions](./general_instructions.md) in order to participate. They contain: From e655b0692700d32b28777880ce33133f37312090 Mon Sep 17 00:00:00 2001 From: gresm <> Date: Thu, 14 Oct 2021 13:19:56 +0200 Subject: [PATCH 50/80] added 'polastyn2030' folder --- 02-particle-system/polastyn2030/main.py | 62 +++ 02-particle-system/polastyn2030/objects.py | 373 ++++++++++++++++++ .../polastyn2030/requirements.txt | 8 + 02-particle-system/polastyn2030/utils.py | 97 +++++ 4 files changed, 540 insertions(+) create mode 100644 02-particle-system/polastyn2030/main.py create mode 100644 02-particle-system/polastyn2030/objects.py create mode 100644 02-particle-system/polastyn2030/requirements.txt create mode 100644 02-particle-system/polastyn2030/utils.py diff --git a/02-particle-system/polastyn2030/main.py b/02-particle-system/polastyn2030/main.py new file mode 100644 index 0000000..f803c69 --- /dev/null +++ b/02-particle-system/polastyn2030/main.py @@ -0,0 +1,62 @@ +import sys +from pathlib import Path + +try: + import wclib +except ImportError: + # wclib may not be in the path because of the architecture + # of all the challenges and the fact that there are many + # way to run them (through the showcase, or on their own) + + ROOT_FOLDER = Path(__file__).parent.parent.parent + sys.path.append(str(ROOT_FOLDER)) + import wclib + +# This line tells python how to handle the relative imports +# when you run this file directly. +__package__ = "02-particle-system." + Path(__file__).parent.name + +# ---- Recommended: don't modify anything above this line ---- # + +# Metadata about your submission +__author__ = "CozyFractal#0042" # Put yours! +__achievements__ = [ # Uncomment the ones you've done + # "Casual", + # "Ambitious", + # "Adventurous", +] + +# To import the modules in yourname/, you need to use relative imports, +# otherwise your project will not be compatible with the showcase. +# noinspection PyPackages +from .objects import * + +BACKGROUND = 0x0F1012 + + +def mainloop(): + pygame.init() + + player = Player((SIZE[0] / 2, SIZE[1] / 2), (0, 0)) + # The state is just a collection of all the objects in the game + state = State(player, FpsCounter(60), *Asteroid.generate_many()) + + while True: + screen, events = yield + for event in events: + if event.type == pygame.QUIT: + return + else: + state.handle_event(event) + + # Note: the logic for collisions is in the Asteroids class. + # This may seem arbitrary, but the only collisions that we consider + # are with asteroids. + state.logic() + + screen.fill(BACKGROUND) + state.draw(screen) + + +if __name__ == "__main__": + wclib.run(mainloop()) diff --git a/02-particle-system/polastyn2030/objects.py b/02-particle-system/polastyn2030/objects.py new file mode 100644 index 0000000..f18e8f2 --- /dev/null +++ b/02-particle-system/polastyn2030/objects.py @@ -0,0 +1,373 @@ +""" +This file provides objects that can be used to make up +a basic playground for the challenges. + +This code is provided so that you can focus on implementing +your particle system, without needing to implement a game that +goes with it too. +Feel free to modify everything in this file to your liking. +""" + +import time +from collections import deque +from colorsys import hsv_to_rgb +from functools import lru_cache +from operator import attrgetter +from random import gauss, choices, uniform + +import pygame + +# noinspection PyPackages +from .utils import * + + +class State: + def __init__(self, *initial_objects: "Object"): + self.objects = set() + self.objects_to_add = set() + + for obj in initial_objects: + self.add(obj) + + def add(self, obj: "Object"): + # We don't add objects immediately, + # as it could invalidate iterations. + self.objects_to_add.add(obj) + obj.state = self + return obj + + def logic(self): + to_remove = set() + for obj in self.objects: + obj.logic() + if not obj.alive: + to_remove.add(obj) + self.objects.difference_update(to_remove) + self.objects.update(self.objects_to_add) + self.objects_to_add.clear() + + def draw(self, screen): + for obj in sorted(self.objects, key=attrgetter("Z")): + obj.draw(screen) + + def handle_event(self, event): + for obj in self.objects: + if obj.handle_event(event): + break + + +class Object: + """ + The base class for all objects of the game. + + Controls: + - [d] Show the hitboxes for debugging. + """ + + # Controls the order of draw. + # Objects are sorted according to Z before drawing. + Z = 0 + + # All the objects are considered circles, + # Their hit-box is scaled by the given amount, to the advantage of the player. + HIT_BOX_SCALE = 1.2 + + def __init__(self, pos, vel, sprite: pygame.Surface): + # The state is set when the object is added to a state. + self.state: "State" = None + self.center = pygame.Vector2(pos) + self.vel = pygame.Vector2(vel) + self.sprite = sprite + self.rotation = 0.0 # for the sprite + self.alive = True + # Cache it every frame, as it was taking 10% (!!) of the processing power. + self.rect = self.get_rect() + + def __str__(self): + return f"<{self.__class__.__name__}(center={self.center}, vel={self.vel}, rotation={int(self.rotation)})>" + + @property + def radius(self): + """All objects are considered circles of this radius for collisions.""" + # The 1.2 is to be nicer to the player + return self.sprite.get_width() / 2 * self.HIT_BOX_SCALE + + def collide(self, other: "Object") -> bool: + """Whether two objects collide.""" + # The distance must be modified because everything wraps + dx = (self.center.x - other.center.x) % SIZE[0] + dx = min(dx, SIZE[0] - dx) + dy = (self.center.y - other.center.y) % SIZE[1] + dy = min(dy, SIZE[1] - dy) + return (dx ** 2 + dy ** 2) <= (self.radius + other.radius) ** 2 + + @property + def rotated_sprite(self): + # We round the rotation to the nearest integer so that + # the cache has a chance to work. Otherwise there would + # always be cache misses: it is very unlikely to have + # to floats that are equal. + return rotate_image(self.sprite, int(self.rotation)) + + def get_rect(self): + """Compute the rectangle containing the object.""" + return self.rotated_sprite.get_rect(center=self.center) + + def handle_event(self, event): + """Override this method to make an object react to events. + Returns True if the event was handled and should not be given to other objects.""" + return False + + def draw(self, screen): + screen.blit(self.rotated_sprite, self.rect) + + # Goal: wrap around the screen. + w, h = SIZE + tl = 0, 0 + tr = w, 0 + br = w, h + bl = 0, h + + shifts = [] + for a, b, offset in [ + (tl, tr, (0, h)), + (bl, br, (0, -h)), + (tl, bl, (w, 0)), + (tr, br, (-w, 0)), + ]: + # For each side [a,b] of the screen that it overlaps + if self.rect.clipline(a, b): + shifts.append(offset) + # Draw the spaceship at the other edge too. + screen.blit( + self.rotated_sprite, + self.rotated_sprite.get_rect(center=self.center + offset), + ) + + # Take care of the corners of the screen. + # Here I assume that no object can touch two sides of the screen + # at the same time. If so, the code wouldn't be correct, but still + # produce the expected result -.-' + assert len(shifts) <= 2 + if len(shifts) == 2: + screen.blit( + self.rotated_sprite, + self.rotated_sprite.get_rect(center=self.center + shifts[0] + shifts[1]), + ) + + # To see the exact size of the hitboxes + if pygame.key.get_pressed()[pygame.K_d]: + pygame.draw.circle(screen, "red", self.center, self.radius, width=1) + + def logic(self, **kwargs): + # self.vel = clamp_vector(self.vel, self.MAX_VEL) + self.center += self.vel + + self.center.x %= SIZE[0] + self.center.y %= SIZE[1] + + self.rect = self.get_rect() + + +class Player(Object): + Z = 10 + HIT_BOX_SCALE = 0.7 # harder to touch the player + ACCELERATION = 0.7 + FRICTION = 0.9 + ROTATION_ACCELERATION = 3 + INITIAL_ROTATION = 90 + FIRE_COOLDOWN = 15 # frames + + def __init__(self, pos, vel): + super().__init__(pos, vel, load_image("player", 3)) + + self.speed = 0 + self.fire_cooldown = -1 + + def handle_event(self, event): + if event.type == pygame.KEYDOWN: + if event.key == pygame.K_SPACE: + self.fire() + + def logic(self): + self.fire_cooldown -= 1 + + # For continuous shooting: + # if pressed[pygame.K_SPACE]: + # self.fire(new_objects) + + # Motion + pressed = pygame.key.get_pressed() + rotation_acc = pressed[pygame.K_LEFT] - pressed[pygame.K_RIGHT] + raw_acceleration = 0.5 * pressed[pygame.K_DOWN] - pressed[pygame.K_UP] + + self.speed += raw_acceleration * self.ACCELERATION + self.speed *= self.FRICTION # friction + + # The min term makes it harder to turn at slow speed. + self.rotation += rotation_acc * self.ROTATION_ACCELERATION * min(1.0, 0.4 + abs(self.speed)) + + self.vel.from_polar((self.speed, self.INITIAL_ROTATION - self.rotation)) + + super().logic() + + def fire(self): + if self.fire_cooldown >= 0: + return + + self.fire_cooldown = self.FIRE_COOLDOWN + bullet = Bullet(self.center, 270 - self.rotation) + self.state.add(bullet) + + # You can add particles here too. + ... + + def on_asteroid_collision(self, asteroid: "Asteroid"): + # For simplicity I just explode the asteroid, but depending on what you aim for, + # it might be better to just loose some life or even reset the game... + asteroid.explode(Bullet(self.center, self.rotation)) + + # Add particles here (and maybe damage the ship or something...) + ... + + +class Bullet(Object): + Z = 1 + SPEED = 10 + TIME_TO_LIVE = 60 * 2 + + def __init__(self, pos, angle): + super().__init__(pos, from_polar(self.SPEED, angle), load_image("bullet", 2)) + self.rotation = 90 - angle + self.time_to_live = self.TIME_TO_LIVE + + def logic(self, **kwargs): + super().logic(**kwargs) + + self.time_to_live -= 1 + + if self.time_to_live <= 0: + self.alive = False + + # Maybe some trail particles here ? You can put particles EVERYWHERE. Really. + ... + + +class Asteroid(Object): + AVG_SPEED = 1 + EXPLOSION_SPEED_BOOST = 1.8 + + def __init__(self, pos, vel, size=4, color=None): + assert 1 <= size <= 4 + self.level = size + # We copy to change the color + self.color = color or self.random_color() + + super().__init__(pos, vel, self.colored_image(size, self.color)) + + @staticmethod + @lru_cache(100) + def colored_image(size, color): + sprite = load_image(f"asteroid-{16*2**size}").copy() + sprite.fill(color, special_flags=pygame.BLEND_RGB_MULT) + return sprite + + def logic(self): + super().logic() + + for obj in self.state.objects: + if not obj.alive: + continue + + if isinstance(obj, Bullet): + # Detect if the bullet and asteroid collide. + if self.collide(obj): + self.explode(obj) + break + elif isinstance(obj, Player): + if self.collide(obj): + obj.on_asteroid_collision(self) + + def explode(self, bullet): + bullet.alive = False + self.alive = False + if self.level > 1: + # We spawn two smaller asteroids in the direction perpendicular to the collision. + perp_velocity = pygame.Vector2(bullet.vel.y, -bullet.vel.x) + perp_velocity.scale_to_length(self.vel.length() * self.EXPLOSION_SPEED_BOOST) + for mult in (-1, 1): + self.state.add( + Asteroid(self.center, perp_velocity * mult, self.level - 1, self.color) + ) + + # You'll add particles here for sure ;) + ... + + def random_color(self): + r, g, b = hsv_to_rgb(uniform(0, 1), 0.8, 0.8) + return int(r * 255), int(g * 255), int(b * 255) + + @classmethod + def generate_many(cls, nb=10): + """Return a set of nb Asteroids randomly generated.""" + objects = set() + for _ in range(nb): + angle = uniform(0, 360) + distance_from_center = gauss(SIZE[1] / 2, SIZE[1] / 12) + pos = SCREEN.center + from_polar(distance_from_center, angle) + vel = from_polar(gauss(cls.AVG_SPEED, cls.AVG_SPEED / 6), gauss(180 + angle, 30)) + size = choices([1, 2, 3, 4], [4, 3, 2, 1])[0] + objects.add(cls(pos, vel, size)) + + return objects + + +class FpsCounter(Object): + """ + A wrapper around pygame.time.Clock that shows the FPS on screen. + + Controls: + - [F] Toggles the display of FPS + - [U] Toggles the capping of FPS + """ + + Z = 1000 + REMEMBER = 30 + + def __init__(self, fps): + self.hidden = False + self.cap_fps = True + self.target_fps = fps + self.clock = pygame.time.Clock() + self.frame_starts = deque([time.time()], maxlen=self.REMEMBER) + + dummy_surface = pygame.Surface((1, 1)) + super().__init__((4, 8), (0, 0), dummy_surface) + + def handle_event(self, event): + if event.type == pygame.KEYDOWN: + if event.key == pygame.K_f: + self.hidden = not self.hidden + elif event.key == pygame.K_u: + self.cap_fps = not self.cap_fps + + def logic(self, **kwargs): + # Passing 0 to tick() removes the cap on FPS. + self.clock.tick(self.target_fps * self.cap_fps) + + self.frame_starts.append(time.time()) + + @property + def current_fps(self): + if len(self.frame_starts) <= 1: + return 0 + seconds = self.frame_starts[-1] - self.frame_starts[0] + return (len(self.frame_starts) - 1) / seconds + + def draw(self, screen): + if self.hidden: + return + + color = "#89C4F4" + t = text(f"FPS: {int(self.current_fps)}", color) + screen.blit(t, self.center) diff --git a/02-particle-system/polastyn2030/requirements.txt b/02-particle-system/polastyn2030/requirements.txt new file mode 100644 index 0000000..2a1e6fe --- /dev/null +++ b/02-particle-system/polastyn2030/requirements.txt @@ -0,0 +1,8 @@ +# Add here the extra requirements for your project. +# You cannot specify version numbers (yet). +# Lines starting with a "#" are ignored. +# DO NOT list pygame here. + +# Please try to limit you dependencies as much as you can + +# numpy diff --git a/02-particle-system/polastyn2030/utils.py b/02-particle-system/polastyn2030/utils.py new file mode 100644 index 0000000..46d50b1 --- /dev/null +++ b/02-particle-system/polastyn2030/utils.py @@ -0,0 +1,97 @@ +from functools import lru_cache +from pathlib import Path +from random import uniform + +import pygame + +from wclib.constants import SIZE, ROOT_DIR + +__all__ = [ + "SIZE", + "SUBMISSION_DIR", + "ASSETS", + "SCREEN", + "load_image", + "rotate_image", + "clamp", + "random_in_rect", + "from_polar", + "clamp_vector", + "text", +] + +SUBMISSION_DIR = Path(__file__).parent +ASSETS = SUBMISSION_DIR.parent / "assets" +SCREEN = pygame.Rect(0, 0, *SIZE) + + +@lru_cache() +def load_image(name: str, scale=1, alpha=True): + """Load a image from the disk and caches the results.""" + image = pygame.image.load(ASSETS / f"{name}.png") + if scale != 1: + new_size = image.get_width() * scale, image.get_height() * scale + image = pygame.transform.scale(image, new_size) + if alpha: + return image.convert_alpha() + else: + return image.convert() + + +@lru_cache() +def rotate_image(surf, angle: int): + """Rotate function that caches its results for performance.""" + return pygame.transform.rotate(surf, angle) + + +def clamp(value, mini, maxi): + """Clamp value between mini and maxi""" + if value < mini: + return mini + elif maxi < value: + return maxi + else: + return value + + +def random_in_rect(rect): + """Return a random point uniformly in a rectangle.""" + rect = pygame.Rect(rect) + return pygame.Vector2(uniform(rect.left, rect.right), uniform(rect.top, rect.bottom)) + + +def from_polar(rho, theta): + """Create a Vector2 from its polar representation.""" + v = pygame.Vector2() + v.from_polar((rho, theta)) + return v + + +def clamp_vector(v: pygame.Vector2, max_length): + """Ensure that a vector has a magnitude less than max_length.""" + if v.length() > max_length: + return v.normalize() * max_length + return v + + +@lru_cache() +def font(size=20, name=None): + """ + Load a font from its name in the wclib/assets folder. + + If a Path object is given as the name, this path will be used instead. + Results are cached. + """ + + name = name or "regular" + if isinstance(name, Path): + path = name + else: + path = ROOT_DIR / "wclib" / "assets" / (name + ".ttf") + return pygame.font.Font(path, size) + + +@lru_cache(5000) +def text(txt, color, size=20, font_name=None): + """Render a text on a surface. Results are cached.""" + return font(size, font_name).render(str(txt), True, color) From a251889e0502a2bc241c26a5c84860531159f9b3 Mon Sep 17 00:00:00 2001 From: gresm <> Date: Thu, 14 Oct 2021 17:12:26 +0200 Subject: [PATCH 51/80] dicord tag added --- 02-particle-system/polastyn2030/main.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/02-particle-system/polastyn2030/main.py b/02-particle-system/polastyn2030/main.py index f803c69..e400470 100644 --- a/02-particle-system/polastyn2030/main.py +++ b/02-particle-system/polastyn2030/main.py @@ -19,7 +19,7 @@ # ---- Recommended: don't modify anything above this line ---- # # Metadata about your submission -__author__ = "CozyFractal#0042" # Put yours! +__author__ = "polastyn#7640" # Put yours! __achievements__ = [ # Uncomment the ones you've done # "Casual", # "Ambitious", From 0f11636ba7b2aeca0d756754741656244cf4a6e6 Mon Sep 17 00:00:00 2001 From: gresm <> Date: Sat, 16 Oct 2021 12:52:57 +0200 Subject: [PATCH 52/80] + particle_system.py - added --- .../polastyn2030/particle_system.py | 42 +++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 02-particle-system/polastyn2030/particle_system.py diff --git a/02-particle-system/polastyn2030/particle_system.py b/02-particle-system/polastyn2030/particle_system.py new file mode 100644 index 0000000..02ab9b0 --- /dev/null +++ b/02-particle-system/polastyn2030/particle_system.py @@ -0,0 +1,42 @@ +import pygame as pg + + +# theoretically I could use system in 'objects.py', but the script must be independent +# and reusable in other projects, so I have to write it again... +# I'll remove this comment if I am going to re-use this code. +class BaseParticleObject: + def __init__( + self, surface: pg.Surface, + size: pg.Vector2, position: pg.Vector2, + rotation: float, bounding_box: pg.Rect + ): + self.source_surface = surface + self.size = size + self.position = position + self.rotation = rotation + self.source_rect = bounding_box + + self._smooth_scale = True + + @property + def surface(self): + copy = self.source_surface.copy() + + if self._smooth_scale: + copy = pg.transform.smoothscale(copy, self.tuple_size) + else: + copy = pg.transform.smoothscale(copy, self.tuple_size) + + copy = pg.transform.rotate(copy, self.rotation) + + return copy + + @property + def rect(self): + copy = self.source_rect.copy() + copy.topleft = pg.Vector2(copy.topleft) + self.position + return copy + + @property + def tuple_size(self): + return int(self.size.x), int(self.size.y) From 4566a8b5db207ea3921dec2c88e73a03c3668e97 Mon Sep 17 00:00:00 2001 From: gresm <> Date: Tue, 19 Oct 2021 20:39:38 +0200 Subject: [PATCH 53/80] ~ particle_system.py - dynamic surface added --- .../polastyn2030/particle_system.py | 92 ++++++++++++++++++- 1 file changed, 88 insertions(+), 4 deletions(-) diff --git a/02-particle-system/polastyn2030/particle_system.py b/02-particle-system/polastyn2030/particle_system.py index 02ab9b0..3acfb6f 100644 --- a/02-particle-system/polastyn2030/particle_system.py +++ b/02-particle-system/polastyn2030/particle_system.py @@ -1,12 +1,43 @@ -import pygame as pg - - # theoretically I could use system in 'objects.py', but the script must be independent # and reusable in other projects, so I have to write it again... # I'll remove this comment if I am going to re-use this code. + +from __future__ import annotations + + +from typing import Callable, TypeVar as _TypeVar + +import pygame as pg + + +class BaseDynamicSurface(pg.Surface): + # noinspection PyMissingConstructor + def __init__(self, source_surface: pg.Surface, *arg_configs, **kwarg_configs): + self.source_surface = source_surface + self.arg_configs = arg_configs + self.kwarg_configs = kwarg_configs + self.__names__ = {"source_surface", "arg_configs", "kwarg_configs", "tick", "map_self_to_new"} + + def __getattribute__(self, item: str): + if item.startswith("__") and item.endswith("__"): + return object.__getattribute__(self, item) + elif item in self.__names__: + return object.__getattribute__(self, item) + else: + return getattr(self.source_surface, item) + + def tick(self): + pass + + def map_self_to_new(self, surface: pg.Surface | None = None): + return self.__cls__( + surface if surface else self.source_surface, *self.arg_configs, **self.kwarg_configs + ) + + class BaseParticleObject: def __init__( - self, surface: pg.Surface, + self, surface: pg.Surface | BaseDynamicSurface, size: pg.Vector2, position: pg.Vector2, rotation: float, bounding_box: pg.Rect ): @@ -29,6 +60,9 @@ def surface(self): copy = pg.transform.rotate(copy, self.rotation) + if isinstance(self.source_surface, BaseDynamicSurface): + copy = self.source_surface.map_self_to_new(copy) + return copy @property @@ -40,3 +74,53 @@ def rect(self): @property def tuple_size(self): return int(self.size.x), int(self.size.y) + + +class DynamicParticle(BaseParticleObject): + def __init__( + self, + surface: pg.Surface | BaseDynamicSurface, size: pg.Vector2, + position: pg.Vector2, rotation: float, + bounding_box: pg.Rect, life_time: int, + speed: pg.Vector2, + rotation_speed: float, + scale_change: pg.Vector2 + ): + + super().__init__(surface, size, position, rotation, bounding_box) + self.life_time = life_time + + self.speed = speed + self.rotation_speed = rotation_speed + self.scale_change = scale_change + + @property + def alive(self): + return self.life_time > 0 + + def tick(self): + if not self.alive: + return + + self.life_time -= 1 + + self.__change("position", self.speed) + self.__change("rotation", self.rotation_speed) + self.__change("size", self.scale_change) + + if isinstance(self.surface, BaseDynamicSurface): + self.surface.tick() + + _T = _TypeVar("_T", bound=object) + + def __change(self, name: str, by: Callable[[_T], _T] | _T): + self.__change_value(name, getattr(self, name, None), by) + + def __change_value(self, name: str, data: _T, by: Callable[[_T], _T] | _T): + if getattr(by, "__call__", False): + setattr(self, name, by(data)) + else: + try: + setattr(self, name, data + by) + except TypeError: + pass From 7ac080d01b70b6d1ce99c409d33b9fa0aefa03c3 Mon Sep 17 00:00:00 2001 From: gresm <> Date: Sat, 23 Oct 2021 09:02:07 +0200 Subject: [PATCH 54/80] ~ particle_system.py - sprite support for particles --- .../polastyn2030/particle_system.py | 35 ++++++++++++------- 1 file changed, 23 insertions(+), 12 deletions(-) diff --git a/02-particle-system/polastyn2030/particle_system.py b/02-particle-system/polastyn2030/particle_system.py index 3acfb6f..4570235 100644 --- a/02-particle-system/polastyn2030/particle_system.py +++ b/02-particle-system/polastyn2030/particle_system.py @@ -35,20 +35,23 @@ def map_self_to_new(self, surface: pg.Surface | None = None): ) -class BaseParticleObject: - def __init__( - self, surface: pg.Surface | BaseDynamicSurface, - size: pg.Vector2, position: pg.Vector2, - rotation: float, bounding_box: pg.Rect - ): +class BaseParticleObject(pg.sprite.Sprite): + def __init__(self, surface: pg.Surface | BaseDynamicSurface, size: pg.Vector2, position: pg.Vector2, + rotation: float, bounding_box: pg.Rect, life_time: int): + super().__init__() self.source_surface = surface self.size = size self.position = position self.rotation = rotation self.source_rect = bounding_box + self.life_time = life_time self._smooth_scale = True + @property + def alive(self): + return self.life_time > 0 + @property def surface(self): copy = self.source_surface.copy() @@ -65,6 +68,10 @@ def surface(self): return copy + @property + def image(self): + return self.surface + @property def rect(self): copy = self.source_rect.copy() @@ -75,6 +82,15 @@ def rect(self): def tuple_size(self): return int(self.size.x), int(self.size.y) + def update(self, *args, **kwargs) -> None: + if not self.alive: + self.kill() + + self.tick() + + def tick(self): + pass + class DynamicParticle(BaseParticleObject): def __init__( @@ -87,17 +103,12 @@ def __init__( scale_change: pg.Vector2 ): - super().__init__(surface, size, position, rotation, bounding_box) - self.life_time = life_time + super().__init__(surface, size, position, rotation, bounding_box, life_time) self.speed = speed self.rotation_speed = rotation_speed self.scale_change = scale_change - @property - def alive(self): - return self.life_time > 0 - def tick(self): if not self.alive: return From 3fc1fcf285931632d6230c73ff7091e20720bada Mon Sep 17 00:00:00 2001 From: gresm <> Date: Sat, 23 Oct 2021 15:02:29 +0200 Subject: [PATCH 55/80] ~ particle_system.py - BaseParticleSpawner added --- .../polastyn2030/particle_system.py | 117 +++++++++++++++++- 1 file changed, 116 insertions(+), 1 deletion(-) diff --git a/02-particle-system/polastyn2030/particle_system.py b/02-particle-system/polastyn2030/particle_system.py index 4570235..4196b42 100644 --- a/02-particle-system/polastyn2030/particle_system.py +++ b/02-particle-system/polastyn2030/particle_system.py @@ -5,7 +5,8 @@ from __future__ import annotations -from typing import Callable, TypeVar as _TypeVar +from typing import Callable, TypeVar as _TypeVar, Type +import random as rd import pygame as pg @@ -135,3 +136,117 @@ def __change_value(self, name: str, data: _T, by: Callable[[_T], _T] | _T): setattr(self, name, data + by) except TypeError: pass + + +class RandomPos: + def __init__(self, center: pg.Vector2, pos_range: float | pg.Rect): + self.center = center + self.pos_range = pos_range + + def __get__(self, instance, owner): + if instance is None: + return self + + def get(self): + if isinstance(self.pos_range, float): + offset = pg.Vector2(1, 0) + offset.rotate(rd.randint(0, 360)) + offset *= rd.randint(0, int(self.pos_range)) + return self.center + offset + + x = rd.randint(0, self.pos_range.w) + y = rd.randint(0, self.pos_range.h) + + pos = pg.Vector2(x, y) + pos += pg.Vector2(self.pos_range.topleft) + + return pos + + +class RandomFloat: + def __init__(self, smallest: float, biggest: float): + self.smallest = smallest + self.biggest = biggest + + def __get__(self, instance, owner): + if instance is None: + return self + return self.get() + + def get(self): + random = rd.random() + diff = self.biggest - self.smallest + random *= diff + random += self.smallest + return random + + +class RandomInt(RandomFloat): + def get(self): + ret = super(RandomInt, self).get() + return int(ret) + + +class ParticleObjectInfo: + def __init__(self, + surface: pg.Surface | BaseDynamicSurface, + size: pg.Vector2 | RandomPos, + size_change: pg.Vector2 | RandomPos, + rotation: float | RandomFloat, + rotation_speed: float | RandomFloat, + life_time: int | RandomInt, + bounding_box: pg.Rect, + speed: float | RandomFloat, + moving_angle: float | RandomFloat, + particle_class: Type[DynamicParticle] | None = None + ): + self.surface = surface + self.size = size + self.size_change = size_change + self.rotation = rotation + self.rotation_speed = rotation_speed + self.life_time = life_time + self.bounding_box = bounding_box + self.speed = speed + self.angle = moving_angle + self.particle_class = particle_class if particle_class is not None else DynamicParticle + + +class ParticleSpawnerInfo: + def __init__( + self, + spawn_pos: pg.Vector2 | RandomPos, + spawn_delay: int | RandomInt, + object_info: ParticleObjectInfo + ): + self.spawn_pos = spawn_pos + self.spawn_delay = spawn_delay + self.object_info = object_info + + def generate(self): + info = self.object_info + speed = pg.Vector2(1, 0) * info.angle * info.speed + obj = self.object_info.particle_class( + info.surface, info.size, self.spawn_pos, info.rotation, info.bounding_box, + info.life_time, speed, info.rotation_speed, info.size_change + ) + return obj + + +class BaseParticleSpawner(pg.sprite.Group): + def __init__(self, info: ParticleSpawnerInfo): + super().__init__() + self.info = info + self.active = True + self.next_spawn = 0 + + def spawn(self): + self.add(self.info.generate()) + + def update(self, *args, **kwargs) -> None: + if self.active: + if self.next_spawn <= 0: + self.spawn() + self.next_spawn += self.info.spawn_delay + self.next_spawn -= 1 + super(BaseParticleSpawner, self).update(*args, **kwargs) From 2a901ed976bbcd631ab9a27d0fff95c58af4263f Mon Sep 17 00:00:00 2001 From: gresm <> Date: Sat, 23 Oct 2021 15:21:26 +0200 Subject: [PATCH 56/80] ~ particle_system.py - burst functionality added --- 02-particle-system/polastyn2030/particle_system.py | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/02-particle-system/polastyn2030/particle_system.py b/02-particle-system/polastyn2030/particle_system.py index 4196b42..40bc954 100644 --- a/02-particle-system/polastyn2030/particle_system.py +++ b/02-particle-system/polastyn2030/particle_system.py @@ -217,11 +217,13 @@ def __init__( self, spawn_pos: pg.Vector2 | RandomPos, spawn_delay: int | RandomInt, - object_info: ParticleObjectInfo + object_info: ParticleObjectInfo, + burst_function: Callable[[int], int] | None ): self.spawn_pos = spawn_pos self.spawn_delay = spawn_delay self.object_info = object_info + self.burst_function = burst_function def generate(self): info = self.object_info @@ -239,9 +241,15 @@ def __init__(self, info: ParticleSpawnerInfo): self.info = info self.active = True self.next_spawn = 0 + self.spawn_count = 0 def spawn(self): - self.add(self.info.generate()) + if self.info.burst_function: + for _ in range(self.info.burst_function(self.spawn_count)): + self.add(self.info.generate()) + else: + self.add(self.info.generate()) + self.spawn_count += 1 def update(self, *args, **kwargs) -> None: if self.active: From 9e46a0a07a0046d176ba509fcd8faf2970edabeb Mon Sep 17 00:00:00 2001 From: gresm <> Date: Mon, 25 Oct 2021 09:23:53 +0200 Subject: [PATCH 57/80] ~ particle_system_template.py - added --- .../polastyn2030/particle_system_template.py | 41 +++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 02-particle-system/polastyn2030/particle_system_template.py diff --git a/02-particle-system/polastyn2030/particle_system_template.py b/02-particle-system/polastyn2030/particle_system_template.py new file mode 100644 index 0000000..a27086d --- /dev/null +++ b/02-particle-system/polastyn2030/particle_system_template.py @@ -0,0 +1,41 @@ +""" +Typing part pg particle_system - required to run particle_system.py +""" +from __future__ import annotations +from typing import TypedDict, Tuple, Union + + +# Union[Tuple[float, float], Tuple[float, float, float, float]] +# Union[float, Tuple[float, float]] +# Union[int, Tuple[int, int]] +# Tuple[float, float, float, float] +class _NeededParticleTemplate(TypedDict): + size: Union[Tuple[float, float], Tuple[float, float, float, float]] + life_time: Union[int, Tuple[int, int]] + + +class _NotImportantParticleTemplate(TypedDict, total=False): + size_change: Union[Tuple[float, float], Tuple[float, float, float, float]] + rotation: Union[float, Tuple[float, float]] + rotation_speed: Union[float, Tuple[float, float]] + bounding_box: Tuple[float, float, float, float] + speed: Union[float, Tuple[float, float]] + moving_angle: Union[float, Tuple[float, float]] + + +class ParticleTemplate(_NeededParticleTemplate, _NotImportantParticleTemplate): + pass + + +particle_template_filler: _NotImportantParticleTemplate = _NotImportantParticleTemplate( + size_change=(0, 0), + rotation=0, + rotation_speed=0, + speed=0, + moving_angle=(0, 0) +) + + +class SpawnerTemplate(TypedDict): + spawn_pos: Union[Tuple[float, float], Tuple[float, float, float, float]] + spawn_delay: Union[int, Tuple[int, int]] From 5f543bb33e8e444dcbafff2b79b3186de4957f21 Mon Sep 17 00:00:00 2001 From: gresm <> Date: Mon, 25 Oct 2021 20:57:53 +0200 Subject: [PATCH 58/80] ~ particle_system.py - loading from template (in progress) --- .../polastyn2030/particle_system.py | 82 +++++++++++++++++-- .../polastyn2030/particle_system_template.py | 8 +- 2 files changed, 78 insertions(+), 12 deletions(-) diff --git a/02-particle-system/polastyn2030/particle_system.py b/02-particle-system/polastyn2030/particle_system.py index 40bc954..99eb38c 100644 --- a/02-particle-system/polastyn2030/particle_system.py +++ b/02-particle-system/polastyn2030/particle_system.py @@ -1,15 +1,15 @@ -# theoretically I could use system in 'objects.py', but the script must be independent -# and reusable in other projects, so I have to write it again... -# I'll remove this comment if I am going to re-use this code. - +""" +File for particle system +""" from __future__ import annotations - -from typing import Callable, TypeVar as _TypeVar, Type +from typing import Callable, TypeVar as _TypeVar, Type, cast, overload, Union, Tuple, Literal import random as rd import pygame as pg +import particle_system_template as pst + class BaseDynamicSurface(pg.Surface): # noinspection PyMissingConstructor @@ -245,8 +245,15 @@ def __init__(self, info: ParticleSpawnerInfo): def spawn(self): if self.info.burst_function: - for _ in range(self.info.burst_function(self.spawn_count)): - self.add(self.info.generate()) + # noinspection PyBroadException + try: + value = self.info.burst_function(self.spawn_count) + + for _ in range(value): + self.add(self.info.generate()) + except Exception: + self.info.burst_function = None + self.spawn() else: self.add(self.info.generate()) self.spawn_count += 1 @@ -258,3 +265,62 @@ def update(self, *args, **kwargs) -> None: self.next_spawn += self.info.spawn_delay self.next_spawn -= 1 super(BaseParticleSpawner, self).update(*args, **kwargs) + + +@overload +def _convert_to_valid( + data: Union[Tuple[float, float], Tuple[float, float, float], Tuple[float, float, float, float]], + mode: Literal["p", "pos", "v", "vector2", "Vector2"] +) -> pg.Vector2 | RandomPos: ... + + +@overload +def _convert_to_valid(data: Union[float, Tuple[float, float]], mode: Literal["f", "float"]) -> float | RandomFloat: ... + + +@overload +def _convert_to_valid(data: Union[int, Tuple[int, int]], mode: Literal["i", "int"]) -> int | RandomInt: ... + + +@overload +def _convert_to_valid(data: Tuple[float, float, float, float], mode: Literal["r", "rect", "Rect"]) -> pg.Rect: ... + + +def _convert_to_valid(data, mode): + if mode in {"p", "pos", "v", "vector2", "Vector2"}: + data = cast(Union[Tuple[float, float], Tuple[float, float, float], Tuple[float, float, float, float]], data) + if len(data) == 2: + return pg.Vector2(data) + elif len(data) == 3: + return RandomPos(pg.Vector2(data[:2]), data[2]) + else: + return RandomPos(pg.Vector2(data[:2]), pg.Rect(data)) + elif mode in {"f", "float"}: + data = cast(Union[float, Tuple[float, float]], data) + if isinstance(data, float): + return data + return RandomFloat(*data) + elif mode in {"i", "int"}: + data = cast(Union[int, Tuple[int, int]], data) + if isinstance(data, int): + return data + return RandomInt(*data) + elif mode in {"r", "rect", "Rect"}: + data = cast(Tuple[float, float, float, float], data) + return pg.Rect(data) + else: + raise TypeError("mode argument not in valid options") + + +def load_particle_info( + surface: pg.Surface, template: pst.ParticleTemplate, + particle_class: Type[DynamicParticle] | None = None +): + particle_class = particle_class if particle_class is not None else DynamicParticle + full_template = pst.particle_template_filler.copy() + full_template.update(dict(template)) + full_template = cast(pst.ParticleTemplate, full_template) + + +def load_spawner_info(template: pst.SpawnerTemplate, burst_function: Callable[[int], int] | None = None): + pass diff --git a/02-particle-system/polastyn2030/particle_system_template.py b/02-particle-system/polastyn2030/particle_system_template.py index a27086d..05eb6c5 100644 --- a/02-particle-system/polastyn2030/particle_system_template.py +++ b/02-particle-system/polastyn2030/particle_system_template.py @@ -5,17 +5,17 @@ from typing import TypedDict, Tuple, Union -# Union[Tuple[float, float], Tuple[float, float, float, float]] +# Union[Tuple[float, float], Tuple[float, float, float], Tuple[float, float, float, float]] # Union[float, Tuple[float, float]] # Union[int, Tuple[int, int]] # Tuple[float, float, float, float] class _NeededParticleTemplate(TypedDict): - size: Union[Tuple[float, float], Tuple[float, float, float, float]] + size: Union[Tuple[float, float], Tuple[float, float, float], Tuple[float, float, float, float]] life_time: Union[int, Tuple[int, int]] class _NotImportantParticleTemplate(TypedDict, total=False): - size_change: Union[Tuple[float, float], Tuple[float, float, float, float]] + size_change: Union[Tuple[float, float], Tuple[float, float, float], Tuple[float, float, float, float]] rotation: Union[float, Tuple[float, float]] rotation_speed: Union[float, Tuple[float, float]] bounding_box: Tuple[float, float, float, float] @@ -37,5 +37,5 @@ class ParticleTemplate(_NeededParticleTemplate, _NotImportantParticleTemplate): class SpawnerTemplate(TypedDict): - spawn_pos: Union[Tuple[float, float], Tuple[float, float, float, float]] + spawn_pos: Union[Tuple[float, float], Tuple[float, float, float], Tuple[float, float, float, float]] spawn_delay: Union[int, Tuple[int, int]] From 043fa7e1e0bcf43cd5ba932e594eeaf993a5b26e Mon Sep 17 00:00:00 2001 From: gresm <> Date: Mon, 25 Oct 2021 21:23:32 +0200 Subject: [PATCH 59/80] ~ particle_system.py - finished? --- .../polastyn2030/particle_system.py | 34 +++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-) diff --git a/02-particle-system/polastyn2030/particle_system.py b/02-particle-system/polastyn2030/particle_system.py index 99eb38c..056e824 100644 --- a/02-particle-system/polastyn2030/particle_system.py +++ b/02-particle-system/polastyn2030/particle_system.py @@ -312,6 +312,18 @@ def _convert_to_valid(data, mode): raise TypeError("mode argument not in valid options") +def _fix_particle_template(template: pst.ParticleTemplate): + translating = { + "size": "v", "life_time": "i", "size_change": "p", "rotation": "f", "rotation_speed": "f", + "bounding_box": "r", "speed": "f", "moving_angle": "f" + } + new = {} + for el in template: + # noinspection PyTypeChecker,PyTypedDict + new[el] = _convert_to_valid(template[el], translating[el]) + return new + + def load_particle_info( surface: pg.Surface, template: pst.ParticleTemplate, particle_class: Type[DynamicParticle] | None = None @@ -320,7 +332,25 @@ def load_particle_info( full_template = pst.particle_template_filler.copy() full_template.update(dict(template)) full_template = cast(pst.ParticleTemplate, full_template) + return ParticleObjectInfo(surface=surface, particle_class=particle_class, **_fix_particle_template(full_template)) + + +def load_spawner_info( + template: pst.SpawnerTemplate, + object_info: ParticleObjectInfo, + burst_function: Callable[[int], int] | None = None +): + spawn_pos = _convert_to_valid(template['spawn_pos'], "p") + spawn_delay = _convert_to_valid(template['spawn_delay'], 'i') + return ParticleSpawnerInfo(spawn_pos, spawn_delay, object_info, burst_function) -def load_spawner_info(template: pst.SpawnerTemplate, burst_function: Callable[[int], int] | None = None): - pass +def load_particle_spawner( + particle_template: pst.ParticleTemplate, + surface: pg.Surface, + spawner_template: pst.SpawnerTemplate, + particle_class: Type[DynamicParticle] | None = None, + burst_function: Callable[[int], int] | None = None +): + particle_info = load_particle_info(surface, particle_template, particle_class) + return load_spawner_info(spawner_template, particle_info, burst_function) From c2412254d09b58e53d8e003475e4050e48e86102 Mon Sep 17 00:00:00 2001 From: gresm <> Date: Mon, 25 Oct 2021 21:50:45 +0200 Subject: [PATCH 60/80] ~ particle_system.py - bug hunted --- 02-particle-system/polastyn2030/main.py | 2 +- .../polastyn2030/particle_system.py | 25 +++++++++++++------ .../polastyn2030/particle_system_template.py | 2 +- 3 files changed, 19 insertions(+), 10 deletions(-) diff --git a/02-particle-system/polastyn2030/main.py b/02-particle-system/polastyn2030/main.py index e400470..6eb3615 100644 --- a/02-particle-system/polastyn2030/main.py +++ b/02-particle-system/polastyn2030/main.py @@ -23,7 +23,7 @@ __achievements__ = [ # Uncomment the ones you've done # "Casual", # "Ambitious", - # "Adventurous", + "Adventurous", ] # To import the modules in yourname/, you need to use relative imports, diff --git a/02-particle-system/polastyn2030/particle_system.py b/02-particle-system/polastyn2030/particle_system.py index 056e824..81f0f5e 100644 --- a/02-particle-system/polastyn2030/particle_system.py +++ b/02-particle-system/polastyn2030/particle_system.py @@ -144,8 +144,7 @@ def __init__(self, center: pg.Vector2, pos_range: float | pg.Rect): self.pos_range = pos_range def __get__(self, instance, owner): - if instance is None: - return self + return self.get() def get(self): if isinstance(self.pos_range, float): @@ -169,8 +168,9 @@ def __init__(self, smallest: float, biggest: float): self.biggest = biggest def __get__(self, instance, owner): - if instance is None: - return self + return self.get() + + def __float__(self): return self.get() def get(self): @@ -227,7 +227,7 @@ def __init__( def generate(self): info = self.object_info - speed = pg.Vector2(1, 0) * info.angle * info.speed + speed = pg.Vector2(1, 0).rotate(float(self.object_info.angle)) * self.object_info.speed obj = self.object_info.particle_class( info.surface, info.size, self.spawn_pos, info.rotation, info.bounding_box, info.life_time, speed, info.rotation_speed, info.size_change @@ -299,6 +299,8 @@ def _convert_to_valid(data, mode): data = cast(Union[float, Tuple[float, float]], data) if isinstance(data, float): return data + elif isinstance(data, int): + return float(data) return RandomFloat(*data) elif mode in {"i", "int"}: data = cast(Union[int, Tuple[int, int]], data) @@ -332,7 +334,12 @@ def load_particle_info( full_template = pst.particle_template_filler.copy() full_template.update(dict(template)) full_template = cast(pst.ParticleTemplate, full_template) - return ParticleObjectInfo(surface=surface, particle_class=particle_class, **_fix_particle_template(full_template)) + fixed = _fix_particle_template(full_template) + + if "bounding_box" not in fixed: + fixed["bounding_box"] = surface.get_rect() + + return ParticleObjectInfo(surface=surface, particle_class=particle_class, **fixed) def load_spawner_info( @@ -350,7 +357,9 @@ def load_particle_spawner( surface: pg.Surface, spawner_template: pst.SpawnerTemplate, particle_class: Type[DynamicParticle] | None = None, - burst_function: Callable[[int], int] | None = None + burst_function: Callable[[int], int] | None = None, + spawner_class: Type[BaseParticleSpawner] | None = None ): + spawner_class = spawner_class if spawner_class is not None else BaseParticleSpawner particle_info = load_particle_info(surface, particle_template, particle_class) - return load_spawner_info(spawner_template, particle_info, burst_function) + return spawner_class(load_spawner_info(spawner_template, particle_info, burst_function)) diff --git a/02-particle-system/polastyn2030/particle_system_template.py b/02-particle-system/polastyn2030/particle_system_template.py index 05eb6c5..0c96d3a 100644 --- a/02-particle-system/polastyn2030/particle_system_template.py +++ b/02-particle-system/polastyn2030/particle_system_template.py @@ -32,7 +32,7 @@ class ParticleTemplate(_NeededParticleTemplate, _NotImportantParticleTemplate): rotation=0, rotation_speed=0, speed=0, - moving_angle=(0, 0) + moving_angle=0 ) From 4146498804009bbd059773771588ef6cf1dc039c Mon Sep 17 00:00:00 2001 From: gresm <> Date: Wed, 27 Oct 2021 17:00:35 +0200 Subject: [PATCH 61/80] ~ particle_system.py - bug hunting part 2 ~ main.py - test !!Not working!! --- 02-particle-system/polastyn2030/main.py | 14 ++++ .../polastyn2030/particle_system.py | 82 +++++++++++++++++-- 2 files changed, 89 insertions(+), 7 deletions(-) diff --git a/02-particle-system/polastyn2030/main.py b/02-particle-system/polastyn2030/main.py index 6eb3615..43055fc 100644 --- a/02-particle-system/polastyn2030/main.py +++ b/02-particle-system/polastyn2030/main.py @@ -30,6 +30,12 @@ # otherwise your project will not be compatible with the showcase. # noinspection PyPackages from .objects import * +# noinspection PyPackages +from .particle_system import load_particle_spawner as load +# noinspection PyPackages +from .particle_system_template import ParticleTemplate, SpawnerTemplate +# noinspection PyPackages +from . import particle_system as par BACKGROUND = 0x0F1012 @@ -40,6 +46,12 @@ def mainloop(): player = Player((SIZE[0] / 2, SIZE[1] / 2), (0, 0)) # The state is just a collection of all the objects in the game state = State(player, FpsCounter(60), *Asteroid.generate_many()) + image = pygame.Surface((10, 10)) + image.fill((255, 255, 255)) + spawner = load( + ParticleTemplate(life_time=100, size=(20, 20, 20, 20), speed=(10, 20), moving_angle=(-90, 90)), + image, SpawnerTemplate(spawn_pos=(30, 30, 30), spawn_delay=0) + ) while True: screen, events = yield @@ -53,9 +65,11 @@ def mainloop(): # This may seem arbitrary, but the only collisions that we consider # are with asteroids. state.logic() + spawner.update() screen.fill(BACKGROUND) state.draw(screen) + spawner.draw(screen) if __name__ == "__main__": diff --git a/02-particle-system/polastyn2030/particle_system.py b/02-particle-system/polastyn2030/particle_system.py index 81f0f5e..762524a 100644 --- a/02-particle-system/polastyn2030/particle_system.py +++ b/02-particle-system/polastyn2030/particle_system.py @@ -3,12 +3,27 @@ """ from __future__ import annotations +from builtins import super from typing import Callable, TypeVar as _TypeVar, Type, cast, overload, Union, Tuple, Literal import random as rd import pygame as pg -import particle_system_template as pst +try: + # noinspection PyPackages + from . import particle_system_template as pst +except ImportError: + import particle_system_template as pst + + +class _FixedGetAttr: + def __getattribute__(self, item: str): + data = super().__getattribute__(item) + try: + data = data.__get__(self, self.__class__) + except AttributeError: + pass + return data class BaseDynamicSurface(pg.Surface): @@ -36,7 +51,7 @@ def map_self_to_new(self, surface: pg.Surface | None = None): ) -class BaseParticleObject(pg.sprite.Sprite): +class BaseParticleObject(_FixedGetAttr, pg.sprite.Sprite): def __init__(self, surface: pg.Surface | BaseDynamicSurface, size: pg.Vector2, position: pg.Vector2, rotation: float, bounding_box: pg.Rect, life_time: int): super().__init__() @@ -142,10 +157,24 @@ class RandomPos: def __init__(self, center: pg.Vector2, pos_range: float | pg.Rect): self.center = center self.pos_range = pos_range + self.__names__ = {"center", "pos_range", "get"} def __get__(self, instance, owner): return self.get() + def __getattribute__(self, item: str): + if item.startswith("__") and item.endswith("__"): + try: + return super().__getattribute__(item) + except ValueError: + val = self.get() + return getattr(val, item) + elif item in self.__names__: + return super().__getattribute__(item) + else: + val = self.get() + return getattr(val, item) + def get(self): if isinstance(self.pos_range, float): offset = pg.Vector2(1, 0) @@ -163,15 +192,27 @@ def get(self): class RandomFloat: + # noinspection PyInitNewSignature def __init__(self, smallest: float, biggest: float): self.smallest = smallest self.biggest = biggest + self.__names__ = {"smallest", "biggest", "get"} def __get__(self, instance, owner): return self.get() - def __float__(self): - return self.get() + def __getattribute__(self, item: str): + if item.startswith("__") and item.endswith("__"): + try: + return super().__getattribute__(item) + except ValueError: + val = self.get() + return getattr(val, item) + elif item in self.__names__: + return super().__getattribute__(item) + else: + val = self.get() + return getattr(val, item) def get(self): random = rd.random() @@ -187,7 +228,34 @@ def get(self): return int(ret) -class ParticleObjectInfo: +class RemotePos(RandomPos): + # noinspection PyMissingConstructor + def __init__(self, obj: object, attr: str): + self.obj = obj + self.attr = attr + self.__names__ = {"obj", "attr", "get"} + + def get(self): + return pg.Vector2(getattr(self.obj, self.attr)) + + +class RemoteFloat(RandomFloat): + # noinspection PyMissingConstructor + def __init__(self, obj: object, attr: str): + self.obj = obj + self.attr = attr + self.__names__ = {"obj", "attr", "get"} + + def get(self): + return float(getattr(self.obj, self.attr)) + + +class RemoteInt(RemoteFloat): + def get(self): + return int(super(RemoteInt, self).get()) + + +class ParticleObjectInfo(_FixedGetAttr): def __init__(self, surface: pg.Surface | BaseDynamicSurface, size: pg.Vector2 | RandomPos, @@ -212,7 +280,7 @@ def __init__(self, self.particle_class = particle_class if particle_class is not None else DynamicParticle -class ParticleSpawnerInfo: +class ParticleSpawnerInfo(_FixedGetAttr): def __init__( self, spawn_pos: pg.Vector2 | RandomPos, @@ -227,7 +295,7 @@ def __init__( def generate(self): info = self.object_info - speed = pg.Vector2(1, 0).rotate(float(self.object_info.angle)) * self.object_info.speed + speed = pg.Vector2(1, 0).rotate(info.angle) * info.speed obj = self.object_info.particle_class( info.surface, info.size, self.spawn_pos, info.rotation, info.bounding_box, info.life_time, speed, info.rotation_speed, info.size_change From 79b4eefed0a6e924dde22777dc16ccb4da2a1d8b Mon Sep 17 00:00:00 2001 From: gresm <> Date: Wed, 27 Oct 2021 17:49:35 +0200 Subject: [PATCH 62/80] ~ particle_system.py - limit to particle generator added ~ main.py - test !Now working! --- 02-particle-system/polastyn2030/main.py | 8 +++-- .../polastyn2030/particle_system.py | 35 +++++++++++++------ .../polastyn2030/particle_system_template.py | 1 + 3 files changed, 30 insertions(+), 14 deletions(-) diff --git a/02-particle-system/polastyn2030/main.py b/02-particle-system/polastyn2030/main.py index 43055fc..c7d5450 100644 --- a/02-particle-system/polastyn2030/main.py +++ b/02-particle-system/polastyn2030/main.py @@ -49,9 +49,11 @@ def mainloop(): image = pygame.Surface((10, 10)) image.fill((255, 255, 255)) spawner = load( - ParticleTemplate(life_time=100, size=(20, 20, 20, 20), speed=(10, 20), moving_angle=(-90, 90)), - image, SpawnerTemplate(spawn_pos=(30, 30, 30), spawn_delay=0) + ParticleTemplate(life_time=10, size=(5, 5), speed=(10, 20)), + image, SpawnerTemplate(spawn_pos=(30, 30, 30), spawn_delay=0, limit=10) ) + spawner.info.spawn_pos = par.RemotePos(player, "center") + spawner.info.object_info.angle = par.RemoteFloat(player, "rotation", "-x+90") while True: screen, events = yield @@ -68,8 +70,8 @@ def mainloop(): spawner.update() screen.fill(BACKGROUND) - state.draw(screen) spawner.draw(screen) + state.draw(screen) if __name__ == "__main__": diff --git a/02-particle-system/polastyn2030/particle_system.py b/02-particle-system/polastyn2030/particle_system.py index 762524a..8bb552d 100644 --- a/02-particle-system/polastyn2030/particle_system.py +++ b/02-particle-system/polastyn2030/particle_system.py @@ -19,6 +19,10 @@ class _FixedGetAttr: def __getattribute__(self, item: str): data = super().__getattribute__(item) + + if item.startswith("__") and item.endswith("__"): + return data + try: data = data.__get__(self, self.__class__) except AttributeError: @@ -176,7 +180,7 @@ def __getattribute__(self, item: str): return getattr(val, item) def get(self): - if isinstance(self.pos_range, float): + if isinstance(self.pos_range, (float, int)): offset = pg.Vector2(1, 0) offset.rotate(rd.randint(0, 360)) offset *= rd.randint(0, int(self.pos_range)) @@ -230,24 +234,26 @@ def get(self): class RemotePos(RandomPos): # noinspection PyMissingConstructor - def __init__(self, obj: object, attr: str): + def __init__(self, obj: object, attr: str, op: str = "x"): self.obj = obj self.attr = attr - self.__names__ = {"obj", "attr", "get"} + self.op = op + self.__names__ = {"obj", "attr", "op", "get"} def get(self): - return pg.Vector2(getattr(self.obj, self.attr)) + return eval(self.op, {}, {"x": pg.Vector2(getattr(self.obj, self.attr))}) class RemoteFloat(RandomFloat): # noinspection PyMissingConstructor - def __init__(self, obj: object, attr: str): + def __init__(self, obj: object, attr: str, op: str = "x"): self.obj = obj self.attr = attr - self.__names__ = {"obj", "attr", "get"} + self.op = op + self.__names__ = {"obj", "attr", "op", "get"} def get(self): - return float(getattr(self.obj, self.attr)) + return eval(self.op, {}, {"x": float(getattr(self.obj, self.attr))}) class RemoteInt(RemoteFloat): @@ -286,11 +292,13 @@ def __init__( spawn_pos: pg.Vector2 | RandomPos, spawn_delay: int | RandomInt, object_info: ParticleObjectInfo, - burst_function: Callable[[int], int] | None + limit: int = -1, + burst_function: Callable[[int], int] | None = None ): self.spawn_pos = spawn_pos self.spawn_delay = spawn_delay self.object_info = object_info + self.limit = limit self.burst_function = burst_function def generate(self): @@ -305,11 +313,15 @@ def generate(self): class BaseParticleSpawner(pg.sprite.Group): def __init__(self, info: ParticleSpawnerInfo): - super().__init__() self.info = info self.active = True self.next_spawn = 0 self.spawn_count = 0 + super().__init__() + + def add(self, *sprites: pg.Sprite) -> None: + if len(self) < self.info.limit: + super(BaseParticleSpawner, self).add(*sprites) def spawn(self): if self.info.burst_function: @@ -416,8 +428,9 @@ def load_spawner_info( burst_function: Callable[[int], int] | None = None ): spawn_pos = _convert_to_valid(template['spawn_pos'], "p") - spawn_delay = _convert_to_valid(template['spawn_delay'], 'i') - return ParticleSpawnerInfo(spawn_pos, spawn_delay, object_info, burst_function) + spawn_delay = _convert_to_valid(template['spawn_delay'], "i") + limit = _convert_to_valid(template['limit'], "i") + return ParticleSpawnerInfo(spawn_pos, spawn_delay, object_info, limit, burst_function) def load_particle_spawner( diff --git a/02-particle-system/polastyn2030/particle_system_template.py b/02-particle-system/polastyn2030/particle_system_template.py index 0c96d3a..a3a8e20 100644 --- a/02-particle-system/polastyn2030/particle_system_template.py +++ b/02-particle-system/polastyn2030/particle_system_template.py @@ -39,3 +39,4 @@ class ParticleTemplate(_NeededParticleTemplate, _NotImportantParticleTemplate): class SpawnerTemplate(TypedDict): spawn_pos: Union[Tuple[float, float], Tuple[float, float, float], Tuple[float, float, float, float]] spawn_delay: Union[int, Tuple[int, int]] + limit: Union[int, Tuple[int, int]] From fe2eb06ea9a2389703cdca350218636cf11201ae Mon Sep 17 00:00:00 2001 From: gresm <> Date: Wed, 27 Oct 2021 18:14:09 +0200 Subject: [PATCH 63/80] ~ particle_system.py - added functionality to offset RandomFloat range --- 02-particle-system/polastyn2030/main.py | 4 +++- .../polastyn2030/particle_system.py | 20 +++++++++++++++++-- 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/02-particle-system/polastyn2030/main.py b/02-particle-system/polastyn2030/main.py index c7d5450..f940422 100644 --- a/02-particle-system/polastyn2030/main.py +++ b/02-particle-system/polastyn2030/main.py @@ -53,7 +53,8 @@ def mainloop(): image, SpawnerTemplate(spawn_pos=(30, 30, 30), spawn_delay=0, limit=10) ) spawner.info.spawn_pos = par.RemotePos(player, "center") - spawner.info.object_info.angle = par.RemoteFloat(player, "rotation", "-x+90") + spawner_angle = par.RandomFloat(-10, 10) + spawner.info.object_info.angle = spawner_angle while True: screen, events = yield @@ -67,6 +68,7 @@ def mainloop(): # This may seem arbitrary, but the only collisions that we consider # are with asteroids. state.logic() + spawner_angle.move_center(-player.rotation+90) spawner.update() screen.fill(BACKGROUND) diff --git a/02-particle-system/polastyn2030/particle_system.py b/02-particle-system/polastyn2030/particle_system.py index 8bb552d..373b853 100644 --- a/02-particle-system/polastyn2030/particle_system.py +++ b/02-particle-system/polastyn2030/particle_system.py @@ -79,7 +79,7 @@ def surface(self): if self._smooth_scale: copy = pg.transform.smoothscale(copy, self.tuple_size) else: - copy = pg.transform.smoothscale(copy, self.tuple_size) + copy = pg.transform.scale(copy, self.tuple_size) copy = pg.transform.rotate(copy, self.rotation) @@ -200,7 +200,7 @@ class RandomFloat: def __init__(self, smallest: float, biggest: float): self.smallest = smallest self.biggest = biggest - self.__names__ = {"smallest", "biggest", "get"} + self.__names__ = {"smallest", "biggest", "get", "move_left", "move_right", "move_center"} def __get__(self, instance, owner): return self.get() @@ -225,6 +225,22 @@ def get(self): random += self.smallest return random + def move_left(self, to: float): + diff = self.biggest - self.smallest + self.smallest = to + self.biggest = to + diff + + def move_right(self, to: float): + diff = self.biggest - self.smallest + self.biggest = to + self.smallest = to - diff + + def move_center(self, to: float): + diff = self.biggest - self.smallest + half = diff / 2 + self.smallest = to - half + self.biggest = to + half + class RandomInt(RandomFloat): def get(self): From f0e5a1ee904504dec2b8d9ab6d5f2bfb014cf211 Mon Sep 17 00:00:00 2001 From: gresm <> Date: Sat, 27 Nov 2021 12:03:45 +0100 Subject: [PATCH 64/80] + my_entry (for bouncing bubbles) --- 04-bouncing-bubbles/polastyn/main.py | 225 +++++++++++++++++++ 04-bouncing-bubbles/polastyn/metadata.py | 36 +++ 04-bouncing-bubbles/polastyn/utils.py | 266 +++++++++++++++++++++++ 3 files changed, 527 insertions(+) create mode 100644 04-bouncing-bubbles/polastyn/main.py create mode 100644 04-bouncing-bubbles/polastyn/metadata.py create mode 100644 04-bouncing-bubbles/polastyn/utils.py diff --git a/04-bouncing-bubbles/polastyn/main.py b/04-bouncing-bubbles/polastyn/main.py new file mode 100644 index 0000000..b4a8c3c --- /dev/null +++ b/04-bouncing-bubbles/polastyn/main.py @@ -0,0 +1,225 @@ +import sys +from dataclasses import dataclass +from pathlib import Path +from random import gauss, uniform, randint +from typing import List, Optional + +import pygame + +# This line tells python how to handle the relative imports +# when you run this file directly. Don't modify this line. +__package__ = "04-bouncing-bubbles." + Path(__file__).absolute().parent.name + +# To import the modules in yourname/, you need to use relative imports, +# otherwise your project will not be compatible with the showcase. +from .utils import * + +BACKGROUND = 0x0F1012 +NB_BUBBLES = 42 + + +class Bubble: + MAX_VELOCITY = 7 + + def __init__(self, position=None): + self.radius = int(gauss(25, 5)) + + if position is None: + # Default position is random. + self.position = pygame.Vector2( + randint(self.radius, SIZE[0] - self.radius), + randint(self.radius, SIZE[1] - self.radius), + ) + else: + self.position = position + + # Set a random direction and a speed of around 3. + self.velocity = pygame.Vector2() + self.velocity.from_polar((gauss(3, 0.5), uniform(0, 360))) + + # Pick a random color with high saturation and value. + self.color = pygame.Color(0) + self.color.hsva = uniform(0, 360), 80, 80, 100 + + @property + def mass(self): + return self.radius ** 2 + + def draw(self, screen: pygame.Surface): + pygame.draw.circle(screen, self.color, self.position, self.radius) + + def move_away_from_mouse(self, mouse_pos: pygame.Vector2): + """Apply a force on the bubble to move away from the mouse.""" + bubble_to_mouse = mouse_pos - self.position + distance_to_mouse = bubble_to_mouse.length() + if 0 < distance_to_mouse < 200: + strength = chrange(distance_to_mouse, (0, 200), (1, 0), power=2) + self.velocity -= bubble_to_mouse.normalize() * strength + + def move(self): + """Move the bubble according to its velocity.""" + # We first limit the velocity to not get bubbles that go faster than what we can enjoy. + if self.velocity.length() > self.MAX_VELOCITY: + self.velocity.scale_to_length(self.MAX_VELOCITY) + + self.position += self.velocity + debug.vector(self.velocity, self.position, scale=10) + + def collide_borders(self): + # The first challenge is to make the bubbles bounce against the border. + # Hover that doesn't mean that a bubble must always be completely inside of the screen: + # If for instance it spawned on the edge, we don't want it to teleport so that it fits the screen, + # we want everything to be *smooooth*. + # + # To be sure it is smooth, a good rule is to never modify self.position directly, + # but instead modify self.velocity when needed. + # + # The second golden principle is to be lazy and not do anything if the collision will + # resolve itself naturally in a few frames, that is, if the bubble is already moving + # away from the wall. + + # TODO: handle collisions for each of the four edges. + + if not "self-resolving collision with left wall": + self.velocity.x *= -1 + ... + + # Remove this. It is only a placeholder to keep the bubble inside the screen + self.position.x %= SIZE[0] + self.position.y %= SIZE[1] + + def collide(self, other: "Bubble") -> Optional["Collision"]: + """Get the collision data if there is a collision with the other Bubble""" + return None + + +# The second challenge contains two parts. +# The first one is to generate a list of all the collisions +# between bubbles. +# The data for a collision is stored into the Collision class below, +# and is generated by the Bubble.collide method above. +# The second part is then to process those collision data, and resolve them. + + +@dataclass +class Collision: + """ + The data of a collision consist of four attributes. + + [first] and [second] are the the two objects that collided. + [center] is the collision point, that is, the point from which you + would like to push both circles away from. It corresponds to the center + of the overlapping area of the two moving circles, which is also the + midpoint between the two centers. + [normal] is the axis along which the two circles should bounce. That is, + if two bubbles move horizontally they bounce against the vertical axis, + so normal would be a vertical vector. + """ + + first: "Bubble" + second: "Bubble" + center: pygame.Vector2 + normal: pygame.Vector2 + + def resolve(self): + """Apply a force on both colliding object to help them move out of collision.""" + + # The second part of the Ambitious challenge is to resolve the collisions that we have collected. + # (See below in World.logic for how all this is put together). + + # TODO: Resolve the collision. + # Resolving a collision, here, means to modify the velocity of the two bubbles + # so that they move out of collision. Not necessarly in one frame, but if + # they move away from each other for say 2-5 frames, the collision will be resolved. + + # To do so, add a force to the velocity of each bubble to help the two bubbles to separate. + # The separating force is perpendicular to the normal, similarly to how bubbles bounce + # against a wall: only the part of the velocity perpendicular to the wall is reflected. + # Keep in mind that one bubble an have multiple collisions at the same time. + # You may need to define extra methods. + # If you have troubles handling the mass of the particles, start by assuming they + # have a mass of 1, and then upgrade your code to take the mass into account. + + ... + + +# The world is a list of bubbles. +class World(List[Bubble]): + def __init__(self, nb): + super().__init__(Bubble() for _ in range(nb)) + + def logic(self, mouse_position: pygame.Vector2): + """Handles the collision and evolution of all the objects.""" + + # Second part of the ambitious challenge is to make the algorithm that solves the collisions. + # A part of it is already provided so that you can focus on the important part. + + # We start by moving the bubbles and do the collisions with the static objects, the walls. + for bubble in self: + bubble.move() + bubble.collide_borders() + bubble.move_away_from_mouse(mouse_position) + + # Then we check each pair of bubbles to collect all collisions. + collisions = [] + for i, b1 in enumerate(self): + for b2 in self[i + 1 :]: + collision = b1.collide(b2) + if collision: + collisions.append(collision) + + # And finally we resolve them all at once, so that it doesn't impact the detection of collision. + for collision in collisions: + collision.resolve() + + def draw(self, screen): + for bubble in self: + bubble.draw(screen) + + +def mainloop(): + pygame.init() + + world = World(NB_BUBBLES) + + mouse_position = pygame.Vector2() + + fps_counter = FpsCounter(60, Bubbles=world) + while True: + screen, events = yield + for event in events: + if event.type == pygame.QUIT: + return + elif event.type == pygame.MOUSEMOTION: + mouse_position.xy = event.pos + elif event.type == pygame.MOUSEBUTTONDOWN: + world.append(Bubble(event.pos)) + debug.handle_event(event) + fps_counter.handle_event(event) + + # Handle the collisions + world.logic(mouse_position) + fps_counter.logic() + + # Drawing the screen + screen.fill(BACKGROUND) + world.draw(screen) + fps_counter.draw(screen) + debug.draw(screen) + + +# ---- Recommended: don't modify anything below this line ---- # +if __name__ == "__main__": + try: + # Note: your editor might say that this is an error, but it's not. + # Most editors can't understand that we are messing with the path. + import wclib + except ImportError: + # wclib may not be in the path because of the architecture + # of all the challenges and the fact that there are many + # way to run them (through the showcase, or on their own) + ROOT_FOLDER = Path(__file__).absolute().parent.parent.parent + sys.path.append(str(ROOT_FOLDER)) + import wclib + + wclib.run(mainloop()) diff --git a/04-bouncing-bubbles/polastyn/metadata.py b/04-bouncing-bubbles/polastyn/metadata.py new file mode 100644 index 0000000..f5ab638 --- /dev/null +++ b/04-bouncing-bubbles/polastyn/metadata.py @@ -0,0 +1,36 @@ +# Do not change the class name. +class Metadata: + # Your discord name and tag, so that we can award you the points + # in the leaderboards. + discord_tag = "polastyn2030#7640" + + # The name that should be diplayed below your entry in the menu. + display_name = "polastyn" + + # All the challenges that you think you have achieved. + # Uncomment each one that you have done and not only the highest. + achievements = [ + # "Casual", + # "Ambitious", + # "Adventurous", + ] + + # The lowest python version on which your code can run. + # It is specified as a tuple, so (3, 7) mean python 3.7 + # If you don't know how retro-compatible your code is, + # set this to your python version. + # In order to have the most people to run your entry, try to + # keep the minimum version as low as possible (ie. don't use + # match, := etc... + min_python_version = (3, 7) + + # A list of all the modules that one should install + # to run your entry. Each string is what you would pass to + # the import statement. + # Each line will be passed to pip install if needed, but you cannot + # (yet?) specify version constraints. Modules that have a different name + # on install and import are also not supported. If you need it, + # please open an issue on the GitHub. + dependencies = [ + # "numpy", + ] diff --git a/04-bouncing-bubbles/polastyn/utils.py b/04-bouncing-bubbles/polastyn/utils.py new file mode 100644 index 0000000..5ed757e --- /dev/null +++ b/04-bouncing-bubbles/polastyn/utils.py @@ -0,0 +1,266 @@ +import time +from collections import deque +from functools import lru_cache +from pathlib import Path +from typing import Tuple, Sized + +import pygame + +from wclib.constants import SIZE, ROOT_DIR + +__all__ = [ + "SIZE", + "SUBMISSION_DIR", + "ASSETS", + "SCREEN", + "load_image", + "text", + "chrange", + "FpsCounter", + "debug", +] + +SUBMISSION_DIR = Path(__file__).parent +ASSETS = SUBMISSION_DIR.parent / "assets" +SCREEN = pygame.Rect(0, 0, *SIZE) + + +@lru_cache() +def load_image(name: str, scale=1, alpha=True, base: Path = ASSETS): + """Load an image from the global assets folder given its name. + + If [base] is given, load a n image from this folder instead. + For instance you can pass SUBMISSION_DIR to load an image from your own directory. + + If [scale] is not one, scales the images in both directions by the given factor. + + The function automatically calls convert_alpha() but if transparency is not needed, + one can set [alpha] to False to .convert() the image instead. + + The results are cached, so this function returns the same surface every time it + is called with the same arguments. If you want to modify the returned surface, + .copy() it first. + """ + + image = pygame.image.load(base / f"{name}.png") + if scale != 1: + new_size = int(image.get_width() * scale), int(image.get_height() * scale) + image = pygame.transform.scale(image, new_size) + + if alpha: + return image.convert_alpha() + else: + return image.convert() + + +@lru_cache() +def font(size=20, name=None): + """ + Load a font from its name in the wclib/assets folder. + + If a Path object is given as the name, this path will be used instead. + This way, you can use custom fonts that are inside your own folder. + Results are cached. + """ + + name = name or "regular" + if isinstance(name, Path): + path = name + else: + path = ROOT_DIR / "wclib" / "assets" / (name + ".ttf") + return pygame.font.Font(path, size) + + +@lru_cache(5000) +def text(txt, color, size=20, font_name=None): + """Render a text on a surface. Results are cached.""" + return font(size, font_name).render(str(txt), True, color) + + +def chrange( + x: float, + initial_range: Tuple[float, float], + target_range: Tuple[float, float], + power=1, + flipped=False, +): + """Change the range of a number by mapping the initial_range to target_range using a linear transformation.""" + normalised = (x - initial_range[0]) / (initial_range[1] - initial_range[0]) + normalised **= power + if flipped: + normalised = 1 - normalised + return normalised * (target_range[1] - target_range[0]) + target_range[0] + + +class FpsCounter: + """ + A wrapper around pygame.time.Clock that shows the FPS on screen. + + It can also show the lengths of different collections (nb of objects/particles...). + + Controls: + - [F] Toggles the display of FPS + - [U] Toggles the capping of FPS + """ + + Z = 1000 + REMEMBER = 30 + + def __init__(self, fps, **counters: Sized): + """ + Show and manage the FPS of the game. + + Args: + fps: the desired number of frames per second. + **counters: pairs of labels and collections + whose size will be displayed. + """ + + self.hidden = False + self.cap_fps = True + self.target_fps = fps + self.clock = pygame.time.Clock() + self.frame_starts = deque([time.time()], maxlen=self.REMEMBER) + self.counters = counters + + def handle_event(self, event): + if event.type == pygame.KEYDOWN: + if event.key == pygame.K_f: + self.hidden = not self.hidden + elif event.key == pygame.K_u: + self.cap_fps = not self.cap_fps + + def logic(self, **kwargs): + # Passing 0 to tick() removes the cap on FPS. + self.clock.tick(self.target_fps * self.cap_fps) + + self.frame_starts.append(time.time()) + + @property + def current_fps(self): + if len(self.frame_starts) <= 1: + return 0 + seconds = self.frame_starts[-1] - self.frame_starts[0] + return (len(self.frame_starts) - 1) / seconds + + def draw(self, screen): + if self.hidden: + return + + color = "#89C4F4" + t = text(f"FPS: {int(self.current_fps)}", color) + r = screen.blit(t, t.get_rect(topleft=(15, 15))) + + for label, collection in self.counters.items(): + t = text(f"{label}: {len(collection)}", color) + r = screen.blit(t, r.bottomleft) + + +class Debug: + """ + This class helps with graphical debuging. + It allows to draw points, vectors, rectangles and text + on top of the window at any moment of the execution. + + You can use this from any function to visualise vectors, + intermediates computations and anything that you would like to know + the value without printing it. + It is + + All debug drawing disapear after one frame, except the texts + for which the last [texts_to_keep] stay on the screen so that there + is sufficient time to read them. + + All debug methods return their arguments so that can be chained. + For instance, you can write: + + >>> debug = Debug() + >>> pos += debug.vector(velocity, pos) + + Which is equivalent to: + + >>> pos += velocity + But also draws the [velocity] vector centered at [pos] so that you see it. + """ + + def __init__(self, texts_to_keep=20): + self.texts_to_keep = texts_to_keep + + self.points = [] + self.vectors = [] + self.rects = [] + self.texts = [] + self.nb_txt_this_frame = 0 + + # Backup to restore if the game is paused, + # this way, anotations are not lost when objects + # are not updated anymore. + self.lasts = [[], [], [], []] + + self.enabled = False + self.paused = False + + def point(self, x, y, color="red"): + """Draw a point on the screen.""" + if self.enabled: + self.points.append((x, y, color)) + return x, y + + def vector(self, vec, anchor, color="red", scale=1): + """Draw a vector centered at [anchor] on the next frame. + It can be useful to [scale] if the expected length is too small or too large.""" + if self.enabled: + self.vectors.append((pygame.Vector2(anchor), pygame.Vector2(vec) * scale, color)) + return vec + + def rectangle(self, rect, color="red"): + """Draw a rectangle on the next frame.""" + if self.enabled: + self.rects.append((rect, color)) + return rect + + def text(self, *obj): + """Draw a text on the screen until there too many texts.""" + if self.enabled: + self.texts.append(obj) + self.nb_txt_this_frame += 1 + + def handle_event(self, event): + if event.type == pygame.KEYDOWN and event.key == pygame.K_d: + self.enabled = not self.enabled + + def draw(self, screen: pygame.Surface): + if not self.enabled: + return + + if self.paused: + self.points, self.vectors, self.rects, self.texts = self.lasts + + for (x, y, color) in self.points: + pygame.draw.circle(screen, color, (x, y), 1) + + for (anchor, vec, color) in self.vectors: + pygame.draw.line(screen, color, anchor, anchor + vec) + + for rect, color in self.rects: + pygame.draw.rect(screen, color, rect, 1) + + y = SIZE[1] - 15 + for i, obj in enumerate(self.texts): + color = "white" if len(self.texts) - i - 1 >= self.nb_txt_this_frame else "yellow" + s = text(" ".join(map(str, obj)), color) + r = screen.blit(s, s.get_rect(bottomleft=(15, y))) + y = r.top + + # Clear everything for the next frame. + self.lasts = [self.points, self.vectors, self.rects, self.texts] + self.points = [] + self.vectors = [] + self.rects = [] + self.texts = self.texts[-self.texts_to_keep:] + if not self.paused: + self.nb_txt_this_frame = 0 + + +# Global debug instance, accessible from everywhere. +debug = Debug() From 72f7f0f9df3694c72bdb67441137bf5751c99c7c Mon Sep 17 00:00:00 2001 From: gresm <> Date: Sat, 27 Nov 2021 21:55:05 +0100 Subject: [PATCH 65/80] ~ main.py - collision detection --- 04-bouncing-bubbles/polastyn/main.py | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/04-bouncing-bubbles/polastyn/main.py b/04-bouncing-bubbles/polastyn/main.py index b4a8c3c..9ec6ba0 100644 --- a/04-bouncing-bubbles/polastyn/main.py +++ b/04-bouncing-bubbles/polastyn/main.py @@ -31,7 +31,7 @@ def __init__(self, position=None): randint(self.radius, SIZE[1] - self.radius), ) else: - self.position = position + self.position: pygame.Vector2 = position # Set a random direction and a speed of around 3. self.velocity = pygame.Vector2() @@ -90,6 +90,19 @@ def collide_borders(self): def collide(self, other: "Bubble") -> Optional["Collision"]: """Get the collision data if there is a collision with the other Bubble""" + diff = other.position - self.position + diff_len = diff.length() + + if diff_len <= self.radius + other.radius: + left_to_right_way = diff / diff_len + right_to_left_way = left_to_right_way * -1 + left_collided_point = self.position + left_to_right_way * self.radius + right_collided_point = other.position + right_to_left_way * other.radius + center_collision_point = (right_collided_point - left_collided_point) / 2 + left_collided_point + + rotated_way = diff.rotate(90) + + return Collision(self, other, center_collision_point, rotated_way) return None @@ -163,7 +176,7 @@ def logic(self, mouse_position: pygame.Vector2): # Then we check each pair of bubbles to collect all collisions. collisions = [] for i, b1 in enumerate(self): - for b2 in self[i + 1 :]: + for b2 in self[i + 1:]: collision = b1.collide(b2) if collision: collisions.append(collision) From 3b2d1414a67e41c03c4431c8f551207638550533 Mon Sep 17 00:00:00 2001 From: gresm <> Date: Sun, 28 Nov 2021 21:19:22 +0100 Subject: [PATCH 66/80] ~ main.py - debug info added --- 04-bouncing-bubbles/polastyn/main.py | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/04-bouncing-bubbles/polastyn/main.py b/04-bouncing-bubbles/polastyn/main.py index 9ec6ba0..990e74b 100644 --- a/04-bouncing-bubbles/polastyn/main.py +++ b/04-bouncing-bubbles/polastyn/main.py @@ -101,6 +101,9 @@ def collide(self, other: "Bubble") -> Optional["Collision"]: center_collision_point = (right_collided_point - left_collided_point) / 2 + left_collided_point rotated_way = diff.rotate(90) + rotated_way = rotated_way / rotated_way.length() + + debug.vector(rotated_way * 20, center_collision_point, "blue") return Collision(self, other, center_collision_point, rotated_way) return None @@ -210,9 +213,17 @@ def mainloop(): debug.handle_event(event) fps_counter.handle_event(event) - # Handle the collisions - world.logic(mouse_position) - fps_counter.logic() + if pygame.key.get_pressed()[pygame.K_SPACE]: + collisions = [] + for i, b1 in enumerate(world): + for b2 in world[i + 1:]: + collision = b1.collide(b2) + if collision: + collisions.append(collision) + else: + # Handle the collisions + world.logic(mouse_position) + fps_counter.logic() # Drawing the screen screen.fill(BACKGROUND) From 1b56a13bf96d5564011787bd1af99b714cf3b22e Mon Sep 17 00:00:00 2001 From: gresm <> Date: Sun, 28 Nov 2021 21:41:13 +0100 Subject: [PATCH 67/80] ~ main.py - walls collision simple --- 04-bouncing-bubbles/polastyn/main.py | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/04-bouncing-bubbles/polastyn/main.py b/04-bouncing-bubbles/polastyn/main.py index 990e74b..ecda9b0 100644 --- a/04-bouncing-bubbles/polastyn/main.py +++ b/04-bouncing-bubbles/polastyn/main.py @@ -41,6 +41,8 @@ def __init__(self, position=None): self.color = pygame.Color(0) self.color.hsva = uniform(0, 360), 80, 80, 100 + self.border = pygame.display.get_window_size() + @property def mass(self): return self.radius ** 2 @@ -65,6 +67,13 @@ def move(self): self.position += self.velocity debug.vector(self.velocity, self.position, scale=10) + def how_colliding_border(self): + left = self.position.x - self.radius <= 0 + right = self.position.x + self.radius >= self.border[0] + top = self.position.y - self.radius <= 0 + down = self.position.y + self.radius >= self.border[1] + return left, right, top, down + def collide_borders(self): # The first challenge is to make the bubbles bounce against the border. # Hover that doesn't mean that a bubble must always be completely inside of the screen: @@ -78,15 +87,13 @@ def collide_borders(self): # resolve itself naturally in a few frames, that is, if the bubble is already moving # away from the wall. - # TODO: handle collisions for each of the four edges. + # TODO: Make it smooth and without glitches. - if not "self-resolving collision with left wall": + collided = self.how_colliding_border() + if collided[0] or collided[1]: self.velocity.x *= -1 - ... - - # Remove this. It is only a placeholder to keep the bubble inside the screen - self.position.x %= SIZE[0] - self.position.y %= SIZE[1] + if collided[2] or collided[3]: + self.velocity.y *= -1 def collide(self, other: "Bubble") -> Optional["Collision"]: """Get the collision data if there is a collision with the other Bubble""" From f92f71694a1db0385358970a8ebfb3f4633858cf Mon Sep 17 00:00:00 2001 From: gresm <> Date: Sun, 28 Nov 2021 22:00:04 +0100 Subject: [PATCH 68/80] ~ main.py - walls collision final --- 04-bouncing-bubbles/polastyn/main.py | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/04-bouncing-bubbles/polastyn/main.py b/04-bouncing-bubbles/polastyn/main.py index ecda9b0..66dfb0b 100644 --- a/04-bouncing-bubbles/polastyn/main.py +++ b/04-bouncing-bubbles/polastyn/main.py @@ -43,6 +43,8 @@ def __init__(self, position=None): self.border = pygame.display.get_window_size() + self._fix_force = 5 + @property def mass(self): return self.radius ** 2 @@ -90,10 +92,21 @@ def collide_borders(self): # TODO: Make it smooth and without glitches. collided = self.how_colliding_border() - if collided[0] or collided[1]: - self.velocity.x *= -1 - if collided[2] or collided[3]: - self.velocity.y *= -1 + if collided[0]: + change = min(self.velocity.x * 0.25, -self._fix_force) + self.velocity.x -= change + + if collided[1]: + change = max(self.velocity.x * 0.25, self._fix_force) + self.velocity.x -= change + + if collided[2]: + change = min(self.velocity.y * 0.25, -self._fix_force) + self.velocity.y -= change + + if collided[3]: + change = max(self.velocity.y * 0.25, self._fix_force) + self.velocity.y -= change def collide(self, other: "Bubble") -> Optional["Collision"]: """Get the collision data if there is a collision with the other Bubble""" From 09e4f46821efd73e68a4779209403a8062050c9e Mon Sep 17 00:00:00 2001 From: gresm <> Date: Mon, 29 Nov 2021 08:49:10 +0100 Subject: [PATCH 69/80] ~ main.py - 1 todo removed --- 04-bouncing-bubbles/polastyn/main.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/04-bouncing-bubbles/polastyn/main.py b/04-bouncing-bubbles/polastyn/main.py index 66dfb0b..703bca4 100644 --- a/04-bouncing-bubbles/polastyn/main.py +++ b/04-bouncing-bubbles/polastyn/main.py @@ -89,8 +89,6 @@ def collide_borders(self): # resolve itself naturally in a few frames, that is, if the bubble is already moving # away from the wall. - # TODO: Make it smooth and without glitches. - collided = self.how_colliding_border() if collided[0]: change = min(self.velocity.x * 0.25, -self._fix_force) From 96e1e2aa5f0944735ad3bf56b94d682e4ce5f33d Mon Sep 17 00:00:00 2001 From: gresm <> Date: Mon, 29 Nov 2021 09:07:19 +0100 Subject: [PATCH 70/80] ~ main.py - first try to make bouncing bubbles --- 04-bouncing-bubbles/polastyn/main.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/04-bouncing-bubbles/polastyn/main.py b/04-bouncing-bubbles/polastyn/main.py index 703bca4..596fe7f 100644 --- a/04-bouncing-bubbles/polastyn/main.py +++ b/04-bouncing-bubbles/polastyn/main.py @@ -18,6 +18,10 @@ NB_BUBBLES = 42 +def mul_vectors(v1: pygame.Vector2, v2: pygame.Vector2): + return pygame.Vector2(v1.x * v2.x, v1.y * v2.y) + + class Bubble: MAX_VELOCITY = 7 @@ -174,7 +178,8 @@ def resolve(self): # If you have troubles handling the mass of the particles, start by assuming they # have a mass of 1, and then upgrade your code to take the mass into account. - ... + self.first.velocity = mul_vectors(self.first.velocity, self.normal) + self.second.velocity = mul_vectors(self.second.velocity, self.normal) # The world is a list of bubbles. @@ -243,6 +248,9 @@ def mainloop(): world.logic(mouse_position) fps_counter.logic() + if pygame.key.get_pressed()[pygame.K_c]: + world.clear() + # Drawing the screen screen.fill(BACKGROUND) world.draw(screen) From fd322c754d2c93f803702993be10b8fd8f9e8d35 Mon Sep 17 00:00:00 2001 From: gresm <> Date: Mon, 29 Nov 2021 10:02:19 +0100 Subject: [PATCH 71/80] ~ main.py - bouncing bubbles (final) --- 04-bouncing-bubbles/polastyn/main.py | 18 +++++++++++++++--- 04-bouncing-bubbles/polastyn/metadata.py | 2 +- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/04-bouncing-bubbles/polastyn/main.py b/04-bouncing-bubbles/polastyn/main.py index 596fe7f..b317639 100644 --- a/04-bouncing-bubbles/polastyn/main.py +++ b/04-bouncing-bubbles/polastyn/main.py @@ -22,6 +22,14 @@ def mul_vectors(v1: pygame.Vector2, v2: pygame.Vector2): return pygame.Vector2(v1.x * v2.x, v1.y * v2.y) +def perp_vec(vec: pygame.Vector2): + return pygame.Vector2(vec.y, -vec.x) + + +def counter_perp_vec(vec: pygame.Vector2): + return pygame.Vector2(-vec.y, vec.x) + + class Bubble: MAX_VELOCITY = 7 @@ -122,7 +130,7 @@ def collide(self, other: "Bubble") -> Optional["Collision"]: right_collided_point = other.position + right_to_left_way * other.radius center_collision_point = (right_collided_point - left_collided_point) / 2 + left_collided_point - rotated_way = diff.rotate(90) + rotated_way = perp_vec(diff) rotated_way = rotated_way / rotated_way.length() debug.vector(rotated_way * 20, center_collision_point, "blue") @@ -178,8 +186,12 @@ def resolve(self): # If you have troubles handling the mass of the particles, start by assuming they # have a mass of 1, and then upgrade your code to take the mass into account. - self.first.velocity = mul_vectors(self.first.velocity, self.normal) - self.second.velocity = mul_vectors(self.second.velocity, self.normal) + v1 = perp_vec(self.normal * self.first.velocity.length()) + v2 = counter_perp_vec(self.normal * self.second.velocity.length()) + self.first.velocity += v1 + self.second.velocity += v2 + debug.vector(v1, self.first.position, "green") + debug.vector(v2, self.second.position, "green") # The world is a list of bubbles. diff --git a/04-bouncing-bubbles/polastyn/metadata.py b/04-bouncing-bubbles/polastyn/metadata.py index f5ab638..74fb41e 100644 --- a/04-bouncing-bubbles/polastyn/metadata.py +++ b/04-bouncing-bubbles/polastyn/metadata.py @@ -10,7 +10,7 @@ class Metadata: # All the challenges that you think you have achieved. # Uncomment each one that you have done and not only the highest. achievements = [ - # "Casual", + "Casual", # "Ambitious", # "Adventurous", ] From 62f5fcb1317d83119f855a06e6d4c17960a9d965 Mon Sep 17 00:00:00 2001 From: gresm <> Date: Mon, 29 Nov 2021 14:37:48 +0100 Subject: [PATCH 72/80] ~ main.py - removed all TODOs --- 04-bouncing-bubbles/polastyn/main.py | 1 - 04-bouncing-bubbles/polastyn/metadata.py | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/04-bouncing-bubbles/polastyn/main.py b/04-bouncing-bubbles/polastyn/main.py index b317639..293e2f8 100644 --- a/04-bouncing-bubbles/polastyn/main.py +++ b/04-bouncing-bubbles/polastyn/main.py @@ -173,7 +173,6 @@ def resolve(self): # The second part of the Ambitious challenge is to resolve the collisions that we have collected. # (See below in World.logic for how all this is put together). - # TODO: Resolve the collision. # Resolving a collision, here, means to modify the velocity of the two bubbles # so that they move out of collision. Not necessarly in one frame, but if # they move away from each other for say 2-5 frames, the collision will be resolved. diff --git a/04-bouncing-bubbles/polastyn/metadata.py b/04-bouncing-bubbles/polastyn/metadata.py index 74fb41e..e553494 100644 --- a/04-bouncing-bubbles/polastyn/metadata.py +++ b/04-bouncing-bubbles/polastyn/metadata.py @@ -11,7 +11,7 @@ class Metadata: # Uncomment each one that you have done and not only the highest. achievements = [ "Casual", - # "Ambitious", + "Ambitious", # "Adventurous", ] From b5c9e40fca3b267762e1f850906ef3d1d32b52ea Mon Sep 17 00:00:00 2001 From: gresm <> Date: Tue, 30 Nov 2021 08:33:47 +0100 Subject: [PATCH 73/80] ~ main.py - + 1TODO --- 04-bouncing-bubbles/polastyn/main.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/04-bouncing-bubbles/polastyn/main.py b/04-bouncing-bubbles/polastyn/main.py index 293e2f8..2dcbbff 100644 --- a/04-bouncing-bubbles/polastyn/main.py +++ b/04-bouncing-bubbles/polastyn/main.py @@ -31,6 +31,7 @@ def counter_perp_vec(vec: pygame.Vector2): class Bubble: + # TODO: add rectangular variant MAX_VELOCITY = 7 def __init__(self, position=None): @@ -53,8 +54,6 @@ def __init__(self, position=None): self.color = pygame.Color(0) self.color.hsva = uniform(0, 360), 80, 80, 100 - self.border = pygame.display.get_window_size() - self._fix_force = 5 @property @@ -83,9 +82,9 @@ def move(self): def how_colliding_border(self): left = self.position.x - self.radius <= 0 - right = self.position.x + self.radius >= self.border[0] + right = self.position.x + self.radius >= SIZE[0] top = self.position.y - self.radius <= 0 - down = self.position.y + self.radius >= self.border[1] + down = self.position.y + self.radius >= SIZE[1] return left, right, top, down def collide_borders(self): From a51b84f8f1ad630f1c404dd4a6a9af5f0da69e4e Mon Sep 17 00:00:00 2001 From: gresm <> Date: Tue, 30 Nov 2021 22:20:25 +0100 Subject: [PATCH 74/80] ~ main.py - added weak support for rectangles + line_intersection.py - file for detecting line intersection. --- .../polastyn/line_intersection.py | 76 +++++++++++++++++++ 04-bouncing-bubbles/polastyn/main.py | 31 ++++++-- 2 files changed, 100 insertions(+), 7 deletions(-) create mode 100644 04-bouncing-bubbles/polastyn/line_intersection.py diff --git a/04-bouncing-bubbles/polastyn/line_intersection.py b/04-bouncing-bubbles/polastyn/line_intersection.py new file mode 100644 index 0000000..8c4bb8b --- /dev/null +++ b/04-bouncing-bubbles/polastyn/line_intersection.py @@ -0,0 +1,76 @@ +""" +This file is not mine! +The code was grabbed from: https://www.geeksforgeeks.org/check-if-two-given-line-segments-intersect/ +and reformatted. +Credits goes to the creator: Ansh Riyal +""" + + +# Given three collinear points p, q, r, the function checks if +# point q lies on line segment 'pr' +def on_segment(p, q, r): + if ((q.x <= max(p.x, r.x)) and (q.x >= min(p.x, r.x)) and + (q.y <= max(p.y, r.y)) and (q.y >= min(p.y, r.y))): + return True + return False + + +def orientation(p, q, r): + # to find the orientation of an ordered triplet (p,q,r) + # function returns the following values: + # 0 : Collinear points + # 1 : Clockwise points + # 2 : Counterclockwise + + # See https://www.geeksforgeeks.org/orientation-3-ordered-points/amp/ + # for details of below formula. + + val = (float(q.y - p.y) * (r.x - q.x)) - (float(q.x - p.x) * (r.y - q.y)) + if val > 0: + + # Clockwise orientation + return 1 + elif val < 0: + + # Counterclockwise orientation + return 2 + else: + + # Collinear orientation + return 0 + + +# The main function that returns true if +# the line segment 'p1q1' and 'p2q2' intersect. +def do_intersect(p1, q1, p2, q2): + # Find the 4 orientations required for + # the general and special cases + o1 = orientation(p1, q1, p2) + o2 = orientation(p1, q1, q2) + o3 = orientation(p2, q2, p1) + o4 = orientation(p2, q2, q1) + + # General case + if (o1 != o2) and (o3 != o4): + return True + + # Special Cases + + # p1 , q1 and p2 are collinear and p2 lies on segment p1q1 + if (o1 == 0) and on_segment(p1, p2, q1): + return True + + # p1 , q1 and q2 are collinear and q2 lies on segment p1q1 + if (o2 == 0) and on_segment(p1, q2, q1): + return True + + # p2 , q2 and p1 are collinear and p1 lies on segment p2q2 + if (o3 == 0) and on_segment(p2, p1, q2): + return True + + # p2 , q2 and q1 are collinear and q1 lies on segment p2q2 + if (o4 == 0) and on_segment(p2, q1, q2): + return True + + # If none of the cases + return False diff --git a/04-bouncing-bubbles/polastyn/main.py b/04-bouncing-bubbles/polastyn/main.py index 2dcbbff..cb233aa 100644 --- a/04-bouncing-bubbles/polastyn/main.py +++ b/04-bouncing-bubbles/polastyn/main.py @@ -1,7 +1,9 @@ +from __future__ import annotations + import sys from dataclasses import dataclass from pathlib import Path -from random import gauss, uniform, randint +from random import gauss, uniform, randint, getrandbits from typing import List, Optional import pygame @@ -34,7 +36,10 @@ class Bubble: # TODO: add rectangular variant MAX_VELOCITY = 7 - def __init__(self, position=None): + def __init__(self, position=None, is_rect: bool | None = None): + self.is_rect = is_rect if is_rect is not None else not getrandbits(1) + self.rotation = 0 + self.rotation_speed = 0 self.radius = int(gauss(25, 5)) if position is None: @@ -60,8 +65,20 @@ def __init__(self, position=None): def mass(self): return self.radius ** 2 + def get_rect_points(self): + rec = pygame.Rect(0, 0, self.radius * 2, self.radius * 2) + rec.center = 0, 0 + tl = pygame.Vector2(rec.topleft).rotate(self.rotation) + self.position + tr = pygame.Vector2(rec.topright).rotate(self.rotation) + self.position + bl = pygame.Vector2(rec.bottomleft).rotate(self.rotation) + self.position + br = pygame.Vector2(rec.bottomright).rotate(self.rotation) + self.position + return tl, tr, br, bl + def draw(self, screen: pygame.Surface): - pygame.draw.circle(screen, self.color, self.position, self.radius) + if self.is_rect: + pygame.draw.polygon(screen, self.color, self.get_rect_points()) + else: + pygame.draw.circle(screen, self.color, self.position, self.radius) def move_away_from_mouse(self, mouse_pos: pygame.Vector2): """Apply a force on the bubble to move away from the mouse.""" @@ -79,6 +96,8 @@ def move(self): self.position += self.velocity debug.vector(self.velocity, self.position, scale=10) + self.rotation += self.rotation_speed + debug.vector(pygame.Vector2(1, 1), self.position, "yellow", self.rotation_speed) def how_colliding_border(self): left = self.position.x - self.radius <= 0 @@ -184,12 +203,10 @@ def resolve(self): # If you have troubles handling the mass of the particles, start by assuming they # have a mass of 1, and then upgrade your code to take the mass into account. - v1 = perp_vec(self.normal * self.first.velocity.length()) - v2 = counter_perp_vec(self.normal * self.second.velocity.length()) + v1 = perp_vec(self.normal * self.first.velocity.length()) * self.second.mass + v2 = counter_perp_vec(self.normal * self.second.velocity.length()) * self.first.mass self.first.velocity += v1 self.second.velocity += v2 - debug.vector(v1, self.first.position, "green") - debug.vector(v2, self.second.position, "green") # The world is a list of bubbles. From 8f621134b9f19623d5e526a5cb744a3d1118e0e6 Mon Sep 17 00:00:00 2001 From: gresm <> Date: Wed, 1 Dec 2021 11:24:27 +0100 Subject: [PATCH 75/80] ~ main.py - added weak support for rectangle collisions --- 04-bouncing-bubbles/polastyn/main.py | 36 ++++++++++++++++++++++++---- 1 file changed, 32 insertions(+), 4 deletions(-) diff --git a/04-bouncing-bubbles/polastyn/main.py b/04-bouncing-bubbles/polastyn/main.py index cb233aa..9e7ebcd 100644 --- a/04-bouncing-bubbles/polastyn/main.py +++ b/04-bouncing-bubbles/polastyn/main.py @@ -15,6 +15,7 @@ # To import the modules in yourname/, you need to use relative imports, # otherwise your project will not be compatible with the showcase. from .utils import * +from .line_intersection import do_intersect as line_intersect BACKGROUND = 0x0F1012 NB_BUBBLES = 42 @@ -33,7 +34,6 @@ def counter_perp_vec(vec: pygame.Vector2): class Bubble: - # TODO: add rectangular variant MAX_VELOCITY = 7 def __init__(self, position=None, is_rect: bool | None = None): @@ -136,11 +136,16 @@ def collide_borders(self): change = max(self.velocity.y * 0.25, self._fix_force) self.velocity.y -= change - def collide(self, other: "Bubble") -> Optional["Collision"]: - """Get the collision data if there is a collision with the other Bubble""" + # TODO: make variants of collisions + def collide_rect_rect(self, other: "Bubble") -> Optional["Collision"]: + pass + + def collide_circle_rect(self, other: "Bubble") -> Optional["Collision"]: + pass + + def collide_circle_circle(self, other: "Bubble") -> Optional["Collision"]: diff = other.position - self.position diff_len = diff.length() - if diff_len <= self.radius + other.radius: left_to_right_way = diff / diff_len right_to_left_way = left_to_right_way * -1 @@ -156,6 +161,19 @@ def collide(self, other: "Bubble") -> Optional["Collision"]: return Collision(self, other, center_collision_point, rotated_way) return None + def collide(self, other: "Bubble") -> Optional["Collision"]: + """Get the collision data if there is a collision with the other Bubble""" + if self.is_rect: + if other.is_rect: + return self.collide_rect_rect(other) + else: + return self.collide_circle_rect(other) + else: + if other.is_rect: + return other.collide_circle_rect(self) + else: + return self.collide_circle_circle(other) + # The second challenge contains two parts. # The first one is to generate a list of all the collisions @@ -208,6 +226,16 @@ def resolve(self): self.first.velocity += v1 self.second.velocity += v2 + if self.first.is_rect: + self.apply_rotation(0) + + if self.second.is_rect: + self.apply_rotation(1) + + # TODO: make this function + def apply_rotation(self, who: int): + pass + # The world is a list of bubbles. class World(List[Bubble]): From 356b1db698ea37dad25ed3997ae6d35588129803 Mon Sep 17 00:00:00 2001 From: gresm <> Date: Wed, 1 Dec 2021 11:25:56 +0100 Subject: [PATCH 76/80] ~ main.py - fixed call order for applying rotation --- 04-bouncing-bubbles/polastyn/main.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/04-bouncing-bubbles/polastyn/main.py b/04-bouncing-bubbles/polastyn/main.py index 9e7ebcd..49a45c7 100644 --- a/04-bouncing-bubbles/polastyn/main.py +++ b/04-bouncing-bubbles/polastyn/main.py @@ -221,17 +221,18 @@ def resolve(self): # If you have troubles handling the mass of the particles, start by assuming they # have a mass of 1, and then upgrade your code to take the mass into account. - v1 = perp_vec(self.normal * self.first.velocity.length()) * self.second.mass - v2 = counter_perp_vec(self.normal * self.second.velocity.length()) * self.first.mass - self.first.velocity += v1 - self.second.velocity += v2 - if self.first.is_rect: self.apply_rotation(0) if self.second.is_rect: self.apply_rotation(1) + v1 = perp_vec(self.normal * self.first.velocity.length()) * self.second.mass + v2 = counter_perp_vec(self.normal * self.second.velocity.length()) * self.first.mass + self.first.velocity += v1 + self.second.velocity += v2 + + # TODO: make this function def apply_rotation(self, who: int): pass From c40dc83e0c77e415652da0e372912e674406cb9d Mon Sep 17 00:00:00 2001 From: gresm <> Date: Wed, 1 Dec 2021 11:37:42 +0100 Subject: [PATCH 77/80] ~ main.py - rotation? --- 04-bouncing-bubbles/polastyn/main.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/04-bouncing-bubbles/polastyn/main.py b/04-bouncing-bubbles/polastyn/main.py index 49a45c7..03f2a78 100644 --- a/04-bouncing-bubbles/polastyn/main.py +++ b/04-bouncing-bubbles/polastyn/main.py @@ -138,10 +138,10 @@ def collide_borders(self): # TODO: make variants of collisions def collide_rect_rect(self, other: "Bubble") -> Optional["Collision"]: - pass + return self.collide_circle_circle(other) def collide_circle_rect(self, other: "Bubble") -> Optional["Collision"]: - pass + return self.collide_circle_circle(other) def collide_circle_circle(self, other: "Bubble") -> Optional["Collision"]: diff = other.position - self.position @@ -232,10 +232,13 @@ def resolve(self): self.first.velocity += v1 self.second.velocity += v2 - # TODO: make this function def apply_rotation(self, who: int): - pass + him = self.second if who else self.first + her = self.first if who else self.second + central = her.position - him.position + angle = her.velocity.angle_to(central) + him.rotation_speed += angle # The world is a list of bubbles. From 6ab6ab001682ca609e222daa01ce87f23599ff86 Mon Sep 17 00:00:00 2001 From: gresm <> Date: Wed, 1 Dec 2021 12:03:59 +0100 Subject: [PATCH 78/80] ~ main.py - collisions (half way done) --- 04-bouncing-bubbles/polastyn/main.py | 81 +++++++++++++++++++++------- 1 file changed, 62 insertions(+), 19 deletions(-) diff --git a/04-bouncing-bubbles/polastyn/main.py b/04-bouncing-bubbles/polastyn/main.py index 03f2a78..6c31952 100644 --- a/04-bouncing-bubbles/polastyn/main.py +++ b/04-bouncing-bubbles/polastyn/main.py @@ -74,6 +74,19 @@ def get_rect_points(self): br = pygame.Vector2(rec.bottomright).rotate(self.rotation) + self.position return tl, tr, br, bl + def get_lines(self) -> list[list[pygame.Vector2, pygame.Vector2]]: + ret = [] + last = None + for el in self.get_rect_points(): + if last is not None: + ret.append([last, el]) + last = el + + if len(ret) > 1: + ret.append([last, ret[0][0]]) + + return ret + def draw(self, screen: pygame.Surface): if self.is_rect: pygame.draw.polygon(screen, self.color, self.get_rect_points()) @@ -106,6 +119,7 @@ def how_colliding_border(self): down = self.position.y + self.radius >= SIZE[1] return left, right, top, down + # TODO: add support for rectangles def collide_borders(self): # The first challenge is to make the bubbles bounce against the border. # Hover that doesn't mean that a bubble must always be completely inside of the screen: @@ -136,30 +150,63 @@ def collide_borders(self): change = max(self.velocity.y * 0.25, self._fix_force) self.velocity.y -= change - # TODO: make variants of collisions def collide_rect_rect(self, other: "Bubble") -> Optional["Collision"]: - return self.collide_circle_circle(other) + collisions = 0 + + for l1 in self.get_lines(): + for l2 in other.get_lines(): + if line_intersect(l1[0], l1[1], l2[0], l2[1]): + collisions += 1 + + if collisions == 0: + return None + + return self._generate_collision(other) + + def collide_circle_line(self, p1: pygame.Vector2, p2: pygame.Vector2): + angle = p2 - p1 + angle /= angle.length() + + cross1 = perp_vec(angle) * self.radius + cross2 = counter_perp_vec(angle) * self.radius + cross1 += self.position + cross2 += self.position + return line_intersect(p1, p2, cross1, cross2) def collide_circle_rect(self, other: "Bubble") -> Optional["Collision"]: - return self.collide_circle_circle(other) + collisions = 0 + + for line in other.get_lines(): + if self.collide_circle_line(line[0], line[1]): + collisions += 1 + + if collisions == 0: + return None + + return self._generate_collision(other) def collide_circle_circle(self, other: "Bubble") -> Optional["Collision"]: diff = other.position - self.position diff_len = diff.length() if diff_len <= self.radius + other.radius: - left_to_right_way = diff / diff_len - right_to_left_way = left_to_right_way * -1 - left_collided_point = self.position + left_to_right_way * self.radius - right_collided_point = other.position + right_to_left_way * other.radius - center_collision_point = (right_collided_point - left_collided_point) / 2 + left_collided_point + return self._generate_collision(other) + return None + + def _generate_collision(self, other: "Bubble") -> Optional["Collision"]: + diff = other.position - self.position + diff_len = diff.length() + left_to_right_way = diff / diff_len + right_to_left_way = left_to_right_way * -1 + left_collided_point = self.position + left_to_right_way * self.radius + right_collided_point = other.position + right_to_left_way * other.radius + center_collision_point = (right_collided_point - left_collided_point) / 2 + left_collided_point - rotated_way = perp_vec(diff) - rotated_way = rotated_way / rotated_way.length() + rotated_way = perp_vec(diff) + rotated_way = rotated_way / rotated_way.length() - debug.vector(rotated_way * 20, center_collision_point, "blue") + debug.vector(rotated_way * 20, center_collision_point, "blue") - return Collision(self, other, center_collision_point, rotated_way) - return None + return Collision(self, other, center_collision_point, rotated_way) def collide(self, other: "Bubble") -> Optional["Collision"]: """Get the collision data if there is a collision with the other Bubble""" @@ -221,18 +268,14 @@ def resolve(self): # If you have troubles handling the mass of the particles, start by assuming they # have a mass of 1, and then upgrade your code to take the mass into account. - if self.first.is_rect: - self.apply_rotation(0) - - if self.second.is_rect: - self.apply_rotation(1) + self.apply_rotation(0) + self.apply_rotation(1) v1 = perp_vec(self.normal * self.first.velocity.length()) * self.second.mass v2 = counter_perp_vec(self.normal * self.second.velocity.length()) * self.first.mass self.first.velocity += v1 self.second.velocity += v2 - # TODO: make this function def apply_rotation(self, who: int): him = self.second if who else self.first her = self.first if who else self.second From a6a683e29a7b90273ec8abc5213104a2ba24095b Mon Sep 17 00:00:00 2001 From: gresm <> Date: Wed, 1 Dec 2021 12:26:46 +0100 Subject: [PATCH 79/80] ~ main.py - final commit --- 04-bouncing-bubbles/polastyn/main.py | 42 ++++++++++++++++++++++------ 1 file changed, 33 insertions(+), 9 deletions(-) diff --git a/04-bouncing-bubbles/polastyn/main.py b/04-bouncing-bubbles/polastyn/main.py index 6c31952..ed6aef0 100644 --- a/04-bouncing-bubbles/polastyn/main.py +++ b/04-bouncing-bubbles/polastyn/main.py @@ -61,6 +61,13 @@ def __init__(self, position=None, is_rect: bool | None = None): self._fix_force = 5 + self.border_lines = [ + [pygame.Vector2(0, 0), pygame.Vector2(0, SIZE[1])], # left + [pygame.Vector2(0, 0), pygame.Vector2(SIZE[0], 0)], # up + [pygame.Vector2(SIZE[0], 0), pygame.Vector2(SIZE)], # right + [pygame.Vector2(0, SIZE[1]), pygame.Vector2(SIZE)] # down + ] + @property def mass(self): return self.radius ** 2 @@ -110,14 +117,25 @@ def move(self): self.position += self.velocity debug.vector(self.velocity, self.position, scale=10) self.rotation += self.rotation_speed - debug.vector(pygame.Vector2(1, 1), self.position, "yellow", self.rotation_speed) - - def how_colliding_border(self): - left = self.position.x - self.radius <= 0 - right = self.position.x + self.radius >= SIZE[0] - top = self.position.y - self.radius <= 0 - down = self.position.y + self.radius >= SIZE[1] - return left, right, top, down + debug.vector(pygame.Vector2(1, 0), self.position, "yellow", self.rotation_speed) + + def how_colliding_border(self, mode: int): + """ + :param mode: 0 or 1 (0 circle, 1 rect) + :return: + """ + if mode: + left = self.collide_rect_line(*self.border_lines[0]) + top = self.collide_rect_line(*self.border_lines[1]) + right = self.collide_rect_line(*self.border_lines[2]) + down = self.collide_rect_line(*self.border_lines[3]) + return left, right, top, down + else: + left = self.position.x - self.radius <= 0 + right = self.position.x + self.radius >= SIZE[0] + top = self.position.y - self.radius <= 0 + down = self.position.y + self.radius >= SIZE[1] + return left, right, top, down # TODO: add support for rectangles def collide_borders(self): @@ -133,7 +151,7 @@ def collide_borders(self): # resolve itself naturally in a few frames, that is, if the bubble is already moving # away from the wall. - collided = self.how_colliding_border() + collided = self.how_colliding_border(int(self.is_rect)) if collided[0]: change = min(self.velocity.x * 0.25, -self._fix_force) self.velocity.x -= change @@ -173,6 +191,12 @@ def collide_circle_line(self, p1: pygame.Vector2, p2: pygame.Vector2): cross2 += self.position return line_intersect(p1, p2, cross1, cross2) + def collide_rect_line(self, p1: pygame.Vector2, p2: pygame.Vector2): + for el in self.get_lines(): + if line_intersect(el[0], el[1], p1, p2): + return True + return False + def collide_circle_rect(self, other: "Bubble") -> Optional["Collision"]: collisions = 0 From dca1347f45ff1ac99a14cdb1c3dab178665b11a7 Mon Sep 17 00:00:00 2001 From: gresm <> Date: Wed, 1 Dec 2021 13:47:27 +0100 Subject: [PATCH 80/80] ~ 04-bouncing-bubbles/ - code cleanup --- 04-bouncing-bubbles/polastyn/main.py | 1 - 04-bouncing-bubbles/polastyn/metadata.py | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/04-bouncing-bubbles/polastyn/main.py b/04-bouncing-bubbles/polastyn/main.py index ed6aef0..520bb64 100644 --- a/04-bouncing-bubbles/polastyn/main.py +++ b/04-bouncing-bubbles/polastyn/main.py @@ -137,7 +137,6 @@ def how_colliding_border(self, mode: int): down = self.position.y + self.radius >= SIZE[1] return left, right, top, down - # TODO: add support for rectangles def collide_borders(self): # The first challenge is to make the bubbles bounce against the border. # Hover that doesn't mean that a bubble must always be completely inside of the screen: diff --git a/04-bouncing-bubbles/polastyn/metadata.py b/04-bouncing-bubbles/polastyn/metadata.py index e553494..aa5e1cf 100644 --- a/04-bouncing-bubbles/polastyn/metadata.py +++ b/04-bouncing-bubbles/polastyn/metadata.py @@ -12,7 +12,7 @@ class Metadata: achievements = [ "Casual", "Ambitious", - # "Adventurous", + "Adventurous", ] # The lowest python version on which your code can run.