SCROLLER GAME TUTORIAL

This tutorial will teach you how to build a basic side scrolling game with Python and Kivy. You will start out by displaying a few basic shapes on the screen, then adding some of the game mechanics, handling user input, and then finally adding nicer graphics and adding the "fun" parts of the game - obstacles, win / lose conditions, and scoring!

Step 0

The first thing we need to do is set up our Kivy environment. Follow the instructions for setup here:

Once everything is installed set up, you should be able to try out the Pong demo, found in the kivy/examples/tutorials directory.


In [ ]:
!python kivy/examples/tutorials/pong/main.py

NOTE: On newer version of Ubuntu, if you see Permissions error messages when you start the tutorial, you may need to run the following in order to allow Kivy to properly see touchscreen / touchpad input devices.


In [ ]:
!sudo chmod o+rx /etc/input*

Step 1

The first thing we want to do is create the basic game setup. In order to run our game, we have to create a Kivy App object, and our root game object, which will control everything else in our game. We also need to create our basic .kv file for our game, where we will some information about the game objects in our game - positions, sizes, colors, etc.


In [ ]:
# Main.py

from kivy.app import App
from kivy.uix.widget import Widget
from kivy.properties import NumericProperty, ReferenceListProperty
from kivy.clock import Clock
from kivy.vector import Vector


class ScrollerGame(Widget):
    def update(self, dt):
        pass


class RectangleMan(Widget):
    velocity_x = NumericProperty(0)
    velocity_y = NumericProperty(0)
    velocity = ReferenceListProperty(velocity_x, velocity_y)

    def move(self):
        pass


class ScrollerApp(App):
    def build(self):
        game = ScrollerGame()
        Clock.schedule_interval(game.update, 1.0/60.0)
        return game


if __name__ == '__main__':
    ScrollerApp().run()

In our code, we build a class RectangleMan which will represent our main character. He has a few properties to manage his current velocity.

class RectangleMan(Widget):
    velocity_x = NumericProperty(0)
    velocity_y = NumericProperty(0)
    velocity = ReferenceListProperty(velocity_x, velocity_y)

The RectangleMan class also has a single method, move which will manipulate the velocity and position of our character on the screen. For now it does nothing, but we'll fill in the details in further steps.

def move(self):
        pass

We also created the ScrollerGame class, which will actually be part of the main event loop of the game, and which will call methods on other game objects to cause things to happen in our game. For now, our update method does nothing, but we will that in later.

class ScrollerGame(Widget):
    def update(self, dt):
        pass

Lastly, to tie it all together, we created our ScrollerApp class, which represents the overall application. This will do a few things to set the game up and get it running. The ScrollerApp class has to inherit from Kivy's App class, and defines just one method - the build method, which Kivy will call for us when setting up the game initially. In the build method, we create an instance of our root game object, ScrollerGame. Then we use Kivy's Clock class to call the ScrollerGame.update method we defined. The Clock class takes the time interval on which to call the update method - in this case we define it as 1.0 / 60.0, which means our game will run at 60 frames per second.

class ScrollerApp(App):
    def build(self):
        game = ScrollerGame()
        Clock.schedule_interval(game.update, 1.0/60.0)
        return game

At the bottom of our script, we use the standard Python trick that allows us to run our module as a script. Here, we simply instantiate our ScrollerApp, and then call the run method that Kivy provides to beginning running the application.


In [ ]:
# scroller.kv

<ScrollerGame>:
    canvas:
        Rectangle:
            pos: 0, 0
            size: self.width, 15

    RectangleMan:
        pos: 0, 15


<RectangleMan>:
    size: 20, 50
    canvas:
        Color:
            rgba: 0, 1, 0, 1
        Rectangle:
            pos: self.pos
            size: self.size

In [ ]: