Using Views for Start/End Screens
Views allow you to easily switch “views” for what you are showing on the window. You can use this to support adding screens such as:
Game over screens
View class is a lot like the
Window class that you are already used
View class has methods for
on_draw just like
Window. We can change the current view to quickly change the code that is
managing what is drawn on the window and handling user input.
If you know ahead of time you want to use views, you can build your code around the Instruction Screens and Game Over Screens. However, typically a programmer wants to add these items to a game that already exists.
This tutorial steps you through how to do just that.
Change Main Program to Use a View
First, we’ll start with a simple collect coins example: 01_views.py Full Listing
Then we’ll move our game into a game view. Take the code where we define our window class:
Change it to derive from
arcade.View instead of
I also suggest using “View” as part of the name:
This will require a couple other updates. The
View class does not control
the size of the window, so we’ll need to take that out of the call to the
parent class. Change:
super().__init__(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_TITLE)
Window class still controls if the mouse is visible or not, so to hide
the mouse, we’ll need to use the
window attribute that is part of the
Now in the
main function, instead of just creating a window, we’ll create
a window, a view, and then show that view.
1 2 3 4 5 6 7 8
def main(): """ Main function """ window = arcade.Window(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_TITLE) start_view = GameView() window.show_view(start_view) start_view.setup() arcade.run()
At this point, run your game and make sure that it still operates properly. It should run just like it did before, but now we are set up to add additional views.
Add Instruction Screen
Now we are ready to add in our instruction screen as a view. Create a class for it:
Then we need to define the
on_show method that will be run once when we
switch to this view. In this case, we don’t need to do much, just set the
background color. If the game is one that scrolls, we’ll also need to reset
the viewport so that (0, 0) is back to the lower-left coordinate.
def on_show(self): """ This is run once when we switch to this view """ arcade.set_background_color(arcade.csscolor.DARK_SLATE_BLUE) # Reset the viewport, necessary if we have a scrolling game and we need # to reset the viewport back to the start so we can see what we draw. arcade.set_viewport(0, self.window.width, 0, self.window.height)
on_draw method works just like the window class’s method, but it will
only be called when this view is active.
In this case, we’ll just draw some text for the instruction screen. Another alternative is to make a graphic in a paint program, and show that image. We’ll do that below where we show the Game Over screen.
def on_draw(self): """ Draw this view """ arcade.start_render() arcade.draw_text("Instructions Screen", self.window.width / 2, self.window.height / 2, arcade.color.WHITE, font_size=50, anchor_x="center") arcade.draw_text("Click to advance", self.window.width / 2, self.window.height / 2-75, arcade.color.WHITE, font_size=20, anchor_x="center")
Then we’ll put in a method to respond to a mouse click. Here we’ll create our
GameView and call the setup method.
def on_mouse_press(self, _x, _y, _button, _modifiers): """ If the user presses the mouse button, start the game. """ game_view = GameView() game_view.setup() self.window.show_view(game_view)
Now we need to go back to the
main function. Instead of creating a
GameView it needs to now create an
1 2 3 4 5 6 7
def main(): """ Main function """ window = arcade.Window(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_TITLE) start_view = InstructionView() window.show_view(start_view) arcade.run()
Game Over Screen
Another way of doing instruction, pause, and game over screens is with a graphic.
In this example, we’ve created a separate image with the same size as our
window (800x600) and saved it as
game_over.png. You can use the Windows “Paint”
app or get an app for your Mac to make images in order to do this yourself.
GameOverView view that we are adding loads in the game over screen
image as a texture in its
on_draw method draws that texture
to the screen. By using an image, we can fancy up the game over screen using an
image editor as much as we want, while keeping the code simple.
When the user clicks the mouse button, we just start the game over.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
class GameOverView(arcade.View): """ View to show when game is over """ def __init__(self): """ This is run once when we switch to this view """ super().__init__() self.texture = arcade.load_texture("game_over.png") # Reset the viewport, necessary if we have a scrolling game and we need # to reset the viewport back to the start so we can see what we draw. arcade.set_viewport(0, SCREEN_WIDTH - 1, 0, SCREEN_HEIGHT - 1) def on_draw(self): """ Draw this view """ arcade.start_render() self.texture.draw_sized(SCREEN_WIDTH / 2, SCREEN_HEIGHT / 2, SCREEN_WIDTH, SCREEN_HEIGHT) def on_mouse_press(self, _x, _y, _button, _modifiers): """ If the user presses the mouse button, re-start the game. """ game_view = GameView() game_view.setup() self.window.show_view(game_view)
The last thing we need, is to trigger the “Game Over” view. In our
method, we can check the list length. As soon as it hits zero, we’ll change
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
def on_update(self, delta_time): """ Movement and game logic """ # Call update on all sprites (The sprites don't do much in this # example though.) self.coin_list.update() # Generate a list of all sprites that collided with the player. coins_hit_list = arcade.check_for_collision_with_list(self.player_sprite, self.coin_list) # Loop through each colliding sprite, remove it, and add to the score. for coin in coins_hit_list: coin.remove_from_sprite_lists() self.score += 1 # Check length of coin list. If it is zero, flip to the # game over view. if len(self.coin_list) == 0: view = GameOverView() self.window.show_view(view)