Skip to content

Commit d4947c9

Browse files
authored
feat(section): untie sections and arcade (#2345)
* feat(section): untie sections and arcade
1 parent e9dd36a commit d4947c9

File tree

11 files changed

+427
-232
lines changed

11 files changed

+427
-232
lines changed

arcade/application.py

Lines changed: 2 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@
2020
from arcade.clock import GLOBAL_CLOCK, GLOBAL_FIXED_CLOCK, _setup_clock, _setup_fixed_clock
2121
from arcade.color import TRANSPARENT_BLACK
2222
from arcade.context import ArcadeContext
23-
from arcade.sections import SectionManager
2423
from arcade.types import LBWH, Color, Rect, RGBANormalized, RGBOrA255
2524
from arcade.utils import is_raspberry_pi
2625
from arcade.window_commands import get_display_size, set_window
@@ -979,37 +978,21 @@ def show_view(self, new_view: View) -> None:
979978
# remove previously shown view's handlers
980979
if self._current_view is not None:
981980
self._current_view.on_hide_view()
982-
if self._current_view.has_sections:
983-
self.remove_handlers(self._current_view.section_manager)
984981
self.remove_handlers(self._current_view)
985982

986983
# push new view's handlers
987984
self._current_view = new_view
988-
if new_view.has_sections:
989-
section_manager_managed_events = new_view.section_manager.managed_events
990-
section_handlers = {
991-
event_type: getattr(new_view.section_manager, event_type, None)
992-
for event_type in section_manager_managed_events
993-
}
994-
if section_handlers:
995-
self.push_handlers(**section_handlers)
996-
else:
997-
section_manager_managed_events = set()
998985

999986
# Note: Excluding on_show because this even can trigger multiple times.
1000987
# It should only be called once when the view is shown.
1001988
view_handlers = {
1002989
event_type: getattr(new_view, event_type, None)
1003990
for event_type in self.event_types
1004-
if event_type != "on_show"
1005-
and event_type not in section_manager_managed_events
1006-
and hasattr(new_view, event_type)
991+
if event_type != "on_show" and hasattr(new_view, event_type)
1007992
}
1008993
if view_handlers:
1009994
self.push_handlers(**view_handlers)
1010995
self._current_view.on_show_view()
1011-
if self._current_view.has_sections:
1012-
self._current_view.section_manager.on_show_view()
1013996

1014997
# Note: After the View has been pushed onto pyglet's stack of event handlers
1015998
# (via push_handlers()), pyglet
@@ -1028,18 +1011,9 @@ def hide_view(self) -> None:
10281011
return
10291012

10301013
self._current_view.on_hide_view()
1031-
if self._current_view.has_sections:
1032-
self._current_view.section_manager.on_hide_view()
1033-
self.remove_handlers(self._current_view.section_manager)
10341014
self.remove_handlers(self._current_view)
10351015
self._current_view = None
10361016

1037-
# def _create(self) -> None:
1038-
# super()._create()
1039-
1040-
# def _recreate(self, changes) -> None:
1041-
# super()._recreate(changes)
1042-
10431017
def flip(self) -> None:
10441018
"""
10451019
Present the rendered content to the screen.
@@ -1249,7 +1223,7 @@ class View:
12491223
Subclassing the window is very inflexible since you can't easily switch
12501224
your update and draw logic.
12511225
1252-
A view is a way to encapsulate that logic so you can easily switch between
1226+
A view is a way to encapsulate that logic, so you can easily switch between
12531227
different parts of your game. Maybe you have a title screen, a game screen,
12541228
and a game over screen. Each of these could be a different view.
12551229
@@ -1261,46 +1235,6 @@ class View:
12611235

12621236
def __init__(self, window: Window | None = None) -> None:
12631237
self.window = arcade.get_window() if window is None else window
1264-
self.key: int | None = None
1265-
self._section_manager: SectionManager | None = None
1266-
1267-
@property
1268-
def section_manager(self) -> SectionManager:
1269-
"""The section manager for this view.
1270-
1271-
If the view has section manager one will be created.
1272-
"""
1273-
if self._section_manager is None:
1274-
self._section_manager = SectionManager(self)
1275-
return self._section_manager
1276-
1277-
@property
1278-
def has_sections(self) -> bool:
1279-
"""Returns ``True`` if this view has sections."""
1280-
if self._section_manager is None:
1281-
return False
1282-
else:
1283-
return self.section_manager.has_sections
1284-
1285-
def add_section(
1286-
self,
1287-
section: arcade.Section,
1288-
at_index: int | None = None,
1289-
at_draw_order: int | None = None,
1290-
) -> None:
1291-
"""
1292-
Adds a section to the view Section Manager.
1293-
1294-
Args:
1295-
section:
1296-
The section to add to this section manager
1297-
at_index (optional):
1298-
The index to insert the section for event capture and
1299-
update events. If ``None`` it will be added at the end.
1300-
at_draw_order (optional):
1301-
Inserts the section in a specific draw order. Overwrites section.draw_order
1302-
"""
1303-
self.section_manager.add_section(section, at_index, at_draw_order)
13041238

13051239
def clear(
13061240
self,

arcade/examples/sections_demo_1.py

Lines changed: 42 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,15 @@
1515
If Python and Arcade are installed, this example can be run from the command line with:
1616
python -m arcade.examples.sections_demo_1
1717
"""
18+
1819
from __future__ import annotations
1920

2021
import arcade
22+
from arcade import SectionManager
2123

2224

2325
class Box(arcade.SpriteSolidColor):
24-
""" This is a Solid Sprite that represents a GREEN Box on the screen """
26+
"""This is a Solid Sprite that represents a GREEN Box on the screen"""
2527

2628
def __init__(self, section):
2729
super().__init__(100, 100, color=arcade.color.APPLE_GREEN)
@@ -47,8 +49,7 @@ class ScreenPart(arcade.Section):
4749
boundaries (left, bottom, etc.)
4850
"""
4951

50-
def __init__(self, left: int, bottom: int, width: int, height: int,
51-
**kwargs):
52+
def __init__(self, left: int, bottom: int, width: int, height: int, **kwargs):
5253
super().__init__(left, bottom, width, height, **kwargs)
5354

5455
self.selected: bool = False # if this section is selected
@@ -66,19 +67,26 @@ def on_update(self, delta_time: float):
6667
self.box.on_update(delta_time)
6768

6869
def on_draw(self):
69-
""" Draw this section """
70+
"""Draw this section"""
7071
if self.selected:
7172
# Section is selected when mouse is within its boundaries
72-
arcade.draw_lrbt_rectangle_filled(self.left, self.right, self.bottom,
73-
self.top, arcade.color.GRAY)
74-
arcade.draw_text(f'You\'re are on the {self.name}', self.left + 30,
75-
self.top - 50, arcade.color.BLACK, 16)
73+
arcade.draw_lrbt_rectangle_filled(
74+
self.left, self.right, self.bottom, self.top, arcade.color.GRAY
75+
)
76+
arcade.draw_text(
77+
f"You're are on the {self.name}",
78+
self.left + 30,
79+
self.top - 50,
80+
arcade.color.BLACK,
81+
16,
82+
)
7683

7784
# draw the box
7885
arcade.draw_sprite(self.box)
7986

80-
def on_mouse_drag(self, x: float, y: float, dx: float, dy: float,
81-
_buttons: int, _modifiers: int):
87+
def on_mouse_drag(
88+
self, x: float, y: float, dx: float, dy: float, _buttons: int, _modifiers: int
89+
):
8290
# if we hold a box, then whe move it at the same rate the mouse moves
8391
if self.hold_box:
8492
self.hold_box.position = x, y
@@ -110,28 +118,43 @@ def on_mouse_leave(self, x: float, y: float):
110118

111119

112120
class GameView(arcade.View):
113-
114121
def __init__(self):
115122
super().__init__()
116123

117124
# add sections to the view
125+
self.section_manager = SectionManager(self)
118126

119127
# 1) First section holds half of the screen
120-
self.add_section(ScreenPart(0, 0, self.window.width / 2,
121-
self.window.height, name='Left'))
128+
self.section_manager.add_section(
129+
ScreenPart(0, 0, self.window.width / 2, self.window.height, name="Left")
130+
)
122131

123132
# 2) Second section holds the other half of the screen
124-
self.add_section(ScreenPart(self.window.width / 2, 0,
125-
self.window.width / 2, self.window.height,
126-
name='Right'))
133+
self.section_manager.add_section(
134+
ScreenPart(
135+
self.window.width / 2, 0, self.window.width / 2, self.window.height, name="Right"
136+
)
137+
)
138+
139+
def on_show_view(self) -> None:
140+
self.section_manager.enable()
141+
142+
def on_hide_view(self) -> None:
143+
self.section_manager.disable()
127144

128145
def on_draw(self):
129146
# clear the screen
130147
self.clear(color=arcade.color.BEAU_BLUE)
131148

132149
# draw a line separating each Section
133-
arcade.draw_line(self.window.width / 2, 0, self.window.width / 2,
134-
self.window.height, arcade.color.BLACK, 1)
150+
arcade.draw_line(
151+
self.window.width / 2,
152+
0,
153+
self.window.width / 2,
154+
self.window.height,
155+
arcade.color.BLACK,
156+
1,
157+
)
135158

136159

137160
def main():
@@ -148,5 +171,5 @@ def main():
148171
window.run()
149172

150173

151-
if __name__ == '__main__':
174+
if __name__ == "__main__":
152175
main()

arcade/examples/sections_demo_2.py

Lines changed: 38 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,10 @@
1818
If Python and Arcade are installed, this example can be run from the command line with:
1919
python -m arcade.examples.sections_demo_2
2020
"""
21+
2122
import random
2223

23-
import arcade
24+
import arcade
2425
from arcade.color import BLACK, BLUE, RED, BEAU_BLUE, GRAY
2526
from arcade.key import W, S, UP, DOWN
2627

@@ -35,9 +36,8 @@ class Player(arcade.Section):
3536
"""
3637

3738
def __init__(
38-
self, left: int, bottom: int, width: int, height: int,
39-
key_up: int, key_down: int, **kwargs
40-
):
39+
self, left: int, bottom: int, width: int, height: int, key_up: int, key_down: int, **kwargs
40+
):
4141
super().__init__(
4242
left,
4343
bottom,
@@ -67,19 +67,24 @@ def on_update(self, delta_time: float):
6767

6868
def on_draw(self):
6969
# draw sections info and score
70-
if self.name == 'Left':
71-
keys = 'W and S'
70+
if self.name == "Left":
71+
keys = "W and S"
7272
start_x = self.left + 5
7373
else:
74-
keys = 'UP and DOWN'
74+
keys = "UP and DOWN"
7575
start_x = self.left - 290
7676
arcade.draw_text(
77-
f'Player {self.name} (move paddle with: {keys})',
78-
start_x, self.top - 20, BLUE, 9,
77+
f"Player {self.name} (move paddle with: {keys})",
78+
start_x,
79+
self.top - 20,
80+
BLUE,
81+
9,
7982
)
8083
arcade.draw_text(
81-
f'Score: {self.score}', self.left + 20,
82-
self.bottom + 20, BLUE,
84+
f"Score: {self.score}",
85+
self.left + 20,
86+
self.bottom + 20,
87+
BLUE,
8388
)
8489

8590
# draw the paddle
@@ -98,7 +103,6 @@ def on_key_release(self, _symbol: int, _modifiers: int):
98103

99104

100105
class Pong(arcade.View):
101-
102106
def __init__(self):
103107
super().__init__()
104108

@@ -108,15 +112,22 @@ def __init__(self):
108112

109113
# we store each Section
110114
self.left_player: Player = Player(
111-
0, 0, PLAYER_SECTION_WIDTH, self.window.height, key_up=W,
112-
key_down=S, name='Left')
115+
0, 0, PLAYER_SECTION_WIDTH, self.window.height, key_up=W, key_down=S, name="Left"
116+
)
113117
self.right_player: Player = Player(
114-
self.window.width - PLAYER_SECTION_WIDTH, 0, PLAYER_SECTION_WIDTH,
115-
self.window.height, key_up=UP, key_down=DOWN, name='Right')
118+
self.window.width - PLAYER_SECTION_WIDTH,
119+
0,
120+
PLAYER_SECTION_WIDTH,
121+
self.window.height,
122+
key_up=UP,
123+
key_down=DOWN,
124+
name="Right",
125+
)
116126

117127
# add the sections to the SectionManager so Sections start to work
118-
self.add_section(self.left_player)
119-
self.add_section(self.right_player)
128+
self.section_manager = arcade.SectionManager(self)
129+
self.section_manager.add_section(self.left_player)
130+
self.section_manager.add_section(self.right_player)
120131

121132
# add each paddle to the sprite list
122133
self.paddles.append(self.left_player.paddle)
@@ -139,6 +150,12 @@ def setup(self):
139150
self.left_player.setup()
140151
self.right_player.setup()
141152

153+
def on_show_view(self) -> None:
154+
self.section_manager.enable()
155+
156+
def on_hide_view(self) -> None:
157+
self.section_manager.disable()
158+
142159
def on_update(self, delta_time: float):
143160
self.ball.update() # update the ball
144161

@@ -168,7 +185,7 @@ def on_update(self, delta_time: float):
168185
self.end_game(self.left_player)
169186

170187
def end_game(self, winner: Player):
171-
""" Called when one player wins """
188+
"""Called when one player wins"""
172189
winner.score += 1 # increment the winner score
173190
self.setup() # prepare a new game
174191

@@ -185,7 +202,7 @@ def on_draw(self):
185202

186203
def main():
187204
# create the window
188-
window = arcade.Window(title='Two player simple Pong with Sections!')
205+
window = arcade.Window(title="Two player simple Pong with Sections!")
189206

190207
# create the custom View
191208
game = Pong()
@@ -200,5 +217,5 @@ def main():
200217
window.run()
201218

202219

203-
if __name__ == '__main__':
220+
if __name__ == "__main__":
204221
main()

0 commit comments

Comments
 (0)