Table of Contents for
Gaming Hacks

Version ebook / Retour

Cover image for bash Cookbook, 2nd Edition Gaming Hacks by Simon Carless Published by O'Reilly Media, Inc., 2004
  1. Cover
  2. Gaming Hacks
  3. Credits
  4. Contributors
  5. Acknowledgments
  6. Foreword
  7. Preface
  8. How to Use This Book
  9. How This Book Is Organized
  10. Conventions Used in This Book
  11. Using Code Examples
  12. Comments and Questions
  13. Got a Hack?
  14. 1. Playing Classic Games
  15. Legal Emulation
  16. Play Commodore 64 Games Without the C-64
  17. Play Atari ROMs Without the Atari
  18. Use Atari Paddles with Your PC
  19. Run Homebrew Games on the Atari 2600
  20. Create Your Own Atari 2600 Homebrew Games
  21. Play Classic PC Graphic Adventures
  22. Play Old Games Through DOSBox
  23. Play Reissued All-in-One Joystick Games
  24. Play Arcade Games Without the Arcade
  25. Add and Manipulate a MAME Frontend
  26. Keep Your ROMs Tidy and Organized
  27. Learn Game-Specific MAME Controls
  28. Filter Inappropriate MAME ROMs
  29. Autoboot into MAME Heaven
  30. Play Emulated Arcade Games Online
  31. Play Classic Pinball Without the Table
  32. Emulate the SNES on the Dreamcast
  33. 2. Playing Portably
  34. Play Games on Your iPod
  35. Mod Your Game Boy
  36. Take and Print Photos with Your Game Boy
  37. Compose Music on Your Game Boy
  38. Explore the GP32 Handheld Gaming System
  39. Take Your Console with You
  40. Explore the Bandai WonderSwan
  41. Play Real Games on Your PDA
  42. Install a PlayStation 2 in Your Car
  43. 3. Playing Well with Others
  44. Practice Proper MMORPG Etiquette
  45. Understand MMORPG Lingo
  46. Grind Without Going Crazy
  47. Make a Profit in Vana’diel
  48. Write MMORPG Macros
  49. Build an Effective Group
  50. Catch Half-Life FPS Cheaters Redhanded
  51. 4. Playing with Hardware
  52. Build a Quiet, Killer Gaming Rig
  53. Find and Configure the Best FPS Peripherals
  54. Adapt Old Video Game Controllers to the PC
  55. Choose the Right Audio/Video Receiver
  56. Place Your Speakers Properly
  57. Connect Your Console to Your Home Theater
  58. Tune Console Video Output
  59. Tune Your TV for Console Video
  60. PC Audio Hacking
  61. Optimize PC Video Performance
  62. Build a Dedicated Multimedia PC
  63. Use a Multimedia Projector for Gaming
  64. 5. Playing with Console and Arcade Hardware
  65. Play LAN-Only Console Games Online
  66. Hack the Nuon DVD Player/Gaming System
  67. Play Import Games on American Consoles
  68. Find a Hackable Dreamcast
  69. Play Movies and Music on Your Dreamcast
  70. Hack the Dreamcast Visual Memory Unit
  71. Unblur Your Dreamcast Video
  72. Use Your Dreamcast Online
  73. Host Dreamcast Games Online
  74. Burn Dreamcast-Compatible Discs on Your PC
  75. Burn Dreamcast Homebrew Discs
  76. Buy Your Own Arcade Hardware
  77. Configure Your Arcade Controls, Connectors, and Cartridges
  78. Reorient and Align Your Arcade Monitor
  79. Buy Cart-Based JAMMA Boards
  80. Programming Music for the Nintendo Entertainment System
  81. 6. Playing Around the Game Engine
  82. Explore Machinima
  83. Choose a Machinima Engine
  84. Film Your First Machinima Movie
  85. Improve Your Camera Control
  86. Record Game Footage to Video
  87. Speedrun Your Way Through Metroid Prime
  88. Sequence-Break Quake
  89. Run Classic Game ROM Translations
  90. Change Games with ROM Hacks
  91. Apply ROM Hacks and Patches
  92. Create PS2 Cheat Codes
  93. Hack Xbox Game Saves
  94. Cheat on Other Consoles
  95. Modify PC Game Saves and Settings
  96. Buff Your Saved Characters
  97. Create Console Game Levels
  98. 7. Playing Your Own Games
  99. Adventure Game Studio Editing Tips
  100. Create and Play Pinball Tables
  101. Put Your Face in DOOM
  102. Create a Vehicle Model for Unreal Tournament 2004
  103. Add a Vehicle to Unreal Tournament 2004
  104. Modify the Behavior of a UT2004 Model
  105. Download, Compile, and Create an Inform Adventure
  106. Decorate Your IF Rooms
  107. Add Puzzles to Your IF Games
  108. Add Nonplayer Characters to IF Adventures
  109. Make Your IF NPCs Move
  110. Make Your IF NPCs Talk
  111. Create Your Own Animations
  112. Add Interactivity to Your Animations
  113. Write a Game in an Afternoon
  114. 8. Playing Everything Else
  115. Tweak Your Tactics for FPS Glory
  116. Beat Any Shoot-Em-Up
  117. Drive a Physics-Crazed Motorcycle
  118. Play Japanese Games Without Speaking Japanese
  119. Back Up, Modify, and Restore PlayStation Saved Games
  120. Access Your Console’s Memory Card Offline
  121. Overclock Your Console
  122. Index
  123. Colophon

