Merge pull request #39 from n0remac/monster-collisions

Added monster collisions
This commit is contained in:
Lief9100
2020-04-23 19:25:51 -07:00
committed by GitHub
4 changed files with 106 additions and 54 deletions

View File

@@ -47,7 +47,7 @@ class Config(object):
DEBUG = False DEBUG = False
# Monster Count to be spawned # Monster Count to be spawned
MONSTER_COUNT = 10 MONSTER_COUNT = 6
class Enums(Enum): class Enums(Enum):

View File

@@ -13,7 +13,7 @@ from typing import Tuple, List
import arcade import arcade
from config import Config from config import Config
from map import Dungeon from map import Dungeon
from mobs import Player, Enemy from mobs import Player, MobHandler
from projectiles import Temp from projectiles import Temp
from recipe import ActiveRecipe from recipe import ActiveRecipe
@@ -54,19 +54,16 @@ class Game(arcade.Window):
# Game Objects # Game Objects
self.dungeon = None self.dungeon = None
self.prev_keypress = [] # A list that assists with tracking keypress events 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 # Used to keep track of our scrolling
self.view_bottom = self.view_left = 0 self.view_bottom = self.view_left = 0
self.active_recipe = [] self.Recipe = []
self.enemies_in_range = []
arcade.set_background_color(arcade.color.BLACK) arcade.set_background_color(arcade.color.BLACK)
def setup(self): def setup(self):
""" Set up the game here. Call this function to restart the game. """ """ Set up the game here. Call this function to restart the game. """
# Create the Sprite lists # Create the Sprite lists
self.enemy_list = arcade.SpriteList()
self.active_enemies = arcade.SpriteList()
self.fps = FPSCounter() self.fps = FPSCounter()
self.bullet_list = arcade.SpriteList() self.bullet_list = arcade.SpriteList()
@@ -74,32 +71,21 @@ class Game(arcade.Window):
self.dungeon = Dungeon(0, 3) self.dungeon = Dungeon(0, 3)
# Set up recipes # Set up recipes
self.active_recipe = ActiveRecipe() self.Recipe = ActiveRecipe()
self.active_recipe.set_ghosts() self.Recipe.set_ghosts()
# Set up the player, specifically placing it at these coordinates. # Set up the player, specifically placing it at these coordinates.
self.player = Player(self.dungeon) self.player = Player(self.dungeon)
self.player.scale = 1 self.player.scale = 1
level = random.choice(self.dungeon.levelList) level = random.choice(self.dungeon.levelList)
self.player.center_x, self.player.center_y = level.center() self.player.center_x, self.player.center_y = level.center()
self.player.cur_recipe = self.active_recipe.active self.player.cur_recipe = self.Recipe.active
# x, y = level.center() self.player.monster_collisions = arcade.PhysicsEngineSimple(self.player, self.dungeon.getWalls())
# Set up monsters # Set up monsters
for count in range(Config.MONSTER_COUNT//2): self.Mobs = MobHandler()
mob = Enemy(filename="resources/images/monsters/ghost/ghost1.png", dungeon=self.dungeon) self.enemy_list = self.Mobs.setup(Config.MONSTER_COUNT, Config.MONSTER_COUNT, self.player, self.dungeon)
mob.center_x, mob.center_y = random.choice(self.dungeon.levelList).center() self.active_enemies = self.Mobs.active_enemies
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)
# Setup viewport # Setup viewport
self.view_bottom = self.player.center_x - (0.5 * Config.SCREEN_WIDTH) + 300 self.view_bottom = self.player.center_x - (0.5 * Config.SCREEN_WIDTH) + 300
@@ -109,9 +95,6 @@ class Game(arcade.Window):
self.view_bottom, self.view_bottom,
Config.SCREEN_HEIGHT + 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): def on_draw(self):
""" Render the screen. """ """ Render the screen. """
try: try:
@@ -121,10 +104,10 @@ class Game(arcade.Window):
# Draw our sprites # Draw our sprites
self.dungeon.render() self.dungeon.render()
self.player.draw() self.player.draw()
self.enemy_list.draw() self.Mobs.render()
self.active_enemies.draw() self.active_enemies.draw()
self.bullet_list.draw() self.bullet_list.draw()
self.active_recipe.render() self.Recipe.render()
if Config.DEBUG: if Config.DEBUG:
x, y = self.player.position x, y = self.player.position
@@ -182,8 +165,8 @@ class Game(arcade.Window):
elif key == 65307: elif key == 65307:
self.close() self.close()
elif key == 65505: elif key == 65505:
self.active_recipe.next_recipe() self.Recipe.next_recipe()
self.player.cur_recipe = self.active_recipe.active self.player.cur_recipe = self.Recipe.active
def on_key_release(self, key, modifiers): def on_key_release(self, key, modifiers):
"""Called when the user releases a key. """ """Called when the user releases a key. """
@@ -243,7 +226,7 @@ class Game(arcade.Window):
""" Movement and game logic """ """ Movement and game logic """
# Move the player with the physics engine # Move the player with the physics engine
self.physics_engine.update() self.player.monster_collisions.update()
self.player.update_animation() self.player.update_animation()
changed = False # Track if we need to change the viewport changed = False # Track if we need to change the viewport
@@ -281,26 +264,9 @@ class Game(arcade.Window):
Config.SCREEN_WIDTH + self.view_left, Config.SCREEN_WIDTH + self.view_left,
self.view_bottom, self.view_bottom,
Config.SCREEN_HEIGHT + self.view_bottom) Config.SCREEN_HEIGHT + self.view_bottom)
# Enemy activation and update # Update Mobs
for enemy in reversed(self.enemy_list): self.Mobs.update()
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()
# Projectile updates # Projectile updates
self.bullet_list.update() self.bullet_list.update()
for bullet in self.bullet_list: for bullet in self.bullet_list:
@@ -313,7 +279,9 @@ class Game(arcade.Window):
bullet.remove_from_sprite_lists() bullet.remove_from_sprite_lists()
if len(enemy_hit_list): if len(enemy_hit_list):
self.player.add_kill(enemy_hit_list[0].monster_type) 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() 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 the bullet flies off-screen, remove it. TEMP change to range calc
if ( if (

View File

@@ -6,10 +6,76 @@ Organizes all classes related to Mobs, Entities, Enemies, Players and Items.
from typing import List, Tuple from typing import List, Tuple
import arcade import arcade
import random
import math
from config import Config, Enums, SpritePaths from config import Config, Enums, SpritePaths
from map import Dungeon from map import Dungeon
from sprites import PlayerAnimations 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): class Mob(arcade.Sprite):
""" """
@@ -27,9 +93,10 @@ class Mob(arcade.Sprite):
self.up_textures = [] self.up_textures = []
self.down_textures = [] self.down_textures = []
self.cur_texture = 0 self.cur_texture = 0
self.monster_collisions = None
self.dungeon = dungeon self.dungeon = dungeon
self.target = None self.target = None
self.collisions = None
class Player(Mob): class Player(Mob):
@@ -114,6 +181,7 @@ class Enemy(Mob):
def __init__(self, *args, **kwargs) -> None: def __init__(self, *args, **kwargs) -> None:
super(Enemy, self).__init__(*args, **kwargs) super(Enemy, self).__init__(*args, **kwargs)
self.monster_type = '' self.monster_type = ''
self.active = False
def nearestPosition(self) -> Tuple[int, int]: 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. A on_update function, the Mob should decide it's next actions here.
""" """
curpos, nextpos = self.nearestPosition(), path[1] curpos, nextpos = self.nearestPosition(), path[1]
# print(curpos, nextpos) # print(curpos, nextpos)

View File

@@ -26,6 +26,8 @@ class ActiveRecipe(arcade.SpriteList):
self.active = Recipe.GHOSTS self.active = Recipe.GHOSTS
self.cycle_recipes = [self.set_frogs, self.set_ghosts] self.cycle_recipes = [self.set_frogs, self.set_ghosts]
self.pos = 0 self.pos = 0
self.kill_num = 0
def render(self) -> None: def render(self) -> None:
x = 0 x = 0
@@ -35,6 +37,7 @@ class ActiveRecipe(arcade.SpriteList):
sprite.scale = 4 sprite.scale = 4
sprite.center_x = screen_right - x sprite.center_x = screen_right - x
sprite.center_y = screen_top sprite.center_y = screen_top
x += 70 x += 70
sprite.draw() sprite.draw()
@@ -44,6 +47,17 @@ class ActiveRecipe(arcade.SpriteList):
if self.pos == len(self.cycle_recipes): if self.pos == len(self.cycle_recipes):
self.pos = 0 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: def set_ghosts(self) -> None:
self.active = Recipe.GHOSTS self.active = Recipe.GHOSTS
self.sprite_list = [] self.sprite_list = []
@@ -51,6 +65,7 @@ class ActiveRecipe(arcade.SpriteList):
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")) self.sprite_list.append(arcade.Sprite(filename="resources/images/monsters/ghost/ghost1.png"))
def set_frogs(self) -> None: def set_frogs(self) -> None:
self.active = Recipe.FROGS self.active = Recipe.FROGS
self.sprite_list = [] self.sprite_list = []