Skip to content

Commit 6d64946

Browse files
authored
Scene Manager and Tilemap Rework (#891)
* Initial object-oriented tilemap rework * Update example 08_load_map for tilemap rework * Make layer options optional * Map level default scaling value * Update example 09_endgame * Initial Scene manager * Update example 08_load_map for scene manager * Update example 09_endgame for Scene manager * Update physics engines to accept lists of SpriteList * Fix typo in tilemap * Update physics_engines to accept lists of SpriteList * Add map_directory to animated Sprites * Update platformer_tutorial examples * Remove timeit from example * Add update utility functions to scene * Use scene update utilities * Update example 12_animate_character for scene graph * Update example 13_add_enemies for scene graph update * Use spatial hash for moving platforms in platform_tutorial * Add 14_moving_enemies to platformer tutorial * Update variable naming in 13_add_enemies * Finish development merge to scene-graph * Add missed function to sprite_list package * Move tilemap module into package * Fix PhysicsEngineSimple * Slight rework of some Scene functions * Update all platform_tutorial examples for scene-graph changes * Initial platform tutorial re-write * Add spatial hash support to scene * Structural Update for platformer_tutorial * Fix formatting for examples * Initial Scene Object step for platformer_tutorial * Add docstrings to Scene module * Add docstrings to user facing tilemap functions
1 parent 5f345a0 commit 6d64946

81 files changed

Lines changed: 3165 additions & 1790 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

arcade/__init__.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -242,10 +242,13 @@ def configure_logging(level: int = None):
242242
from .sprite_list import SpriteList
243243
from .sprite_list import check_for_collision
244244
from .sprite_list import check_for_collision_with_list
245+
from .sprite_list import check_for_collision_with_lists
245246
from .sprite_list import get_closest_sprite
246247
from .sprite_list import get_sprites_at_exact_point
247248
from .sprite_list import get_sprites_at_point
248249

250+
from .scene import Scene
251+
249252
from .physics_engines import PhysicsEnginePlatformer
250253
from .physics_engines import PhysicsEngineSimple
251254

@@ -255,10 +258,7 @@ def configure_logging(level: int = None):
255258
from .text import create_text_image
256259
from .text import create_text_sprite
257260

258-
from .tilemap import get_tilemap_layer
259-
from .tilemap import process_layer
260-
from .tilemap import read_map
261-
from .tilemap import read_tmx
261+
from .tilemap import load_tilemap
262262

263263
from .pymunk_physics_engine import PymunkPhysicsEngine
264264
from .pymunk_physics_engine import PymunkPhysicsObject
@@ -341,6 +341,7 @@ def configure_logging(level: int = None):
341341
'calculate_hit_box_points_simple',
342342
'check_for_collision',
343343
'check_for_collision_with_list',
344+
'check_for_collision_with_lists',
344345
'clamp',
345346
'cleanup_texture_cache',
346347
'close_window',
@@ -412,6 +413,7 @@ def configure_logging(level: int = None):
412413
'get_screens',
413414
'get_sprites_at_exact_point',
414415
'get_sprites_at_point',
416+
'get_text_image',
415417
'create_text_image',
416418
'get_tilemap_layer',
417419
'get_viewport',

arcade/arcade_types.py

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,25 @@
11
"""
22
Module specifying data custom types used for type hinting.
33
"""
4-
from typing import Tuple
5-
from typing import List
6-
from typing import Union
7-
from typing import Sequence
84
from collections import namedtuple
5+
from typing import List, NamedTuple, Optional, Sequence, Tuple, Union
96

7+
from pytiled_parser import Properties
108

119
RGB = Union[Tuple[int, int, int], List[int]]
1210
RGBA = Union[Tuple[int, int, int, int], List[int]]
1311
Color = Union[RGB, RGBA]
1412
Point = Union[Tuple[float, float], List[float]]
15-
NamedPoint = namedtuple('NamedPoint', ['x', 'y'])
13+
NamedPoint = namedtuple("NamedPoint", ["x", "y"])
1614

1715
Vector = Point
1816
PointList = Sequence[Point]
1917
Rect = Union[Tuple[float, float, float, float], List[float]] # x, y, width, height
2018
RectList = Union[Tuple[Rect, ...], List[Rect]]
19+
20+
21+
class TiledObject(NamedTuple):
22+
shape: Union[Point, PointList, Rect]
23+
properties: Optional[Properties] = None
24+
name: Optional[str] = None
25+
type: Optional[str] = None

arcade/examples/platform_tutorial/01_open_window.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,18 +22,18 @@ def __init__(self):
2222
arcade.set_background_color(arcade.csscolor.CORNFLOWER_BLUE)
2323

2424
def setup(self):
25-
""" Set up the game here. Call this function to restart the game. """
25+
"""Set up the game here. Call this function to restart the game."""
2626
pass
2727

2828
def on_draw(self):
29-
""" Render the screen. """
29+
"""Render the screen."""
3030

3131
arcade.start_render()
3232
# Code to draw the screen goes here
3333

3434

3535
def main():
36-
""" Main method """
36+
"""Main method"""
3737
window = MyGame()
3838
window.setup()
3939
arcade.run()

arcade/examples/platform_tutorial/02_draw_sprites.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ def __init__(self):
3636
arcade.set_background_color(arcade.csscolor.CORNFLOWER_BLUE)
3737

3838
def setup(self):
39-
""" Set up the game here. Call this function to restart the game. """
39+
"""Set up the game here. Call this function to restart the game."""
4040
# Create the Sprite lists
4141
self.player_list = arcade.SpriteList()
4242
self.wall_list = arcade.SpriteList(use_spatial_hash=True)
@@ -59,18 +59,18 @@ def setup(self):
5959

6060
# Put some crates on the ground
6161
# This shows using a coordinate list to place sprites
62-
coordinate_list = [[512, 96],
63-
[256, 96],
64-
[768, 96]]
62+
coordinate_list = [[512, 96], [256, 96], [768, 96]]
6563

6664
for coordinate in coordinate_list:
6765
# Add a crate on the ground
68-
wall = arcade.Sprite(":resources:images/tiles/boxCrate_double.png", TILE_SCALING)
66+
wall = arcade.Sprite(
67+
":resources:images/tiles/boxCrate_double.png", TILE_SCALING
68+
)
6969
wall.position = coordinate
7070
self.wall_list.append(wall)
7171

7272
def on_draw(self):
73-
""" Render the screen. """
73+
"""Render the screen."""
7474

7575
# Clear the screen to the background color
7676
arcade.start_render()
@@ -82,7 +82,7 @@ def on_draw(self):
8282

8383

8484
def main():
85-
""" Main method """
85+
"""Main method"""
8686
window = MyGame()
8787
window.setup()
8888
arcade.run()
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
"""
2+
Platformer Game
3+
"""
4+
import arcade
5+
6+
# Constants
7+
SCREEN_WIDTH = 1000
8+
SCREEN_HEIGHT = 650
9+
SCREEN_TITLE = "Platformer"
10+
11+
# Constants used to scale our sprites from their original size
12+
CHARACTER_SCALING = 1
13+
TILE_SCALING = 0.5
14+
COIN_SCALING = 0.5
15+
16+
17+
class MyGame(arcade.Window):
18+
"""
19+
Main application class.
20+
"""
21+
22+
def __init__(self):
23+
24+
# Call the parent class and set up the window
25+
super().__init__(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_TITLE)
26+
27+
# Our Scene Object
28+
self.scene = None
29+
30+
# Separate variable that holds the player sprite
31+
self.player_sprite = None
32+
33+
arcade.set_background_color(arcade.csscolor.CORNFLOWER_BLUE)
34+
35+
def setup(self):
36+
"""Set up the game here. Call this function to restart the game."""
37+
38+
# Initialize Scene
39+
self.scene = arcade.Scene()
40+
41+
# Create the Sprite lists
42+
self.scene.add_sprite_list("Player")
43+
self.scene.add_sprite_list("Walls", use_spatial_hash=True)
44+
45+
# Set up the player, specifically placing it at these coordinates.
46+
image_source = ":resources:images/animated_characters/female_adventurer/femaleAdventurer_idle.png"
47+
self.player_sprite = arcade.Sprite(image_source, CHARACTER_SCALING)
48+
self.player_sprite.center_x = 64
49+
self.player_sprite.center_y = 128
50+
self.scene.add_sprite("Player", self.player_sprite)
51+
52+
# Create the ground
53+
# This shows using a loop to place multiple sprites horizontally
54+
for x in range(0, 1250, 64):
55+
wall = arcade.Sprite(":resources:images/tiles/grassMid.png", TILE_SCALING)
56+
wall.center_x = x
57+
wall.center_y = 32
58+
self.scene.add_sprite("Walls", wall)
59+
60+
# Put some crates on the ground
61+
# This shows using a coordinate list to place sprites
62+
coordinate_list = [[512, 96], [256, 96], [768, 96]]
63+
64+
for coordinate in coordinate_list:
65+
# Add a crate on the ground
66+
wall = arcade.Sprite(
67+
":resources:images/tiles/boxCrate_double.png", TILE_SCALING
68+
)
69+
wall.position = coordinate
70+
self.scene.add_sprite("Walls", wall)
71+
72+
def on_draw(self):
73+
"""Render the screen."""
74+
75+
# Clear the screen to the background color
76+
arcade.start_render()
77+
78+
# Draw our Scene
79+
self.scene.draw()
80+
81+
82+
def main():
83+
"""Main method"""
84+
window = MyGame()
85+
window.setup()
86+
arcade.run()
87+
88+
89+
if __name__ == "__main__":
90+
main()

arcade/examples/platform_tutorial/03_user_control.py renamed to arcade/examples/platform_tutorial/04_user_control.py

Lines changed: 23 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,8 @@ def __init__(self):
2727
# Call the parent class and set up the window
2828
super().__init__(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_TITLE)
2929

30-
# These are 'lists' that keep track of our sprites. Each sprite should
31-
# go into a list.
32-
self.coin_list = None
33-
self.wall_list = None
34-
self.player_list = None
30+
# Our Scene Object
31+
self.scene = None
3532

3633
# Separate variable that holds the player sprite
3734
self.player_sprite = None
@@ -42,55 +39,54 @@ def __init__(self):
4239
arcade.set_background_color(arcade.csscolor.CORNFLOWER_BLUE)
4340

4441
def setup(self):
45-
""" Set up the game here. Call this function to restart the game. """
46-
# Create the Sprite lists
47-
self.player_list = arcade.SpriteList()
48-
self.wall_list = arcade.SpriteList(use_spatial_hash=True)
49-
self.coin_list = arcade.SpriteList(use_spatial_hash=True)
42+
"""Set up the game here. Call this function to restart the game."""
43+
44+
# Initialize Scene
45+
self.scene = arcade.Scene()
5046

5147
# Set up the player, specifically placing it at these coordinates.
5248
image_source = ":resources:images/animated_characters/female_adventurer/femaleAdventurer_idle.png"
5349
self.player_sprite = arcade.Sprite(image_source, CHARACTER_SCALING)
5450
self.player_sprite.center_x = 64
5551
self.player_sprite.center_y = 128
56-
self.player_list.append(self.player_sprite)
52+
self.scene.add_sprite("Player", self.player_sprite)
5753

5854
# Create the ground
5955
# This shows using a loop to place multiple sprites horizontally
6056
for x in range(0, 1250, 64):
6157
wall = arcade.Sprite(":resources:images/tiles/grassMid.png", TILE_SCALING)
6258
wall.center_x = x
6359
wall.center_y = 32
64-
self.wall_list.append(wall)
60+
self.scene.add_sprite("Walls", wall)
6561

6662
# Put some crates on the ground
6763
# This shows using a coordinate list to place sprites
68-
coordinate_list = [[512, 96],
69-
[256, 96],
70-
[768, 96]]
64+
coordinate_list = [[512, 96], [256, 96], [768, 96]]
7165

7266
for coordinate in coordinate_list:
7367
# Add a crate on the ground
74-
wall = arcade.Sprite(":resources:images/tiles/boxCrate_double.png", TILE_SCALING)
68+
wall = arcade.Sprite(
69+
":resources:images/tiles/boxCrate_double.png", TILE_SCALING
70+
)
7571
wall.position = coordinate
76-
self.wall_list.append(wall)
72+
self.scene.add_sprite("Walls", wall)
7773

7874
# Create the 'physics engine'
79-
self.physics_engine = arcade.PhysicsEngineSimple(self.player_sprite, self.wall_list)
75+
self.physics_engine = arcade.PhysicsEngineSimple(
76+
self.player_sprite, self.scene.get_sprite_list("Walls")
77+
)
8078

8179
def on_draw(self):
82-
""" Render the screen. """
80+
"""Render the screen."""
8381

8482
# Clear the screen to the background color
8583
arcade.start_render()
8684

87-
# Draw our sprites
88-
self.wall_list.draw()
89-
self.coin_list.draw()
90-
self.player_list.draw()
85+
# Draw our Scene
86+
self.scene.draw()
9187

9288
def on_key_press(self, key, modifiers):
93-
"""Called whenever a key is pressed. """
89+
"""Called whenever a key is pressed."""
9490

9591
if key == arcade.key.UP or key == arcade.key.W:
9692
self.player_sprite.change_y = PLAYER_MOVEMENT_SPEED
@@ -102,7 +98,7 @@ def on_key_press(self, key, modifiers):
10298
self.player_sprite.change_x = PLAYER_MOVEMENT_SPEED
10399

104100
def on_key_release(self, key, modifiers):
105-
"""Called when the user releases a key. """
101+
"""Called when the user releases a key."""
106102

107103
if key == arcade.key.UP or key == arcade.key.W:
108104
self.player_sprite.change_y = 0
@@ -114,14 +110,14 @@ def on_key_release(self, key, modifiers):
114110
self.player_sprite.change_x = 0
115111

116112
def on_update(self, delta_time):
117-
""" Movement and game logic """
113+
"""Movement and game logic"""
118114

119115
# Move the player with the physics engine
120116
self.physics_engine.update()
121117

122118

123119
def main():
124-
""" Main method """
120+
"""Main method"""
125121
window = MyGame()
126122
window.setup()
127123
arcade.run()

0 commit comments

Comments
 (0)