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 = 800
 25HEIGHT = 600
 26SPRITE_SCALING = 0.5
 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 = 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(":resources:images/animated_characters/female_person/femalePerson_idle.png",
 74                                           scale=SPRITE_SCALING)
 75        self.player_sprite.center_x = 50
 76        self.player_sprite.center_y = 50
 77        self.player_list.append(self.player_sprite)
 78
 79        for i in range(5):
 80
 81            # Create the coin instance
 82            coin = arcade.Sprite(":resources:images/items/coinGold.png", scale=SPRITE_SCALING / 3)
 83
 84            # Position the coin
 85            coin.center_x = random.randrange(WIDTH)
 86            coin.center_y = random.randrange(HEIGHT)
 87
 88            # Add the coin to the lists
 89            self.coin_list.append(coin)
 90
 91    def on_show_view(self):
 92        self.window.background_color = arcade.color.AMAZON
 93
 94        # Don't show the mouse cursor
 95        self.window.set_mouse_visible(False)
 96
 97    def on_draw(self):
 98        self.clear()
 99        # Draw all the sprites.
100        self.player_list.draw()
101        self.coin_list.draw()
102
103        # Put the text on the screen.
104        output = f"Score: {self.score}"
105        arcade.draw_text(output, 10, 30, arcade.color.WHITE, 14)
106        output_total = f"Total Score: {self.window.total_score}"
107        arcade.draw_text(output_total, 10, 10, arcade.color.WHITE, 14)
108
109    def on_update(self, delta_time):
110        self.time_taken += delta_time
111
112        # Call update on all sprites (The sprites don't do much in this
113        # example though.)
114        self.coin_list.update()
115        self.player_list.update()
116
117        # Generate a list of all sprites that collided with the player.
118        hit_list = arcade.check_for_collision_with_list(self.player_sprite, self.coin_list)
119
120        # Loop through each colliding sprite, remove it, and add to the
121        # score.
122        for coin in hit_list:
123            coin.kill()
124            self.score += 1
125            self.window.total_score += 1
126
127        # If we've collected all the games, then move to a "GAME_OVER"
128        # state.
129        if len(self.coin_list) == 0:
130            game_over_view = GameOverView()
131            game_over_view.time_taken = self.time_taken
132            self.window.set_mouse_visible(True)
133            self.window.show_view(game_over_view)
134
135    def on_mouse_motion(self, x, y, _dx, _dy):
136        """
137        Called whenever the mouse moves.
138        """
139        self.player_sprite.center_x = x
140        self.player_sprite.center_y = y
141
142
143class GameOverView(arcade.View):
144    def __init__(self):
145        super().__init__()
146        self.time_taken = 0
147
148    def on_show_view(self):
149        self.window.background_color = arcade.color.BLACK
150
151    def on_draw(self):
152        self.clear()
153        """
154        Draw "Game over" across the screen.
155        """
156        arcade.draw_text("Game Over", 240, 400, arcade.color.WHITE, 54)
157        arcade.draw_text("Click to restart", 310, 300, arcade.color.WHITE, 24)
158
159        time_taken_formatted = f"{round(self.time_taken, 2)} seconds"
160        arcade.draw_text(f"Time taken: {time_taken_formatted}",
161                         WIDTH / 2,
162                         200,
163                         arcade.color.GRAY,
164                         font_size=15,
165                         anchor_x="center")
166
167        output_total = f"Total Score: {self.window.total_score}"
168        arcade.draw_text(output_total, 10, 10, arcade.color.WHITE, 14)
169
170    def on_mouse_press(self, _x, _y, _button, _modifiers):
171        game_view = GameView()
172        self.window.show_view(game_view)
173
174
175def main():
176    window = arcade.Window(WIDTH, HEIGHT, "Different Views Example")
177    window.total_score = 0
178    menu_view = MenuView()
179    window.show_view(menu_view)
180    arcade.run()
181
182
183if __name__ == "__main__":
184    main()