Step 6 - Resetting#

You might have noticed that throughout this tutorial, there has been a setup function in our Window class. So far, we haven’t used this function at all, so what is it for?

Let’s imagine that we want a way to “reset” our game to it’s initial state. This could be because the player lost, and we want to restart the game, or perhaps we just want to give the player the option to restart.

With our current architecture of creating everything in our __init__ function, we would have to duplicate all of that logic in another function in order to make that happen, or completely re-create our Window, which will be an unpleasent experience for a player.

In this chapter, we will do a small amount of re-organizing our existing code to make use of this setup function in a way that allows to simply call the setup function whenever we want our game to return to it’s original state.

First off, we will change our __init__ function to look like below. We are setting values to something like None, 0, or similar. The purpose of this step is to ensure that the attributes are created on the class. In Python, we cannot add new attributes to a class outside of the __init__ function.

def __init__(self):

    super().__init__(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_TITLE)

    self.player_texture = None
    self.player_sprite = None
    self.player_list = None

    self.wall_list = None

Next we will move the actual creation of these objects into our setup function. This looks almost identical to our original __init__ function. Try and move these sections of code on your own, if you get stuck you can see the setup function in the full source code listing below.

The last thing we need to do is create a way to reset the game. For now we’ll add a simple key press to do it. Add the following in your on_key_press function to reset the game when the Escape key is pressed.

if key == arcade.key.ESCAPE:
    self.setup()

Source Code#

Resetting#
  1"""
  2Platformer Game
  3
  4python -m arcade.examples.platform_tutorial.06_reset
  5"""
  6import arcade
  7
  8# Constants
  9SCREEN_WIDTH = 800
 10SCREEN_HEIGHT = 600
 11SCREEN_TITLE = "Platformer"
 12
 13# Constants used to scale our sprites from their original size
 14TILE_SCALING = 0.5
 15
 16# Movement speed of player, in pixels per frame
 17PLAYER_MOVEMENT_SPEED = 5
 18GRAVITY = 1
 19PLAYER_JUMP_SPEED = 20
 20
 21
 22class MyGame(arcade.Window):
 23    """
 24    Main application class.
 25    """
 26
 27    def __init__(self):
 28
 29        # Call the parent class and set up the window
 30        super().__init__(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_TITLE)
 31
 32        # Variable to hold our texture for our player
 33        self.player_texture = None
 34
 35        # Separate variable that holds the player sprite
 36        self.player_sprite = None
 37
 38        # SpriteList for our player
 39        self.player_list = None
 40
 41        # SpriteList for our boxes and ground
 42        # Putting our ground and box Sprites in the same SpriteList
 43        # will make it easier to perform collision detection against
 44        # them later on. Setting the spatial hash to True will make
 45        # collision detection much faster if the objects in this
 46        # SpriteList do not move.
 47        self.wall_list = None
 48
 49    def setup(self):
 50        """Set up the game here. Call this function to restart the game."""
 51        self.player_texture = arcade.load_texture(":resources:images/animated_characters/female_adventurer/femaleAdventurer_idle.png")
 52
 53        self.player_sprite = arcade.Sprite(self.player_texture)
 54        self.player_sprite.center_x = 64
 55        self.player_sprite.center_y = 128
 56
 57        self.player_list = arcade.SpriteList()
 58        self.player_list.append(self.player_sprite)
 59
 60        self.wall_list = arcade.SpriteList(use_spatial_hash=True)
 61
 62        # Create the ground
 63        # This shows using a loop to place multiple sprites horizontally
 64        for x in range(0, 1250, 64):
 65            wall = arcade.Sprite(":resources:images/tiles/grassMid.png", scale=TILE_SCALING)
 66            wall.center_x = x
 67            wall.center_y = 32
 68            self.wall_list.append(wall)
 69
 70        # Put some crates on the ground
 71        # This shows using a coordinate list to place sprites
 72        coordinate_list = [[512, 96], [256, 96], [768, 96]]
 73
 74        for coordinate in coordinate_list:
 75            # Add a crate on the ground
 76            wall = arcade.Sprite(
 77                ":resources:images/tiles/boxCrate_double.png", scale=TILE_SCALING
 78            )
 79            wall.position = coordinate
 80            self.wall_list.append(wall)
 81
 82        # Create a Platformer Physics Engine, this will handle moving our
 83        # player as well as collisions between the player sprite and
 84        # whatever SpriteList we specify for the walls.
 85        # It is important to supply static to the walls parameter. There is a
 86        # platforms parameter that is intended for moving platforms.
 87        # If a platform is supposed to move, and is added to the walls list,
 88        # it will not be moved.
 89        self.physics_engine = arcade.PhysicsEnginePlatformer(
 90            self.player_sprite, walls=self.wall_list, gravity_constant=GRAVITY
 91        )
 92
 93        self.background_color = arcade.csscolor.CORNFLOWER_BLUE
 94
 95    def on_draw(self):
 96        """Render the screen."""
 97
 98        # Clear the screen to the background color
 99        self.clear()
100
101        # Draw our sprites
102        self.player_list.draw()
103        self.wall_list.draw()
104
105    def on_update(self, delta_time):
106        """Movement and Game Logic"""
107
108        # Move the player using our physics engine
109        self.physics_engine.update()
110
111    def on_key_press(self, key, modifiers):
112        """Called whenever a key is pressed."""
113
114        if key == arcade.key.ESCAPE:
115            self.setup()
116
117        if key == arcade.key.UP or key == arcade.key.W:
118            if self.physics_engine.can_jump():
119                self.player_sprite.change_y = PLAYER_JUMP_SPEED
120
121        if key == arcade.key.LEFT or key == arcade.key.A:
122            self.player_sprite.change_x = -PLAYER_MOVEMENT_SPEED
123        elif key == arcade.key.RIGHT or key == arcade.key.D:
124            self.player_sprite.change_x = PLAYER_MOVEMENT_SPEED
125
126    def on_key_release(self, key, modifiers):
127        """Called whenever a key is released."""
128
129        if key == arcade.key.LEFT or key == arcade.key.A:
130            self.player_sprite.change_x = 0
131        elif key == arcade.key.RIGHT or key == arcade.key.D:
132            self.player_sprite.change_x = 0
133
134
135def main():
136    """Main function"""
137    window = MyGame()
138    window.setup()
139    arcade.run()
140
141
142if __name__ == "__main__":
143    main()

Run This Chapter#

python -m arcade.examples.platform_tutorial.06_reset