0: Installing Stuff:
Installing the Latest Version of Python:
Download the source tarball for Python. In my case I got version 3.3.3.
Extract and open Terminal and go to the extracted directory.
Run the following commands (from the readme) to install:
    ./configure
    make
    make test
    sudo make install
You can now start python by entering:
    python3
You are now in the equivalent of IDLE.
Installing pygame:
To start programming a game we’ll need to install pygame.
To do this exit GCC using Ctrl+D
Go to the pygame directory extracted from the tarball file
Then run “python config.py”
If you get some errors about missing dependencies, run (from here):
#install dependencies
sudo apt-get install mercurial python3-dev python3-numpy ffmpeg \
    libsdl-image1.2-dev libsdl-mixer1.2-dev libsdl-ttf2.0-dev libsmpeg-dev \
    libsdl1.2-dev  libportmidi-dev libswscale-dev libavformat-dev libavcodec-dev

# Grab source
hg clone https://bitbucket.org/pygame/pygame # This seems to be a modified version to support python3

# Finally build and install
cd pygame
python3 setup.py build
sudo python3 setup.py install

To make sure it worked open python3 in GCC using: “python3”
Then try to import pygame using “import pygame”
If it imported, you can check the version using: “pygame.ver”
Getting Started:
Unfortunately, when I try to load *.png using pygame.image.load I get an error:
    "pygame.error: File is not a Windows BMP file"
Trying a *.bmp file works fine… According to the Pygame documentation for images:
    "The image module is a required dependency of Pygame, but it only optionally 
supports any extended file formats. By default it can only load uncompressed BMP 
images. When built with full image support, the pygame.image.load()function can 
support the following formats."
You can use pygame.image.get_extended() to check the extended file support. If it returns 0, means that there aren’t any further supported image types.
After some more effort trying to install PIL and then recompile and install Python3.3 a gave up and reverted back to version 2.6 which seems to be compatible with pygame, including loading .png files!
Later found this: “Pygame for Linux also only supports Python 2, not Python 3.”. Dang it!
***

1. Creating a Window:
The first thing we’ll want to do is import the pygame and sys libraries. We’ll then create the game window (or display surface) using pygame.display.set_mode()
pygame.display.set_mode()
Initialize a window or screen for display
set_mode(resolution=(0,0), flags=0, depth=0) -> Surface

This function will create a display Surface. The arguments passed in are requests for a display type. The actual created display will be the best possible match supported by the system.
The resolution argument is a pair of numbers representing the width and height. The flags argument is a collection of additional options. The depth argument represents the number of bits to use for color.
The Surface that gets returned can be drawn to like a regular Surface but changes will eventually be seen on the monitor.
If no resolution is passed or is set to (0, 0) and pygame uses SDLversion 1.2.10 or above, the created Surface will have the same size as the current screen resolution. If only the width or height are set to 0, the Surface will have the same width or height as the screen resolution. Using a SDL version prior to 1.2.10 will raise an exception.
It is usually best to not pass the depth argument. It will default to the best and fastest color depth for the system. If your game requires a specific color format you can control the depth with this argument. Pygame will emulate an unavailable color depth which can be slow.
When requesting fullscreen display modes, sometimes an exact match for the requested resolution cannot be made. In these situations pygame will select the closest compatible match. The returned surface will still always match the requested resolution.
The flags argument controls which type of display you want. There are several to choose from, and you can even combine multiple types using the bitwise or operator, (the pipe “|” character). If you pass 0 or no flags argument it will default to a software driven window. Here are the display flags you will want to choose from:

pygame.FULLSCREEN    create a fullscreen display
pygame.DOUBLEBUF     recommended for HWSURFACE or OPENGL
pygame.HWSURFACE     hardware accelerated, only in FULLSCREEN
pygame.OPENGL        create an OpenGL renderable display
pygame.RESIZABLE     display window should be sizeable
pygame.NOFRAME       display window will have no border or controls

For example:

# Open a window on the screen
screen_width=700
screen_height=400
screen=pygame.display.set_mode([screen_width,screen_height])
We all so need to stop the program from exiting straight away, so we have a chance to see the display surface.This is implemented using the concept of a main loop.
The Main/Game Loop:
The main loop in the program is an infinite loop where the display is continuously updating . In this loop the code does three things:
  1. Handles events.
  2. Updates the game state.
  3. Draws the game state to the screen.
The game state is simply a way of referring to a set of values for all the variables in a game program. In many games, the game state includes the values in the variables that tracks the player’s health, position of any enemies, or whose turn it is. Whenever something happens like the player taking damage, or an enemy moves, or something happens in the game world we say that the game state has changed.
If you’ve ever played a game that let you saved, the “save state” is the game state at the point that you’ve saved it. In most games, pausing the game will prevent the game state from changing.

Since the game state is usually updated in response to events (such as mouse clicks or keyboard presses) or the passage of time, the game loop is constantly checking and re-checking many times a second for any new events that have happened. Inside the main loop the code checks which events have been created by calling the pygame.event.get() function). The main loop also has code that updates the game state based on which events have been created. This is usually called event handling.”

