Tagged: pygame

PyGame : Tutorial PT2 (Drawing objects to the screen)

So its that time of the week … I apologise if the tutorials are slow in being published as I’m working on a few other projects in my spare time and want these tutorials to be correctly written so I don’t get you in to any bad habits or poor coding situations … (I’ve been reading the documentation for pygame A LOT) so without further a do, here’s pygame tutorial part 2. (Click here for part 1)

In the last tutorial we covered setting up the basic game window and initialising pygame.

In this tutorial were going to be drawing some simple shapes and text to the screen and moving them around using the keyboard.

There are some minor modifications to last weeks code I will explain these as we go along.

normal = from original tutorial
bold = added or modified

import pygame
from pygame.locals import *

wWIDTH = 640 # game window width
wHEIGHT = 480 # game window height
loc = [0, 0] # location data

The above code is pretty much the same as last week apart from the loc[0,0] (loc[x,y]) variable this is going to be used to store the xy location of the player.
Here we set the variables both equal to zero. These numbers represent the players starting position so x=0 and y=0 would result in the player starting in the top left hand corner.

def main():

r = 1
while(1): # do for a while (game loop)

for event in pygame.event.get(): # handle events

if event.type == QUIT: # ctrl+c

r = 0 # return 0 = (game is over)

elif event.type == KEYDOWN: # down arrow

if event.key == K_ESCAPE:

r = 0 # return 0 = (game is over)

if event.key == K_q: # q key pressed

r = 0

if event.key == K_LEFT:

loc[0] = loc[0] – 1 # move left

if event.key == K_RIGHT:

loc[0] = loc[0] + 1 # move right

if event.key == K_UP:

loc[1] = loc[1] – 1 # move up

if event.key == K_DOWN:

loc[1] = loc[1] + 1 # move down

So whats changed above well again most of the code is exactly the same but this time were trapping keys to trigger more events. In the first tutorial we trapped the escape key to make the game exit. Here we are trapping the arrow keys to change the variables held in the (loc) location variable. If the key is pressed down then add or subtract to the loc[x,y] variable depending on which key is being pressed (UP, DOWN, LEFT or RIGHT).

We will use the loc variable later to draw the objects to the screen.

# keep location visible on the screen
# check loc is not out of bounds (screen/window size)

if loc[0] < 0:

loc[0] = wWIDTH

if loc[0] > wWIDTH:

loc[0] = 0

if loc[1] < 0:

loc[1] = wHEIGHT

if loc[1] > wHEIGHT:

loc[1] = 0

The above code checks that the numbers stored in the loc(x,y) variable are within the bounds of the screen. If the bounds are exceeded the code keeps them on the screen. So if the object goes off the left of the screen it will appear on the right and also if the object / player moves off the bottom they will appear at the top and vice versa. The loc positions are compared to the window bounds (the variables we defined at the top of the code. wWIDTH amd wHEIGHT)

#fill the screen with black
GSURF.fill((0, 0, 0))

#draw stuff here …
#circle(Surface, color, pos, radius, width=0) -> Rect
#rect(top,left,width,height)
pygame.draw.circle(GSURF, (0, 255, 0), (loc[0], loc[1]), 6, 2)
pygame.draw.circle(GSURF, (255, 0, 0), (loc[0], loc[1]), 4)

pygame.draw.rect(GSURF, (0, 0, 255), [loc[0]-10, loc[1]-10, 20, 20], 3)
pygame.draw.ellipse(GSURF, (0,255,0), [loc[0]-30, loc[1]-10, 60, 20], 1)
pygame.draw.arc(GSURF, (255,0,0), [loc[0]-40, loc[1]-40, 80, 80], 3.141, 2*3.141, 1)
pygame.draw.line(GSURF, (0,0,255), [loc[0]-50, loc[1]-50], [loc[0]+50, loc[1]+50] , 1)

Here’s the good stuff … first of all we fill the canvas / surface black. Its important to draw the background colour first, if we drew the bg colour last we would just end up with a black screen no matter what we’d drawn underneath / first.

