Python Arcade Library Logo

About

  • Introduction
    • Learning Resources
      • Getting Started
      • Experienced Developers
    • Community driven
    • History
  • Frequently asked questions
    • Can I use Arcade resources in my own educational materials?
    • Can I use Arcade in a commercial project?
    • Can I copy and adapt example code for my own projects?
    • Can Arcade run on…?
      • Windows, Mac, and Linux
      • Raspberry Pi and Other SBCs
      • Web
      • Mobile
  • Freedom to Remix and Share
    • Yes, You Can Make Commercial Games!
      • How Do I Publish My Games?
    • The MIT License
    • Public Domain Assets
      • Where are all these assets from?
    • What About Academia?
  • For Educators & Researchers
    • Citation Template
    • Version Considerations
      • Arcade Textbook
    • 2.6.X Maintenance?
    • Raspberry Pi and other SBCs
      • SBC Purchasing Rules of Thumb

Getting Started

  • Install
    • Requirements
      • Windows, Linux, and Intel Mac
      • Raspberry Pi and Other ARM SBCs
    • Using pip
    • Development version
    • Running examples
    • Batteries Included
  • Examples
    • Starting Templates
    • Primitives
      • Drawing Primitives
      • Animating Drawing Primitives
      • Faster Drawing with ShapeElementLists
    • Sprites
      • Player Movement
      • Non-Player Movement
      • Easing
      • Calculating a Path
      • Sprite Properties
      • Games with Levels
      • Shooting with Sprites
    • Audio
      • Sound Effects
      • Music
    • Display Management
      • Resizable Windows
      • Backgrounds
      • Cameras
    • View Management
      • Instruction and Game Over Screens
      • Sectioning a View
    • Platformers
      • Basic Platformers
      • Tiled Map Editor
      • Procedural Generation
    • Graphical User Interface
      • Experimental Widgets
    • Grid-Based Games
    • Advanced
      • Using PyMunk for Physics
      • Frame Buffers
      • OpenGL
    • Concept Games
    • Odds and Ends
      • Particle System
    • Tutorials
    • Stress Tests
  • Tutorials
    • Simple Platformer
      • Step 1 - Install and Open a Window
      • Step 2 - Textures and Sprites
      • Step 3 - Many Sprites with SpriteList
      • Step 4 - Add User Control
      • Step 5 - Add Gravity
      • Step 6 - Resetting
      • Step 7 - Adding a Camera
      • Step 8 - Collecting Coins
      • Step 9 - Adding Sound
      • Step 10 - Adding a Score
      • Step 11 - Using a Scene
      • Step 12 - Loading a Map From a Map Editor
      • Step 13 - More Types of Layers
      • Step 14 - Multiple Levels
    • Pymunk Platformer
      • Common Issues
      • Open a Window
      • Create Constants
      • Create Instance Variables
      • Load and Display Map
      • Add Physics Engine
      • Add Player Movement
      • Add Player Jumping
      • Add Player Animation
      • Shoot Bullets
      • Destroy Bullets and Items
      • Add Moving Platforms
      • Add Ladders
    • Using Views for Start/End Screens
      • Change Main Program to Use a View
      • Add Instruction Screen
      • Game Over Screen
    • Solitaire
      • Open a Window
      • Create Card Sprites
      • Implement Drag and Drop
      • Draw Pile Mats
      • Snap Cards to Piles
      • Shuffle the Cards
      • Track Card Piles
      • Pick Up Card Stacks
      • Deal Out Cards
      • Face Down Cards
      • Restart Game
      • Flip Three From Draw Pile
      • Conclusion
    • Lights
    • Bundling a Game with PyInstaller
      • Bundling a Simple Arcade Script
      • Handling Data Files
      • Troubleshooting
      • Extra Details
      • PyInstaller Documentation
    • Compiling a Game with Nuitka
      • Compiling a Simple Arcade Script
      • But What About Data Files And Folders?
      • Removing The Console Window
      • What About A Custom Taskbar Icon?
      • Additional Information
    • Shaders - Shadertoy
      • Ray-casting Shadows
      • CRT Filter
      • Shader Toy - Glow
      • Shader Toy - Particles
      • Compute Shader
      • GPU Particle Burst
      • Working With Shaders
    • Making a Menu with Arcade’s GUI
      • Step 1: Open a Window
      • Step 2: Switching to Menu View
      • Step 3: Setting Up the Menu View
      • Step 4: Configuring the Menu Buttons
      • Step 5: Finalising the Fake Window aka the Sub Menu
      • Adding a Title label
    • Working with Hexagonal Tilemaps
      • Hexagonal Coordinate Systems
      • Hex Layout
      • Loading a Hex Map from Tiled
      • Working with Hex Tiles in Code
      • Creating a Hex Map in Tiled
      • Full Example
    • Working With FrameBuffer Objects
  • The Arcade Book
    • Installation
    • Getting Help
    • Tutorials
    • Arcade Skill Tree
  • Built-In Resources
    • Do I have to credit anyone?
    • How do I use these?
    • Top-Level Resources
    • Fonts
      • Kenney TTFs
      • Liberation TTFs
    • GUI Basic Assets
      • Button
      • Checkbox
      • Icons
      • Scroll
      • Simple Checkbox
      • Slider
      • Toggle
      • Window & Panel
    • Image Theme Sets
      • Alien
      • Animated Characters
      • Backgrounds
      • Cards
      • Cybercity Background
      • Enemies
      • Items
      • Miami Synth Parallax
      • Pinball
      • Space Shooter
      • Spritesheets
      • Test Textures
      • Tiles
      • Topdown Tanks
    • Input Prompt
      • Xbox
    • Music
    • Onscreen Controls
      • Flat Dark
      • Flat Light
      • Shaded Dark
      • Shaded Light
    • Sounds
    • Tiled Maps
    • Video