pygame.event.get()
get events from the queue
get() -> Eventlist
get(type) -> Eventlist
get(typelist) -> Eventlist

This will get all the messages and remove them from the queue. If a type or sequence of types is given only those messages will be removed from the queue.
If you are only taking specific events from the queue, be aware that the queue could eventually fill up with the events you are not interested.

Once an Eventlist has be retrieved, the list can be queried to see which events have occured as well as any information particular to that event. Here are some important events types:


QUIT             none
KEYDOWN          unicode, key, mod
KEYUP            key, mod
MOUSEMOTION      pos, rel, buttons
MOUSEBUTTONUP    pos, button
MOUSEBUTTONDOWN  pos, button

The code:

span { font-family: ‘Courier New’; font-size: 10pt; color: #000000; } .sc0 { } .sc1 { color: #008000; } .sc2 { color: #FF0000; } .sc5 { font-weight: bold; color: #0000FF; } .sc10 { font-weight: bold; color: #000080; } .sc11 { }
import pygame;import sys; #required to close/exit the program win_width = 100; win_height = 50;screen = pygame.display.set_mode((win_width, win_height));running = True; #flag for the main loop while running: for event in pygame.event.get(): if event.type == pygame.QUIT: running = False; #pygame.quit(); #I had to add this for a cleaner exit when using IDLE on Windows sys.exit();
***
2. A Simple Example – Moving an Image:
Lets have a look at an example. We’ll start by loading an image using pygame.image.load():
load new image from a file
load(filename) -> Surface
load(fileobj, namehint=””) -> Surface

Load an image from a file source. You can pass either a filename or a Python file-like object.
Pygame will automatically determine the image type (e.g., GIF or bitmap) and create a new Surface object from the data. In some cases it will need to know the file extension (e.g., GIF images should end in ”.gif”). If you pass a raw file-like object, you may also want to pass the original filename as the namehint argument.
The returned Surface will contain the same color format, colorkey and alpha transparency as the file it came from. You will often want to call Surface.convert() with no arguments, to create a copy that will draw more quickly on the screen.
For alpha transparency, like in .png images use the convert_alpha()method after loading so that the image has per pixel transparency.

Surfaces:
So, when an image is loaded, it is loaded onto a surface… what exactly is a surface? “Surface objects are objects that represent a rectangular 2D image. The pixels of the Surface object can be” manipulated using drawing functions and once ready can then be displayed on the screen. “The window border, title bar, and buttons are not part of the display Surface object.”
One important Surface object is the one returned by pygame.display.set_mode() is called the display Surface. “Anything that is drawn on the display Surface object will be displayed on the window when the pygame.display.update() [or pygame.display.flip()] function is called.” A surface (or frame) will generally be prepared in computer memory, and then once it is complete it will be transferred to the computer screen (an exception was when I was debugging in OpenGL – It was helpful to see what was stored on the surface as I was stepping through).
pygame.display.update()
Update portions of the screen for software displays
update(rectangle=None) -> None
update(rectangle_list) -> None

This function is like an optimized version of pygame.display.flip() for software displays. It allows only a portion of the screen to updated, instead of the entire area. If no argument is passed it updates the entire Surface area like pygame.display.flip().
You can pass the function a single rectangle, or a sequence of rectangles. It is more efficient to pass many rectangles at once than to call update multiple times with single or a partial list of rectangles. If passing a sequence of rectangles it is safe to include None values in the list, which will be skipped.
This call cannot be used on pygame.OPENGL displays and will generate an exception.

pygame.display.flip()
Update the full display Surface to the screen
flip() -> None

This will update the contents of the entire display. If your display mode is using the flags pygame.HWSURFACE and pygame.DOUBLEBUF, this will wait for a vertical retrace and swap the surfaces. If you are using a different type of display mode, it will simply update the entire contents of the surface.
When using an pygame.OPENGL display mode this will perform a gl buffer swap.

Ok, if we can only display the display Surface, how do we display the surface our image has been loaded onto? “If you want the images on other Surface objects to appear on the screen, you must “blit” them (that is, copy them) to the display Surface object with the blit() method”.
blit()
draw one image onto another
blit(source, dest, area=None, special_flags = 0) -> Rect

Draws a source Surface onto this Surface. The draw can be positioned with the dest argument. Dest can either be pair of coordinates representing the upper left corner of the source. A Rect can also be passed as the destination and the topleft corner of the rectangle will be used as the position for the blit. The size of the destination rectangle does not effect the blit.
An optional area rectangle can be passed as well. This represents a smaller portion of the source Surface to draw.

Putting this into practice:
Ok, we now have the steps we need to display an image:
  1. Create a main “display surface” using pygame.display.set_mode().
  2. Load an image onto a new surface using pygame.image.load().
  3. Blit the image surface onto the “display surface” using pygame.Surface.blit().
  4. Display the main display surface using pygame.display.update() or pygame.display.flip().
import pygame, sys;pygame.init(); # Create the display surfacewin_width = 200; win_height = 200;screen = pygame.display.set_mode((win_width, win_height)); # Load imageimg = pygame.image.load(“pygame.png”); # Blit image onto the display surfacescreen.blit(img, (win_width/2,win_height/2)); # update the displaypygame.display.update(); # Start main looprunning = True; #flag for the main loopwhile running: for event in pygame.event.get(): if event.type == pygame.QUIT: running = False; sys.exit();

 

 

Moving about:

To move our python about we will need to add some keyboard event checks and add some variables for where to draw the image:

span { font-family: ‘Courier New’; font-size: 10pt; color: #000000; } .sc0 { } .sc1 { color: #008000; } .sc2 { color: #FF0000; } .sc5 { font-weight: bold; color: #0000FF; } .sc10 { font-weight: bold; color: #000080; } .sc11 { }

while running: for event in pygame.event.get(): if event.type == pygame.QUIT: running = False; if event.type == pygame.KEYDOWN: if event.key == pygame.K_RIGHT: x_pos += 5; if event.key == pygame.K_LEFT: x_pos -= 5; if event.key == pygame.K_UP: y_pos += 5; if event.key == pygame.K_DOWN: y_pos -= 5; # Blit image onto the display surface screen.blit(img, (x_pos,y_pos)); # update the display pygame.display.update();

 

 

Improvements:
We can now move the python around the screen but there are a couple of problems:
  • We are not clearing the screen so some of the image at the last position is retained every time we press an arrow. We can fix this by clearing the screen with a background colour each iteration of the main loop. This can be achieved using the fill() function.
  • Due to the inverted nature of the screen coordinates K_UP and K_DOWN are the wrong way round.
  • We might want the movement to be more fluid an the pythons position to update whilst we hold down the directional arrows. To do this we can either keep track of which keys are being pressed by updating flags when KEYDOWN and KEYUP events occur, or, we can use pygame’s implementation of this: pygame.key.get_pressed().
  • We can also replace some of the if’s with elif’s to improve efficiency (as the python can’t move both up and down or both right and left).

 

fill()

 

fill Surface with a solid color
fill(color, rect=None, special_flags=0) -> Rect

Fill the Surface with a solid color. If no rect argument is given the entire Surface will be filled. The rect argument will limit the fill to a specific area. The fill will also be contained by the Surface clip area.
The color argument can be either a RGB sequence, a RGBA sequence or a mapped color index. If using RGBA, the Alpha (A part of RGBA) is ignored unless the surface uses per pixel alpha (Surface has the SRCALPHA flag).
An optional special_flags is for passing in new in 1.8.0: BLEND_ADD, BLEND_SUB, BLEND_MULT, BLEND_MIN, BLEND_MAX new in 1.8.1: BLEND_RGBA_ADD, BLEND_RGBA_SUB, BLEND_RGBA_MULT, BLEND_RGBA_MIN, BLEND_RGBA_MAX BLEND_RGB_ADD, BLEND_RGB_SUB, BLEND_RGB_MULT, BLEND_RGB_MIN, BLEND_RGB_MAX With other special blitting flags perhaps added in the future.
This will return the affected Surface area.

 

pygame.key.get_pressed()
get the state of all keyboard buttons
get_pressed() -> bools

Returns a sequence of boolean values representing the state of every key on the keyboard. Use the key constant values to index the array. A True value means the that button is pressed.
Getting the list of pushed buttons with this function is not the proper way to handle text entry from the user. You have no way to know the order of keys pressed, and rapidly pushed keys can be completely unnoticed between two calls to pygame.key.get_pressed(). There is also no way to translate these pushed keys into a fully translated character value. See the pygame.KEYDOWN events on the event queue for this functionality.

span { font-family: ‘Courier New’; font-size: 10pt; color: #000000; } .sc0 { } .sc1 { color: #008000; } .sc2 { color: #FF0000; } .sc3 { color: #808080; } .sc5 { font-weight: bold; color: #0000FF; } .sc10 { font-weight: bold; color: #000080; } .sc11 { }

import pygame, sys;pygame.init(); # Create the display surfacewin_width = 200; win_height = 200;screen = pygame.display.set_mode((win_width, win_height)); # Load imageimg = pygame.image.load(“pygame.png”); # Python propertiesx_pos = win_width/2;y_pos = win_height/2;speed = 0.05; # Start main looprunning = True; #flag for the main loopwhile running: screen.fill((0,0,0)); for event in pygame.event.get(): if event.type == pygame.QUIT: running = False; keys = pygame.key.get_pressed() if (keys[pygame.K_LEFT]): x_pos -= speed elif (keys[pygame.K_RIGHT]): x_pos += speed if (keys[pygame.K_UP]): y_pos -= speed elif (keys[pygame.K_DOWN]): y_pos += speed # Blit image onto the display surface screen.blit(img, (x_pos,y_pos)); # update the display pygame.display.update(); sys.exit();
 

***

3. References and Further Reading:

Similar:

Advertisements