0
# Window and Application Management
1
2
Comprehensive window lifecycle management, view system for game states, sections for viewport management, and event handling for creating robust game applications.
3
4
## Capabilities
5
6
### Core Window Classes
7
8
Main window and application classes that form the foundation of Arcade applications.
9
10
```python { .api }
11
class Window(pyglet.window.Window):
12
"""
13
Main application window class that handles rendering, events, and game loop management.
14
Inherits from pyglet.window.Window and adds game-specific functionality.
15
"""
16
def __init__(self, width: int = 800, height: int = 600, title: str = "Arcade Window",
17
fullscreen: bool = False, resizable: bool = False, update_rate: float = 1/60,
18
antialiasing: bool = True, gl_version: tuple = (3, 3), screen: int = None,
19
style: str = None, visible: bool = True, vsync: bool = False,
20
gc_mode: str = "context_gc", center_window: bool = False,
21
samples: int = 4, enable_polling: bool = True):
22
"""
23
Create a new game window.
24
25
Args:
26
width: Window width in pixels
27
height: Window height in pixels
28
title: Window title text
29
fullscreen: Whether to open in fullscreen mode
30
resizable: Whether window can be resized
31
update_rate: Target frame rate (frames per second)
32
antialiasing: Enable multisampling antialiasing
33
gl_version: OpenGL version tuple (major, minor)
34
screen: Which screen to open window on (multi-monitor)
35
style: Window style ("default", "dialog", "tool")
36
visible: Whether window is initially visible
37
vsync: Enable vertical synchronization
38
gc_mode: Garbage collection mode ("context_gc", "auto")
39
center_window: Whether to center window on screen
40
samples: Number of samples for antialiasing
41
enable_polling: Enable input device polling
42
"""
43
44
# Window properties
45
width: int
46
height: int
47
title: str
48
fullscreen: bool
49
current_view: arcade.View
50
51
# Rendering properties
52
ctx: arcade.ArcadeContext
53
background_color: tuple[int, int, int, int]
54
55
# Timing properties
56
delta_time: float
57
58
def set_update_rate(self, rate: float) -> None:
59
"""Set the target update rate (FPS)."""
60
61
def set_vsync(self, vsync: bool) -> None:
62
"""Enable or disable vertical synchronization."""
63
64
def set_visible(self, visible: bool) -> None:
65
"""Show or hide the window."""
66
67
def center_window(self) -> None:
68
"""Center the window on the screen."""
69
70
def maximize(self) -> None:
71
"""Maximize the window."""
72
73
def minimize(self) -> None:
74
"""Minimize the window."""
75
76
def set_size(self, width: int, height: int) -> None:
77
"""Set window size."""
78
79
def get_size(self) -> tuple[int, int]:
80
"""Get current window size."""
81
82
def get_location(self) -> tuple[int, int]:
83
"""Get window position on screen."""
84
85
def set_location(self, x: int, y: int) -> None:
86
"""Set window position on screen."""
87
88
# Event handlers (override these in subclasses)
89
def on_draw(self) -> None:
90
"""Called when the window needs to be redrawn."""
91
92
def on_update(self, delta_time: float) -> None:
93
"""
94
Called to update game logic.
95
96
Args:
97
delta_time: Time elapsed since last update (seconds)
98
"""
99
100
def on_resize(self, width: int, height: int) -> None:
101
"""
102
Called when window is resized.
103
104
Args:
105
width: New window width
106
height: New window height
107
"""
108
109
def on_mouse_motion(self, x: int, y: int, dx: int, dy: int) -> None:
110
"""Called when mouse moves."""
111
112
def on_mouse_press(self, x: int, y: int, button: int, modifiers: int) -> None:
113
"""Called when mouse button is pressed."""
114
115
def on_mouse_release(self, x: int, y: int, button: int, modifiers: int) -> None:
116
"""Called when mouse button is released."""
117
118
def on_mouse_scroll(self, x: int, y: int, scroll_x: float, scroll_y: float) -> None:
119
"""Called when mouse wheel is scrolled."""
120
121
def on_key_press(self, symbol: int, modifiers: int) -> None:
122
"""Called when keyboard key is pressed."""
123
124
def on_key_release(self, symbol: int, modifiers: int) -> None:
125
"""Called when keyboard key is released."""
126
127
def on_text(self, text: str) -> None:
128
"""Called when text is typed."""
129
130
def on_text_motion(self, motion: int) -> None:
131
"""Called for text cursor movement."""
132
133
def on_text_motion_select(self, motion: int) -> None:
134
"""Called for text selection movement."""
135
136
def clear(self, color: tuple[int, int, int, int] = None) -> None:
137
"""Clear the window with specified color or background color."""
138
139
def use(self) -> None:
140
"""Make this window the active OpenGL context."""
141
142
def flip(self) -> None:
143
"""Swap the OpenGL front and back buffers."""
144
145
def show_view(self, new_view: arcade.View) -> None:
146
"""Switch to a new view."""
147
148
def hide_view(self) -> None:
149
"""Hide the current view."""
150
```
151
152
### View System
153
154
View classes for managing different game states and scenes.
155
156
```python { .api }
157
class View:
158
"""
159
Base class for managing different screens/states in a game (menu, gameplay, pause, etc.).
160
Views handle their own event processing and drawing.
161
"""
162
def __init__(self):
163
"""Create a new view."""
164
165
window: arcade.Window
166
167
def setup(self) -> None:
168
"""Override to set up the view when it becomes active."""
169
170
def on_show_view(self) -> None:
171
"""Called when this view becomes the active view."""
172
173
def on_hide_view(self) -> None:
174
"""Called when this view is no longer the active view."""
175
176
def on_draw(self) -> None:
177
"""Override to draw the view."""
178
179
def on_update(self, delta_time: float) -> None:
180
"""Override to update view logic."""
181
182
def on_resize(self, width: int, height: int) -> None:
183
"""Called when window is resized."""
184
185
# Input event handlers
186
def on_mouse_motion(self, x: int, y: int, dx: int, dy: int) -> None:
187
"""Called when mouse moves."""
188
189
def on_mouse_press(self, x: int, y: int, button: int, modifiers: int) -> None:
190
"""Called when mouse button is pressed."""
191
192
def on_mouse_release(self, x: int, y: int, button: int, modifiers: int) -> None:
193
"""Called when mouse button is released."""
194
195
def on_mouse_scroll(self, x: int, y: int, scroll_x: float, scroll_y: float) -> None:
196
"""Called when mouse wheel is scrolled."""
197
198
def on_key_press(self, symbol: int, modifiers: int) -> None:
199
"""Called when keyboard key is pressed."""
200
201
def on_key_release(self, symbol: int, modifiers: int) -> None:
202
"""Called when keyboard key is released."""
203
204
def on_text(self, text: str) -> None:
205
"""Called when text is typed."""
206
207
def on_text_motion(self, motion: int) -> None:
208
"""Called for text cursor movement."""
209
210
def on_text_motion_select(self, motion: int) -> None:
211
"""Called for text selection movement."""
212
213
def clear(self, color: tuple[int, int, int, int] = None) -> None:
214
"""Clear the screen."""
215
```
216
217
### Section System
218
219
Classes for managing viewport subdivisions and screen regions.
220
221
```python { .api }
222
class Section:
223
"""
224
Rectangular portion of the viewport for managing different screen regions.
225
Useful for split-screen games, mini-maps, or UI panels.
226
"""
227
def __init__(self, left: int, bottom: int, width: int, height: int,
228
name: str = "Section", accept_keyboard_keys: bool = True,
229
accept_mouse_events: bool = True, enabled: bool = True,
230
local_mouse_coordinates: bool = False, prevent_dispatch: bool = True,
231
prevent_dispatch_view: bool = True):
232
"""
233
Create a section.
234
235
Args:
236
left: Left coordinate of section
237
bottom: Bottom coordinate of section
238
width: Width of section
239
height: Height of section
240
name: Name for identifying the section
241
accept_keyboard_keys: Whether section receives keyboard events
242
accept_mouse_events: Whether section receives mouse events
243
enabled: Whether section is active
244
local_mouse_coordinates: Use section-local mouse coordinates
245
prevent_dispatch: Prevent event propagation to other sections
246
prevent_dispatch_view: Prevent event propagation to views
247
"""
248
249
# Properties
250
left: int
251
bottom: int
252
width: int
253
height: int
254
name: str
255
enabled: bool
256
view: arcade.View
257
camera: arcade.Camera2D
258
259
def on_update(self, delta_time: float) -> None:
260
"""Called to update section logic."""
261
262
def on_draw(self) -> None:
263
"""Called to draw the section."""
264
265
def on_resize(self, width: int, height: int) -> None:
266
"""Called when window is resized."""
267
268
# Input event handlers
269
def on_mouse_motion(self, x: int, y: int, dx: int, dy: int) -> None:
270
"""Called when mouse moves within section."""
271
272
def on_mouse_press(self, x: int, y: int, button: int, modifiers: int) -> None:
273
"""Called when mouse is pressed within section."""
274
275
def on_mouse_release(self, x: int, y: int, button: int, modifiers: int) -> None:
276
"""Called when mouse is released within section."""
277
278
def on_mouse_scroll(self, x: int, y: int, scroll_x: float, scroll_y: float) -> None:
279
"""Called when mouse wheel is scrolled within section."""
280
281
def on_key_press(self, symbol: int, modifiers: int) -> None:
282
"""Called when keyboard key is pressed and section has focus."""
283
284
def on_key_release(self, symbol: int, modifiers: int) -> None:
285
"""Called when keyboard key is released and section has focus."""
286
287
def mouse_is_on_top(self) -> bool:
288
"""Check if mouse is currently over this section."""
289
290
def get_xy_screen_relative(self) -> tuple[int, int]:
291
"""Get section position relative to screen."""
292
293
def get_xy_section_relative(self, x: int, y: int) -> tuple[int, int]:
294
"""Convert screen coordinates to section-relative coordinates."""
295
296
class SectionManager:
297
"""
298
Manages multiple sections within a view, handling event dispatch and rendering order.
299
"""
300
def __init__(self, view: arcade.View):
301
"""
302
Create a section manager.
303
304
Args:
305
view: The view that owns this section manager
306
"""
307
308
view: arcade.View
309
310
def add_section(self, section: arcade.Section, at_index: int = None) -> None:
311
"""
312
Add a section to the manager.
313
314
Args:
315
section: Section to add
316
at_index: Position to insert section (None = append)
317
"""
318
319
def remove_section(self, section: arcade.Section) -> None:
320
"""Remove a section from the manager."""
321
322
def clear(self) -> None:
323
"""Remove all sections."""
324
325
def get_section_by_name(self, name: str) -> arcade.Section:
326
"""Find a section by its name."""
327
328
def disable_all_keyboard_events(self) -> None:
329
"""Disable keyboard events for all sections."""
330
331
def enable_all_keyboard_events(self) -> None:
332
"""Enable keyboard events for all sections."""
333
334
def on_update(self, delta_time: float) -> None:
335
"""Update all enabled sections."""
336
337
def on_draw(self) -> None:
338
"""Draw all enabled sections."""
339
340
def on_resize(self, width: int, height: int) -> None:
341
"""Handle window resize for all sections."""
342
343
# Event dispatch methods
344
def on_mouse_motion(self, x: int, y: int, dx: int, dy: int) -> None:
345
"""Dispatch mouse motion events to appropriate sections."""
346
347
def on_mouse_press(self, x: int, y: int, button: int, modifiers: int) -> None:
348
"""Dispatch mouse press events to appropriate sections."""
349
350
def on_mouse_release(self, x: int, y: int, button: int, modifiers: int) -> None:
351
"""Dispatch mouse release events to appropriate sections."""
352
```
353
354
### Window Management Functions
355
356
Utility functions for window creation and lifecycle management.
357
358
```python { .api }
359
def open_window(width: int, height: int, title: str = "Arcade Window",
360
fullscreen: bool = False, resizable: bool = False,
361
update_rate: float = 1/60, antialiasing: bool = True) -> arcade.Window:
362
"""
363
Create and open a game window with specified parameters.
364
365
Args:
366
width: Window width in pixels
367
height: Window height in pixels
368
title: Window title text
369
fullscreen: Whether to open in fullscreen mode
370
resizable: Whether window can be resized
371
update_rate: Target frame rate (frames per second)
372
antialiasing: Enable multisampling antialiasing
373
374
Returns:
375
The created Window instance
376
"""
377
378
def close_window() -> None:
379
"""Close the current game window and clean up resources."""
380
381
def get_window() -> arcade.Window:
382
"""
383
Get reference to the current active window.
384
385
Returns:
386
The current Window instance or None if no window exists
387
"""
388
389
def set_window(window: arcade.Window) -> None:
390
"""
391
Set the current active window reference.
392
393
Args:
394
window: Window instance to set as current
395
"""
396
397
def run() -> None:
398
"""
399
Start the game loop. This will run until the window is closed.
400
Must be called after creating a window and setting up the initial view.
401
"""
402
403
def exit() -> None:
404
"""
405
Exit the application and close all windows.
406
"""
407
408
def get_display_size(screen_id: int = 0) -> tuple[int, int]:
409
"""
410
Get the display size of a screen.
411
412
Args:
413
screen_id: ID of the screen to query
414
415
Returns:
416
Tuple of (width, height) in pixels
417
"""
418
419
def get_screens() -> list:
420
"""
421
Get list of available screens/displays.
422
423
Returns:
424
List of screen objects with display information
425
"""
426
```
427
428
### Scheduling Functions
429
430
Functions for scheduling timed events and recurring tasks.
431
432
```python { .api }
433
def schedule(function_pointer: callable, interval: float) -> None:
434
"""
435
Schedule a function to be called at regular intervals.
436
437
Args:
438
function_pointer: Function to call (must accept delta_time parameter)
439
interval: Time between calls in seconds
440
"""
441
442
def unschedule(function_pointer: callable) -> None:
443
"""
444
Remove a scheduled function.
445
446
Args:
447
function_pointer: Previously scheduled function to remove
448
"""
449
450
def schedule_once(function_pointer: callable, delay: float) -> None:
451
"""
452
Schedule a function to be called once after a delay.
453
454
Args:
455
function_pointer: Function to call
456
delay: Delay before calling in seconds
457
"""
458
```
459
460
### Input Constants
461
462
Constants for mouse button and key modifier identification.
463
464
```python { .api }
465
# Mouse button constants
466
MOUSE_BUTTON_LEFT: int = 1
467
MOUSE_BUTTON_MIDDLE: int = 2
468
MOUSE_BUTTON_RIGHT: int = 4
469
470
# Controller functions (non-headless mode only)
471
def get_game_controllers() -> list:
472
"""Get list of available game controllers."""
473
474
def get_joysticks() -> list:
475
"""Get list of available joystick devices."""
476
477
class ControllerManager:
478
"""Manages game controller input and events."""
479
def __init__(self):
480
"""Create controller manager."""
481
482
def get_controllers() -> arcade.ControllerManager:
483
"""Get the global controller manager instance."""
484
```
485
486
## Usage Examples
487
488
### Basic Window and View Setup
489
490
```python
491
import arcade
492
493
class MenuView(arcade.View):
494
def on_show_view(self):
495
arcade.set_background_color(arcade.color.DARK_BLUE_GRAY)
496
497
def on_draw(self):
498
self.clear()
499
arcade.draw_text("Main Menu", 400, 300, arcade.color.WHITE, 50, anchor_x="center")
500
arcade.draw_text("Press SPACE to start game", 400, 200, arcade.color.WHITE, 20, anchor_x="center")
501
502
def on_key_press(self, key, modifiers):
503
if key == arcade.key.SPACE:
504
game_view = GameView()
505
game_view.setup()
506
self.window.show_view(game_view)
507
508
class GameView(arcade.View):
509
def __init__(self):
510
super().__init__()
511
self.player_list = None
512
513
def setup(self):
514
arcade.set_background_color(arcade.color.AMAZON)
515
self.player_list = arcade.SpriteList()
516
517
# Create player
518
self.player = arcade.Sprite(":resources:images/animated_characters/female_adventurer/femaleAdventurer_idle.png", 0.5)
519
self.player.center_x = 400
520
self.player.center_y = 300
521
self.player_list.append(self.player)
522
523
def on_draw(self):
524
self.clear()
525
self.player_list.draw()
526
527
# Draw UI
528
arcade.draw_text(f"Position: ({self.player.center_x:.0f}, {self.player.center_y:.0f})",
529
10, 550, arcade.color.WHITE, 16)
530
531
def on_update(self, delta_time):
532
self.player_list.update()
533
534
def on_key_press(self, key, modifiers):
535
if key == arcade.key.ESCAPE:
536
menu_view = MenuView()
537
self.window.show_view(menu_view)
538
elif key == arcade.key.UP:
539
self.player.change_y = 5
540
elif key == arcade.key.DOWN:
541
self.player.change_y = -5
542
elif key == arcade.key.LEFT:
543
self.player.change_x = -5
544
elif key == arcade.key.RIGHT:
545
self.player.change_x = 5
546
547
def on_key_release(self, key, modifiers):
548
if key in (arcade.key.UP, arcade.key.DOWN):
549
self.player.change_y = 0
550
elif key in (arcade.key.LEFT, arcade.key.RIGHT):
551
self.player.change_x = 0
552
553
def main():
554
window = arcade.Window(800, 600, "Game with Views")
555
556
# Start with menu view
557
menu_view = MenuView()
558
window.show_view(menu_view)
559
560
arcade.run()
561
562
if __name__ == "__main__":
563
main()
564
```
565
566
### Split-Screen with Sections
567
568
```python
569
import arcade
570
571
class SplitScreenView(arcade.View):
572
def __init__(self):
573
super().__init__()
574
self.section_manager = arcade.SectionManager(self)
575
576
def setup(self):
577
# Create left section for player 1
578
left_section = PlayerSection(0, 0, 400, 600, "Player 1")
579
left_section.player_x = 100
580
left_section.player_y = 300
581
self.section_manager.add_section(left_section)
582
583
# Create right section for player 2
584
right_section = PlayerSection(400, 0, 400, 600, "Player 2")
585
right_section.player_x = 300
586
right_section.player_y = 300
587
self.section_manager.add_section(right_section)
588
589
def on_draw(self):
590
self.clear()
591
self.section_manager.on_draw()
592
593
# Draw divider line
594
arcade.draw_line(400, 0, 400, 600, arcade.color.WHITE, 2)
595
596
def on_update(self, delta_time):
597
self.section_manager.on_update(delta_time)
598
599
def on_key_press(self, key, modifiers):
600
self.section_manager.on_key_press(key, modifiers)
601
602
def on_key_release(self, key, modifiers):
603
self.section_manager.on_key_release(key, modifiers)
604
605
class PlayerSection(arcade.Section):
606
def __init__(self, left, bottom, width, height, name):
607
super().__init__(left, bottom, width, height, name,
608
accept_keyboard_keys=True, prevent_dispatch=False)
609
self.player_x = 200
610
self.player_y = 300
611
self.player_speed = 5
612
613
def on_draw(self):
614
# Draw player in section coordinates
615
arcade.draw_circle_filled(self.player_x, self.player_y, 20, arcade.color.RED)
616
arcade.draw_text(self.name, 10, self.height - 30, arcade.color.WHITE, 16)
617
618
def on_key_press(self, key, modifiers):
619
if self.name == "Player 1":
620
if key == arcade.key.W:
621
self.player_y = min(self.height - 20, self.player_y + self.player_speed)
622
elif key == arcade.key.S:
623
self.player_y = max(20, self.player_y - self.player_speed)
624
elif key == arcade.key.A:
625
self.player_x = max(20, self.player_x - self.player_speed)
626
elif key == arcade.key.D:
627
self.player_x = min(self.width - 20, self.player_x + self.player_speed)
628
629
elif self.name == "Player 2":
630
if key == arcade.key.UP:
631
self.player_y = min(self.height - 20, self.player_y + self.player_speed)
632
elif key == arcade.key.DOWN:
633
self.player_y = max(20, self.player_y - self.player_speed)
634
elif key == arcade.key.LEFT:
635
self.player_x = max(20, self.player_x - self.player_speed)
636
elif key == arcade.key.RIGHT:
637
self.player_x = min(self.width - 20, self.player_x + self.player_speed)
638
639
def main():
640
window = arcade.Window(800, 600, "Split Screen Game")
641
view = SplitScreenView()
642
view.setup()
643
window.show_view(view)
644
arcade.run()
645
646
if __name__ == "__main__":
647
main()
648
```