mirror of
https://github.com/n0remac/game-jam-2020.git
synced 2025-12-06 17:13:12 -06:00
Monsters on screen move randomly when not active.
This commit is contained in:
@@ -37,6 +37,8 @@ class Config(object):
|
|||||||
# Movement speed of player, in pixels per frame
|
# Movement speed of player, in pixels per frame
|
||||||
PLAYER_MOVEMENT_SPEED = 14
|
PLAYER_MOVEMENT_SPEED = 14
|
||||||
|
|
||||||
|
MONSTER_MOVEMENT_SPEED = 11
|
||||||
|
|
||||||
# How many pixels to keep as a minimum margin between the characters and the edge of the screen.
|
# How many pixels to keep as a minimum margin between the characters and the edge of the screen.
|
||||||
LEFT_VIEWPORT_MARGIN = 700
|
LEFT_VIEWPORT_MARGIN = 700
|
||||||
RIGHT_VIEWPORT_MARGIN = 700
|
RIGHT_VIEWPORT_MARGIN = 700
|
||||||
@@ -47,7 +49,7 @@ class Config(object):
|
|||||||
DEBUG = False
|
DEBUG = False
|
||||||
|
|
||||||
# Monster Count to be spawned
|
# Monster Count to be spawned
|
||||||
MONSTER_COUNT = 6
|
MONSTER_COUNT = 8
|
||||||
|
|
||||||
|
|
||||||
class Enums(Enum):
|
class Enums(Enum):
|
||||||
|
|||||||
@@ -57,7 +57,6 @@ class Game(arcade.Window):
|
|||||||
# 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.Recipe = []
|
self.Recipe = []
|
||||||
self.enemies_in_range = []
|
|
||||||
|
|
||||||
arcade.set_background_color(arcade.color.BLACK)
|
arcade.set_background_color(arcade.color.BLACK)
|
||||||
|
|
||||||
@@ -80,12 +79,11 @@ class Game(arcade.Window):
|
|||||||
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.Recipe.active
|
self.player.cur_recipe = self.Recipe.active
|
||||||
self.player.monster_collisions = arcade.PhysicsEngineSimple(self.player, self.dungeon.getWalls())
|
self.player.collisions = arcade.PhysicsEngineSimple(self.player, self.dungeon.getWalls())
|
||||||
|
|
||||||
# Set up monsters
|
# Set up monsters
|
||||||
self.Mobs = MobHandler()
|
self.Mobs = MobHandler()
|
||||||
self.enemy_list = self.Mobs.setup(Config.MONSTER_COUNT, Config.MONSTER_COUNT, self.player, self.dungeon)
|
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
|
# 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
|
||||||
@@ -103,9 +101,8 @@ class Game(arcade.Window):
|
|||||||
|
|
||||||
# Draw our sprites
|
# Draw our sprites
|
||||||
self.dungeon.render()
|
self.dungeon.render()
|
||||||
self.player.draw()
|
|
||||||
self.Mobs.render()
|
self.Mobs.render()
|
||||||
self.active_enemies.draw()
|
#self.active_enemies.draw()
|
||||||
self.bullet_list.draw()
|
self.bullet_list.draw()
|
||||||
self.Recipe.render()
|
self.Recipe.render()
|
||||||
|
|
||||||
@@ -237,7 +234,7 @@ class Game(arcade.Window):
|
|||||||
|
|
||||||
# Collision Checks
|
# Collision Checks
|
||||||
hit_list = arcade.check_for_collision_with_list(bullet, self.dungeon.getWalls())
|
hit_list = arcade.check_for_collision_with_list(bullet, self.dungeon.getWalls())
|
||||||
enemy_hit_list = arcade.check_for_collision_with_list(bullet, self.active_enemies)
|
enemy_hit_list = arcade.check_for_collision_with_list(bullet, self.enemy_list)
|
||||||
# If it did, get rid of the bullet
|
# If it did, get rid of the bullet
|
||||||
if len(hit_list) > 0:
|
if len(hit_list) > 0:
|
||||||
bullet.remove_from_sprite_lists()
|
bullet.remove_from_sprite_lists()
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import json
|
|||||||
from pprint import pprint
|
from pprint import pprint
|
||||||
|
|
||||||
import arcade
|
import arcade
|
||||||
import numpy as np
|
import random
|
||||||
|
|
||||||
from itertools import chain
|
from itertools import chain
|
||||||
from config import Config
|
from config import Config
|
||||||
@@ -177,13 +177,10 @@ class Level:
|
|||||||
"""
|
"""
|
||||||
return int((self.x + 0.5) * Config.LEVEL_SIZE), int((self.y + 0.5) * Config.LEVEL_SIZE)
|
return int((self.x + 0.5) * Config.LEVEL_SIZE), int((self.y + 0.5) * Config.LEVEL_SIZE)
|
||||||
|
|
||||||
def rotate_level(self, times_rotated):
|
def random(self) -> tuple:
|
||||||
"""
|
"""
|
||||||
Rotates the
|
Returns a random spot in the level.
|
||||||
:param times_rotated:
|
:return: A tuple containing the X and Y coordinates
|
||||||
:return:
|
|
||||||
"""
|
"""
|
||||||
m = np.array(self.level)
|
|
||||||
for i in range(0, times_rotated % 4):
|
return int((self.x + random.randint(1,9)/10) * Config.LEVEL_SIZE), int((self.y + random.randint(1,9)/10) * Config.LEVEL_SIZE)
|
||||||
m = np.rot90(m)
|
|
||||||
self.level = m.tolist()
|
|
||||||
|
|||||||
@@ -13,60 +13,85 @@ 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):
|
class MobHandler:
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.enemy_list = []
|
self.enemy_list = []
|
||||||
self.active_enemies = []
|
self.avoid_list = []
|
||||||
self.dungeon = None
|
self.dungeon = None
|
||||||
self.player = None
|
self.player = None
|
||||||
|
|
||||||
def setup(self, ghost, frogs, player, dungeon) -> list:
|
def setup(self, ghost, frogs, player, dungeon) -> list:
|
||||||
self.enemy_list = arcade.SpriteList()
|
self.enemy_list = arcade.SpriteList()
|
||||||
self.active_enemies = arcade.SpriteList()
|
|
||||||
self.dungeon = dungeon
|
self.dungeon = dungeon
|
||||||
self.player = player
|
self.player = player
|
||||||
|
self.avoid_list = arcade.SpriteList()
|
||||||
|
self.avoid_list.append(self.player)
|
||||||
|
for d in dungeon.getWalls():
|
||||||
|
self.avoid_list.append(d)
|
||||||
|
|
||||||
for count in range(ghost):
|
for count in range(ghost):
|
||||||
mob = Enemy(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()
|
level = random.choice(self.dungeon.levelList)
|
||||||
|
mob.center_x, mob.center_y = level.random()
|
||||||
mob.target = self.player
|
mob.target = self.player
|
||||||
mob.scale = 4
|
mob.scale = 4
|
||||||
mob.monster_type = 'ghost'
|
mob.monster_type = 'ghost'
|
||||||
mob.monster_collisions = arcade.PhysicsEngineSimple(mob, self.active_enemies)
|
mob.collisions = arcade.PhysicsEngineSimple(mob, self.avoid_list)
|
||||||
|
mob.level = level
|
||||||
self.enemy_list.append(mob)
|
self.enemy_list.append(mob)
|
||||||
|
self.avoid_list.append(mob)
|
||||||
for count in range(frogs):
|
for count in range(frogs):
|
||||||
mob = Enemy(filename="resources/images/monsters/frog/frog1.png", dungeon=self.dungeon)
|
mob = Enemy(filename="resources/images/monsters/frog/frog1.png", dungeon=self.dungeon)
|
||||||
mob.center_x, mob.center_y = random.choice(self.dungeon.levelList).center()
|
level = random.choice(self.dungeon.levelList)
|
||||||
|
mob.center_x, mob.center_y = level.random()
|
||||||
mob.target = self.player
|
mob.target = self.player
|
||||||
mob.scale = 4
|
mob.scale = 4
|
||||||
mob.monster_type = 'frog'
|
mob.monster_type = 'frog'
|
||||||
mob.monster_collisions = arcade.PhysicsEngineSimple(mob, self.active_enemies)
|
mob.collisions = arcade.PhysicsEngineSimple(mob, self.avoid_list)
|
||||||
|
mob.level = level
|
||||||
self.enemy_list.append(mob)
|
self.enemy_list.append(mob)
|
||||||
|
self.avoid_list.append(mob)
|
||||||
|
|
||||||
return self.enemy_list
|
return self.enemy_list
|
||||||
|
|
||||||
def render(self) -> None:
|
def render(self) -> None:
|
||||||
|
self.player.draw()
|
||||||
self.enemy_list.draw()
|
self.enemy_list.draw()
|
||||||
|
|
||||||
def update(self) -> None:
|
def update(self) -> None:
|
||||||
#update player
|
#update player
|
||||||
self.player.monster_collisions.update()
|
self.player.collisions.update()
|
||||||
self.player.update_animation()
|
self.player.update_animation()
|
||||||
|
|
||||||
# Enemy activation and update
|
# Enemy activation and update
|
||||||
for enemy in reversed(self.enemy_list):
|
for enemy in reversed(self.enemy_list):
|
||||||
# TODO replace with distance checking
|
# TODO replace with distance checking
|
||||||
distance = self.get_distance(enemy)
|
distance = self.get_distance(enemy)
|
||||||
|
enemy.collisions.update()
|
||||||
if (distance < 300):
|
if (distance < 300):
|
||||||
self.active_enemies.append(enemy)
|
enemy.speed = Config.MONSTER_MOVEMENT_SPEED
|
||||||
self.enemy_list.remove(enemy)
|
|
||||||
enemy.active = True
|
|
||||||
try:
|
try:
|
||||||
for enemy in self.active_enemies:
|
path = enemy.get_path(enemy.target.position)
|
||||||
enemy.monster_collisions.update()
|
enemy.tick(path)
|
||||||
path = enemy.get_path()
|
except Exception:
|
||||||
|
import traceback
|
||||||
|
traceback.print_exc()
|
||||||
|
else:
|
||||||
|
left, right, bottom, top = arcade.get_viewport()
|
||||||
|
if (
|
||||||
|
enemy.bottom > bottom and
|
||||||
|
enemy.top < bottom + Config.SCREEN_HEIGHT and
|
||||||
|
enemy.right < left + Config.SCREEN_WIDTH and
|
||||||
|
enemy.left > left
|
||||||
|
):
|
||||||
|
enemy.speed = 5
|
||||||
|
ran = random.randint(0,1000)
|
||||||
|
if ran > 950:
|
||||||
|
print(ran)
|
||||||
|
try:
|
||||||
|
path = enemy.get_path(enemy.level.random())
|
||||||
enemy.tick(path)
|
enemy.tick(path)
|
||||||
except Exception:
|
except Exception:
|
||||||
import traceback
|
import traceback
|
||||||
@@ -80,6 +105,20 @@ class MobHandler(arcade.SpriteList):
|
|||||||
distance = math.sqrt(math.pow(start_x - end_x, 2) + math.pow(start_y - end_y, 2))
|
distance = math.sqrt(math.pow(start_x - end_x, 2) + math.pow(start_y - end_y, 2))
|
||||||
return distance
|
return distance
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def draw_path(path: List[Tuple[int, int]]) -> None:
|
||||||
|
"""
|
||||||
|
Draws a line between positions in a list of tuple, also known as the path.
|
||||||
|
:param path: A list of tuple positions defining a path that can be traversed.
|
||||||
|
"""
|
||||||
|
|
||||||
|
if len(path) > 2:
|
||||||
|
path = map(lambda point: ((point[0]) * Config.TILE_SIZE, (point[1]) * Config.TILE_SIZE), path)
|
||||||
|
path = list(path)
|
||||||
|
#print(path)
|
||||||
|
for pos1, pos2 in zip(path, path[1:]):
|
||||||
|
arcade.draw_line(*pos1, *pos2, color=arcade.color.RED)
|
||||||
|
|
||||||
|
|
||||||
class Mob(arcade.Sprite):
|
class Mob(arcade.Sprite):
|
||||||
"""
|
"""
|
||||||
@@ -97,10 +136,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.collisions = None
|
||||||
self.dungeon = dungeon
|
self.dungeon = dungeon
|
||||||
self.target = None
|
self.target = None
|
||||||
self.collisions = None
|
self.level = None
|
||||||
|
|
||||||
|
|
||||||
class Player(Mob):
|
class Player(Mob):
|
||||||
@@ -127,6 +166,7 @@ class Player(Mob):
|
|||||||
self.texture = next(self.map[self.prev])
|
self.texture = next(self.map[self.prev])
|
||||||
self.kill_list = []
|
self.kill_list = []
|
||||||
self.cur_recipe = None
|
self.cur_recipe = None
|
||||||
|
self.speed = 14
|
||||||
|
|
||||||
def add_kill(self, creature):
|
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.
|
# Adds a kill to kill_list. If 3 or more check the recipe then give a power up if it matches.
|
||||||
@@ -176,8 +216,6 @@ class Player(Mob):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class Enemy(Mob):
|
class Enemy(Mob):
|
||||||
"""
|
"""
|
||||||
Represents an Enemy Mob.
|
Represents an Enemy Mob.
|
||||||
@@ -187,7 +225,6 @@ 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]:
|
||||||
"""
|
"""
|
||||||
@@ -202,25 +239,26 @@ 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.
|
||||||
"""
|
"""
|
||||||
|
near_pos = self.nearestPosition()
|
||||||
|
|
||||||
curpos, nextpos = self.nearestPosition(), path[1]
|
curpos, nextpos = near_pos, path[1]
|
||||||
# print(curpos, nextpos)
|
# print(curpos, nextpos)
|
||||||
|
|
||||||
if nextpos[0] > curpos[0]:
|
if nextpos[0] > curpos[0]:
|
||||||
self.change_x = Config.PLAYER_MOVEMENT_SPEED - 3
|
self.change_x = self.speed
|
||||||
elif nextpos[0] < curpos[0]:
|
elif nextpos[0] < curpos[0]:
|
||||||
self.change_x = -Config.PLAYER_MOVEMENT_SPEED + 3
|
self.change_x = -self.speed
|
||||||
else:
|
else:
|
||||||
self.change_x = 0
|
self.change_x = 0
|
||||||
|
|
||||||
if nextpos[1] > curpos[1]:
|
if nextpos[1] > curpos[1]:
|
||||||
self.change_y = Config.PLAYER_MOVEMENT_SPEED - 3
|
self.change_y = self.speed
|
||||||
elif nextpos[1] < curpos[1]:
|
elif nextpos[1] < curpos[1]:
|
||||||
self.change_y = -Config.PLAYER_MOVEMENT_SPEED + 3
|
self.change_y = -self.speed
|
||||||
else:
|
else:
|
||||||
self.change_y = 0
|
self.change_y = 0
|
||||||
|
|
||||||
# print(self.change_x, self.change_y)
|
|
||||||
|
|
||||||
def get_path(self, end: Tuple[int, int] = None) -> List[Tuple[int, int]]:
|
def get_path(self, end: Tuple[int, int] = None) -> List[Tuple[int, int]]:
|
||||||
"""
|
"""
|
||||||
@@ -229,8 +267,7 @@ class Enemy(Mob):
|
|||||||
:param end: A the endpoint tuple. Must be a valid position within the matrix.
|
:param end: A the endpoint tuple. Must be a valid position within the matrix.
|
||||||
:return:
|
:return:
|
||||||
"""
|
"""
|
||||||
if end is None:
|
|
||||||
end = self.target.position
|
|
||||||
start, end = self.nearestPosition(), (round(end[0] / Config.TILE_SIZE), round(end[1] / Config.TILE_SIZE))
|
start, end = self.nearestPosition(), (round(end[0] / Config.TILE_SIZE), round(end[1] / Config.TILE_SIZE))
|
||||||
start, end = self.dungeon.grid.node(*start), self.dungeon.grid.node(*end)
|
start, end = self.dungeon.grid.node(*start), self.dungeon.grid.node(*end)
|
||||||
paths, runs = self.dungeon.finder.find_path(start, end, self.dungeon.grid)
|
paths, runs = self.dungeon.finder.find_path(start, end, self.dungeon.grid)
|
||||||
|
|||||||
Reference in New Issue
Block a user