Freitag, 19. August 2011

Development Diary #3

Topics:
  • first project: FastBlocks
  • first experiences with pygame
After I got myself a bit tangled in version control systems in the last post, we will now come to the planning and implementation.
For now, I don't want to prepare full-featured tutorials for my projects, because there are so many in the internet and you can watch the code in my git-repository to learn what's up.
Here I just want to present some special occurrences during my programming and reading articles.
My first project is - as planned - a game like Tetris named "FastBlocks". I have tested some pygame examples as a start and made some notes of the planned features of my game.
The so named "keyfeatures", which are mandatory for the game to work properly:
  • different block types, playingFieldheight/width from xml
  • correct Tetris-Gameplay
    • spawning of new Blocks
    • moving of the Blocks
    • Blocks are falling
    • Block collides with another and stops moving
    • whole lines will be dropped (with animation)
And the optional features:
  • different difficulties
  • GUI to start a game
  • fast falling Block animation
  • line dropping animation
  • Game against KI with the same playing game
You can orientate yourself pretty good with such lists and expand them when you think of something new. So you can't forget anything (Captain Obvious!) and become nostalgic because of your past work! ;)
During the programming, I firstly got used to the object-oriented world in Python and created the first classes for the playing field and a single block. The latter class extends pygame.sprite.Sprite which has a rect for the position and an image to draw the block on the screen. To be more flexible with some parameters I have created a XML-file instead of some global variables. You have to insert informations about the size of the playingfield, the blocks and even the shape of the compounded blocks (review this at the repository! ;) ). This file is parsed at the beginning of the program and then the playingfield gets filled with the different block-shapes and so on.
The first "mistake", which I made, was to use just one sprite for a complete block which is compounded of other boxes. This is not very good for Tetris, because just single blocks in a line should be deleted and not the whole composition. Thus quickly add a new class to use the design-pattern of a "composition"!
Then the next serious issue is the management of collisions. This is used in nearly every game, because for the most part you move an object through an environment with some impermeable obstacles, or simulated projectiles. Pygame has some inbuilt functions to detect collisions of Sprites in a group. But they are not very helpful for a Tetris-game, because you don't need pixel-perfect collisions. I use a array representing the slots for the blocks of the playing field. It stores a zero, when it is empty, and otherwise the ID of the block at this place. With these things a collision check is pretty easy.
The next important function of pygame is the ability to update just the rectangles on the screen, which were changed in the last step, instead of the whole screen. This method is called to work with "dirtyRects" and is extensivly explained in this article and is used in the pygame example "oldalien.py". This method is a good boost for the performance (FPS and the processor workload) and you should use it.
Furthermore there are some cool features of python - e.g. to find the common items of two lists with just one line of code, e.t.c. - which I didn't know. Learning never stops! ;)

Some interesting articles: