Create a 2D game in Python with the library Arcade


    We continue to share with you the interesting things found about the python. Today we decided to deal with 2D games. This, of course, is a bit simpler than what we have on the Python Developer course , but this is certainly no less interesting.

    Original article -
    Author - Paul Vincent Craven

    Let's go.

    Python is an outstanding language for beginners learning programming. It is also ideal for those who want to “just take and do”, and not spend a lot of time on the template code. Arcade- Python library for creating 2D games, with a low threshold of entry, but very functional in experienced hands. In this article I will explain how to start using Python and Arcade to program games.

    I began to develop on Arcade after teaching the basics of the PyGame library to students. I internally taught PyGames for almost 10 years, and also developed for learning online. PyGames is great, but at some point I realized that I was tired of wasting time trying to justify bugs that never get stuck .

    I was worried about teaching such things as the event loop , which I almost never used. And there was a whole sectionin which I explained why the y-coordinates are rotated in the opposite direction. PyGames was rarely updated and was based on the old SDL 1 library , and not something more modern like OpenGL . I did not count on a bright future.

    In my dreams there was a simple and powerful library that would use new features of Python 3, for example, decorators and type hinting. She was Arcade. Let's see how to start using it.


    Arcade, like many other packages, is available on PyPi , which means you can install Arcade using the pip (or pipenv ) command . If Python is already installed, most likely you can simply open the Windows command line and write:

    pip install arcade

    And on Linux and MacOS:

    pip3 install arcade

    For more detailed installation instructions, read the Arcade installation documentation .

    Simple drawing

    You can open a window and draw a simple drawing with just a few lines of code. As an example, let's draw a smiley like in the image below:

    The script below shows how to do this using the Arcade drawing commands . Note that you do not need to know how to use classes or define functions. Programming with quick visual feedback is a good start for those who are just learning.

    import arcade
    # Задать константы для размеров экрана
    SCREEN_WIDTH = 600
    SCREEN_HEIGHT = 600# Открыть окно. Задать заголовок и размеры окна (ширина и высота)
    arcade.open_window(SCREEN_WIDTH, SCREEN_HEIGHT, "Drawing Example")
    # Задать белый цвет фона.# Для просмотра списка названий цветов прочитайте:# Цвета также можно задавать в (красный, зеленый, синий) и# (красный, зеленый, синий, альфа) формате.
    # Начать процесс рендера. Это нужно сделать до команд рисования
    # Нарисовать лицо
    x = 300
    y = 300
    radius = 200
    arcade.draw_circle_filled(x, y, radius, arcade.color.YELLOW)
    # Нарисовать правый глаз
    x = 370
    y = 350
    radius = 20
    arcade.draw_circle_filled(x, y, radius, arcade.color.BLACK)
    # Нарисовать левый глаз
    x = 230
    y = 350
    radius = 20
    arcade.draw_circle_filled(x, y, radius, arcade.color.BLACK)
    # Нарисовать улыбку
    x = 300
    y = 280
    width = 120
    height = 100
    start_angle = 190
    end_angle = 350
    arcade.draw_arc_outline(x, y, width, height, arcade.color.BLACK, start_angle, 
                            end_angle, 10)
    # Завершить рисование и показать результат
    # Держать окно открытым до тех пор, пока пользователь не нажмет кнопку “закрыть”

    Use of functions

    Of course, writing code in a global context is not the best way. Fortunately, using functions will help improve your code. Below is an example of how to draw a tree in given coordinates (x, y) using the function:

    defdraw_pine_tree(x, y):""" Эта функция рисует елку в указанном месте"""# Нарисовать треугольник поверх ствола.# Необходимы три x, y точки для рисования треугольника.
        arcade.draw_triangle_filled(x + 40, y,       # Point 1
                                    x, y - 100,      # Point 2
                                    x + 80, y - 100, # Point 3
        # Нарисовать ствол
        arcade.draw_lrtb_rectangle_filled(x + 30, x + 50, y - 100, y - 140,

    For a complete example, see the drawing with functions .

    More experienced programmers know that modern programs first load graphic information onto a video card, and then ask it to draw it with a batch file. Arcade supports this . Individual rendering of 10,000 rectangles takes 0.8 seconds. Drawing the same amount of batch file takes less than 0.001 seconds.

    Window class

    Large programs are usually based on the Window class or use decorators . This allows the programmer to write code that controls the drawing, updating, and processing of user input. Below is a template for a program with a window base.

    import arcade
    SCREEN_WIDTH = 800
    SCREEN_HEIGHT = 600classMyGame(arcade.Window):""" Главный класс приложения. """def__init__(self, width, height):
            super().__init__(width, height)
        defsetup(self):# Настроить игру здесьpassdefon_draw(self):""" Отрендерить этот экран. """
            # Здесь код рисункаdefupdate(self, delta_time):""" Здесь вся игровая логика и логика перемещения."""passdefmain():
        game = MyGame(SCREEN_WIDTH, SCREEN_HEIGHT)
    if __name__ == "__main__":

    There are several methods in the Window class that your programs can override to provide functionality. Here is a list of those that are used most often:

    • on_draw: All the code for drawing the screen is here.
    • update: All the code for moving objects and practicing game logic is here. Called about 60 times per second.
    • on_key_press: Handles events at the touch of a button, for example, the movement of a character.
    • on_key_release: Handles events when a button is released, for example, stopping a character.
    • on_mouse_motion: Called every time you move the mouse.
    • on_mouse_press: Called when the mouse is pressed.
    • set_viewport: This function is used in scrollers, when the world is much larger than what is visible on one screen. Calling set_viewport allows the programmer to set the part of the screen that will be visible.


    Sprites is a simple way to create 2D bitmap objects in Arcade. It has methods that allow you to easily draw, move and animate sprites. You can also use sprites to track collisions between objects.

    Sprite creation

    Creating an instance of the Sprite Arcade class is very easy. The programmer needs only the name of the image file on which the sprite will be based, and, optionally, the number of times to enlarge or reduce the image. For example:

    coin = arcade.Sprite("coin_01.png", SPRITE_SCALING_COIN)

    This code creates a sprite using the image coin_01.png. The picture will be reduced to 20% of the original.

    List of sprites

    Sprites are usually organized into lists. They help simplify their management. Sprites in the list will use OpenGl for group batch rendering. The code below sets up the game, where there is a player and a lot of coins that the player must collect. We use two lists - one for the player and one for the coins.

    defsetup(self):""" Настроить игру и инициализировать переменные. """# Создать список спрайтов
        self.player_list = arcade.SpriteList()
        self.coin_list = arcade.SpriteList()
        # Счет
        self.score = 0# Задать игрока и# Его изображение из
        self.player_sprite = arcade.Sprite("images/character.png", 
        self.player_sprite.center_x = 50# Стартовая позиция
        self.player_sprite.center_y = 50
        # Создать монеткиfor i in range(COIN_COUNT):
            # Создать инстанс монеток# и их изображение из
            coin = arcade.Sprite("images/coin_01.png", SPRITE_SCALING_COIN)
            # Задать положение монеток
            coin.center_x = random.randrange(SCREEN_WIDTH)
            coin.center_y = random.randrange(SCREEN_HEIGHT)
            # Добавить монетку к списку 

    We can easily draw all the coins in the list of coins:

    defon_draw(self):""" Нарисовать все """

    Sprite collision tracking

    The function check_for_collision_with_list allows you to see if the sprite comes across another sprite from the list. Use it to see all the coins with which the player sprite intersects. By applying a simple for-cycle, you can get rid of the coin in the game and increase the score.

    defupdate(self, delta_time):# Сгенерировать список всех спрайтов монеток, которые пересекаются с игроком.
        coins_hit_list = arcade.check_for_collision_with_list(self.player_sprite, 
        # Пройтись циклом через все пересекаемые спрайты, удаляя их и увеличивая счет.for coin in coins_hit_list:
            self.score += 1

    A complete example can be found in .

    Game physics

    Many games have physics in one form or another. The simplest, for example, is that top-down games do not allow a player to pass through walls. Platformers add complexity with gravity and moving platforms. Some games use full-fledged physical 2D engines with masses, friction, springs, and so on.

    Top-down games

    For simple games with a top view of the program on the Arcade you need a list of walls (or something similar), through which the player can not pass. I usually call this wall_list. Then a physics engine is created in the installation code of the Window class:

    self.physics_engine = arcade.PhysicsEngineSimple(self.player_sprite, self.wall_list)

    Player_sprite gets a motion vector with two attributes change_x and change_y. Just an example of use - moving a player using the keyboard.

    MOVEMENT_SPEED = 5defon_key_press(self, key, modifiers):"""Вызывается при нажатии пользователем клавиши"""if key == arcade.key.UP:
            self.player_sprite.change_y = MOVEMENT_SPEED
        elif key == arcade.key.DOWN:
            self.player_sprite.change_y = -MOVEMENT_SPEED
        elif key == arcade.key.LEFT:
            self.player_sprite.change_x = -MOVEMENT_SPEED
        elif key == arcade.key.RIGHT:
            self.player_sprite.change_x = MOVEMENT_SPEED
    defon_key_release(self, key, modifiers):"""Вызывается, когда пользователь отпускает клавишу"""if key == arcade.key.UP or key == arcade.key.DOWN:
            self.player_sprite.change_y = 0elif key == arcade.key.LEFT or key == arcade.key.RIGHT:
            self.player_sprite.change_x = 0

    Despite the fact that this code sets the speed of the player, it does not move it. The update method in the Window class calls physics_engine.update (), which will force the player to move, but not through the walls.

    defupdate(self, delta_time):""" Передвижение и игровая логика """

    An example can be fully viewed in .


    The transition to the platform with a side view is quite simple. The programmer needs to switch the physics engine to the PhysicsEnginePlatformer and add a gravity constant.

    self.physics_engine = arcade.PhysicsEnginePlatformer(self.player_sprite,

    To add tiles and blocks that will make up a level, you can use a program like Tiled .

    An example is available in

    Learn by example

    Learning by example is one of the best methods. The library Arcade has a large list of sample programs that can be guided when creating a game. These examples reveal the concepts of games that my online and offline students have been asking for for several years.

    Running demos when Arcade is installed is not at all difficult. At the beginning of the program of each example there is a comment with a command that you need to enter on the command line to run this example. For example:

    python -m arcade.examples.sprite_moving_platforms


    As always, we are waiting for your comments and questions that you can leave here or go to Stas for an open day .

    Also popular now: