About Blog Data Tools Toys

Pyglet Tutorial Part 1

Introduction

In this tutorial, we will create a basic 2D pyglet game. Part 1 will cover setting up a basic game window, drawing a character sprite, and adding movement on mouse click. The final code is available here.

Setting Up the Virtual Environment

When starting a new project, it is best if we start with a clean Python environment. I'm using Python 3.6, but older versions of Python should work as well. First, we want to create a new directory, go to it, and then make a new virtual environment. If you do not already have virtualenv, make sure to pip install it.

pip install virtualenv
mkdir pyglet_tutorial
cd pyglet_tutorial
virtualenv ./

This will create a new virtual environment in our project directory. To activate the environment, we can use this command from the directory it lives in:

source bin/activate

Once we have activated our environment, it can be deactivated by typing deactivate. Next, make sure your environment is activated and let's install pyglet.

pip install pyglet==1.3.1

Imports and Making a Window

Great! We should be all ready to start writing our game. Let's start with some imports.

in a new file called main.py:

import os
import pyglet

from pyglet.sprite import Sprite
from pyglet.gl import glClearColor
from pyglet.window import Window

IMAGE_DIR = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'images')

Here we are importing the base of pyglet and a few things we need to get started. Import order doesn't matter so feel free to modify the order to suit your preferences. Next, we need to create a window, give it a background color, and define our draw function.

in main.py:

window = Window(height=800, width=800)
glClearColor(.8, .8, .8, 1)


@window.event
def on_draw():
    window.clear()

We are almost ready to run the game and take a look at what we have so far. We need to create an update function and schedule it to run.

in main.py:

def update(ts):
    pass

if __name__ == '__main__':
    pyglet.clock.schedule(update)
    pyglet.app.run()

Adding a Character

The basic window of the game should now be runnable, albeit without any content. Type python main.py into the console and see what we have. An 800x800 grey window should pop up. Great! You can press escape or the “x” at the top of the screen to exit. With a working window, we are ready to add sprites and controls. Let's start with a Character object.

Note: None of the variables defined below are special to pyglet. They can be called whatever you wish.

in main.py, underneath IMAGE_DIR:

class Character():
    def __init__(self):
        self.x = 400
        self.y = 400
        self.moving = False
        self.move_x = 0
        self.move_y = 0
        self.speed = 5
        self.sprite = Sprite(
            pyglet.image.load(os.path.join(IMAGE_DIR, 'archer.png')),
            self.x, self.y
        )

    def move(self, x, y):
        self.moving = True
        self.move_x = x
        self.move_y = y

    def update(self):
        pass

alt text archer <---- tiny archer Sprite

You can get your own sprite or download and use the one provided above. Make a new folder in your project and call it “images”. Add the sprite there with whatever name you want. If you do not use the “archer.png”, make sure you change that bit of code to match the name of your file!

Now we can add on to the update and on_draw functions to incorporate our new player object.

in main.py, update function:

def update(ts):
    player.update()

in main.py, on_draw function:

@window.event
def on_draw():
    window.clear()
    player.sprite.draw()

in main.py, near our window creation:

window = Window(800, 800)
glClearColor(.8, .8, .8, 1)
player = Character()

Adding movement

Running the code now, the archer sprite should appear on the screen. Having an image on the screen is nice, but what we really want is to interact with the character somehow. Let's make it so that the character moves to wherever the mouse is clicked on screen. To start, we need a way to capture mouse input. Pyglet has some built in functionality for this, once again using a decorator.

in main.py right above our on_draw function:

@window.event
def on_mouse_release(x, y, button, modifiers):
    player.move(x, y)

With each click, our character will be told to move. We just need to turn that location information into movement for our character. We'll do this by giving the Character object a new update method.

in main.py in our Character class:

def update(self):
    if self.moving:
        diff_x = (self.x - self.move_x)
        diff_y = (self.y - self.move_y)
        diff_sum = abs(diff_x) + abs(diff_y)
        if diff_sum < 5.5:
            self.x = self.move_x
            self.y = self.move_y
            self.moving = False
        else:
            mx = self.speed * float(diff_x / diff_sum)
            my = self.speed * float(diff_y / diff_sum)
            self.x -= mx
            self.y -= my
        self.sprite.x = self.x
        self.sprite.y = self.y

This function could be simplified, but I've left it this way to make it easier to understand. What it does is checks to see if the character needs to move. If so, it calculates the degree to which it needs to move in the x and y dimensions. The character has a speed attribute that determines how much it can move each tick. It then calculates the ratio between the x and y dimensions to see how much the speed should be allocated to moving up or over. Once it knows how far to move, the self.x and self.y are updated, along with the location of the sprite. In order to simplify things, if we have to move fewer than 5.5 units (an amount near our max speed), we just move straight to our destination.

Closing Thoughts

That wraps up this first tutorial on creating a basic pyglet setup and creating a character that can move. The next part will deal with enabling our character to attack and generating enemies. If you have any problems or questions, feel free to click on our email link below and send us a message.

Author: Addison Schiller
Published: April 6, 2018