Sunday, November 25, 2012

Walking Animation with Pygame

My son spent an hour going through a great video from the Films by Kris site.  The video PyGame - Sprite Animation Walk Loop is a great introduction to walking animation and quite rewarding.  My son was able to create the application above in under an hour.

Although the original video has the character walking backward, my son changed the orientation of the character with the pygame.transform.flip method.

It's a fairly minor change.

        if self.direction == "right":
            windowSurface.blit(self.img, (self.x, self.y))
        elif self.direction == "left":
            self.left_img = pygame.transform.flip(self.img, True, False)  
            windowSurface.blit(self.left_img, (self.x, self.y))

More information on Pygame surface transformation is available here.

The tutorial that Films by Kris used is embedded below.

Porting Pygame Apps to Android

Since my son is on Thanksgiving holiday, I taught him two classes today.  I'm sure he would have preferred fishing.   The first class covered how to port one of his earlier Pygame desktop applications to Android.  The process only took an hour.  The game now works on his LG Optimus S Android phone and he can enjoy playing it while lying on his bed or after school with his friends.

His game, dropper, does not use any raster graphics.  Dropper only uses the primitive shapes from the pygame.draw module.  Despite the simple graphics and lack of sound effects, it's one of the most playable games he's developed.  It works quite well on his phone.

Here's an overview of the simple changes.

  • import android module
  • change screen width and height to 480, 320 (low-end phone screen)
  • change player size to make it easier to dodge bullets on a smaller screen
  • change frame rate to 30 fps to slow down the movements and make the game easier.  The smaller screen makes it more difficult to avoid the bombs.
  • android.init()
  • map the ESCAPE key in pygame to the physical back button on the phone.  He uses this to exit the game loop.
    • android.key_map(android.KEYCODE_BACK, pygame.K_ESCAPE)
  • adjust the height of the text boxes for the Game Over screen and final score.
  • use free clip art to create the android-icon.png file for the Android app launcher
  • use free clip art to create the android-presplash.jpg file for the initial splash screen that shows up prior to the game starting. 
In the future, it might be rewarding for the student to use Inkscape to create a logo for a mock software company.

Since the original game used the keyboard for controls, he added mouse controls.  PGS4A maps the mouse to the touchscreen.  This is so nice.  For this game, he created active areas of the screen to control left and right movement.  There's no instructions, but it seems intuitive to most people playing the game.

The original game also used the default system fonts on Ubuntu.  He saved the fonts from 
/usr/share/fonts/truetype/freefont/FreeSansBold.ttf on Ubuntu to his build directory and packaged the font as part of the Android app bundle. 

Saturday, November 24, 2012

Sprites and Tiles

My son finished his shooter game and I started to research tiles for the next project.

During Thanksgiving break, I started with Tiled TMX Loader.  This initially proved quite rewarding since there were several nice examples of Pygame code that shipped with the library.    I used Tiled Map Editor to make the maps from tile sets.

Since my son wants to show his friends his games on his phone, I was planning to package the Pygame application for his phone using Pygame Subset for Android (PGS4A).    

Unfortunately, when I did the build, I realized that Pygame Subset for Android does not support the XML libraries that Tiled TMX Loader requires.  There does not appear to be an easy way to build the XML C libraries into PGS4A or include a Python library with the application.    Here is a discussion thread from the Pygame Subset for Android forum.  The workaround people were using involved converting the tmx maps to JSON files and loading the map into the Pygame on Android application using the JSON module that was supported by PGS4A. 

Although Tiled can output a tile map to JSON, I realized that all the python JSON library does is load the JSON file data into dictionaries and lists that can then be accessed by the program.  Taking this route, I'm going to need to develop all the map camera movements, layer management, and collision detection myself.  Bummer.   The data is there, but I didn't want to think about how to manipulate it.

Feeling that manipulating map data from JSON files was too much of a task, I instead started to research sprites, basically shelving the idea for a complex map and focusing on understanding smaller lists and dictionaries of tiles made up of 32 x 32 pixel tiles.

piman's sprite tutorial was the most useful.  The application above is basically an extension of piman's tutorial.  Instead of colored rectangles, I used pygame.image.load("filename") to create image surfaces.  I used a single grass tile as the background and simply repeated it.

The controls at the bottom select the character to move.  

def select_character(buttons, mouse_pos, selection):
    selected_char = selection
    for b in buttons:
        if b.rect.collidepoint(mouse_pos):
            selected_char = b.character

I recently realized that I can use pygame.Rect.collidepoint instead of pygame.Rect.colliderect.  The rectangles are the same ones that you use to blit the images onto the screen.

It's easy to get the mouse position with pygame.mouse.get_pos().

In the main event loop, I simply check for the mouse button up or down:
  • elif event.type == pygame.MOUSEBUTTONDOWN:
  • elif event.type == pygame.MOUSEBUTTONUP

Sunday, November 18, 2012

Pygame Subset For Android

My student recently bought an Android 2.2 smartphone on eBay for $40.  It's quite a good deal.  The phone is unlocked and can run games from GooglePlay as well as custom games.

I spent about an hour today teaching a lesson using Pygame Subset for Android.  Wow, talk about big bang for the buck.  By the end of an hour, my student was running a native Android app on his phone completely from a blank text editor.  The app has working animation, touchscreen interaction, and hard-buttons.

Since I was completely new to Android development, I ran into a small problem building the project with Ant.

When I ran the example build from the Pygame Subset for Android, I got an error message when the script ran Ant.

~/$ build mygame install release


Initially, I spent some time trying to create a build.xml file.   This led to a dead end.

The solution is to look at the Target id, android-8.

In the android-sdk directory, you need to have the android-8 platform listed in the platforms directory.

ubuntu-desktop:~/Documents/python/pgs4a-0.9.4/android-sdk$ ls platforms/
android-17  android-8

If you don't have this platform, and you probably won't by default, run the android program within the android-sdk/tools directory.

The reason this wasn't immediately obvious to me is that the error message for the missing android-8 target was at the top of the screen output and the build.xml error message was at the bottom.  I should have read the error messages closely, starting at the top of the output.

  $ ./android --help 

for help or

  $ ./android update sdk 

to install API-8, Android 2.2 platform support.