Add Interactivity to Your Animations

What’s better than animation? Interactivity!

Now that you know how to put images on the screen and move them around ( [Hack #91] ), you’re two steps away from creating games. Step 1 is to make things interactive; step 2 is to add gameplay ( [Hack #93] ). Fortunately, with PyGame, it’s easy to make your animations respond to the human touch.

Building a small program to move a robot around on the screen with the cursor keys takes only a few minutes, yet it demonstrates the larger concepts of almost any interactive and visual game.

PyGame Input

PyGame relies on SDL for its input, so to work with input in PyGame, you need to understand SDL events. Every time an input source generates input, such as a timer going off, the user pressing a key, or someone moving the mouse, SDL turns this into an event. It then puts this event in a queue for your program to handle later. Think of SDL events as an answering service; you don’t want to answer the telephone every time something happens, so you let your answering service buffer the interruptions so that you can filter through the list of messages when it’s convenient.

SDL events have one vitally important attribute, the type designator. Every possible input type SDL supports has its own type. The most important include QUIT, KEYDOWN, and KEYUP, though there are other types for mice, joysticks, and window manager events. For keyboard events, both KEYDOWN and KEYUP have a subtype that represents the actual key pressed.

Tip

Why are there separate events for keyboard presses and releases? Consider a space game that applies thrust to a rocket ship as long as you hold down the Fire Engines key. Set a flag when you process the KEYDOWN event, unset the flag when you process the KEYUP event, and fire the engines only while the flag is set.

The Main Loop

PyGame’s event-handling support is in the pygame.event class. The core of a main loop to handle events is:

def loop( screen, background, player ):
    key_events  = {
        K_UP:     player.move_up,
        K_DOWN:   player.move_down,
        K_LEFT:   player.move_left,
        K_RIGHT:  player.move_right,
        K_SPACE:  player.stop,
    }

    while 1:
         for event in pygame.event.get( ):
            if event.type =  = QUIT:
                return
            if event.type =  = KEYDOWN:
                if key_events.has_key( event.key ):
                    key_events[ event.key ]( )
                elif event.key =  = K_ESCAPE:
                    return

          background.fill(( 255, 255, 255 ))
          surface.blit( background, background.get_rect( ) )

          player.draw( background )
          screen.blit( background, ( 0, 0 ))
          pygame.display.flip( )

The first several lines define the key_events dictionary that maps keys to actions. The uppercase symbols come from the PyGame events library. The player.move_ direction entries are method calls on a Player object. Don’t worry about the details right now; just think of them as actions the player character should do. It can move up, down, left, and right. It can also stop moving.

Within the main game loop, there’s another loop over all of the events PyGame has processed. The two if blocks check the type of the event. If the game receives a QUIT event, such as when the player closes the game window, the game returns from this function and exits the program.

If the game receives a KEYDOWN event, it checks the key_events dict to see if there’s an action to perform for that key. If so, it does that action (telling the Player object what to do). Otherwise, if the user presses the Esc key, the game exits.

After this has processed all pending events, the loop redraws the screen—background first, then player—then updates it. The loop will continue from the start until the player quits.

Okay, that’s how to detect actions. How does the player actually move? That’s the job of the Player object.

The Player Object

Clearly, all of this input handling implies that there is some entity in the program, a player, that knows how to move and draw itself. That’s the purpose of the Player class.

For the Player to do its job, it needs to keep track of several pieces of information: its current position, the maximum X and Y coordinates allowed, the image to display, and the Player’s velocities along the X and Y axes. Since there’s only one Player at a time in this program, these could be global variables. However, it’s easier to organize them into separate units of behavior. This allows you to add new Player objects in the future with minimal code changes.

Initialization

When you create a new Player object, Python calls the special method _ _init_ _ to initialize values for that object. Here’s the start of the class:

class Player:
    def _ _init_ _( self, image, max_x, max_y ):
        self.image  = pygame.image.load( image ).convert_alpha( )
        self.rect   = self.image.get_rect( )

        self.max_x  = max_x - self.rect.width
        self.max_y  = max_y - self.rect.height

        self.x_vel  = 0
        self.y_vel  = 0

        self.rect.x = random.randint( 0, self.max_x )
        self.rect.y = random.randint( 0, self.max_y )

The first line gives the name of this class. The second declares the information this class needs to initialize an object, specifically the object itself (handled automatically for you), the name of an image to load, and the maximum X and Y coordinates of the world.

The next line loads the image and converts its transparency information to work with SDL. The method then fetches the SDL rectangle representing this image and stores it in the class itself to make things more convenient.

The max_x and max_y coordinates help keep the player from running off the right side and bottom of the screen. Because the image coordinates start at the upper-left corner of the image, you need to subtract the image’s width and height from the maximum X and Y coordinates, respectively, to figure out how far to the right and down the player can travel without hitting a wall. Without this step, the player can move all of the way off the screen.

x_vel and y_vel represent velocities along the X and Y axes, respectively. When the player presses a direction key, the input-handling code sets one of these velocities. The player should start out stationary, so these values start as zero.

Movement

As implied by the main loop earlier, the Player needs several methods to perform its moments. They are:

def move_up( self ):
    self.y_vel = -1

def move_down( self ):
    self.y_vel = +1

def move_left( self ):
    self.x_vel = -1

def move_right( self ):
    self.x_vel = +1

def stop( self ):
    self.x_vel = 0
    self.y_vel = 0

These are pretty straightforward; the Y coordinate controls the player’s up and down movements, and the X coordinate governs left and right. stop, of course, ceases all motion.

What good does all this do? It doesn’t directly affect the player’s position. That’s the job of move():

def move( self ):
    x     = self.rect.x
    y     = self.rect.y
    x_vel = self.x_vel
    y_vel = self.y_vel

    if ( x_vel and 0 < x < self.max_x ):
            self.rect.x += x_vel

    if ( y_vel and 0 < y < self.max_y ):
            self.rect.y += y_vel

This method finally calculates the player’s new position. If x_vel isn’t zero (it can be -1, 0, or 1), and if the player isn’t at the farthest left or right edge of the screen, it adds that value to the current X coordinate. The same goes for the Y velocity and coordinate.

Drawing

Finally, the image has to make it to the screen somehow. That’s what draw() does:

def draw( self, surface ):
    self.move( )
    surface.blit( self.image, self.rect )

The second argument to this method is the SDL surface to which to draw this image. Note that it uses the SDL rectangle within this object to govern its position. That’s all the magic.

The Rest of the Code

Of course, that’s not all of the code it takes to make the program work. There’s a little bit of initialization to go, namely loading the appropriate PyGame modules and creating a couple of surfaces and the Player object:

#!/usr/bin/python

import pygame
import random

from   pygame.locals import *

The program starts by loading the pygame and random modules then importing all symbols from pygame.locals. These include the SDL key constants used in the main loop.

Next, the program needs to initialize PyGame and the drawable objects:

def main( ):
    pygame.init( )
    pygame.display.set_caption( 'Robot Moves Around' )

    max_x       = 640
    max_y       = 480
    screen      = pygame.display.set_mode(( max_x, max_y ))
    background  = pygame.Surface( screen.get_size( ) ).convert( )
    player      = Player( 'robot.png', max_x, max_y )

    loop( screen, background, player )

if _ _name_ _ =  = '_ _main_ _': main( )

The first two lines initialize PyGame and set the caption of the window appropriately. max_x and max_y define the size of the window to create. background is an SDL surface the same size as the screen.

The Player() call creates a new Player object, passing the robot.png filename and the maximum X and Y values. The function then kicks off the game by calling loop(), passing in the three drawable objects.

Finally, if you call the program directly, the last line of code launches the main() function:

$ python move_robot.py

or the equivalent for your platform.

Movement Strategies

There’s plenty of room to experiment with other options for handling movement. One approach is to move the player when encountering a KEYDOWN event. However, if the player moves only one pixel at a time (for smoothest movement), it’ll take several hundred keypresses to reach the other side of the screen.

Another approach is to set a movement flag for each KEYDOWN event seen, and unset it when a corresponding KEYUP event is received. This allows players to hold down a key for as long as the character should move. More sophisticated systems make holding down a key actually increase the character’s velocity.

This program merely sets the appropriate X or Y velocity when it encounters a key press. Holding down the key has no effect, and releasing the key has no effect. You can only move in the opposite direction or stop.