pygame.draw.circle(GSURF, (0, 255, 0), (loc[0], loc[1]), 6, 2)
draws a green circle to the game surface at the location held in loc[x,y] make the radius 6 pixels and make the stroke / border 2 pixels wide
so this will not fill the circle

pygame.draw.circle(GSURF, (255, 0, 0), (loc[0], loc[1]), 4)
The above code is the same as the last snippet but will fill the circle in red (if the stroke isn’t provided the circle is filled.)

pygame.draw.rect(GSURF, (0, 0, 255), [loc[0]-10, loc[1]-10, 20, 20], 3)
Draws a red rectangle to the screen. Again the last parameter is optional if you omit this parameter the rectangle will be filled red.

pygame.draw.ellipse(GSURF, (0,255,0), [loc[0]-30, loc[1]-10, 60, 20], 1)
Draws an ellipse to the screen. Optional border parameter.

pygame.draw.arc(GSURF, (255,0,0), [loc[0]-40, loc[1]-40, 80, 80], 3.141, 2*3.141, 1)
Draws an arc to the screen. Last parameter represents line thickness.
NB. Arc start point and endpoints are measured in radiants.
These sound complicated but they are really easy.
Basically a circle contains 6.28 radiants. (2*pi).
A start point of 0 and endpoint of 3.141 would draw half a circle.
A start point of 0 and endpoint of 6.282 would draw a whole circle.
Degrees to radiants = 6.282 / 360 * Degrees

pygame.draw.line(GSURF, (0,0,255), [loc[0]-50, loc[1]-50], [loc[0]+50, loc[1]+50] , 1)
Draws a line from one point to another.

All the above shapes are drawn @ the location of the player.

myfont = pygame.font.SysFont(“monospace”, 15)
label = myfont.render(“Frame rate : ” + str(int(GCLOCK.get_fps())), 1, (255,255,0))
GSURF.blit(label, (loc[0], loc[1]))

# check the ‘pygame draw’ documentation for more information on other you can draw to the screen
# above are most of the basics.
pygame.display.flip() # update the screen
GCLOCK.tick() # update the clock

if r != 1:

break

return r

Above we define a font variable as myfont we use the default pygame fonts (which are all available in the documentation.) Next we make a label variable this variable is going to contain the frame rate as this variable isnt a string we have to use str() to convert the fps from a number to a string. (NB. I think I made a school boy error above. Fps is returned as an int, there is no need for the int() function u can remove this. Edit the code so it looks like this str(GCLOCK.get_fps()) ) Then we blit the label object to the screen at the specified location. display.flip() is used for double buffering (which is a whole other topic) ill cover it briefly here if we replaced the last frames image with the current one we were drawing in the loop bad things would happen basically double buffering displays the last drawn image until the next has been drawn and is ready to be displayed. Double buffering cuts out screen flicker.

tick() is then called to update the pygame clock and advance to the next frame. No numbers are passed in here. Before we were passing a number which will restrict or slow the pace of your game by a set amount depending on what number you use. This will also help us to determine accurately how many cycles the game is running at per second accurately.

if __name__ == “__main__”: # main function call

r = 1 # set variable for return value

pygame.init() # initialise python pygame

GCLOCK = pygame.time.Clock() # set game clock

GSURF = pygame.display.set_mode((wWIDTH, wHEIGHT)) # main game surface

pygame.key.set_repeat(1, 0) # repeat keys delay by 0

while r == 1: # quit on 0

r = main() # get return value from main loop (1 == OK … 0 == exit)

pygame.quit()

Here is the last bit of code (that initialises the whole game rather important) only one line changed here which is the keyboard repeat rate, this forces the keyboard to repeat key presses if they are held down for a specified period of time.

That concludes tutorial part two.

Here is a screen shot of what the code does …
Screenshot from 2013-07-09 01:58:41