Manual

  • Drawing & Using Sprites
    • Drawing with Sprites and SpriteLists
      • What’s a Sprite?
      • Why SpriteLists?
      • Using Sprites and SpriteLists
      • Using Images with Sprites
      • Viewports, Cameras, and Screens
    • Advanced SpriteList Techniques
      • Draw Order & Sorting
      • Custom Texture Atlases
      • Lazy SpriteLists
  • Input Handling
    • Simple Input
      • Event Based
      • Polling
      • Keyboard
    • Advanced Input
      • Key Concepts
      • A Small Example
      • Active Device Switching
      • Controller Binding and Multiple Players
  • Sound
    • Why Is Sound Important?
    • Sound Basics
      • Loading Sounds
      • Playing Sounds
      • Stopping Sounds
    • Intermediate Loading and Playback
      • Streaming or Static Loading?
      • Intermediate-Level Playback Control
    • Cross-Platform Compatibility
      • The Most Reliable Formats & Features
      • Loading In-Depth
      • Backends Determine Playback Features
      • Choosing the Audio Backend
    • Other Sound Libraries
      • Using Pyglet
      • External Libraries
  • Textures
    • Introduction
    • Texture Uniqueness
    • Texture Cache
    • Custom Textures
  • Event Loop
    • Introduction
      • on_draw()
      • on_update()
      • on_fixed_update()
    • Time
      • Clock
      • FixedClock
      • Up Coming
    • More on Fixed update
      • Death Spiral
      • Update Interpolation
    • Vertical Synchronization
      • What is vertical sync?
      • Vertical sync disabled as a default
  • Camera
    • Key Concepts
      • World Space
      • Screen Space
      • View Matrices
      • Projection Matrices
      • Viewports
    • Key Objects
  • Sections
    • A simple example
    • How to work with Sections
    • Sections configuration and logic with an example
    • Section Unique Events
    • The Section Manager
  • GUI
    • GUI Concepts
      • Classes
      • Drawing
      • UIMixin
      • UIConstructs
      • Available Elements
      • User-interface events
      • Different event systems
    • GUI Layouts
      • Included Layouts
      • When to use which layout?
    • GUI Style
      • Which Widgets Can I Style?
      • Basic Usage
      • Advanced
    • Own Widgets
      • Where to start
      • Example ProgressBar
    • Own Layout
      • Where to start
      • Example CircleLayout
    • GUI Controller Support
      • Basic Setup
      • Advanced Usage
  • Texture Atlas
    • Introduction
    • Size Restriction
    • Resize
    • Default Texture Atlas
    • Custom Atlas
    • Border
    • Updating Texture
    • Removing Texture
    • Rendering Into Atlas
    • Debugging
  • Resource Handles
    • Using Resource Handles
      • How Do I Use Resource Handles?
      • When & Where Can I Use Resource Handles?
      • Adding Your Own Resource Handles
      • Adding your New Resource Handle
    • Adding Multiple Directories to a Resource Handle
    • Cleaner Code with Pathlib
      • Finding your Project Folder
    • More on How Resource Handles Work
      • Implementation Details
    • Resources Handles and PyInstaller/Nuitka one-file builds
  • OpenGL
    • Initialization
    • Garbage Collection & Threads
    • Threads & vsync
    • SpriteList & Threads
    • Writing Raw Bytes to GL Buffers & Textures
  • OpenGL ES Devices: Raspberry Pi, Etc
    • OpenGL ES
    • Supported Raspberry Pi Configurations
      • Operating Systems
    • Unsupported Raspberry Pi Devices
      • Incompatible Older Devices
      • Incompatible New Devices
    • SBC Requirements
      • Standard Python
      • Supported OpenGL ES Versions
      • Arcade’s Binary Dependencies
      • An Adequate Power Supply
  • Performance
    • Collision Detection Performance
      • Why are collisions slow?
      • The Faster Alternatives
      • Spatial Hashing
      • Pymunk Physics Engine
      • Compute Shader
    • Drawing Performance
      • Drawing Shapes
    • Sprite drawing performance
      • An Option for Advanced Users
    • Text drawing performance
    • Loading Performance
      • Loading Screens and Rooms
    • Sound Performance in Depth
      • Static Sounds are for Speed
      • Streaming Saves Memory
  • Headless Arcade
    • Enabling headless mode
    • How is this affecting my code?
    • Examples
      • Simple headless mode
      • Headless mode while extending the Arcade Window
    • Advanced
    • Issues?

