Sunday, November 2, 2014

Pygame Virtual Controller Update

I worked with my son for about 2 hours today on the Pygame virtual controller for Android.   The main challenge with the controller is the use of sine, cosine, and tangent.  Although we all learn trigonometry in school, how often do you use it?  Outside of making games, I never use it.

Another challenge is getting comfortable with sprites and sprite groups for the bullets.  Since the bullets are simple, we could easily make the game without sprites.  It's possible to use rectangles stored in lists.  Sprites have a number of advantages over rectangles.  I like to use sprites because its a concise way to organize all the bullets into a single sprite group and then use bullet_group.update() and bullet_group.draw() to manage all the bullets on the screen.

The first time you type in a sprite class, it looks a bit odd.  I think the oddness of the line pygame.sprite.Sprite.__init__(self) makes the sprite more intimidating than it really is.



class Bullet(pygame.sprite.Sprite):
    def __init__(self):
        pygame.sprite.Sprite.__init__(self)
        self.image = pygame.Surface((6,6))
        self.rect = self.image.get_rect()



After getting the bullets to fire properly with sprite groups, the next challenge was to get the player to move around the screen with a secondary virtual controller.  Although we built the code to calculate the angle of the controller for firing in the previous lesson, the player wasn't moving.  Once the player starts moving, the angle needs to be calculated from the center point of the player.  The modification to the code is minimal, but the conceptual leap of thinking of the opposite, adjacent and hypotenuse sides can be daunting when the triangle is moving all around the screen.  

Once you get the angle and the center, the code to move the player is straightforward.

def move(angle, center):
    hypotenuse = 10.0
    adjacent = math.cos(angle) * hypotenuse
    x = int(adjacent + center[0])
    opposite = math.sin(angle) * hypotenuse
    y = int(center[1] - opposite)
    return ((x, y))
At the end of the lesson, he had a working app with 360 degree firing and movement.

The next step is to get this working on his accelerometer game.  We're bumping up into the limitations of single-point touch and are trying to use the accelerometer for movement.  It's easy to access the Android accelerometer, but it's uncertain how playable the game will be.  We're using Cube Runner as a model for playability.


No comments:

Post a Comment