Sections Demo 1

Screen shot of using sections
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()