Sections Demo 1

sections_demo_1.py
1"""
2Section Example 1:
3
4In this Section example we divide the screen in two sections and let the user
5pick a box depending on the selected Section
6
7Note:
8 - How View know nothing of what's happening inside the sections.
9 Each section knows what to do.
10 - Each event mouse input is handled by each Section even if the class
11 it's the same (ScreenPart).
12 - How on_mouse_enter/leave triggers in each Section when the mouse
13 enter or leaves the section boundaries
14
15If Python and Arcade are installed, this example can be run from the command line with:
16python -m arcade.examples.sections_demo_1
17"""
18
19from __future__ import annotations
20
21import arcade
22from arcade import SectionManager
23
24
25class Box(arcade.SpriteSolidColor):
26 """This is a Solid Sprite that represents a GREEN Box on the screen"""
27
28 def __init__(self, section):
29 super().__init__(100, 100, color=arcade.color.APPLE_GREEN)
30 self.section = section
31
32 def on_update(self, delta_time: float = 1 / 60):
33 # update the box (this actually moves the Box by changing its position)
34 self.update()
35
36 # if we hit the ground then lay on the ground and stop movement
37 if self.bottom <= 0:
38 self.bottom = 0
39 self.stop()
40
41 def release(self):
42 self.section.hold_box = None
43 self.change_y = -10
44
45
46class ScreenPart(arcade.Section):
47 """
48 This represents a part of the View defined by its
49 boundaries (left, bottom, etc.)
50 """
51
52 def __init__(self, left: int, bottom: int, width: int, height: int, **kwargs):
53 super().__init__(left, bottom, width, height, **kwargs)
54
55 self.selected: bool = False # if this section is selected
56
57 self.box: Box = Box(self) # the section Box Sprite
58
59 # position the Box inside this section using self.left + self.width
60 self.box.position = self.left + (self.width / 2), 50
61
62 # variable that will hold the Box when it's being dragged
63 self.hold_box: Box | None = None
64
65 def on_update(self, delta_time: float):
66 # call on_update on the owned Box
67 self.box.on_update(delta_time)
68
69 def on_draw(self):
70 """Draw this section"""
71 if self.selected:
72 # Section is selected when mouse is within its boundaries
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 )
83
84 # draw the box
85 arcade.draw_sprite(self.box)
86
87 def on_mouse_drag(
88 self, x: float, y: float, dx: float, dy: float, _buttons: int, _modifiers: int
89 ):
90 # if we hold a box, then whe move it at the same rate the mouse moves
91 if self.hold_box:
92 self.hold_box.position = x, y
93
94 def on_mouse_press(self, x: float, y: float, button: int, modifiers: int):
95 # if we pick a Box with the mouse, "hold" it and stop its movement
96 if self.box.collides_with_point((x, y)):
97 self.hold_box = self.box
98 self.hold_box.stop()
99
100 def on_mouse_release(self, x: float, y: float, button: int, modifiers: int):
101 # if hold_box is True because we pick it with on_mouse_press
102 # then release the Box
103 if self.hold_box:
104 self.hold_box.release()
105
106 def on_mouse_enter(self, x: float, y: float):
107 # select this section
108 self.selected = True
109
110 def on_mouse_leave(self, x: float, y: float):
111 # unselect this section
112 self.selected = False
113
114 # if we are holding this section box and we leave the section
115 # we release the box as if we release the mouse button
116 if self.hold_box:
117 self.hold_box.release()
118
119
120class GameView(arcade.View):
121 def __init__(self):
122 super().__init__()
123
124 # add sections to the view
125 self.section_manager = SectionManager(self)
126
127 # 1) First section holds half of the screen
128 self.section_manager.add_section(
129 ScreenPart(0, 0, self.window.width / 2, self.window.height, name="Left")
130 )
131
132 # 2) Second section holds the other half of the screen
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()
144
145 def on_draw(self):
146 # clear the screen
147 self.clear(color=arcade.color.BEAU_BLUE)
148
149 # draw a line separating each Section
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 )
158
159
160def main():
161 # create the window
162 window = arcade.Window()
163
164 # create the custom View. Sections are initialized inside the GameView init
165 view = GameView()
166
167 # show the view
168 window.show_view(view)
169
170 # run arcade loop
171 window.run()
172
173
174if __name__ == "__main__":
175 main()