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
 19import arcade
 20from arcade import SectionManager
 21
 22
 23class Box(arcade.SpriteSolidColor):
 24    """This is a Solid Sprite that represents a GREEN Box on the screen"""
 25
 26    def __init__(self, section):
 27        super().__init__(100, 100, color=arcade.color.APPLE_GREEN)
 28        self.section = section
 29
 30    def on_update(self, delta_time: float = 1 / 60):
 31        # update the box (this actually moves the Box by changing its position)
 32        self.update()
 33
 34        # if we hit the ground then lay on the ground and stop movement
 35        if self.bottom <= 0:
 36            self.bottom = 0
 37            self.stop()
 38
 39    def release(self):
 40        self.section.hold_box = None
 41        self.change_y = -10
 42
 43
 44class ScreenPart(arcade.Section):
 45    """
 46    This represents a part of the View defined by its
 47    boundaries (left, bottom, etc.)
 48    """
 49
 50    def __init__(self, left: int, bottom: int, width: int, height: int, **kwargs):
 51        super().__init__(left, bottom, width, height, **kwargs)
 52
 53        self.selected: bool = False  # if this section is selected
 54
 55        self.box: Box = Box(self)  # the section Box Sprite
 56
 57        # position the Box inside this section using self.left + self.width
 58        self.box.position = self.left + (self.width / 2), 50
 59
 60        # variable that will hold the Box when it's being dragged
 61        self.hold_box: Box | None = None
 62
 63    def on_update(self, delta_time: float):
 64        # call on_update on the owned Box
 65        self.box.on_update(delta_time)
 66
 67    def on_draw(self):
 68        """Draw this section"""
 69        if self.selected:
 70            # Section is selected when mouse is within its boundaries
 71            arcade.draw_lrbt_rectangle_filled(
 72                self.left, self.right, self.bottom, self.top, arcade.color.GRAY
 73            )
 74            arcade.draw_text(
 75                f"You're are on the {self.name}",
 76                self.left + 30,
 77                self.top - 50,
 78                arcade.color.BLACK,
 79                16,
 80            )
 81
 82        # draw the box
 83        arcade.draw_sprite(self.box)
 84
 85    def on_mouse_drag(
 86        self, x: float, y: float, dx: float, dy: float, _buttons: int, _modifiers: int
 87    ):
 88        # if we hold a box, then whe move it at the same rate the mouse moves
 89        if self.hold_box:
 90            self.hold_box.position = x, y
 91
 92    def on_mouse_press(self, x: float, y: float, button: int, modifiers: int):
 93        # if we pick a Box with the mouse, "hold" it and stop its movement
 94        if self.box.collides_with_point((x, y)):
 95            self.hold_box = self.box
 96            self.hold_box.stop()
 97
 98    def on_mouse_release(self, x: float, y: float, button: int, modifiers: int):
 99        # if hold_box is True because we pick it with on_mouse_press
100        # then release the Box
101        if self.hold_box:
102            self.hold_box.release()
103
104    def on_mouse_enter(self, x: float, y: float):
105        # select this section
106        self.selected = True
107
108    def on_mouse_leave(self, x: float, y: float):
109        # unselect this section
110        self.selected = False
111
112        # if we are holding this section box and we leave the section
113        # we release the box as if we release the mouse button
114        if self.hold_box:
115            self.hold_box.release()
116
117
118class GameView(arcade.View):
119    def __init__(self):
120        super().__init__()
121
122        # add sections to the view
123        self.section_manager = SectionManager(self)
124
125        # 1) First section holds half of the screen
126        self.section_manager.add_section(
127            ScreenPart(0, 0, self.window.width / 2, self.window.height, name="Left")
128        )
129
130        # 2) Second section holds the other half of the screen
131        self.section_manager.add_section(
132            ScreenPart(
133                self.window.width / 2, 0, self.window.width / 2, self.window.height, name="Right"
134            )
135        )
136
137    def on_show_view(self) -> None:
138        self.section_manager.enable()
139
140    def on_hide_view(self) -> None:
141        self.section_manager.disable()
142
143    def on_draw(self):
144        # clear the screen
145        self.clear(color=arcade.color.BEAU_BLUE)
146
147        # draw a line separating each Section
148        arcade.draw_line(
149            self.window.width / 2,
150            0,
151            self.window.width / 2,
152            self.window.height,
153            arcade.color.BLACK,
154            1,
155        )
156
157
158def main():
159    # create the window
160    window = arcade.Window()
161
162    # create the custom View. Sections are initialized inside the GameView init
163    view = GameView()
164
165    # show the view
166    window.show_view(view)
167
168    # run arcade loop
169    window.run()
170
171
172if __name__ == "__main__":
173    main()