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
# Monster Count to be spawned
MONSTER_COUNT = 10
MONSTER_COUNT = 6
class Enums(Enum):

View File

@@ -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 (

View File

@@ -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)

View File

@@ -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