Merge branch 'master' of github.com:n0remac/game-jam-2020 into tests

This commit is contained in:
Xevion
2020-04-20 22:15:21 -05:00
7 changed files with 185 additions and 34 deletions

View File

@@ -8,6 +8,7 @@ verify_ssl = true
[packages]
arcade = "*"
networkx = "*"
pathfinding = "*"
[requires]
python_version = "3.7"

View File

@@ -1,7 +1,7 @@
{
"_meta": {
"hash": {
"sha256": "800f10e10ab907fd0589f880f7c7bbf82acfb39f3450331a1f3bdcdabc8e561d"
"sha256": "072e8938371eb0a39830868ce97961536e15f31d82fcdf3019e870522684c661"
},
"pipfile-spec": 6,
"requires": {
@@ -47,29 +47,37 @@
},
"numpy": {
"hashes": [
"sha256:1598a6de323508cfeed6b7cd6c4efb43324f4692e20d1f76e1feec7f59013448",
"sha256:1b0ece94018ae21163d1f651b527156e1f03943b986188dd81bc7e066eae9d1c",
"sha256:2e40be731ad618cb4974d5ba60d373cdf4f1b8dcbf1dcf4d9dff5e212baf69c5",
"sha256:4ba59db1fcc27ea31368af524dcf874d9277f21fd2e1f7f1e2e0c75ee61419ed",
"sha256:59ca9c6592da581a03d42cc4e270732552243dc45e87248aa8d636d53812f6a5",
"sha256:5e0feb76849ca3e83dd396254e47c7dba65b3fa9ed3df67c2556293ae3e16de3",
"sha256:6d205249a0293e62bbb3898c4c2e1ff8a22f98375a34775a259a0523111a8f6c",
"sha256:6fcc5a3990e269f86d388f165a089259893851437b904f422d301cdce4ff25c8",
"sha256:82847f2765835c8e5308f136bc34018d09b49037ec23ecc42b246424c767056b",
"sha256:87902e5c03355335fc5992a74ba0247a70d937f326d852fc613b7f53516c0963",
"sha256:9ab21d1cb156a620d3999dd92f7d1c86824c622873841d6b080ca5495fa10fef",
"sha256:a1baa1dc8ecd88fb2d2a651671a84b9938461e8a8eed13e2f0a812a94084d1fa",
"sha256:a244f7af80dacf21054386539699ce29bcc64796ed9850c99a34b41305630286",
"sha256:a35af656a7ba1d3decdd4fae5322b87277de8ac98b7d9da657d9e212ece76a61",
"sha256:b1fe1a6f3a6f355f6c29789b5927f8bd4f134a4bd9a781099a7c4f66af8850f5",
"sha256:b5ad0adb51b2dee7d0ee75a69e9871e2ddfb061c73ea8bc439376298141f77f5",
"sha256:ba3c7a2814ec8a176bb71f91478293d633c08582119e713a0c5351c0f77698da",
"sha256:cd77d58fb2acf57c1d1ee2835567cd70e6f1835e32090538f17f8a3a99e5e34b",
"sha256:cdb3a70285e8220875e4d2bc394e49b4988bdb1298ffa4e0bd81b2f613be397c",
"sha256:deb529c40c3f1e38d53d5ae6cd077c21f1d49e13afc7936f7f868455e16b64a0",
"sha256:e7894793e6e8540dbeac77c87b489e331947813511108ae097f1715c018b8f3d"
"sha256:0aa2b318cf81eb1693fcfcbb8007e95e231d7e1aa24288137f3b19905736c3ee",
"sha256:163c78c04f47f26ca1b21068cea25ed7c5ecafe5f5ab2ea4895656a750582b56",
"sha256:1e37626bcb8895c4b3873fcfd54e9bfc5ffec8d0f525651d6985fcc5c6b6003c",
"sha256:264fd15590b3f02a1fbc095e7e1f37cdac698ff3829e12ffdcffdce3772f9d44",
"sha256:3d9e1554cd9b5999070c467b18e5ae3ebd7369f02706a8850816f576a954295f",
"sha256:40c24960cd5cec55222963f255858a1c47c6fa50a65a5b03fd7de75e3700eaaa",
"sha256:46f404314dbec78cb342904f9596f25f9b16e7cf304030f1339e553c8e77f51c",
"sha256:4847f0c993298b82fad809ea2916d857d0073dc17b0510fbbced663b3265929d",
"sha256:48e15612a8357393d176638c8f68a19273676877caea983f8baf188bad430379",
"sha256:6725d2797c65598778409aba8cd67077bb089d5b7d3d87c2719b206dc84ec05e",
"sha256:99f0ba97e369f02a21bb95faa3a0de55991fd5f0ece2e30a9e2eaebeac238921",
"sha256:a41f303b3f9157a31ce7203e3ca757a0c40c96669e72d9b6ee1bce8507638970",
"sha256:a4305564e93f5c4584f6758149fd446df39fd1e0a8c89ca0deb3cce56106a027",
"sha256:a551d8cc267c634774830086da42e4ba157fa41dd3b93982bc9501b284b0c689",
"sha256:a6bc9432c2640b008d5f29bad737714eb3e14bb8854878eacf3d7955c4e91c36",
"sha256:c60175d011a2e551a2f74c84e21e7c982489b96b6a5e4b030ecdeacf2914da68",
"sha256:e46e2384209c91996d5ec16744234d1c906ab79a701ce1a26155c9ec890b8dc8",
"sha256:e607b8cdc2ae5d5a63cd1bec30a15b5ed583ac6a39f04b7ba0f03fcfbf29c05b",
"sha256:e94a39d5c40fffe7696009dbd11bc14a349b377e03a384ed011e03d698787dd3",
"sha256:eb2286249ebfe8fcb5b425e5ec77e4736d53ee56d3ad296f8947f67150f495e3",
"sha256:fdee7540d12519865b423af411bd60ddb513d2eb2cd921149b732854995bbf8b"
],
"version": "==1.18.2"
"version": "==1.18.3"
},
"pathfinding": {
"hashes": [
"sha256:3e3809abada1fdb292ced85cd7f63700c4f28a20f10eae68168a760be52ca746",
"sha256:e71ac5e1d933d67a3b402600f3dfb766da8c0113a0df328661c89a24bd5f21a5"
],
"index": "pypi",
"version": "==0.0.4"
},
"pillow": {
"hashes": [

View File

@@ -42,6 +42,9 @@ class Config(object):
BOTTOM_VIEWPORT_MARGIN = 50
TOP_VIEWPORT_MARGIN = 100
# All debug statements and renderings should use this
DEBUG = True
class Enums(Enum):
"""

View File

@@ -3,13 +3,37 @@ main.py
The main class used to load the game.
Holds the main game window, as well as manages basic functions for organizing the game.
"""
import collections
import random
import time
import arcade
import math
from config import Config
from map import Dungeon
from mobs import Player
from mobs import Player, Enemy
from config import Config
from projectiles import Temp
class FPSCounter:
def __init__(self):
self.time = time.perf_counter()
self.frame_times = collections.deque(maxlen=60)
def tick(self):
t1 = time.perf_counter()
dt = t1 - self.time
self.time = t1
self.frame_times.append(dt)
def get_fps(self):
total_time = sum(self.frame_times)
if total_time == 0:
return 0
else:
return len(self.frame_times) / sum(self.frame_times)
class Game(arcade.Window):
@@ -24,6 +48,7 @@ class Game(arcade.Window):
# These are 'lists' that keep track of our sprites. Each sprite should
# go into a list.
self.enemy_list = None
self.bullet_list = None
self.player = None
self.dungeon = None
@@ -45,9 +70,11 @@ class Game(arcade.Window):
# Create the Sprite lists
self.enemy_list = arcade.SpriteList()
self.fps = FPSCounter()
self.bullet_list = arcade.SpriteList()
# Create the dungeon
self.dungeon = Dungeon(0, 3)
self.dungeon = Dungeon(0, 8)
# Set up the player, specifically placing it at these coordinates.
self.player = Player()
@@ -74,7 +101,6 @@ class Game(arcade.Window):
def on_draw(self):
""" Render the screen. """
try:
# Clear the screen to the background color
arcade.start_render()
@@ -82,10 +108,14 @@ class Game(arcade.Window):
self.dungeon.render()
self.player.draw()
self.enemy_list.draw()
self.bullet_list.draw()
self.player.draw_hit_box()
x, y = self.player.center_x, self.player.center_y
arcade.draw_text(str((x, y)), x - 40, y + 50, arcade.color.WHITE, 15)
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.fps.tick()
except Exception:
import traceback
traceback.print_exc()
@@ -126,13 +156,47 @@ class Game(arcade.Window):
if self.prev_keypress:
self.on_key_press(self.prev_keypress.pop(0), 0)
def on_mouse_press(self, x, y, button, modifiers):
"""
Called whenever the mouse is clicked.
"""
# Create a bullet TEMP SPRITE, currently wielding frog slingshot
bullet = Temp()
# Position the bullet at the player's current location
start_x = self.player.center_x
start_y = self.player.center_y
bullet.center_x = start_x
bullet.center_y = start_y
# Get from the mouse the destination location for the bullet
dest_x = x+self.view_left
dest_y = y+self.view_bottom
# Do math to calculate how to get the bullet to the destination.
# Calculation the angle in radians between the start points
# and end points. This is the angle the bullet will travel.
x_diff = dest_x - start_x
y_diff = dest_y - start_y
angle = math.atan2(y_diff, x_diff)
# Angle the bullet sprite so it doesn't look like it is flying sideways.
bullet.angle = math.degrees(angle)
# Taking into account the angle, calculate our change_x
# and change_y. Velocity is how fast the bullet travels.
bullet.change_x = math.cos(angle) * bullet.speed
bullet.change_y = math.sin(angle) * bullet.speed
# Add the bullet to the appropriate lists
self.bullet_list.append(bullet)
def on_update(self, delta_time):
""" Movement and game logic """
# Move the player with the physics engine
self.physics_engine.update()
self.player.update_animation()
changed = False # Track if we need to change the viewport
# Below manages all scrolling mechanics
@@ -169,6 +233,25 @@ class Game(arcade.Window):
self.view_bottom,
Config.SCREEN_HEIGHT + self.view_bottom)
# Projectile updates
self.bullet_list.update()
for bullet in self.bullet_list:
# Collision Checks
hit_list = arcade.check_for_collision_with_list(bullet, self.dungeon.getWalls())
# If it did, get rid of the bullet
if len(hit_list) > 0:
bullet.remove_from_sprite_lists()
# If the bullet flies off-screen, remove it. TEMP change to range calc
if (
bullet.bottom < self.view_bottom or
bullet.top > self.view_bottom+Config.SCREEN_HEIGHT or
bullet.right > self.view_left+Config.SCREEN_WIDTH or
bullet.left < self.view_left
):
bullet.remove_from_sprite_lists()
def main() -> None:
"""

View File

@@ -32,8 +32,8 @@ class Dungeon(object):
self.level_count = level_count
self.size = size
self.floor_list = arcade.SpriteList()
self.wall_list = arcade.SpriteList()
self.floor_list = arcade.SpriteList(is_static=True)
self.wall_list = arcade.SpriteList(is_static=True)
# center = Level.load_file(1, 1, 'resources/levels/map1/center.json')
# side = Level.load_file(2, 1, 'resources/levels/map1/room.json')
@@ -48,10 +48,10 @@ class Dungeon(object):
Simple one time function for getting all Wall sprites from all Levels.
Used by the physics engine during game startup.
:return: A SpriteList containing all Sprites.
:return: A SpriteList containing all Wall (Collidable) Sprites.
"""
walls = arcade.SpriteList()
walls = arcade.SpriteList(is_static=True)
walls.extend(
list(chain.from_iterable(
chain.from_iterable([level.wallSprites for level in column if level is not None]) for column in
@@ -102,8 +102,8 @@ class Level:
self.sprites = []
self.structure = []
self.floorSprites = arcade.SpriteList()
self.wallSprites = arcade.SpriteList()
self.floorSprites = arcade.SpriteList(is_static=True)
self.wallSprites = arcade.SpriteList(is_static=True)
# Tuples containing the Node positions of where walls, floor and entrances are.
# All positions are generated based on the level's X and Y position, so that all points within

21
triple-dungeon/path.py Normal file
View File

@@ -0,0 +1,21 @@
from pathfinding.core.diagonal_movement import DiagonalMovement
from pathfinding.core.grid import Grid
from pathfinding.finder.a_star import AStarFinder
def route(start, end, matrix) -> path:
"""
Take a matrix of the level in the form wighted numbers, a start and stop point, and return a path between them.
param: start: (x, y) location of the monster
param: end: (x, y) location of the player
param: matrix: a 2d list of the level. 0s are walls, numbers greater than 0 are weighted
"""
grid = Grid(matrix=matrix)
start = grid.node(start[0], start[1])
end = grid.node(end[0], end[1])
finder = AStarFinder(diagonal_movement=DiagonalMovement.always)
path, runs = finder.find_path(start, end, grid)
return path

View File

@@ -0,0 +1,35 @@
"""
projectiles.py
Organizes classes related to projectiles
"""
import arcade
class Projectile(arcade.Sprite):
"""
Represents a Projectile. Damage, sprite, speed, range, collision list?
"""
def __init__(self, speed=7, damage=0, range=100, *args, **kwargs) -> None:
# Set up parent class
super().__init__()
self.speed = speed
self.damage = damage # unimplemented
self.texture = None
self.range = range # unimplemented
self.collision_list = []
class Temp(Projectile):
"""
Temporary extension of projectile to demonstrate usage
"""
def __init__(self, *args, **kwargs) -> None:
super(Temp, self).__init__(*args, **kwargs)
self.texture = arcade.load_texture("resources/images/monsters/frog/frog1.png")
self.speed = 20
self.scale = 1
# collision list for who/what to collide with: wall, player, enemy
# Can place function for starting on player or enemy