[Tutorial] How to build Python for Android with Ubuntu and Buildozer

Welcome,

I’m Aron, from Byte::Debugger();, and in this post we are going to see how to compile Python targeting Android with Ubuntu(tested on Ubuntu 14.04) and Buildozer!! This process works with others Linux distros, but I’ll need to find the appropriate package. So, let’s start.

Continue Reading

[Tutorial] Flappy Ship, a step-by-step guide to making an android game: Part 1

Introduction

We all dream of making an app that’s wildly popular. It goes viral and gives you enough income to quit your day job. Flappy Bird was an app that managed to get big, and I will give you all the tools to reproduce it.

Flappy Ship is a clone of the wildly popular Flappy Bird. You guide your ship through an asteroid field. Tap to make the ship float up, and avoid touching asteroids. In this quick tutorial we will go over the following topics:

* Drawing graphics

* Moving graphics

* Handling touch input

* Detecting collisions

* Buttons

Subscribe to be notified of future tutorials. Part 2 will focus on animations and menus. If you get stuck somewhere, have a question, or feedback please leave a comment or send me a message. I’d love to help you get through this tutorial.

If you haven’t gotten kivy up and running yet, check out my previous posts:

Writing the code

Remember to use the kivy documentation at kivy.org.

Step 1: Load the essential modules you’ll use


import kivy
kivy.require('1.7.2')

from kivy.app import App
from kivy.uix.widget import Widget
from kivy.uix.label import Label
from kivy.uix.button import Button
from kivy.core.window import Window
from kivy.properties import NumericProperty
from kivy.clock import Clock
from kivy.graphics import Rectangle
from random import

Step 2: Set desired graphic settings


from kivy.config import Config
Config.set('graphics','resizable',0) #don't make the app re-sizeable
#Graphics fix
 #this fixes drawing issues on some phones
Window.clearcolor = (0,0,0,1.) 

Step 3: Create your classes

The game consists of the ship, asteroids, and the main application. We create a class for each of these, and we create a class to for buttons. Since multiple objects in a game will handle graphics, its useful to have a generic class that sets up widgets in kivy in a way that they can be displayed and moved around the screen. The kivy way of doing things involves using a .kv file, but I prefer to have everything done in python. This means that it’s slightly more difficult to place graphics initially, but I find it much easier to move them around and keep track of things when only dealing with python code.

Because I want to do all of the coding in python and not use the kv scripting language, the following code is extremely important. It took me dozens of hours of googling around to learn how to do this properly. It is the most important snippet of code you’ll find on this blog, and I hope it serves you well.


class WidgetDrawer(Widget):
    #This widget is used to draw all of the objects on the screen
    #it handles the following:
    # widget movement, size, positioning
    #whever a WidgetDrawer object is created, an image string needs to be specified
    #example:    wid - WidgetDrawer('./image.png')

    #objects of this class must be initiated with an image string
#;You can use **kwargs to let your functions take an arbitrary number of keyword arguments
#kwargs ; keyword arguments
    def __init__(self, imageStr, **kwargs): 
        super(WidgetDrawer, self).__init__(**kwargs) #this is part of the **kwargs notation
#if you haven't seen with before, here's a link http://effbot.org/zone/python-with-statement.html     
        with self.canvas: 
#setup a default size for the object
            self.size = (Window.width*.002*25,Window.width*.002*25) 
#this line creates a rectangle with the image drawn on top
            self.rect_bg=Rectangle(source=imageStr,pos=self.pos,size = self.size) 
#this line calls the update_graphics_pos function every time the position variable is modified
            self.bind(pos=self.update_graphics_pos) 
            self.x = self.center_x
            self.y = self.center_y
#center the widget 
            self.pos = (self.x,self.y) 
#center the rectangle on the widget
            self.rect_bg.pos = self.pos 

    def update_graphics_pos(self, instance, value):
#if the widgets position moves, the rectangle that contains the image is also moved
        self.rect_bg.pos = value  
#use this function to change widget size        
    def setSize(self,width, height): 
        self.size = (width, height)
 #use this function to change widget position    
    def setPos(xpos,ypos):
        self.x = xpos
        self.y = ypos

The above class is used to draw the graphics. It also makes the image moveable, and updates the drawing of the image every time the position property is modified. This means that changing the x position of your widget also changes the x position of its image. Every widget with a drawing will inherit this class, to save time and clean up the code.