Contributing

  • Contributing To Arcade
    • Contributing Code
    • I Can’t Code Yet
      • Tell Us About Documentation Issues
      • Play Games made with Arcade
      • Create Art, Music, and Sound
    • Report Bugs
      • Excellent Bug Reports

Community

  • Community Locations
    • Community Standards
    • Where to Post
    • Other Locations
  • How to Get Help
    • Sharing & Formatting Your Code
      • Formatting for Discord & Github Issues
      • Code Hosting
    • Arcade Version & Basic Environment Info
  • Games made with Arcade
    • User-submitted Games
      • Brazier
      • PhotoShip
      • Space Station Builder
      • Notepad Doodles
      • BoxHead Survivor
      • Temporum
      • SOL Defender
      • Binary Defense
      • Space Invaders
      • Ready or Not?
      • Age of Divisiveness
      • Fishy-Game
      • Adventure
      • Transcience Animation
      • Stellar Arena Demo
      • Battle Bros
      • Rabbit Herder
      • The Great Skeleton War
      • Python Knife Hit
      • Kayzee
      • lixingqiu Games
      • Space Typer
      • FlapPy Bird
      • PyOverheadGame
      • Dungeon
      • Two Worlds
      • Mama Nyah’s House of Tarot
      • Simpson College Spring 2017 CMSC 150 Course
    • Python Discord GameJam 2020
      • 3 Keys on the Run
      • Triple Blocks
      • Triple Vision
      • Hatchlings
      • Gem Matcher
      • Tri-Chess
      • Insane Irradiated Insectz
      • Flimsy Billy’s Coin Dash 3
      • ZeYoughEzh
      • Coin Collector

