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