BubbleBobble
From WikiFlashed
A Bubble Bobble Remake in Actionscript 3. This is one of the most classic fun games. I love it so much that I had to make it in AS3. The hardest part of this game is a obviously recursive scanning. Tree algorithm is the most important thing because, it must be fast enough so that game play is not affected. Thanks to FL9's new rendering engine. Algorithms like binary search etc can be achieved much more efficiently.
This engine is used in another project of mine, "mostwanted.com.au". Go there and compete with thousands of other players.
Contents |
Author
- WikiFlashed
- http://www.wikiflashed.com
Demo Play
Logics
Below are the main parts that illustrates the logics of this game.
- Ball Movement
- Algorithm
- Level
- Render
Ball Movement
Like any vector calculations, you use either vector style or the usual cos and sin angle method. The problems encountered here are quite fundamental, resulting numerous rounds of rewrite.
- How to know when the ball has reached a spot that it should stop and attach itself to the right spot?
- Collision Detection
- Path Calculation
At first, I used collission detection, and was adding some fancy ease to the movement of the shooting bubbles. However, collision detection has its down flaws, because it doesn't always work. A skip in CPU load can skip a segment of rendering, and causing the collision to fail because the two detecting clips never touched each other. At the end, instead of letting the logic to be dependent on collision detection, I came up with a much simpler approach and it seem to work really well. Further, instead of having an ease, lets just stick to constant speed.
Now, let's say "currentGrid" is a 2D array that holds the current grid plan. We will first perform a pre-movement path calculation and test all the translated coordinate path points against the current grid plan. Thanks to AS3 Virtual Machine's improved loop speed, it made pre path calculation possible. It is probably fast enough in AS2 but who cares. Now, having a vector speed of say 2 pixels, we will just use a for loop and in every shifted 2 pixel vector loop, we will:
- translate the new nx, ny position point to the correct grid coordinate
- test the new coordinate against the same coordinate on the current grid
- see if the new coordinate collides anything, or if it goes outside x,y bounds, and if it does then the attaching coordinate point becomes (nx-1, ny-1). It is -1 because, we want the previous coordinate since the current coordinate is already taken.
Done! A big problem solved.
Algorithm
The most difficult thing with BubbleBobble is the algorithm. I have RE-approached this game about 3 times, and changing the way it works every time.
- How to traverse through the tree the most efficient way?
At the start, I was trying to be cool by planning early with the grid. I used de.polygonal 's collection classes to construct the 2d array for everything. I had all my levels setup in a static singleton level manager class file in a normal 2d array form [[0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0]] kinda thing. The engine spec is pretty much made to an exact copy of the original classic. Things like column size, row size is pretty much the same as the original game. (Note: every second row has 1 less bubble because of the nature of the grid)
Algorithm is mainly used to find out which bubbles need to be removed after the bubble stops moving. Traversing through the grid happens at quite a few points during the game. A slow algorithm can definitely impact the overal performance and game play. At first, I figured out that the best way is just to use a recursive function on the grid from the coordinate of the attaching point. However, its inevitable for you to get a slight pause or lag when I do that. Bubble Bobble is really a hexagonal sided system. Recursing 6 levels ^ n where n is number of connections simply wasn't good enough. It is quite similar to the way Hexic's grid system is setup but it has to be optimized and simplified a lot more for better performance. What we need to do is basically to check through every bubble that is connected and add the one of the same color to an disposal array. Once the disposal array reaches a size of 3 or more, each of those bubbles gets removed. In this demo, there are no fancy specialty bubbles like how it is on "mostwanted.com.au".
So instead of doing a huge recursion, I split up the traversal into 2 segments. The direct touching balls and the indirect touching balls. Indirect touching balls are balls that need to fall after their branching connection is broken. Also, instead of doing recursion to the max, we can just do a 2 level recursion which is enough to cover all scenarios. Source snippets are written here for a more low level idea of how things work. (do not ask for more code as already provided)
Level
There isn't much to talk about with levels. It is just a class that holds the level information. You might want to load coordinates from xml or txt file. Take a look and feel free to suggest better ways of storing grid level data.
public var level1 : Array = [ [0, 0, 0, 2, 2, 0, 0, 0], [0, 0, 0, 2, 0, 0, 0], [0, 0, 0, 3, 0, 0, 0, 0], [1, 0, 0, 2, 0, 0, 1], [0, 1, 0, 5, 0, 0, 1, 0], [0, 0, 0, 3, 0, 0, 0], [8, 0, 0, 2, 0, 0, 0, 0], [0, 0, 0, 1, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0]]; }