diff --git a/triple-dungeon/config.py b/triple-dungeon/config.py index 393d685..ddf7fc0 100644 --- a/triple-dungeon/config.py +++ b/triple-dungeon/config.py @@ -47,7 +47,7 @@ class Config(object): DEBUG = False # Monster Count to be spawned - MONSTER_COUNT = 10 + MONSTER_COUNT = 6 class Enums(Enum): diff --git a/triple-dungeon/main.py b/triple-dungeon/main.py index 2ecb526..b1b0151 100644 --- a/triple-dungeon/main.py +++ b/triple-dungeon/main.py @@ -13,7 +13,7 @@ from typing import Tuple, List import arcade from config import Config from map import Dungeon -from mobs import Player, Enemy +from mobs import Player, MobHandler from projectiles import Temp from recipe import ActiveRecipe @@ -54,19 +54,16 @@ class Game(arcade.Window): # Game Objects self.dungeon = None self.prev_keypress = [] # A list that assists with tracking keypress events - self.physics_engine = None # Our physics engine # Used to keep track of our scrolling self.view_bottom = self.view_left = 0 - self.active_recipe = [] + self.Recipe = [] + self.enemies_in_range = [] arcade.set_background_color(arcade.color.BLACK) def setup(self): """ Set up the game here. Call this function to restart the game. """ # Create the Sprite lists - - self.enemy_list = arcade.SpriteList() - self.active_enemies = arcade.SpriteList() self.fps = FPSCounter() self.bullet_list = arcade.SpriteList() @@ -74,32 +71,21 @@ class Game(arcade.Window): self.dungeon = Dungeon(0, 3) # Set up recipes - self.active_recipe = ActiveRecipe() - self.active_recipe.set_ghosts() + self.Recipe = ActiveRecipe() + self.Recipe.set_ghosts() # Set up the player, specifically placing it at these coordinates. self.player = Player(self.dungeon) self.player.scale = 1 level = random.choice(self.dungeon.levelList) self.player.center_x, self.player.center_y = level.center() - self.player.cur_recipe = self.active_recipe.active - # x, y = level.center() + self.player.cur_recipe = self.Recipe.active + self.player.monster_collisions = arcade.PhysicsEngineSimple(self.player, self.dungeon.getWalls()) # Set up monsters - for count in range(Config.MONSTER_COUNT//2): - mob = Enemy(filename="resources/images/monsters/ghost/ghost1.png", dungeon=self.dungeon) - mob.center_x, mob.center_y = random.choice(self.dungeon.levelList).center() - mob.target = self.player - mob.scale = 4 - mob.monster_type = 'ghost' - self.enemy_list.append(mob) - for count in range(Config.MONSTER_COUNT//2): - mob = Enemy(filename="resources/images/monsters/frog/frog1.png", dungeon=self.dungeon) - mob.center_x, mob.center_y = random.choice(self.dungeon.levelList).center() - mob.target = self.player - mob.scale = 4 - mob.monster_type = 'frog' - self.enemy_list.append(mob) + self.Mobs = MobHandler() + self.enemy_list = self.Mobs.setup(Config.MONSTER_COUNT, Config.MONSTER_COUNT, self.player, self.dungeon) + self.active_enemies = self.Mobs.active_enemies # Setup viewport self.view_bottom = self.player.center_x - (0.5 * Config.SCREEN_WIDTH) + 300 @@ -109,9 +95,6 @@ class Game(arcade.Window): self.view_bottom, Config.SCREEN_HEIGHT + self.view_bottom) - # Create the 'physics engine' - self.physics_engine = arcade.PhysicsEngineSimple(self.player, self.dungeon.getWalls()) - def on_draw(self): """ Render the screen. """ try: @@ -121,10 +104,10 @@ class Game(arcade.Window): # Draw our sprites self.dungeon.render() self.player.draw() - self.enemy_list.draw() + self.Mobs.render() self.active_enemies.draw() self.bullet_list.draw() - self.active_recipe.render() + self.Recipe.render() if Config.DEBUG: x, y = self.player.position @@ -182,8 +165,8 @@ class Game(arcade.Window): elif key == 65307: self.close() elif key == 65505: - self.active_recipe.next_recipe() - self.player.cur_recipe = self.active_recipe.active + self.Recipe.next_recipe() + self.player.cur_recipe = self.Recipe.active def on_key_release(self, key, modifiers): """Called when the user releases a key. """ @@ -243,7 +226,7 @@ class Game(arcade.Window): """ Movement and game logic """ # Move the player with the physics engine - self.physics_engine.update() + self.player.monster_collisions.update() self.player.update_animation() changed = False # Track if we need to change the viewport @@ -281,26 +264,9 @@ class Game(arcade.Window): Config.SCREEN_WIDTH + self.view_left, self.view_bottom, Config.SCREEN_HEIGHT + self.view_bottom) - # Enemy activation and update - for enemy in reversed(self.enemy_list): - if ( - enemy.bottom > self.view_bottom and - enemy.top < self.view_bottom + Config.SCREEN_HEIGHT and - enemy.right < self.view_left + Config.SCREEN_WIDTH and - enemy.left > self.view_left - ): - if Config.DEBUG: - print("Activate Enemy") - self.active_enemies.append(enemy) - self.enemy_list.remove(enemy) - try: - for enemy in self.active_enemies: - enemy.update() - path = enemy.get_path() - enemy.tick(path) - except Exception: - import traceback - traceback.print_exc() + # Update Mobs + self.Mobs.update() + # Projectile updates self.bullet_list.update() for bullet in self.bullet_list: @@ -313,7 +279,9 @@ class Game(arcade.Window): bullet.remove_from_sprite_lists() if len(enemy_hit_list): self.player.add_kill(enemy_hit_list[0].monster_type) + self.Recipe.add_kill(enemy_hit_list[0].monster_type) enemy_hit_list[0].remove_from_sprite_lists() + bullet.remove_from_sprite_lists() # If the bullet flies off-screen, remove it. TEMP change to range calc if ( diff --git a/triple-dungeon/mobs.py b/triple-dungeon/mobs.py index 9560f13..e50bc4b 100644 --- a/triple-dungeon/mobs.py +++ b/triple-dungeon/mobs.py @@ -6,10 +6,76 @@ Organizes all classes related to Mobs, Entities, Enemies, Players and Items. from typing import List, Tuple import arcade +import random +import math + from config import Config, Enums, SpritePaths from map import Dungeon from sprites import PlayerAnimations +class MobHandler(arcade.SpriteList): + + def __init__(self): + super().__init__() + self.enemy_list = [] + self.active_enemies = [] + self.dungeon = None + self.player = None + + def setup(self, ghost, frogs, player, dungeon) -> list: + self.enemy_list = arcade.SpriteList() + self.active_enemies = arcade.SpriteList() + self.dungeon = dungeon + self.player = player + + for count in range(ghost): + mob = Enemy(filename="resources/images/monsters/ghost/ghost1.png", dungeon=self.dungeon) + mob.center_x, mob.center_y = random.choice(self.dungeon.levelList).center() + mob.target = self.player + mob.scale = 4 + mob.monster_type = 'ghost' + mob.monster_collisions = arcade.PhysicsEngineSimple(mob, self.active_enemies) + self.enemy_list.append(mob) + for count in range(frogs): + mob = Enemy(filename="resources/images/monsters/frog/frog1.png", dungeon=self.dungeon) + mob.center_x, mob.center_y = random.choice(self.dungeon.levelList).center() + mob.target = self.player + mob.scale = 4 + mob.monster_type = 'frog' + mob.monster_collisions = arcade.PhysicsEngineSimple(mob, self.active_enemies) + self.enemy_list.append(mob) + + return self.enemy_list + + def render(self) -> None: + self.enemy_list.draw() + + def update(self) -> None: + # Enemy activation and update + for enemy in reversed(self.enemy_list): + # TODO replace with distance checking + distance = self.get_distance(enemy) + if (distance < 300): + self.active_enemies.append(enemy) + self.enemy_list.remove(enemy) + enemy.active = True + try: + for enemy in self.active_enemies: + enemy.monster_collisions.update() + path = enemy.get_path() + enemy.tick(path) + except Exception: + import traceback + traceback.print_exc() + + def get_distance(self, enemy) -> int: + start_x = enemy.center_x + start_y = enemy.center_y + end_x = self.player.center_x + end_y = self.player.center_y + distance = math.sqrt(math.pow(start_x - end_x, 2) + math.pow(start_y - end_y, 2)) + return distance + class Mob(arcade.Sprite): """ @@ -27,9 +93,10 @@ class Mob(arcade.Sprite): self.up_textures = [] self.down_textures = [] self.cur_texture = 0 - + self.monster_collisions = None self.dungeon = dungeon self.target = None + self.collisions = None class Player(Mob): @@ -114,6 +181,7 @@ class Enemy(Mob): def __init__(self, *args, **kwargs) -> None: super(Enemy, self).__init__(*args, **kwargs) self.monster_type = '' + self.active = False def nearestPosition(self) -> Tuple[int, int]: """ @@ -128,6 +196,7 @@ class Enemy(Mob): """ A on_update function, the Mob should decide it's next actions here. """ + curpos, nextpos = self.nearestPosition(), path[1] # print(curpos, nextpos) diff --git a/triple-dungeon/recipe.py b/triple-dungeon/recipe.py index 2a35ca0..6a2588b 100644 --- a/triple-dungeon/recipe.py +++ b/triple-dungeon/recipe.py @@ -26,6 +26,8 @@ class ActiveRecipe(arcade.SpriteList): self.active = Recipe.GHOSTS self.cycle_recipes = [self.set_frogs, self.set_ghosts] self.pos = 0 + self.kill_num = 0 + def render(self) -> None: x = 0 @@ -35,6 +37,7 @@ class ActiveRecipe(arcade.SpriteList): sprite.scale = 4 sprite.center_x = screen_right - x sprite.center_y = screen_top + x += 70 sprite.draw() @@ -44,12 +47,24 @@ class ActiveRecipe(arcade.SpriteList): if self.pos == len(self.cycle_recipes): self.pos = 0 + def add_kill(self, monster_type): + for sprite in self.sprite_list: + if monster_type in "ghost": + r, g, b = sprite.color + darken = lambda c, s: c * (1 - s) + r = darken(r, .5) + g = darken(g, .5) + b = darken(b, .5) + sprite.color = (r, g, b) + return + def set_ghosts(self) -> None: self.active = Recipe.GHOSTS self.sprite_list = [] self.sprite_list.append(arcade.Sprite(filename="resources/images/monsters/ghost/ghost1.png")) self.sprite_list.append(arcade.Sprite(filename="resources/images/monsters/ghost/ghost1.png")) self.sprite_list.append(arcade.Sprite(filename="resources/images/monsters/ghost/ghost1.png")) + def set_frogs(self) -> None: self.active = Recipe.FROGS