Using Views for Instruction and Game Over Screens#

You might also want to check out Using Views for Start/End Screens.

view_instructions_and_game_over.py#
  1"""
  2This program shows how to:
  3  * Have one or more instruction screens
  4  * Show a 'Game over' text and halt the game
  5  * Allow the user to restart the game
  6
  7Make a separate class for each view (screen) in your game.
  8The class will inherit from arcade.View. The structure will
  9look like an arcade.Window as each view will need to have its own draw,
 10update and window event methods. To switch a view, simply create a view
 11with `view = MyView()` and then use the view.show() method.
 12
 13This example shows how you can set data from one View on another View to pass data
 14around (see: time_taken), or you can store data on the Window object to share data between
 15all Views (see: total_score).
 16
 17If Python and Arcade are installed, this example can be run from the command line with:
 18python -m arcade.examples.view_instructions_and_game_over
 19"""
 20
 21from __future__ import annotations
 22
 23import arcade
 24import random
 25
 26WIDTH = 800
 27HEIGHT = 600
 28SPRITE_SCALING = 0.5
 29
 30
 31class MenuView(arcade.View):
 32    def on_show_view(self):
 33        self.window.background_color = arcade.color.WHITE
 34
 35    def on_draw(self):
 36        self.clear()
 37        arcade.draw_text("Menu Screen", WIDTH / 2, HEIGHT / 2,
 38                         arcade.color.BLACK, font_size=50, anchor_x="center")
 39        arcade.draw_text("Click to advance", WIDTH / 2, HEIGHT / 2 - 75,
 40                         arcade.color.GRAY, font_size=20, anchor_x="center")
 41
 42    def on_mouse_press(self, _x, _y, _button, _modifiers):
 43        instructions_view = InstructionView()
 44        self.window.show_view(instructions_view)
 45
 46
 47class InstructionView(arcade.View):
 48    def on_show_view(self):
 49        self.window.background = arcade.color.ORANGE_PEEL
 50
 51    def on_draw(self):
 52        self.clear()
 53        arcade.draw_text("Instructions Screen", WIDTH / 2, HEIGHT / 2,
 54                         arcade.color.BLACK, font_size=50, anchor_x="center")
 55        arcade.draw_text("Click to advance", WIDTH / 2, HEIGHT / 2 - 75,
 56                         arcade.color.GRAY, font_size=20, anchor_x="center")
 57
 58    def on_mouse_press(self, _x, _y, _button, _modifiers):
 59        game_view = GameView()
 60        self.window.show_view(game_view)
 61
 62
 63class GameView(arcade.View):
 64    def __init__(self):
 65        super().__init__()
 66
 67        self.time_taken = 0
 68
 69        # Sprite lists
 70        self.player_list = arcade.SpriteList()
 71        self.coin_list = arcade.SpriteList()
 72
 73        # Set up the player
 74        self.score = 0
 75        self.player_sprite = arcade.Sprite(":resources:images/animated_characters/female_person/femalePerson_idle.png",
 76                                           scale=SPRITE_SCALING)
 77        self.player_sprite.center_x = 50
 78        self.player_sprite.center_y = 50
 79        self.player_list.append(self.player_sprite)
 80
 81        for i in range(5):
 82
 83            # Create the coin instance
 84            coin = arcade.Sprite(":resources:images/items/coinGold.png", scale=SPRITE_SCALING / 3)
 85
 86            # Position the coin
 87            coin.center_x = random.randrange(WIDTH)
 88            coin.center_y = random.randrange(HEIGHT)
 89
 90            # Add the coin to the lists
 91            self.coin_list.append(coin)
 92
 93    def on_show_view(self):
 94        self.window.background_color = arcade.color.AMAZON
 95
 96        # Don't show the mouse cursor
 97        self.window.set_mouse_visible(False)
 98
 99    def on_draw(self):
100        self.clear()
101        # Draw all the sprites.
102        self.player_list.draw()
103        self.coin_list.draw()
104
105        # Put the text on the screen.
106        output = f"Score: {self.score}"
107        arcade.draw_text(output, 10, 30, arcade.color.WHITE, 14)
108        output_total = f"Total Score: {self.window.total_score}"
109        arcade.draw_text(output_total, 10, 10, arcade.color.WHITE, 14)
110
111    def on_update(self, delta_time):
112        self.time_taken += delta_time
113
114        # Call update on all sprites (The sprites don't do much in this
115        # example though.)
116        self.coin_list.update()
117        self.player_list.update()
118
119        # Generate a list of all sprites that collided with the player.
120        hit_list = arcade.check_for_collision_with_list(self.player_sprite, self.coin_list)
121
122        # Loop through each colliding sprite, remove it, and add to the
123        # score.
124        for coin in hit_list:
125            coin.kill()
126            self.score += 1
127            self.window.total_score += 1
128
129        # If we've collected all the games, then move to a "GAME_OVER"
130        # state.
131        if len(self.coin_list) == 0:
132            game_over_view = GameOverView()
133            game_over_view.time_taken = self.time_taken
134            self.window.set_mouse_visible(True)
135            self.window.show_view(game_over_view)
136
137    def on_mouse_motion(self, x, y, _dx, _dy):
138        """
139        Called whenever the mouse moves.
140        """
141        self.player_sprite.center_x = x
142        self.player_sprite.center_y = y
143
144
145class GameOverView(arcade.View):
146    def __init__(self):
147        super().__init__()
148        self.time_taken = 0
149
150    def on_show_view(self):
151        self.window.background_color = arcade.color.BLACK
152
153    def on_draw(self):
154        self.clear()
155        """
156        Draw "Game over" across the screen.
157        """
158        arcade.draw_text("Game Over", 240, 400, arcade.color.WHITE, 54)
159        arcade.draw_text("Click to restart", 310, 300, arcade.color.WHITE, 24)
160
161        time_taken_formatted = f"{round(self.time_taken, 2)} seconds"
162        arcade.draw_text(f"Time taken: {time_taken_formatted}",
163                         WIDTH / 2,
164                         200,
165                         arcade.color.GRAY,
166                         font_size=15,
167                         anchor_x="center")
168
169        output_total = f"Total Score: {self.window.total_score}"
170        arcade.draw_text(output_total, 10, 10, arcade.color.WHITE, 14)
171
172    def on_mouse_press(self, _x, _y, _button, _modifiers):
173        game_view = GameView()
174        self.window.show_view(game_view)
175
176
177def main():
178    window = arcade.Window(WIDTH, HEIGHT, "Different Views Example")
179    window.total_score = 0
180    menu_view = MenuView()
181    window.show_view(menu_view)
182    arcade.run()
183
184
185if __name__ == "__main__":
186    main()