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
 21import arcade
 22import random
 23
 24WIDTH = 1280
 25HEIGHT = 720
 26SPRITE_SCALING = 1.0
 27
 28
 29class MenuView(arcade.View):
 30    def on_show_view(self):
 31        self.window.background_color = arcade.color.WHITE
 32
 33    def on_draw(self):
 34        self.clear()
 35        arcade.draw_text("Menu Screen", WIDTH / 2, HEIGHT / 2,
 36                         arcade.color.BLACK, font_size=50, anchor_x="center")
 37        arcade.draw_text("Click to advance", WIDTH / 2, HEIGHT / 2 - 75,
 38                         arcade.color.GRAY, font_size=20, anchor_x="center")
 39
 40    def on_mouse_press(self, _x, _y, _button, _modifiers):
 41        instructions_view = InstructionView()
 42        self.window.show_view(instructions_view)
 43
 44
 45class InstructionView(arcade.View):
 46    def on_show_view(self):
 47        self.window.background_color = arcade.color.ORANGE_PEEL
 48
 49    def on_draw(self):
 50        self.clear()
 51        arcade.draw_text("Instructions Screen", WIDTH / 2, HEIGHT / 2,
 52                         arcade.color.BLACK, font_size=50, anchor_x="center")
 53        arcade.draw_text("Click to advance", WIDTH / 2, HEIGHT / 2 - 75,
 54                         arcade.color.GRAY, font_size=20, anchor_x="center")
 55
 56    def on_mouse_press(self, _x, _y, _button, _modifiers):
 57        game_view = GameView()
 58        self.window.show_view(game_view)
 59
 60
 61class GameView(arcade.View):
 62    def __init__(self):
 63        super().__init__()
 64
 65        self.time_taken = 0
 66
 67        # Sprite lists
 68        self.player_list = arcade.SpriteList()
 69        self.coin_list = arcade.SpriteList()
 70
 71        # Set up the player
 72        self.score = 0
 73        self.player_sprite = arcade.Sprite(
 74            ":resources:images/animated_characters/female_person/femalePerson_idle.png",
 75            scale=SPRITE_SCALING,
 76        )
 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(
 85                ":resources:images/items/coinGold.png",
 86                scale=SPRITE_SCALING / 3,
 87            )
 88
 89            # Position the coin
 90            coin.center_x = random.randrange(WIDTH)
 91            coin.center_y = random.randrange(HEIGHT)
 92
 93            # Add the coin to the lists
 94            self.coin_list.append(coin)
 95
 96    def on_show_view(self):
 97        self.window.background_color = arcade.color.AMAZON
 98
 99        # Don't show the mouse cursor
100        self.window.set_mouse_visible(False)
101
102    def on_draw(self):
103        self.clear()
104        # Draw all the sprites.
105        self.player_list.draw()
106        self.coin_list.draw()
107
108        # Put the text on the screen.
109        output = f"Score: {self.score}"
110        arcade.draw_text(output, 10, 30, arcade.color.WHITE, 14)
111        output_total = f"Total Score: {self.window.total_score}"
112        arcade.draw_text(output_total, 10, 10, arcade.color.WHITE, 14)
113
114    def on_update(self, delta_time):
115        self.time_taken += delta_time
116
117        # Call update on all sprites (The sprites don't do much in this
118        # example though.)
119        self.coin_list.update()
120        self.player_list.update()
121
122        # Generate a list of all sprites that collided with the player.
123        hit_list = arcade.check_for_collision_with_list(self.player_sprite, self.coin_list)
124
125        # Loop through each colliding sprite, remove it, and add to the
126        # score.
127        for coin in hit_list:
128            coin.kill()
129            self.score += 1
130            self.window.total_score += 1
131
132        # If we've collected all the games, then move to a "GAME_OVER"
133        # state.
134        if len(self.coin_list) == 0:
135            game_over_view = GameOverView()
136            game_over_view.time_taken = self.time_taken
137            self.window.set_mouse_visible(True)
138            self.window.show_view(game_over_view)
139
140    def on_mouse_motion(self, x, y, _dx, _dy):
141        """
142        Called whenever the mouse moves.
143        """
144        self.player_sprite.center_x = x
145        self.player_sprite.center_y = y
146
147
148class GameOverView(arcade.View):
149    def __init__(self):
150        super().__init__()
151        self.time_taken = 0
152
153    def on_show_view(self):
154        self.window.background_color = arcade.color.BLACK
155
156    def on_draw(self):
157        self.clear()
158        """
159        Draw "Game over" across the screen.
160        """
161        arcade.draw_text(
162            "Game Over",
163            x=WIDTH / 2,
164            y=400,
165            color=arcade.color.WHITE,
166            font_size=54,
167            anchor_x="center"
168        )
169        arcade.draw_text(
170            "Click to restart",
171            x=WIDTH / 2,
172            y=300,
173            color=arcade.color.WHITE,
174            font_size=24,
175            anchor_x="center",
176        )
177
178        time_taken_formatted = f"{round(self.time_taken, 2)} seconds"
179        arcade.draw_text(f"Time taken: {time_taken_formatted}",
180                         WIDTH / 2,
181                         200,
182                         arcade.color.GRAY,
183                         font_size=15,
184                         anchor_x="center")
185
186        output_total = f"Total Score: {self.window.total_score}"
187        arcade.draw_text(output_total, 10, 10, arcade.color.WHITE, 14)
188
189    def on_mouse_press(self, _x, _y, _button, _modifiers):
190        game_view = GameView()
191        self.window.show_view(game_view)
192
193
194def main():
195    window = arcade.Window(WIDTH, HEIGHT, "Different Views Example")
196    window.total_score = 0
197    menu_view = MenuView()
198    window.show_view(menu_view)
199    arcade.run()
200
201
202if __name__ == "__main__":
203    main()