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
# 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
from config import Config
# 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
class MyGame(arcade.Window):
class Game(arcade.Window):
"""
Main application class.
"""
def __init__(self):
# 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
# go into a list.
@@ -45,7 +30,7 @@ class MyGame(arcade.Window):
# Our physics engine
self.physics_engine = None
#list to keep track of keypresses
# list to keep track of keypresses
self.prev_keypress = []
# 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.
image_source = "images/monsters/skeleton.png"
self.player_sprite = arcade.Sprite(image_source, CHARACTER_SCALING)
self.player_sprite.center_x = SCREEN_WIDTH / 2
self.player_sprite.center_y = SCREEN_HEIGHT / 2
self.player_sprite = arcade.Sprite(image_source, Config.CHARACTER_SCALING)
self.player_sprite.center_x = Config.SCREEN_WIDTH / 2
self.player_sprite.center_y = Config.SCREEN_HEIGHT / 2
self.player_sprite.scale = 4
self.player_list.append(self.player_sprite)
# Create the floor
# This shows using a loop to place multiple sprites horizontally and vertically
for y in range(0, 1250, 63 * TILE_SCALING):
for x in range(0, 1250, 63 * TILE_SCALING):
floor = arcade.Sprite("images/tiles/floor_tile.png", TILE_SCALING)
for y in range(0, 1250, 63 * Config.TILE_SCALING):
for x in range(0, 1250, 63 * Config.TILE_SCALING):
floor = arcade.Sprite("images/tiles/floor_tile.png", Config.TILE_SCALING)
floor.center_x = x
floor.center_y = y
self.floor_list.append(floor)
@@ -95,16 +80,16 @@ class MyGame(arcade.Window):
"""Called whenever a key is pressed. """
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)
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)
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)
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)
def on_key_release(self, key, modifiers):
@@ -124,40 +109,33 @@ class MyGame(arcade.Window):
self.prev_keypress.remove(key)
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):
""" Movement and game logic """
# Move the player with the physics engine
self.physics_engine.update()
changed = False # Track if we need to change the viewport
# --- Manage Scrolling ---
# Track if we need to change the viewport
changed = False
# Below manages all scrolling mechanics
# 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:
self.view_left -= left_boundary - self.player_sprite.left
changed = True
# 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:
self.view_left += self.player_sprite.right - right_boundary
changed = True
# 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:
self.view_bottom += self.player_sprite.top - top_boundary
changed = True
# 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:
self.view_bottom -= bottom_boundary - self.player_sprite.bottom
changed = True
@@ -170,14 +148,17 @@ class MyGame(arcade.Window):
# Do the scrolling
arcade.set_viewport(self.view_left,
SCREEN_WIDTH + self.view_left,
Config.SCREEN_WIDTH + self.view_left,
self.view_bottom,
SCREEN_HEIGHT + self.view_bottom)
Config.SCREEN_HEIGHT + self.view_bottom)
def main():
""" Main method """
window = MyGame()
def main() -> None:
"""
Setups up window classes and runs the game.
"""
window = Game()
window.setup()
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