-
Notifications
You must be signed in to change notification settings - Fork 0
Home
We will recreate the arcade game Qix in Python using pygame for the 40th anniversary of the arcade release. This tutorial is divided into 10 Parts. At the end you have a faithful conversion of the original arcade game with all features.
Qix is a very 40 year old game from the early 80ies running on an 8 bit system. You can look for a MAME Rom (playable under https://archive.org/details/arcade_qix). It was released by TAITO on October 18, 1981 by Randy and Sandy Pfeiffer.
In qix you control a diamond-shaped marker (Stix) that initially moves along the edges of the playfield. Holding down one of the draw buttons allows the marker to draw a line in unclaimed territory in an attempt to create a closed shape. A captured area is filled with color. To complete a level, the player must claim a 75% percentage of the playfield.
There are 3 opponents:
- Qix, a bunch of lines flying randomly inside the playfield. If it touches the path of the player on unclaimed territory, player dies
- Sparx, patrolling the playfield
- Fuse, an opponent following the player on unclaimed territory, if he pauses to long
Interestingly we need to fully reinvent the game mechanics as the original approach was bitmap/memory based but a modern approach should be vector based.
in bitmap approach you have an array with a byte per pixel. As the QIX-screen is 256x256 this means 65536 Bytes. If you set a byte to something different than 0, the corresponding pixel will lit (in different colors according to the value), if you want to check, if a pixel is lit, just read the byte and test if it is 0. So if you want to check for a collision between a line you want to paint and some other playfield elements, you calculate the points (via Bresenham's line algorithm) and before setting the pixels in your byte array, you check, if the value is zero. If not, you have a collision. This is from a computational point of view as fast as it gets. Unfortunately this nice approach works only for very simple graphics: you need an all-black background, you can not really differentiate what you hit, except by color and in todays resolution this approach would be not workable, as you would need to color-code your enemies .
Todays GFX-Cards have a special memory which is not directly read/writeable via the CPU. To transfer all the Bytes in a todays resolution (say 1920x1080) will take a big burden on the PCI bus. So we will represent the graphics as vectors (lists of lines) and will calculate intersections. This is not very costly in terms of performance on todays machines and represents more the style you would code such a game (or any other game) today. These routines you can easily reuse for other games as well, for example for movement, collision or line-of-sight calculations.