API Reference

  • Quick Index
  • API Reference
    • Types
      • HasAddSubMul
      • TiledObject
      • SupportsDunderLT
      • SupportsDunderGT
      • AnchorPoint
      • Color
      • RectKwargs
      • Rect
      • LRBT()
      • LBWH()
      • XYWH()
      • XYRR()
      • Viewport()
      • BoxKwargs
      • Box
      • XYZWHD()
      • LBNWHD()
      • LRBTNF()
    • Resources
      • resolve_resource_path()
      • resolve()
      • add_resource_handle()
      • get_resource_handle_paths()
      • list_built_in_assets()
      • load_kenney_fonts()
      • load_liberation_fonts()
    • Primitives
      • draw_arc_filled()
      • draw_arc_outline()
      • draw_circle_filled()
      • draw_circle_outline()
      • draw_ellipse_filled()
      • draw_ellipse_outline()
      • get_points_for_thick_line()
      • draw_line_strip()
      • draw_line()
      • draw_lines()
      • draw_parabola_filled()
      • draw_parabola_outline()
      • draw_point()
      • draw_points()
      • draw_polygon_filled()
      • draw_polygon_outline()
      • draw_texture_rect()
      • draw_sprite()
      • draw_sprite_rect()
      • draw_lrbt_rectangle_outline()
      • draw_lbwh_rectangle_outline()
      • draw_lrbt_rectangle_filled()
      • draw_lbwh_rectangle_filled()
      • draw_rect_outline()
      • draw_rect_filled()
      • draw_triangle_filled()
      • draw_triangle_outline()
    • Shape Lists
      • Shape
      • ShapeElementList
      • create_line()
      • create_line_generic_with_colors()
      • create_line_generic()
      • create_line_strip()
      • create_line_loop()
      • create_lines()
      • create_lines_with_colors()
      • create_polygon()
      • create_rectangle_filled()
      • create_rectangle_outline()
      • get_rectangle_points()
      • create_rectangle()
      • create_rectangle_filled_with_colors()
      • create_rectangles_filled_with_colors()
      • create_triangles_filled_with_colors()
      • create_triangles_strip_filled_with_colors()
      • create_ellipse_filled()
      • create_ellipse_outline()
      • create_ellipse()
      • create_ellipse_filled_with_colors()
    • Sprites
      • load_animated_gif()
      • BasicSprite
      • Sprite
      • SpriteSolidColor
      • SpriteCircle
      • PyMunk
      • PymunkMixin
      • TextureKeyframe
      • TextureAnimation
      • TextureAnimationSprite
      • AnimatedWalkingSprite
    • Camera 2D
      • Camera2D
    • Sprite Lists
      • SpriteSequence
      • SpriteList
      • SpriteListData
      • SpriteListBufferData
      • SpriteListTextureData
      • ReadOnlySpatialHash
      • SpatialHash
      • get_distance_between_sprites()
      • get_closest_sprite()
      • check_for_collision()
      • check_for_collision_with_list()
      • check_for_collision_with_lists()
      • get_sprites_at_point()
      • get_sprites_at_exact_point()
      • get_sprites_in_rect()
    • Sprite Scenes
      • SceneKeyError
      • Scene
    • Clock
      • Clock
      • FixedClock
    • Text
      • Text
      • TextPool
      • load_font()
      • create_text_sprite()
      • draw_text()
    • Tiled Map Reader
      • TileMap
      • load_tilemap()
    • Texture Management
      • ImageData
      • Texture
      • load_texture()
      • load_image()
      • load_spritesheet()
      • make_circle_texture()
      • make_soft_circle_texture()
      • make_soft_square_texture()
      • TextureCacheManager
      • SpriteSheet
      • get_default_texture()
      • get_default_image()
    • Hitbox
      • calculate_hit_box_points_simple()
      • calculate_hit_box_points_detailed()
      • HitBoxAlgorithm
      • HitBox
      • RotatableHitBox
      • BoundingHitBoxAlgorithm
      • SimpleHitBoxAlgorithm
      • PymunkHitBoxAlgorithm
    • Texture Transforms
      • VertexOrder
      • Transform
      • Rotate90Transform
      • Rotate180Transform
      • Rotate270Transform
      • FlipLeftRightTransform
      • FlipTopBottomTransform
      • TransposeTransform
      • TransverseTransform
    • Texture Atlas
      • TextureAtlasBase
      • DefaultTextureAtlas
      • AtlasRegion
      • UVData
      • ImageDataRefCounter
      • UniqueTextureRefCounter
    • Performance Information
      • print_timings()
      • clear_timings()
      • get_timings()
      • enable_timings()
      • disable_timings()
      • get_fps()
      • timings_enabled()
      • PerfGraph
    • Physics Engines
      • PhysicsEngineSimple
      • PhysicsEnginePlatformer
      • PymunkPhysicsObject
      • PymunkException
      • PymunkPhysicsEngine
    • Misc Utility Functions
      • configure_logging()
      • Chain
      • as_type()
      • type_name()
      • is_iterable()
      • is_nonstr_iterable()
      • is_str_or_noniterable()
      • grow_sequence()
      • copy_dunders_unimplemented()
      • is_raspberry_pi()
      • get_raspberry_pi_info()
      • unpack_asfloat_or_point()
    • Geometry Support
      • are_polygons_intersecting()
      • is_point_in_box()
      • get_triangle_orientation()
      • are_lines_intersecting()
      • is_point_in_polygon()
    • Game Controller
      • ControllerManager
      • get_controllers()
    • Joystick
      • get_joysticks()
      • get_game_controllers()
    • Window and View
      • NoOpenGLException
      • Window
      • View
      • get_screens()
      • open_window()
      • get_display_size()
      • get_window()
      • set_window()
      • window_exists()
      • close_window()
      • run()
      • exit()
      • start_render()
      • finish_render()
      • set_background_color()
      • schedule()
      • unschedule()
      • schedule_once()
      • Section
      • SectionManager
      • get_pixel()
      • get_image()
    • Sound
      • Sound
      • load_sound()
      • play_sound()
      • stop_sound()
    • Advanced Camera Features
      • ZeroProjectionDimension
      • CameraData
      • OrthographicProjectionData
      • PerspectiveProjectionData
      • Projection
      • Projector
      • duplicate_camera_data()
      • constrain_camera_data()
      • orthographic_from_rect()
      • generate_view_matrix()
      • generate_orthographic_matrix()
      • generate_perspective_matrix()
      • project_orthographic()
      • unproject_orthographic()
      • project_perspective()
      • unproject_perspective()
      • OrthographicProjector
      • PerspectiveProjector
      • DefaultProjector
      • static_from_orthographic()
      • static_from_perspective()
      • static_from_raw_orthographic()
      • static_from_raw_perspective()
      • static_from_matrices()
    • Pathfinding
      • AStarBarrierList
      • astar_calculate_path()
      • has_line_of_sight()
    • Isometric Map (incomplete)
      • isometric_grid_to_screen()
      • screen_to_isometric_grid()
      • create_isometric_grid_lines()
    • Earclip
      • earclip()
    • Easing
      • EasingFunction
      • Interpolatable
      • Easing
      • norm()
      • lerp()
      • ease()
    • OpenGL Context
      • ArcadeContext
    • Math
      • clamp()
      • lerp()
      • lerp_2d()
      • lerp_3d()
      • smerp()
      • smerp_2d()
      • smerp_3d()
      • lerp_angle()
      • rand_in_rect()
      • rand_in_circle()
      • rand_on_circle()
      • rand_on_line()
      • rand_angle_360_deg()
      • rand_angle_spread_deg()
      • rand_vec_spread_deg()
      • rand_vec_magnitude()
      • get_distance()
      • rotate_point()
      • rescale_relative_to_point()
      • rotate_around_point()
      • get_angle_degrees()
      • get_angle_radians()
      • quaternion_rotation()
    • Arcade’s Graphics Layer
      • Using This Module
      • Graphics API Gotchas
      • Supported Backends
    • Exceptions
      • NoArcadeWindowError
      • OutsideRangeError
      • IntOutsideRangeError
      • FloatOutsideRangeError
      • ByteRangeError
      • NormalizedRangeError
      • PerformanceWarning
      • ReplacementWarning
      • warning()
    • Start/Finish Render
      • StartFinishRenderData
    • Cache
      • crate_str_from_values()
      • crate_str_from_list()
      • HitBoxCache
      • TextureBucket
      • TextureCache
      • ImageDataCache
    • Future Features
      • Light
      • LightLayer
      • VideoPlayer
      • VideoPlayerView
    • GUI
      • UIMessageBox
      • UIButtonRow
      • UIDraggableMixin
      • UIMouseFilterMixin
      • UIWindowLikeMixin
      • Surface
      • UIManager
      • NinePatchTexture
      • UIView
    • GUI Widgets
      • FocusMode
      • WeakRef
      • UIWidget
      • UIInteractiveWidget
      • UIDummy
      • UISpriteWidget
      • UIInteractiveSpriteWidget
      • UILayout
      • UISpace
      • UITextureButtonStyle
      • UITextureButton
      • UIFlatButtonStyle
      • UIFlatButton
      • UIDropdown
      • UIAnchorLayout
      • UIBoxLayout
      • UIGridLayout
      • UIBaseSlider
      • UISliderStyle
      • UISlider
      • UITextureSlider
      • UILabel
      • UITextWidget
      • UIInputTextStyle
      • UIInputText
      • UITextArea
      • UITextureToggle
      • UIImage
    • GUI Events
      • UIEvent
      • UIMouseEvent
      • UIMouseMovementEvent
      • UIMousePressEvent
      • UIMouseDragEvent
      • UIMouseReleaseEvent
      • UIMouseScrollEvent
      • UIKeyEvent
      • UIKeyPressEvent
      • UIKeyReleaseEvent
      • UITextEvent
      • UITextInputEvent
      • UITextMotionEvent
      • UITextMotionSelectEvent
      • UIOnClickEvent
      • UIOnUpdateEvent
      • UIOnChangeEvent
      • UIOnActionEvent
      • UIControllerEvent
      • UIControllerConnectEvent
      • UIControllerDisconnectEvent
      • UIControllerStickEvent
      • UIControllerTriggerEvent
      • UIControllerButtonEvent
      • UIControllerButtonPressEvent
      • UIControllerButtonReleaseEvent
      • UIControllerDpadEvent
    • GUI Properties
      • Property
      • DictProperty
      • ListProperty
      • bind()
      • unbind()
    • GUI Style
      • UIStyleBase
      • UIStyledWidget
    • GUI Experimental Features
      • UIPasswordInput
      • UIScrollBar
      • UIScrollArea
      • UITypedTextInput
    • arcade.key package
    • arcade.csscolor package
    • arcade.color package
    • arcade.uicolor package
