Success and some comments

Posted by (twitter: @kwrky)
April 29th, 2013 2:34 am

Got it in and submitted!

So far I’ve had some nice comments from everyone, and I am thankful for that.

One particular point people seem to like is the transitions between levels.

For those who haven’t played it, the level is defined by blocks of either 64×64 or 32×32 size, and during a level transition these all fly into the middle of the screen. They are then re-allocated behind the scenes (the green and black tile that make the games logo never get deleted), and explode out into the new level configuration.

This effect is actually extremely simple to do, and for impact to code is well worth your time, so I thought I’d go into how I did it.

For each drawn object in your game, construct their position call something like as follows

#Reset the visual position
self.player.vX = self.cPan * 480 + ((1 – self.cPan) * self.player.rX)
self.player.vY = self.cPan * 352 + ((1 – self.cPan) * self.player.rY)
This is Python, but you could use C# or whatever you like syntatically. What is happening above is we have a global variable “cPan” which is applied to a fixed x coordinate (the centre of the screen) and then the inverse (1 – cPan) applied to the players rX variable (that is “real x”, vX being “visual X”). Separating out the draw and position coords means you can do funky effects isolated from logic. Particular doing it like this allows you to do things like jitter with one or two lines of added code.

So now we have this transformation applied every frame, we can see our drawn position will smoothly animate from the centre of the screen (480, 352) when cPan is 1, to the objects real position when cPan is 0.

I added the following section in my global state update function:

#Visual processing, animations, fades, pans etc
if abs(self.cPan – self.cPanT) < 0.01:
self.cPan = self.cPanT
else:
self.cPan = self.cPan + ((self.cPanT – self.cPan) * 0.1)

Our variable cPanT (cPan Target) is compared to the current value of cPan. If the difference is less than 0.01 set them equal to each other. This provides a nice “snap” effect at the end of the move, and also prevents 1 pixel jittering from making it look messy. If the difference is larger than 0.01, we move cPan towards cPanT by 10% of the difference. Because of this use of percentage, when the distance is large it moves quickly, when it is small it moves slowly, giving us our nice explosion effect.

Lastly, I added a command to my internal scripting system as follows

if action[0] == “CPAN”:
self.cPanT = float(action[1])
if self.cPanT == 0:
self.sound_level_expand.play()
elif self.cPanT == 1:
self.sound_level_compress.play()

The system works by queueing events programmed into the game logic object, and then processing them. Events are a command in the [0]’th array position followed by some arguments. In this case we can have either “CPAN 0” or “CPAN 1”. The script sets the cPanT variable, plays the funky sound effect, and removes the command.

Here’s what my script looks like for the level transition:

“NEXTLEVEL”:[
(0, “MODE NONINTERACTIVE”),
(100, “WAIT”),
(0, “CPAN 1”),
(150, “WAIT”),
(0, “SPAWN_LEVEL”),
(0, “CPAN 0”),
(100, “WAIT”),
(0, “MODE INTERACTIVE”)],

100 = 1 second. 0 = execute this instantly. It’s pretty readable, but it sets the system non-interactive so your commands are ignored, waits a second (you just won, thats your “victory savoring” time), zooms everything into the centre of the screen, waits again, spawns the new level (I should probably reverse these!), zooms out in the new configuration, gives you another second to look at the level before it starts, and then sets the game interactive again.

Cool transitions in a total of 6 lines of code!


Leave a Reply

You must be logged in to post a comment.

[cache: storing page]