Merge pull request #4 from n0remac/map

Skeleton Classes
This commit is contained in:
Cameron
2020-04-18 00:01:40 -07:00
committed by GitHub
5 changed files with 165 additions and 52 deletions

1
triple-dungeon/.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
.idea/**

30
triple-dungeon/config.py Normal file
View File

@@ -0,0 +1,30 @@
"""
config.py
Holds all constants used for setting up the game.
May later hold functions for loading/saving configuration files.
"""
class Config(object):
"""
A simple class dedicated to loading, storing and organizing constants.
"""
# Constants
SCREEN_WIDTH = 1000
SCREEN_HEIGHT = 650
SCREEN_TITLE = "Triple Dungeon"
# Constants used to scale our sprites from their original size
CHARACTER_SCALING = 1
TILE_SCALING = 2
# Movement speed of player, in pixels per frame
PLAYER_MOVEMENT_SPEED = 5
# How many pixels to keep as a minimum margin between the character
# and the edge of the screen.
LEFT_VIEWPORT_MARGIN = 250
RIGHT_VIEWPORT_MARGIN = 250
BOTTOM_VIEWPORT_MARGIN = 50
TOP_VIEWPORT_MARGIN = 100

View File

@@ -1,37 +1,22 @@
""" """
Platformer Game 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 arcade import arcade
# Constants from config import Config
SCREEN_WIDTH = 1000
SCREEN_HEIGHT = 650
SCREEN_TITLE = "Triple Dungeon!!!"
# Constants used to scale our sprites from their original size
CHARACTER_SCALING = 1
TILE_SCALING = 2
# Movement speed of player, in pixels per frame
PLAYER_MOVEMENT_SPEED = 5
# How many pixels to keep as a minimum margin between the character class Game(arcade.Window):
# and the edge of the screen.
LEFT_VIEWPORT_MARGIN = 250
RIGHT_VIEWPORT_MARGIN = 250
BOTTOM_VIEWPORT_MARGIN = 50
TOP_VIEWPORT_MARGIN = 100
class MyGame(arcade.Window):
""" """
Main application class. Main application class.
""" """
def __init__(self): def __init__(self):
# Call the parent class and set up the window # Call the parent class and set up the window
super().__init__(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_TITLE) super().__init__(Config.SCREEN_WIDTH, Config.SCREEN_HEIGHT, Config.SCREEN_TITLE)
# These are 'lists' that keep track of our sprites. Each sprite should # These are 'lists' that keep track of our sprites. Each sprite should
# go into a list. # go into a list.
@@ -45,7 +30,7 @@ class MyGame(arcade.Window):
# Our physics engine # Our physics engine
self.physics_engine = None self.physics_engine = None
#list to keep track of keypresses # list to keep track of keypresses
self.prev_keypress = [] self.prev_keypress = []
# Used to keep track of our scrolling # Used to keep track of our scrolling
@@ -63,17 +48,17 @@ class MyGame(arcade.Window):
# Set up the player, specifically placing it at these coordinates. # Set up the player, specifically placing it at these coordinates.
image_source = "images/monsters/skeleton.png" image_source = "images/monsters/skeleton.png"
self.player_sprite = arcade.Sprite(image_source, CHARACTER_SCALING) self.player_sprite = arcade.Sprite(image_source, Config.CHARACTER_SCALING)
self.player_sprite.center_x = SCREEN_WIDTH / 2 self.player_sprite.center_x = Config.SCREEN_WIDTH / 2
self.player_sprite.center_y = SCREEN_HEIGHT / 2 self.player_sprite.center_y = Config.SCREEN_HEIGHT / 2
self.player_sprite.scale = 4 self.player_sprite.scale = 4
self.player_list.append(self.player_sprite) self.player_list.append(self.player_sprite)
# Create the floor # Create the floor
# This shows using a loop to place multiple sprites horizontally and vertically # This shows using a loop to place multiple sprites horizontally and vertically
for y in range(0, 1250, 63 * TILE_SCALING): for y in range(0, 1250, 63 * Config.TILE_SCALING):
for x in range(0, 1250, 63 * TILE_SCALING): for x in range(0, 1250, 63 * Config.TILE_SCALING):
floor = arcade.Sprite("images/tiles/floor_tile.png", TILE_SCALING) floor = arcade.Sprite("images/tiles/floor_tile.png", Config.TILE_SCALING)
floor.center_x = x floor.center_x = x
floor.center_y = y floor.center_y = y
self.floor_list.append(floor) self.floor_list.append(floor)
@@ -95,16 +80,16 @@ class MyGame(arcade.Window):
"""Called whenever a key is pressed. """ """Called whenever a key is pressed. """
if key == arcade.key.UP or key == arcade.key.W: if key == arcade.key.UP or key == arcade.key.W:
self.player_sprite.change_y = PLAYER_MOVEMENT_SPEED self.player_sprite.change_y = Config.PLAYER_MOVEMENT_SPEED
self.prev_keypress.append(key) self.prev_keypress.append(key)
elif key == arcade.key.DOWN or key == arcade.key.S: elif key == arcade.key.DOWN or key == arcade.key.S:
self.player_sprite.change_y = -PLAYER_MOVEMENT_SPEED self.player_sprite.change_y = -Config.PLAYER_MOVEMENT_SPEED
self.prev_keypress.append(key) self.prev_keypress.append(key)
elif key == arcade.key.LEFT or key == arcade.key.A: elif key == arcade.key.LEFT or key == arcade.key.A:
self.player_sprite.change_x = -PLAYER_MOVEMENT_SPEED self.player_sprite.change_x = -Config.PLAYER_MOVEMENT_SPEED
self.prev_keypress.append(key) self.prev_keypress.append(key)
elif key == arcade.key.RIGHT or key == arcade.key.D: elif key == arcade.key.RIGHT or key == arcade.key.D:
self.player_sprite.change_x = PLAYER_MOVEMENT_SPEED self.player_sprite.change_x = Config.PLAYER_MOVEMENT_SPEED
self.prev_keypress.append(key) self.prev_keypress.append(key)
def on_key_release(self, key, modifiers): def on_key_release(self, key, modifiers):
@@ -124,40 +109,33 @@ class MyGame(arcade.Window):
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), '') self.on_key_press(self.prev_keypress.pop(0), 0)
def on_update(self, delta_time): def on_update(self, delta_time):
""" 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.physics_engine.update()
changed = False # Track if we need to change the viewport
# --- Manage Scrolling --- # Below manages all scrolling mechanics
# Track if we need to change the viewport
changed = False
# Scroll left # Scroll left
left_boundary = self.view_left + LEFT_VIEWPORT_MARGIN left_boundary = self.view_left + Config.LEFT_VIEWPORT_MARGIN
if self.player_sprite.left < left_boundary: if self.player_sprite.left < left_boundary:
self.view_left -= left_boundary - self.player_sprite.left self.view_left -= left_boundary - self.player_sprite.left
changed = True changed = True
# Scroll right # Scroll right
right_boundary = self.view_left + SCREEN_WIDTH - RIGHT_VIEWPORT_MARGIN right_boundary = self.view_left + Config.SCREEN_WIDTH - Config.RIGHT_VIEWPORT_MARGIN
if self.player_sprite.right > right_boundary: if self.player_sprite.right > right_boundary:
self.view_left += self.player_sprite.right - right_boundary self.view_left += self.player_sprite.right - right_boundary
changed = True changed = True
# Scroll up # Scroll up
top_boundary = self.view_bottom + SCREEN_HEIGHT - TOP_VIEWPORT_MARGIN top_boundary = self.view_bottom + Config.SCREEN_HEIGHT - Config.TOP_VIEWPORT_MARGIN
if self.player_sprite.top > top_boundary: if self.player_sprite.top > top_boundary:
self.view_bottom += self.player_sprite.top - top_boundary self.view_bottom += self.player_sprite.top - top_boundary
changed = True changed = True
# Scroll down # Scroll down
bottom_boundary = self.view_bottom + BOTTOM_VIEWPORT_MARGIN bottom_boundary = self.view_bottom + Config.BOTTOM_VIEWPORT_MARGIN
if self.player_sprite.bottom < bottom_boundary: if self.player_sprite.bottom < bottom_boundary:
self.view_bottom -= bottom_boundary - self.player_sprite.bottom self.view_bottom -= bottom_boundary - self.player_sprite.bottom
changed = True changed = True
@@ -170,14 +148,17 @@ class MyGame(arcade.Window):
# Do the scrolling # Do the scrolling
arcade.set_viewport(self.view_left, arcade.set_viewport(self.view_left,
SCREEN_WIDTH + self.view_left, Config.SCREEN_WIDTH + self.view_left,
self.view_bottom, self.view_bottom,
SCREEN_HEIGHT + self.view_bottom) Config.SCREEN_HEIGHT + self.view_bottom)
def main(): def main() -> None:
""" Main method """ """
window = MyGame() Setups up window classes and runs the game.
"""
window = Game()
window.setup() window.setup()
arcade.run() arcade.run()

37
triple-dungeon/map.py Normal file
View File

@@ -0,0 +1,37 @@
from __future__ import annotations
class Dungeon(object):
"""
Organizes Level objects into an easy to render and path through object.
"""
def __init__(self, level_count: int = 3, size: int = 3) -> None:
"""
Initializes the Dungeon object.
:param level_count: The number of Active Levels that should be stored within the Dungeon.
:param size: The diameter of the dungeon. Allows for a total of size^2 slots for levels.
"""
self.levels, self.size = level_count, size
class Level(object):
"""
A 10x10 space holding wall and background sprites, enemies, items and so forth.
Should be loaded from
"""
def __init__(self,) -> None:
self.wallGrid = []
@staticmethod
def load_file(path: str) -> Level:
"""
Builds a Level from a given file path.
:param path: Path to the Level file.
:return: The new generated Level file.
"""
pass

64
triple-dungeon/mobs.py Normal file
View File

@@ -0,0 +1,64 @@
"""
mobs.py
Organizes all classes related to Mobs, Entities, Enemies, Players and Items.
"""
import arcade
from config import Config
class Mob(object):
"""
Represents a Mob. No defined behaviour, it has no intelligence.
"""
def __init__(self, sprite, max_health=100, max_armor=0) -> None:
self.sprite_path = sprite
self.sprite = arcade.Sprite(self.sprite_path, Config.CHARACTER_SCALING)
self.max_health, self.max_armor = max_health, max_armor
self.health, self.armor = max_health, max_armor
def tick(self) -> None:
"""
A on_update function, the Mob should decide it's next actions here.
"""
pass
class Player(Mob):
"""
Represents a Player.
While this is a instance, there should only be one in the world at any given time.
"""
def __init__(self, *args, **kwargs) -> None:
super(Player, self).__init__(*args, **kwargs)
def tick(self):
"""
While Player objects do not have any AI (they are controlled by the user),
the tick function can keep track of statistics that progress over time, like
regenerating health/armor or status effects like poison.
"""
class Enemy(Mob):
"""
Represents an Enemy Mob.
Will take basic offensive actions against Player objects.
"""
def __init__(self, *args, **kwargs) -> None:
super(Enemy, self).__init__(*args, **kwargs)
def tick(self) -> None:
"""
A on_update function, the Enemy Mob should scan for the player, decide how to path to it, and
decide how to take offensive action.
"""
pass
def path(self) -> None:
"""
Not yet decided how this function should work.
Basically, most pathfinding decisions should be kept within this function.
"""
pass