Python Arcade Library
  • menu_05.py Full Listing

menu_05.py Full Listing

menu_05.py
  1"""
  2Menu.
  3
  4Shows the usage of almost every gui widget, switching views and making a modal.
  5"""
  6
  7from typing import List
  8
  9import arcade
 10import arcade.gui
 11
 12# Screen title and size
 13SCREEN_WIDTH = 800
 14SCREEN_HEIGHT = 600
 15SCREEN_TITLE = "Making a Menu"
 16
 17
 18class MainView(arcade.View):
 19    """This is the class where your normal game would go."""
 20
 21    def __init__(self):
 22        super().__init__()
 23
 24        self.manager = arcade.gui.UIManager()
 25
 26        switch_menu_button = arcade.gui.UIFlatButton(text="Pause", width=150)
 27
 28        # Initialise the button with an on_click event.
 29        @switch_menu_button.event("on_click")
 30        def on_click_switch_button(event):
 31            # Passing the main view into menu view as an argument.
 32            menu_view = MenuView(self)
 33            self.window.show_view(menu_view)
 34
 35        # Use the anchor to position the button on the screen.
 36        self.anchor = self.manager.add(arcade.gui.UIAnchorLayout())
 37
 38        self.anchor.add(
 39            anchor_x="center_x",
 40            anchor_y="center_y",
 41            child=switch_menu_button,
 42        )
 43
 44    def on_hide_view(self):
 45        # Disable the UIManager when the view is hidden.
 46        self.manager.disable()
 47
 48    def on_show_view(self):
 49        """This is run once when we switch to this view"""
 50        arcade.set_background_color(arcade.color.DARK_BLUE_GRAY)
 51
 52        # Enable the UIManager when the view is showm.
 53        self.manager.enable()
 54
 55    def on_draw(self):
 56        """Render the screen."""
 57        # Clear the screen
 58        self.clear()
 59
 60        # Draw the manager.
 61        self.manager.draw()
 62
 63
 64class MenuView(arcade.View):
 65    """Main menu view class."""
 66
 67    def __init__(self, main_view):
 68        super().__init__()
 69
 70        self.manager = arcade.gui.UIManager()
 71
 72        resume_button = arcade.gui.UIFlatButton(text="Resume", width=150)
 73        start_new_game_button = arcade.gui.UIFlatButton(text="Start New Game", width=150)
 74        volume_button = arcade.gui.UIFlatButton(text="Volume", width=150)
 75        options_button = arcade.gui.UIFlatButton(text="Options", width=150)
 76
 77        exit_button = arcade.gui.UIFlatButton(text="Exit", width=320)
 78
 79        # Initialise a grid in which widgets can be arranged.
 80        self.grid = arcade.gui.UIGridLayout(
 81            column_count=2, row_count=3, horizontal_spacing=20, vertical_spacing=20
 82        )
 83
 84        # Adding the buttons to the layout.
 85        self.grid.add(resume_button, column=0, row=0)
 86        self.grid.add(start_new_game_button, column=1, row=0)
 87        self.grid.add(volume_button, column=0, row=1)
 88        self.grid.add(options_button, column=1, row=1)
 89        self.grid.add(exit_button, column=0, row=2, column_span=2)
 90
 91        self.anchor = self.manager.add(arcade.gui.UIAnchorLayout())
 92
 93        self.anchor.add(
 94            anchor_x="center_x",
 95            anchor_y="center_y",
 96            child=self.grid,
 97        )
 98
 99        self.main_view = main_view