Here is a link to the code …
GIST : https://gist.github.com/caffeinemonster/5953538
PASTE BIN : http://pastebin.com/sxchRZx7

PyGame : Tutorial PT1 (Setup & Initialisation)

I would consider this my first proper post hehe … I started this blog to make life easier when doing videos about code sometimes the screen capture and editing that goes in to a short clip can be painful and consume a lot of my spare time. Here ill be able to waffle on about code and linux to my hearts content (with the ability to access the articles and update things after they have been published).

So this hopefully will turn in to some kind of archive generated by hakology plus various odds and ends I find lying about the interwebz.

I digress … keeping on point this is a python pygame introduction to simple 2D game engines (with a view to move on to opengl and 3D graphics at some later point) for this tutorial you will need the following:

Python 2.7

Python- Pygame Librarys and Modules

IDE (It doesnt really matter what you use – at the moment I’m really enjoying ninja-ide)

This tutorial is for linux users, the development rig I’m using at the moment is Debian Jessie (Test/Dev Release)

Ok so down to business if your rocking debian jessie or similar you shouldnt have too many problems getting up and running.

First install python

sudo apt-get install python2.7

Now install pygame

sudo apt-get install python-pygame

Now install ninja-ide

sudo apt-get install ninja-ide

Hopefully that all went well 🙂 (if it didn’t please consult google.com/pygame/python/debian documentation)

Now in your home folder we need to create a folder to store everything so pop a terminal and make a directory

mkdir pygame
cd pygame
touch tutorial1.py
ninja-ide tutorial1.py

Now you should have created a folder and a file in the folder and opened that file with ninja-ide

This is where the fun begins.

Add the following to the first lines of your python file ….

import pygame
from pygame.locals import *

The lines above tell the python interpreter to import and load all the librarys and variables from pygame.

Next we need to set some variable to store how big we’d like to make our game window.

wWIDTH = 640
wHEIGHT = 480

Right now were ready to add the first function that is called when the file is executed

if __name__ == “__main__”: # main function call

r = 1 # set variable for return value
pygame.init() # initialise python pygame
GCLOCK = pygame.time.Clock() # set game clock
GSURF = pygame.display.set_mode((wWIDTH, wHEIGHT)) # main game surface
while r != 0: # quit if return not equal to 0 (0 = game exit, 1 = restart main loop)

r = main() # get return value from main loop (1 == OK … 0 == exit)

Ok so lets explain the code … the first line of the above block is defacto python code you will find this in (almost) every python script you encounter, the second line defines a variable called ‘r’ and sets it equal to 1 this value is used later to determine if the game should continue or quit. GCLOCK is a variable used to store pygames clock which is used later for frame rate calculations and game speed. GSURF is the game surface ie. the area or the screen we are going to be drawing to notice we pass in the pre defined screen sizes we set at the top of the script. The while loop and main game call will not quit until the return value is equal to 0. The line within the while loop is the main game loop call when we call this function we expect a return value of either 1 or 0.

Right now to add the main game loop …

When you add this code it needs to go below the variables we created earlier but above the first function call.

def main():

r = 1
while(1): # do for a while (game loop)

for event in pygame.event.get(): # handle events

if event.type == QUIT: # ctrl+c

r = 0 # return 0 = (game is over)

elif event.type == KEYDOWN: # down arrow

if event.key == K_ESCAPE:

r = 0 # return 0 = (game is over)

if event.key == K_q: # q key pressed

r = 0

GSURF.fill((0, 0, 0))

if r != 1: #check value of r

break #exit main game loop

return r

Ok so the above code basically runs and keeps the main game window open it loops forever until the escape key is detected if the escape key is detected or quit program event then the window will close.

You can now test the script by pressing play in the ninja-ide tool bar.

or entering the following in the command line …

cd ~
cd pygame
python tutorial1.py

Enjoy your nice blank window opening and closing.

Whoot well done you and stay tuned for part two coming very very soon 🙂

Pastebin link to raw code – http://pastebin.com/vzACDi3v