Our next two classes will use the WidgetDrawer class to facilitate drawing images. They will be the ship and asteroid classes.

class Asteroid(WidgetDrawer):
    #Asteroid class. The flappy ship will dodge these
    velocity_x = NumericProperty(0) #initialize velocity_x and velocity_y
    velocity_y = NumericProperty(0) #declaring variables is not necessary in python
 #update the position using the velocity defined here. every time move is called we change the position by velocity_x  
    def move(self):                    
        self.x = self.x + self.velocity_x 
        self.y = self.y + self.velocity_y 
    def update(self): 
#the update function moves the astreoid. Other things could happen here as well (speed changes for example)       
        self.move() 

The next class is for the ship. It looks similar to the asteroid class.

class Ship(WidgetDrawer):
    #Ship class. This is for the main ship object. 
    #velocity of ship on x/y axis

    impulse = 3 #this variable will be used to move the ship up
    grav = -0.1 #this variable will be used to pull the ship down

    velocity_x = NumericProperty(0) #we wont actually use x movement
    velocity_y = NumericProperty(0) 

    def move(self):                    
        self.x = self.x + self.velocity_x 
        self.y = self.y + self.velocity_y 

        #don't let the ship go too far
        if self.y  Window.height*0.95: #don't let the ship go up too high
            self.impulse = -3

    def determineVelocity(self):
        #move the ship up and down
        #we need to take into account our acceleration
        #also want to look at gravity
        self.grav = self.grav*1.05  #the gravitational velocity should increase
        #set a grav limit
        if self.grav < -4: #set a maximum falling down speed (terminal velocity)
            self.grav = -4
        #the ship has a propety called self.impulse which is updated
        #whenever the player touches, pushing the ship up
        #use this impulse to determine the ship velocity
        #also decrease the magnitude of the impulse each time its used

        self.velocity_y = self.impulse + self.grav
        self.impulse = 0.95*self.impulse #make the upward velocity decay

    def update(self):
        self.determineVelocity() #first figure out the new velocity
        self.move()              #now move the ship

The next class will be used to streamline buttons. For now we will have just one button. More are planned for future versions.

class MyButton(Button):
    #class used to get uniform button styles
    def __init__(self, **kwargs):
        super(MyButton, self).__init__(**kwargs)
 #all we're doing is setting the font size. more can be done later
        self.font_size = Window.width*0.018

Next we will create the main widget for the screen. This widget will have the ship and asteroids drawn on top of it.



class GUI(Widget):
    #this is the main widget that contains the game. 
    asteroidList =[] #use this to keep track of asteroids
    minProb = 1700 #this variable used in spawning asteroids
    def __init__(self, **kwargs):
        super(GUI, self).__init__(**kwargs)
        l = Label(text='Flappy Ship') #give the game a title
        l.x = Window.width/2 - l.width/2
        l.y = Window.height*0.8
        self.add_widget(l) #add the label to the screen

        #now we create a ship object
 #notice how we specify the ship image
        self.ship = Ship(imageStr = './ship.png')
        self.ship.x = Window.width/4
        self.ship.y = Window.height/2
        self.add_widget(self.ship)

    def addAsteroid(self):
        #add an asteroid to the screen 
        #self.asteroid 
        imageNumber = randint(1,4)
        imageStr = './sandstone_'+str(imageNumber)+'.png'      
        tmpAsteroid = Asteroid(imageStr)
        tmpAsteroid.x = Window.width*0.99

        #randomize y position
        ypos = randint(1,16)

        ypos = ypos*Window.height*.0625

        tmpAsteroid.y = ypos
        tmpAsteroid.velocity_y = 0
        vel = 10
        tmpAsteroid.velocity_x = -0.1*vel

        self.asteroidList.append(tmpAsteroid)
        self.add_widget(tmpAsteroid)

    #handle input events
    #kivy has a great event handler. the on_touch_down function is already recognized 
    #and doesn't need t obe setup. Every time the screen is touched, the on_touch_down function is called
    def on_touch_down(self, touch):
        self.ship.impulse = 3 #give the ship an impulse
        self.ship.grav = -0.1 #reset the gravitational velocity

    def gameOver(self): #this function is called when the game ends
        #add a restart button
        restartButton = MyButton(text='Restart')

        #restartButton.background_color = (.5,.5,1,.2)
        def restart_button(obj):
        #this function will be called whenever the reset button is pushed
            print 'restart button pushed'
            #reset game
            for k in self.asteroidList:
                self.remove_widget(k)

                self.ship.xpos = Window.width*0.25
                self.ship.ypos = Window.height*0.5
                self.minProb = 1700
            self.asteroidList = []

            self.parent.remove_widget(restartButton)
 #stop the game clock in case it hasn't already been stopped
            Clock.unschedule(self.update)
 #start the game clock           
            Clock.schedule_interval(self.update, 1.0/60.0) 
        restartButton.size = (Window.width*.3,Window.width*.1)
        restartButton.pos = Window.width*0.5-restartButton.width/2, Window.height*0.5 
        #bind the button using the built-in on_release event
        #whenever the button is released, the restart_button function is called       
        restartButton.bind(on_release=restart_button) 

        #*** It's important that the parent get the button so you can click on it
        #otherwise you can't click through the main game's canvas
        self.parent.add_widget(restartButton)

    def update(self,dt):
                #This update function is the main update function for the game
                #All of the game logic has its origin here 
                #events are setup here as well
        #update game objects
        #update ship
        self.ship.update()
        #update asteroids
        #randomly add an asteroid
        tmpCount = randint(1,1800)
        if tmpCount > self.minProb:            
            self.addAsteroid()
            if self.minProb < 1300:
                self.minProb = 1300
            self.minProb = self.minProb -1

        for k in self.asteroidList:
            #check for collision with ship
            if k.collide_widget(self.ship):
                print 'death'
                #game over routine
                self.gameOver()
                Clock.unschedule(self.update)
                #add reset button
            k.update()

