From 68f572124aa80d6c95627b2956d40a5aff492b70 Mon Sep 17 00:00:00 2001 From: Cameron Smart Date: Wed, 22 Apr 2020 20:18:00 -0700 Subject: [PATCH] Added kill list and recipes. Checks every three kills. --- triple-dungeon/config.py | 12 +-- triple-dungeon/main.py | 28 ++++--- triple-dungeon/mobs.py | 167 ++++++++++++++++++++------------------- 3 files changed, 107 insertions(+), 100 deletions(-) diff --git a/triple-dungeon/config.py b/triple-dungeon/config.py index 7018973..9a3b166 100644 --- a/triple-dungeon/config.py +++ b/triple-dungeon/config.py @@ -38,16 +38,16 @@ class Config(object): PLAYER_MOVEMENT_SPEED = 14 # How many pixels to keep as a minimum margin between the characters and the edge of the screen. - LEFT_VIEWPORT_MARGIN = 500 - RIGHT_VIEWPORT_MARGIN = 500 - BOTTOM_VIEWPORT_MARGIN = 250 - TOP_VIEWPORT_MARGIN = 200 + LEFT_VIEWPORT_MARGIN = 700 + RIGHT_VIEWPORT_MARGIN = 700 + BOTTOM_VIEWPORT_MARGIN = 300 + TOP_VIEWPORT_MARGIN = 350 # All debug statements and renderings should use this - DEBUG = True + DEBUG = False #Monster Count to be spawned - MONSTER_COUNT = 4 + MONSTER_COUNT = 20 class Enums(Enum): diff --git a/triple-dungeon/main.py b/triple-dungeon/main.py index cf488dd..e1660f2 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, Mob +from mobs import Player, Enemy from projectiles import Temp @@ -80,10 +80,11 @@ class Game(arcade.Window): #Set up monsters for count in range(Config.MONSTER_COUNT): - mob = Mob(filename="resources/images/monsters/ghost/ghost1.png", dungeon=self.dungeon) + 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) ''' mob = Mob(filename="resources/images/monsters/ghost/ghost1.png", dungeon=self.dungeon) @@ -140,10 +141,10 @@ class Game(arcade.Window): arcade.draw_rectangle_outline(round(x / Config.TILE_SIZE) * Config.TILE_SIZE, round(y / Config.TILE_SIZE) * Config.TILE_SIZE, Config.TILE_SIZE, Config.TILE_SIZE, arcade.color.RED) - self.player.draw_hit_box() - arcade.draw_text(str((x, y)), x - 40, y + 50, arcade.color.WHITE, 15, font_name='Arial') - arcade.draw_text(f"FPS: {self.fps.get_fps():3.0f}", self.view_left + 50, self.view_bottom + 30, - arcade.color.WHITE, 16, font_name='Arial') + #self.player.draw_hit_box() + #arcade.draw_text(str((x, y)), x - 40, y + 50, arcade.color.WHITE, 15, font_name='Arial') + #arcade.draw_text(f"FPS: {self.fps.get_fps():3.0f}", self.view_left + 50, self.view_bottom + 30, + # arcade.color.WHITE, 16, font_name='Arial') # Draw paths for all mobs for mob in self.active_enemies: @@ -152,7 +153,7 @@ class Game(arcade.Window): path = mob.get_path() t2 = time.time() #print(f'Path acquired in {round(t2 - t1, 4)}s') - self.draw_path(path) + #self.draw_path(path) mob.tick(path) self.fps.tick() @@ -288,7 +289,6 @@ 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 ( @@ -300,9 +300,14 @@ class Game(arcade.Window): if Config.DEBUG: print("Activate Enemy") self.active_enemies.append(enemy) self.enemy_list.remove(enemy) - for enemy in self.active_enemies: - enemy.update() - + try: + for enemy in self.active_enemies: + enemy.update() + path = enemy.get_path() + enemy.tick(path) + except Exception: + import traceback + traceback.print_exc() # Projectile updates self.bullet_list.update() for bullet in self.bullet_list: @@ -314,6 +319,7 @@ class Game(arcade.Window): if len(hit_list) > 0: bullet.remove_from_sprite_lists() if len(enemy_hit_list): + self.player.add_kill(enemy_hit_list[0].monster_type) enemy_hit_list[0].remove_from_sprite_lists() diff --git a/triple-dungeon/mobs.py b/triple-dungeon/mobs.py index 3f1158e..7534c2d 100644 --- a/triple-dungeon/mobs.py +++ b/triple-dungeon/mobs.py @@ -31,6 +31,90 @@ class Mob(arcade.Sprite): self.dungeon = dungeon self.target = None + + + +class Player(Mob): + """ + Represents a Player. + While this is a instance, there should only be one in the world at any given time. + """ + + def __init__(self, *args, **kwargs) -> None: + super(Player, self).__init__(*args, **kwargs) + + self.animations = PlayerAnimations(SpritePaths.KNIGHT) + # Used for mapping directions to animations + self.map = { + Enums.IDLE: self.animations.idles, + Enums.UP: self.animations.up, + Enums.DOWN: self.animations.down, + Enums.RIGHT: self.animations.right, + Enums.LEFT: self.animations.left + } + + self.refreshIndex = 0 + self.prev = Enums.IDLE + self.texture = next(self.map[self.prev]) + self.kill_list = [] + self.cur_recipe = ['ghost', 'ghost', 'ghost'] + + def add_kill(self, creature): + # Adds a kill to kill_list. If 3 or more check the recipe then give a power up if it matches. + + self.kill_list.append(creature) + if self.cur_recipe == self.kill_list: + print("+++++++++++++++++++++++++++++++++++++++++++++++++++++++") + self.kill_list = [] + + + def update_animation(self, delta_time: float = 1 / 60) -> None: + """ + Updates animations for the Player. + :param delta_time: No idea. + """ + + # Increase the refresh index according + self.refreshIndex = (self.refreshIndex + 1) % Config.RUN_UPDATES_PER_FRAME + + # Logic to determine what direction we're in. + if self.change_x == 0 and self.change_y == 0: + cur = Enums.IDLE + elif self.change_y > 0: # Up + cur = Enums.UP + elif self.change_y < 0: # Down + cur = Enums.DOWN + elif self.change_x > 0: # Left + cur = Enums.RIGHT + elif self.change_x < 0: # Right + cur = Enums.LEFT + else: # Idle + cur = Enums.IDLE + + # If we're in a new direction or the refresh index has reset + if self.prev is not cur or self.refreshIndex == 0: + self.texture = next(self.map[cur]) + + self.prev = cur + + def tick(self): + """ + While Player objects do not have any AI (they are controlled by the user), + the tick function can keep track of statistics that progress over time, like + regenerating health/armor or status effects like poison. + """ + + +class Enemy(Mob): + """ + Represents an Enemy Mob. + Will take basic offensive actions against Player objects. + """ + + def __init__(self, *args, **kwargs) -> None: + super(Enemy, self).__init__(*args, **kwargs) + self.monster_type = '' + def nearestPosition(self) -> Tuple[int, int]: """ Returns the nearest absolute dungeon tile the Mob is placed on. @@ -78,86 +162,3 @@ class Mob(arcade.Sprite): self.dungeon.grid.cleanup() return paths - -class Player(Mob): - """ - Represents a Player. - While this is a instance, there should only be one in the world at any given time. - """ - - def __init__(self, *args, **kwargs) -> None: - super(Player, self).__init__(*args, **kwargs) - - self.animations = PlayerAnimations(SpritePaths.KNIGHT) - # Used for mapping directions to animations - self.map = { - Enums.IDLE: self.animations.idles, - Enums.UP: self.animations.up, - Enums.DOWN: self.animations.down, - Enums.RIGHT: self.animations.right, - Enums.LEFT: self.animations.left - } - - self.refreshIndex = 0 - self.prev = Enums.IDLE - self.texture = next(self.map[self.prev]) - - def update_animation(self, delta_time: float = 1 / 60) -> None: - """ - Updates animations for the Player. - :param delta_time: No idea. - """ - - # Increase the refresh index according - self.refreshIndex = (self.refreshIndex + 1) % Config.RUN_UPDATES_PER_FRAME - - # Logic to determine what direction we're in. - if self.change_x == 0 and self.change_y == 0: - cur = Enums.IDLE - elif self.change_y > 0: # Up - cur = Enums.UP - elif self.change_y < 0: # Down - cur = Enums.DOWN - elif self.change_x > 0: # Left - cur = Enums.RIGHT - elif self.change_x < 0: # Right - cur = Enums.LEFT - else: # Idle - cur = Enums.IDLE - - # If we're in a new direction or the refresh index has reset - if self.prev is not cur or self.refreshIndex == 0: - self.texture = next(self.map[cur]) - - self.prev = cur - - def tick(self): - """ - While Player objects do not have any AI (they are controlled by the user), - the tick function can keep track of statistics that progress over time, like - regenerating health/armor or status effects like poison. - """ - - -class Enemy(Mob): - """ - Represents an Enemy Mob. - Will take basic offensive actions against Player objects. - """ - - def __init__(self, *args, **kwargs) -> None: - super(Enemy, self).__init__(*args, **kwargs) - - def tick(self) -> None: - """ - A on_update function, the Enemy Mob should scan for the player, decide how to path to it, and - decide how to take offensive action. - """ - pass - - def path(self) -> None: - """ - Not yet decided how this function should work. - Basically, most pathfinding decisions should be kept within this function. - """ - pass