mirror of
https://github.com/n0remac/game-jam-2020.git
synced 2025-12-16 12:10:02 -06:00
Merge pull request #38 from n0remac/monster-kill-combos
Monster kill combos
This commit is contained in:
@@ -29,21 +29,25 @@ class Config(object):
|
|||||||
# Constants used to scale our sprites from their original size
|
# Constants used to scale our sprites from their original size
|
||||||
CHARACTER_SCALING = 1
|
CHARACTER_SCALING = 1
|
||||||
TILE_SCALING = 2
|
TILE_SCALING = 2
|
||||||
|
TILE_SIZE = TILE_WIDTH * TILE_SCALING
|
||||||
|
|
||||||
# The number of pixels across the level
|
# The number of pixels across the level
|
||||||
LEVEL_SIZE = 10 * TILE_SCALING * TILE_WIDTH
|
LEVEL_SIZE = 10 * TILE_SCALING * TILE_WIDTH
|
||||||
|
|
||||||
# Movement speed of player, in pixels per frame
|
# Movement speed of player, in pixels per frame
|
||||||
PLAYER_MOVEMENT_SPEED = 7
|
PLAYER_MOVEMENT_SPEED = 14
|
||||||
|
|
||||||
# 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 = 250
|
LEFT_VIEWPORT_MARGIN = 700
|
||||||
RIGHT_VIEWPORT_MARGIN = 250
|
RIGHT_VIEWPORT_MARGIN = 700
|
||||||
BOTTOM_VIEWPORT_MARGIN = 50
|
BOTTOM_VIEWPORT_MARGIN = 300
|
||||||
TOP_VIEWPORT_MARGIN = 100
|
TOP_VIEWPORT_MARGIN = 350
|
||||||
|
|
||||||
# All debug statements and renderings should use this
|
# All debug statements and renderings should use this
|
||||||
DEBUG = True
|
DEBUG = False
|
||||||
|
|
||||||
|
# Monster Count to be spawned
|
||||||
|
MONSTER_COUNT = 10
|
||||||
|
|
||||||
|
|
||||||
class Enums(Enum):
|
class Enums(Enum):
|
||||||
|
|||||||
@@ -8,13 +8,14 @@ import collections
|
|||||||
import math
|
import math
|
||||||
import random
|
import random
|
||||||
import time
|
import time
|
||||||
|
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
|
from mobs import Player, Enemy
|
||||||
from projectiles import Temp
|
from projectiles import Temp
|
||||||
|
from recipe import ActiveRecipe
|
||||||
|
|
||||||
|
|
||||||
class FPSCounter:
|
class FPSCounter:
|
||||||
@@ -47,6 +48,7 @@ class Game(arcade.Window):
|
|||||||
|
|
||||||
# Sprite Lists
|
# Sprite Lists
|
||||||
self.enemy_list = None
|
self.enemy_list = None
|
||||||
|
self.active_enemies = []
|
||||||
self.bullet_list = None
|
self.bullet_list = None
|
||||||
self.player = None
|
self.player = None
|
||||||
# Game Objects
|
# Game Objects
|
||||||
@@ -55,6 +57,7 @@ class Game(arcade.Window):
|
|||||||
self.physics_engine = None # Our physics engine
|
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 = []
|
||||||
|
|
||||||
arcade.set_background_color(arcade.color.BLACK)
|
arcade.set_background_color(arcade.color.BLACK)
|
||||||
|
|
||||||
@@ -63,19 +66,41 @@ class Game(arcade.Window):
|
|||||||
# Create the Sprite lists
|
# Create the Sprite lists
|
||||||
|
|
||||||
self.enemy_list = arcade.SpriteList()
|
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()
|
||||||
|
|
||||||
# Create the dungeon
|
# Create the dungeon
|
||||||
self.dungeon = Dungeon(0, 3)
|
self.dungeon = Dungeon(0, 3)
|
||||||
|
|
||||||
|
# Set up recipes
|
||||||
|
self.active_recipe = ActiveRecipe()
|
||||||
|
self.active_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.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
|
||||||
# x, y = level.center()
|
# x, y = level.center()
|
||||||
|
|
||||||
|
# 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)
|
||||||
|
|
||||||
# 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
|
||||||
self.view_left = self.player.center_x - (0.5 * Config.SCREEN_WIDTH)
|
self.view_left = self.player.center_x - (0.5 * Config.SCREEN_WIDTH)
|
||||||
@@ -84,10 +109,6 @@ class Game(arcade.Window):
|
|||||||
self.view_bottom,
|
self.view_bottom,
|
||||||
Config.SCREEN_HEIGHT + self.view_bottom)
|
Config.SCREEN_HEIGHT + self.view_bottom)
|
||||||
|
|
||||||
# Create monsters
|
|
||||||
# self.enemy_list.append(Enemy("resources/images/monsters/ghost/ghost1.png", 200, 200, 4))
|
|
||||||
# self.enemy_list.append(Enemy("resources/images/monsters/frog/frog1.png", 200, 1000, 4))
|
|
||||||
|
|
||||||
# Create the 'physics engine'
|
# Create the 'physics engine'
|
||||||
self.physics_engine = arcade.PhysicsEngineSimple(self.player, self.dungeon.getWalls())
|
self.physics_engine = arcade.PhysicsEngineSimple(self.player, self.dungeon.getWalls())
|
||||||
|
|
||||||
@@ -101,22 +122,48 @@ class Game(arcade.Window):
|
|||||||
self.dungeon.render()
|
self.dungeon.render()
|
||||||
self.player.draw()
|
self.player.draw()
|
||||||
self.enemy_list.draw()
|
self.enemy_list.draw()
|
||||||
|
self.active_enemies.draw()
|
||||||
self.bullet_list.draw()
|
self.bullet_list.draw()
|
||||||
|
self.active_recipe.render()
|
||||||
|
|
||||||
if Config.DEBUG:
|
if Config.DEBUG:
|
||||||
x, y = self.player.position
|
x, y = self.player.position
|
||||||
tile = Config.TILE_WIDTH * Config.TILE_SCALING
|
arcade.draw_rectangle_outline(round(x / Config.TILE_SIZE) * Config.TILE_SIZE,
|
||||||
arcade.draw_rectangle_outline(round(x / tile) * tile, round(y / tile) * tile, tile, tile,
|
round(y / Config.TILE_SIZE) * Config.TILE_SIZE,
|
||||||
arcade.color.RED)
|
Config.TILE_SIZE, Config.TILE_SIZE, arcade.color.RED)
|
||||||
self.player.draw_hit_box()
|
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(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.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')
|
arcade.color.WHITE, 16, font_name='Arial')
|
||||||
|
|
||||||
|
# Draw paths for all mobs
|
||||||
|
for mob in self.active_enemies:
|
||||||
|
if mob.target is not None:
|
||||||
|
t1 = time.time()
|
||||||
|
path = mob.get_path()
|
||||||
|
t2 = time.time()
|
||||||
|
print(f'Path acquired in {round(t2 - t1, 4)}s')
|
||||||
|
self.draw_path(path)
|
||||||
|
mob.tick(path)
|
||||||
|
|
||||||
self.fps.tick()
|
self.fps.tick()
|
||||||
except Exception:
|
except Exception:
|
||||||
import traceback
|
import traceback
|
||||||
traceback.print_exc()
|
traceback.print_exc()
|
||||||
|
|
||||||
|
@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)
|
||||||
|
for pos1, pos2 in zip(path, path[1:]):
|
||||||
|
arcade.draw_line(*pos1, *pos2, color=arcade.color.RED)
|
||||||
|
|
||||||
def on_key_press(self, key, modifiers):
|
def on_key_press(self, key, modifiers):
|
||||||
"""Called whenever a key is pressed. """
|
"""Called whenever a key is pressed. """
|
||||||
|
|
||||||
@@ -134,6 +181,9 @@ class Game(arcade.Window):
|
|||||||
self.prev_keypress.append(key)
|
self.prev_keypress.append(key)
|
||||||
elif key == 65307:
|
elif key == 65307:
|
||||||
self.close()
|
self.close()
|
||||||
|
elif key == 65505:
|
||||||
|
self.active_recipe.next_recipe()
|
||||||
|
self.player.cur_recipe = self.active_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. """
|
||||||
@@ -150,6 +200,7 @@ class Game(arcade.Window):
|
|||||||
elif key == arcade.key.RIGHT or key == arcade.key.D:
|
elif key == arcade.key.RIGHT or key == arcade.key.D:
|
||||||
self.player.change_x = 0
|
self.player.change_x = 0
|
||||||
self.prev_keypress.remove(key)
|
self.prev_keypress.remove(key)
|
||||||
|
|
||||||
if self.prev_keypress:
|
if self.prev_keypress:
|
||||||
self.on_key_press(self.prev_keypress.pop(0), 0)
|
self.on_key_press(self.prev_keypress.pop(0), 0)
|
||||||
|
|
||||||
@@ -157,6 +208,7 @@ class Game(arcade.Window):
|
|||||||
"""
|
"""
|
||||||
Called whenever the mouse is clicked.
|
Called whenever the mouse is clicked.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# Create a bullet TEMP SPRITE, currently wielding frog slingshot
|
# Create a bullet TEMP SPRITE, currently wielding frog slingshot
|
||||||
bullet = Temp()
|
bullet = Temp()
|
||||||
# Position the bullet at the player's current location
|
# Position the bullet at the player's current location
|
||||||
@@ -229,16 +281,39 @@ 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
|
||||||
|
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()
|
||||||
# Projectile updates
|
# Projectile updates
|
||||||
self.bullet_list.update()
|
self.bullet_list.update()
|
||||||
for bullet in self.bullet_list:
|
for bullet in self.bullet_list:
|
||||||
|
|
||||||
# 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)
|
||||||
# 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()
|
||||||
|
if len(enemy_hit_list):
|
||||||
|
self.player.add_kill(enemy_hit_list[0].monster_type)
|
||||||
|
enemy_hit_list[0].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 (
|
||||||
|
|||||||
@@ -7,11 +7,16 @@ Pathfinding will also depend on objects here, and is thus integral to it's funct
|
|||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
import json
|
import json
|
||||||
|
from pprint import pprint
|
||||||
|
|
||||||
import arcade
|
import arcade
|
||||||
import numpy as np
|
import numpy as np
|
||||||
|
|
||||||
from itertools import chain
|
from itertools import chain
|
||||||
from config import Config
|
from config import Config
|
||||||
|
from pathfinding.core.diagonal_movement import DiagonalMovement
|
||||||
|
from pathfinding.core.grid import Grid
|
||||||
|
from pathfinding.finder.a_star import AStarFinder
|
||||||
|
|
||||||
|
|
||||||
class Dungeon(object):
|
class Dungeon(object):
|
||||||
@@ -40,6 +45,16 @@ class Dungeon(object):
|
|||||||
self.levels = [
|
self.levels = [
|
||||||
[Level.load_file(x, y, center) for y in range(size)] for x in range(size)
|
[Level.load_file(x, y, center) for y in range(size)] for x in range(size)
|
||||||
]
|
]
|
||||||
|
self.matrix = [[1 for yy in range(size * 10)] for xx in range(10 * size)]
|
||||||
|
for column in self.levels:
|
||||||
|
for level in column:
|
||||||
|
for xx in range(10):
|
||||||
|
for yy in range(10):
|
||||||
|
if level.structure[xx][yy] == 'w':
|
||||||
|
self.matrix[(level.x * 10) + xx][(level.y * 10) + yy] = 0
|
||||||
|
self.grid = Grid(matrix=self.matrix)
|
||||||
|
self.finder = AStarFinder(diagonal_movement=DiagonalMovement.always)
|
||||||
|
pprint(self.matrix, width=1000)
|
||||||
|
|
||||||
def getWalls(self) -> arcade.SpriteList:
|
def getWalls(self) -> arcade.SpriteList:
|
||||||
"""
|
"""
|
||||||
|
|||||||
@@ -3,9 +3,11 @@ mobs.py
|
|||||||
Organizes all classes related to Mobs, Entities, Enemies, Players and Items.
|
Organizes all classes related to Mobs, Entities, Enemies, Players and Items.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import arcade
|
from typing import List, Tuple
|
||||||
|
|
||||||
|
import arcade
|
||||||
from config import Config, Enums, SpritePaths
|
from config import Config, Enums, SpritePaths
|
||||||
|
from map import Dungeon
|
||||||
from sprites import PlayerAnimations
|
from sprites import PlayerAnimations
|
||||||
|
|
||||||
|
|
||||||
@@ -14,9 +16,9 @@ class Mob(arcade.Sprite):
|
|||||||
Represents a Mob. No defined behaviour, it has no intelligence.
|
Represents a Mob. No defined behaviour, it has no intelligence.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, max_health=100, max_armor=0, *args, **kwargs) -> None:
|
def __init__(self, dungeon: Dungeon, max_health=100, max_armor=0, *args, **kwargs) -> None:
|
||||||
# Set up parent class
|
# Set up parent class
|
||||||
super().__init__()
|
super(Mob, self).__init__(*args, **kwargs)
|
||||||
|
|
||||||
self.max_health, self.max_armor = max_health, max_armor
|
self.max_health, self.max_armor = max_health, max_armor
|
||||||
self.health, self.armor = max_health, max_armor
|
self.health, self.armor = max_health, max_armor
|
||||||
@@ -26,13 +28,10 @@ class Mob(arcade.Sprite):
|
|||||||
self.down_textures = []
|
self.down_textures = []
|
||||||
self.cur_texture = 0
|
self.cur_texture = 0
|
||||||
|
|
||||||
def tick(self) -> None:
|
self.dungeon = dungeon
|
||||||
"""
|
self.target = None
|
||||||
A on_update function, the Mob should decide it's next actions here.
|
|
||||||
"""
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class Player(Mob):
|
class Player(Mob):
|
||||||
"""
|
"""
|
||||||
Represents a Player.
|
Represents a Player.
|
||||||
@@ -55,6 +54,19 @@ class Player(Mob):
|
|||||||
self.refreshIndex = 0
|
self.refreshIndex = 0
|
||||||
self.prev = Enums.IDLE
|
self.prev = Enums.IDLE
|
||||||
self.texture = next(self.map[self.prev])
|
self.texture = next(self.map[self.prev])
|
||||||
|
self.kill_list = []
|
||||||
|
self.cur_recipe = None
|
||||||
|
|
||||||
|
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)
|
||||||
|
print(self.kill_list)
|
||||||
|
print(self.cur_recipe)
|
||||||
|
if self.cur_recipe == self.kill_list:
|
||||||
|
print("+++++++++++++++++++++++++++++++++++++++++++++++++++++++")
|
||||||
|
self.kill_list = []
|
||||||
|
elif len(self.kill_list) >= 3:
|
||||||
|
self.kill_list = []
|
||||||
|
|
||||||
def update_animation(self, delta_time: float = 1 / 60) -> None:
|
def update_animation(self, delta_time: float = 1 / 60) -> None:
|
||||||
"""
|
"""
|
||||||
@@ -101,17 +113,51 @@ 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 = ''
|
||||||
|
|
||||||
def tick(self) -> None:
|
def nearestPosition(self) -> Tuple[int, int]:
|
||||||
"""
|
"""
|
||||||
A on_update function, the Enemy Mob should scan for the player, decide how to path to it, and
|
Returns the nearest absolute dungeon tile the Mob is placed on.
|
||||||
decide how to take offensive action.
|
|
||||||
"""
|
|
||||||
pass
|
|
||||||
|
|
||||||
def path(self) -> None:
|
:return: A tuple containing the Mob's dungeon tile position.
|
||||||
"""
|
"""
|
||||||
Not yet decided how this function should work.
|
return (round(self.center_x / Config.TILE_SIZE),
|
||||||
Basically, most pathfinding decisions should be kept within this function.
|
round(self.center_y / Config.TILE_SIZE))
|
||||||
|
|
||||||
|
def tick(self, path: Tuple[int, int] = None) -> None:
|
||||||
"""
|
"""
|
||||||
pass
|
A on_update function, the Mob should decide it's next actions here.
|
||||||
|
"""
|
||||||
|
curpos, nextpos = self.nearestPosition(), path[1]
|
||||||
|
# print(curpos, nextpos)
|
||||||
|
|
||||||
|
if nextpos[0] > curpos[0]:
|
||||||
|
self.change_x = Config.PLAYER_MOVEMENT_SPEED - 3
|
||||||
|
elif nextpos[0] < curpos[0]:
|
||||||
|
self.change_x = -Config.PLAYER_MOVEMENT_SPEED + 3
|
||||||
|
else:
|
||||||
|
self.change_x = 0
|
||||||
|
|
||||||
|
if nextpos[1] > curpos[1]:
|
||||||
|
self.change_y = Config.PLAYER_MOVEMENT_SPEED - 3
|
||||||
|
elif nextpos[1] < curpos[1]:
|
||||||
|
self.change_y = -Config.PLAYER_MOVEMENT_SPEED + 3
|
||||||
|
else:
|
||||||
|
self.change_y = 0
|
||||||
|
|
||||||
|
# print(self.change_x, self.change_y)
|
||||||
|
|
||||||
|
def get_path(self, end: Tuple[int, int] = None) -> List[Tuple[int, int]]:
|
||||||
|
"""
|
||||||
|
Returns the path to get to the Mob's target in absolute integer positions.
|
||||||
|
|
||||||
|
:param end: A the endpoint tuple. Must be a valid position within the matrix.
|
||||||
|
: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.dungeon.grid.node(*start), self.dungeon.grid.node(*end)
|
||||||
|
paths, runs = self.dungeon.finder.find_path(start, end, self.dungeon.grid)
|
||||||
|
self.dungeon.grid.cleanup()
|
||||||
|
return paths
|
||||||
|
|||||||
59
triple-dungeon/recipe.py
Normal file
59
triple-dungeon/recipe.py
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
'''
|
||||||
|
Recipes are combinations of three monsters. When a player fills a recipe they get an updgrade
|
||||||
|
'''
|
||||||
|
|
||||||
|
import arcade
|
||||||
|
|
||||||
|
|
||||||
|
class Recipe:
|
||||||
|
'''
|
||||||
|
A class of different recipes
|
||||||
|
'''
|
||||||
|
|
||||||
|
GHOSTS = ['ghost', 'ghost', 'ghost']
|
||||||
|
FROGS = ['frog', 'frog', 'frog']
|
||||||
|
GHOST_FROG = ['ghost', 'ghost', 'frog']
|
||||||
|
FROG_GHOST = ['ghost', 'frog', 'frog']
|
||||||
|
|
||||||
|
|
||||||
|
class ActiveRecipe(arcade.SpriteList):
|
||||||
|
'''
|
||||||
|
Keeps track of the active recipe and draws it.
|
||||||
|
'''
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__()
|
||||||
|
self.active = Recipe.GHOSTS
|
||||||
|
self.cycle_recipes = [self.set_frogs, self.set_ghosts]
|
||||||
|
self.pos = 0
|
||||||
|
|
||||||
|
def render(self) -> None:
|
||||||
|
x = 0
|
||||||
|
for sprite in self.sprite_list:
|
||||||
|
screen_right = arcade.get_viewport()[1] - 100
|
||||||
|
screen_top = arcade.get_viewport()[3] - 80
|
||||||
|
sprite.scale = 4
|
||||||
|
sprite.center_x = screen_right - x
|
||||||
|
sprite.center_y = screen_top
|
||||||
|
x += 70
|
||||||
|
sprite.draw()
|
||||||
|
|
||||||
|
def next_recipe(self):
|
||||||
|
self.cycle_recipes[self.pos]()
|
||||||
|
self.pos += 1
|
||||||
|
if self.pos == len(self.cycle_recipes):
|
||||||
|
self.pos = 0
|
||||||
|
|
||||||
|
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
|
||||||
|
self.sprite_list = []
|
||||||
|
self.sprite_list.append(arcade.Sprite(filename="resources/images/monsters/frog/frog1.png"))
|
||||||
|
self.sprite_list.append(arcade.Sprite(filename="resources/images/monsters/frog/frog1.png"))
|
||||||
|
self.sprite_list.append(arcade.Sprite(filename="resources/images/monsters/frog/frog1.png"))
|
||||||
Reference in New Issue
Block a user