Now it’s time for the final class, our main application class


class ClientApp(App):

    def build(self):
        #this is where the root widget goes
        #should be a canvas
        parent = Widget() #this is an empty holder for buttons, etc

        app = GUI()        
        #Start the game clock (runs update function once every (1/60) seconds
        Clock.schedule_interval(app.update, 1.0/60.0) 
        parent.add_widget(app) #use this hierarchy to make it easy to deal w/buttons
        return parent

Part 4: Run the code

This final piece will get everything started when you run the python script

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

Part 4: Graphic assets

Download the graphics by right-clicking:

What a beautiful rock

What a beautiful rock

What a beautiful rock

What a beautiful rock

What a beautiful rock

What a beautiful rock

What a beautiful rock

What a beautiful rock

Our shiny green ship

Our shiny green ship

Part 5: Put it all together

Go ahead, download the above images, and put all of your code together in a file called main.py. Then run the script!

Part 6: Recap

The above code shows you all the pieces to put together a simple game like Flappy Ship. We were able to handle drawing and positioning graphics using a great deal of the kivy library. The custom class WidgetDrawer ensures that the graphics get updated when the widget moves.

Touch input is extremely easy to use with kivy. The event handler does the heavy lifting, and the code above inside the GUI class above shows you how to use touch input. Collision detection is also very easy because of how kivy is built. Every widget contains the function “collide_widget()” so testing for collision between objects a and b is as easy as “a.collide_widget(b)”. The button example above shows you how to bind a callback to the on_button_release event.

If you are looking for more information about how kivy works, I recommend reading the following:

Events and Properties

Architectural Overview

Kivy Event Loop

[Tutorial] Make your game with Kivy! Introduction to mobile development on android with python and kivy

Ever since I’ve had a smartphone, I’ve been obsessed with making my own apps.  Java development can be slow and clunky, so I decided to use python. If you are a beginner, and you want to know how to make a phone game, follow my lead and start with Kivy! This blog will give you an introduction to mobile development on android using python.

Kivy is a framework that lets you write your app in python and run it on Android/iOS/Linux/MacOS/Windows. It’s designed for touch devices, and handles multi-touch quite nicely.

The main downside is that accessing sensors (accelerometer/gyroscope) and the vibration on your phone takes a bit more work. As I figure these out, I’ll leave a guide here for you.

Get started:
http://kivy.org/#download

Download the Kivy Python for android virtual machine image at the bottom of the page. Using a virtual machine lets you develop in Linux, which is faster. Don’t develop in windows! (I’ve learned this the hard way).

https://www.virtualbox.org/
Install virtual machine software. I use virtualbox.

Follow this  guide to figure out how to get it all up and running
http://archlinux.me/dusty/2012/12/05/building-a-python-kivy-app-in-android-easier-than-it-looks-but-harder-than-it-needs-to-be/