100
101        @resume_button.event("on_click")
102        def on_click_resume_button(event):
103            # Pass already created view because we are resuming.
104            self.window.show_view(self.main_view)
105
106        @start_new_game_button.event("on_click")
107        def on_click_start_new_game_button(event):
108            # Create a new view because we are starting a new game.
109            main_view = MainView()
110            self.window.show_view(main_view)
111
112        @exit_button.event("on_click")
113        def on_click_exit_button(event):
114            arcade.exit()
115
116        @volume_button.event("on_click")
117        def on_click_volume_button(event):
118            volume_menu = SubMenu(
119                "Volume Menu",
120                "How do you like your volume?",
121                "Enable Sound",
122                [
123                    "Play: Rock",
124                    "Play: Punk",
125                    "Play: Pop",
126                    "Play: Jazz",
127                    "Play: Blues",
128                    "Play: Classical",
129                    "Play: Country",
130                    "Play: Electronic",
131                    "Play: Hip Hop",
132                    "Play: Metal",
133                    "Play: R&B",
134                    "Play: Reggae",
135                ],
136                "Adjust Volume",
137            )
138            self.manager.add(volume_menu, layer=1)
139
140        @options_button.event("on_click")
141        def on_click_options_button(event):
142            options_menu = SubMenu(
143                "Funny Menu",
144                "Too much fun here",
145                "Fun?",
146                [
147                    "Make Fun",
148                    "Enjoy Fun",
149                    "Like Fun",
150                    "Share Fun",
151                    "Spread Fun",
152                    "Find Fun",
153                    "Create Fun",
154                    "Discover Fun",
155                    "Embrace Fun",
156                    "Celebrate Fun",
157                    "Inspire Fun",
158                    "Maximize Fun",
159                ],
160                "Adjust Fun",
161            )
162            self.manager.add(options_menu, layer=1)
163
164    def on_hide_view(self):
165        # Disable the UIManager when the view is hidden.
166        self.manager.disable()
167
168    def on_show_view(self):
169        """This is run once when we switch to this view"""
170
171        # Makes the background darker
172        arcade.set_background_color([rgb - 50 for rgb in arcade.color.DARK_BLUE_GRAY])
173
174        # Enable the UIManager when the view is showm.
175        self.manager.enable()
176
177    def on_draw(self):
178        """Render the screen."""
179        # Clear the screen
180        self.clear()
181        self.manager.draw()
182
183
184class SubMenu(arcade.gui.UIMouseFilterMixin, arcade.gui.UIAnchorLayout):
185    """Acts like a fake view/window."""
186
187    def __init__(
188        self,
189        title: str,
190        input_text: str,
191        toggle_label: str,
192        dropdown_options: List[str],
193        slider_label: str,
194    ):
195        super().__init__(size_hint=(1, 1))
196
197        # Setup frame which will act like the window.
198        frame = self.add(arcade.gui.UIAnchorLayout(width=300, height=400, size_hint=None))
199        frame.with_padding(all=20)
200
201        # Add a background to the window.
202        # Nine patch smoothes the edges.
203        frame.with_background(
204            texture=arcade.gui.NinePatchTexture(
205                left=7,
206                right=7,
207                bottom=7,
208                top=7,
209                texture=arcade.load_texture(
210                    ":resources:gui_basic_assets/window/dark_blue_gray_panel.png"
211                ),
212            )
213        )
214
215        back_button = arcade.gui.UIFlatButton(text="Back", width=250)
216        # The type of event listener we used earlier for the button will not work here.
217        back_button.on_click = self.on_click_back_button
218
219        title_label = arcade.gui.UILabel(text=title, align="center", font_size=20, multiline=False)
220        # Adding some extra space around the title.
221        title_label_space = arcade.gui.UISpace(height=30, color=arcade.color.DARK_BLUE_GRAY)
222
223        input_text_widget = arcade.gui.UIInputText(text=input_text, width=250).with_border()
224
225        # Load the on-off textures.
226        on_texture = arcade.load_texture(
227            ":resources:gui_basic_assets/simple_checkbox/circle_on.png"
228        )
229        off_texture = arcade.load_texture(
230            ":resources:gui_basic_assets/simple_checkbox/circle_off.png"
231        )
232
233        # Create the on-off toggle and a label
234        toggle_label = arcade.gui.UILabel(text=toggle_label)
235        toggle = arcade.gui.UITextureToggle(
236            on_texture=on_texture, off_texture=off_texture, width=20, height=20
237        )
238
239        # Align toggle and label horizontally next to each other
240        toggle_group = arcade.gui.UIBoxLayout(vertical=False, space_between=5)
241        toggle_group.add(toggle)
242        toggle_group.add(toggle_label)
243
244        # Create dropdown with a specified default.
245        # When many options are provided, the dropdown automatically scrolls.
246        dropdown = arcade.gui.UIDropdown(
247            default=dropdown_options[0],
248            options=dropdown_options,
249            height=20,
250            width=250,
251            show_scroll_bar=True,
252        )
253
254        slider_label = arcade.gui.UILabel(text=slider_label)
255        pressed_style = arcade.gui.UISlider.UIStyle(
256            filled_track=arcade.color.GREEN, unfilled_track=arcade.color.RED
257        )
258        default_style = arcade.gui.UISlider.UIStyle()
259        style_dict = {
260            "press": pressed_style,
261            "normal": default_style,
262            "hover": default_style,
263            "disabled": default_style,
264        }
265        # Configuring the styles is optional.
266        slider = arcade.gui.UISlider(value=50, width=250, style=style_dict)
267
268        widget_layout = arcade.gui.UIBoxLayout(align="left", space_between=10)
269        widget_layout.add(title_label)
270        widget_layout.add(title_label_space)
271        widget_layout.add(input_text_widget)
272        widget_layout.add(toggle_group)
273        widget_layout.add(dropdown)
274        widget_layout.add(slider_label)
275        widget_layout.add(slider)
276
277        widget_layout.add(back_button)
278
279        frame.add(child=widget_layout, anchor_x="center_x", anchor_y="top")
280
281    def on_click_back_button(self, event):
282        # Removes the widget from the manager.
283        # After this the manager will respond to its events like it previously did.
284        self.parent.remove(self)
285
286
287def main():
288    window = arcade.Window(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_TITLE, resizable=True)
289    main_view = MainView()
290    window.show_view(main_view)
291    arcade.run()
292
293
294if __name__ == "__main__":
295    main()

© Copyright 2026, Paul Vincent Craven.

Built with Sphinx using a theme provided by Read the Docs.