Gaming Your Way

May contain nuts.

Slopes in a tile based game. The dirty way.

In a recent comment posted here I was asked about the slopes in the current platformer, and I promised I'd go over it, so here it is ( Albiet slightly rushed and with no nice diagrams, deadlines and all that ).

In a tile based engine it's fairly simple to work out where the position of the sprite is in relation to the tile he's standing on. So as you move over a tile you're updating the x position which is obvious enough.
Also usually with map data you have an attribute value / byte for each tile, again if you've worked with tiles you're with me so far.

To simulate a slope easily you have an array of y positions for the sprite. In my case I have 8 values for every sloping tile, as the player moves at 4 pixels per frame, and the tiles are 32px wide, so it's 32/4 = 8 possible positions for every tile on the horizontal.

Let's say our slope looks like this ( In array form )

[0,2,4,6,8,12,14,16];

If we're at position 0 on the x of the tile, ie the left hand side, we read the first value in the slope array, in this case 0, and we decrease the sprites._y by that amount ( Decrease 'cause we're moving him up ), so the next step will make the sprite 2 pixels higher up the screen than he was last move and so on.

Above I mentioned using attributes, this is how I get an offset into the array of slopes ( They're just stored as a 2 dimensional array ). If you didn't use an attribute in the map data, just used the tile number, then you'd need to have an array for every single tile ( Where the vast majority would be flat ), which is a hell of a lot of work for no reason, and a waste of resources.

So again we're stepping on our tile, and it's attribute is 1. We know to look into the slope array at attribute-1 ( Arrays start at 0 ), which gives us our first saved slope value, and from there we can get the correct y position for each step of the way.

Simple as you like, hardly any real cpu overhead, and so far with what I've been working on it seems to cope with any angle I've thrown at it. If you wanted to add more realistic movement ( So the sprite stuggles up a hill, sprints down it ) you could store another array with the players max moving speed for each position and add that to the overal speed.

Squize.

It's like having an Amiga again

Worked on Orbs over the w/end, and had to re-organise a ton of stuff ( I'm still finding my feet with this as3 lark ).

The particles worked by using copyPixel to plot them into a bitmap ( Blitting, like the good ol' days ) and then using colorMatrixFilter to fade them down every couple of frames.
I've really been wanting trails on the baddies too ( I want to use the add blendmode, but I think that's going to be too much. That may just be reserved for the Orbs themselves ) so this major reshuffle saw the baddies being changed from sprites to bobs ( Blitter OBjects ) again using copyPixel.

Seems to be running a lot faster for the change, and looks a lot better. Also 'cause I'm fading down the whole bitmap that they're being blitted to I don't have to worry about any kind of clearing up or damage maps. Cool.

I'd been meaning to try blitting sooner, but I was concerned about losing things like hitTest and rotation, but at the moment it's performing nice and fast and I'm hoping I can come up with a good way to cope with the silly amount of collisions I've got planned ( At present I'm looking at doing it sector based using circle to circle checks ).

Next step is to drop the collisions back in and see how the engine copes with that, and then some animation ( So it'll be an animated rotate ).

It's all looking pretty good right now, I'm really happy with it.

Squize.

PS. Next post, something on slopes.

What's in the oven ?

A little update is well over due, so here's a couple of grabs of two current projects.

ts_grab1.png

A platform game, which I'm afraid is covered by an nda, but despite looking nasty with that placeholder art, it's coming along quite nicely. I'm still really buzzing with this project as it's my first ever platform game, and I'm just planning on over delivering by a lot to make it as good as the time will allow.
The scrolling is in and working ( Although the vertical panning is a bit out ), collisions are working just how I wanted ( The player to baddie collisions worked perfectly on the first compile. I mean, when does that ever happen ? Somedays it's almost like I'm a proper coder ) and it's all coming together like an orgy. Nice.
I'll be posting more about it as it develops, within the boundaries of a nda anyway.

orbs_grab1.jpg

A picture paints a thousand words and all that, so I'm not going to go too much into the gameplay. My first as3 game, and I'm nearly getting to the point where I'm not getting a compiler error just by being in the same room as Flex.
AS3 is funny, it gives you so much power that when you try something and it runs slow, it's like wtf ? A good position to be in though.

I think "Orbs" is my first personal project since Crazy Balls, which from memory originally went live in 2004.

Squize.

Hell has a name

The current project, "Phantom Mansion" is a port of a mobile phone game.

When the site actually goes live you'll see ( If your interested ) case studies for all the projects. The case studies are written in a more professional style, outlining the thought processes as well as the development cycle.

They're glossy and nice.

When it comes to describing Mansions' development, I imagine I'll write something like "A difficult development process due to adhering to the existing design restrictions".

In real life, Mansions' development has been a total cunt.

This is why I've been awol from the blog, and I owe a dozen people a dozen emails ( Sorry ). Indulge me why I vent my spleen a little. The game is  I guess what would be called an "Arcade Puzzler" and as a game it's pretty sweet. It's just that it was designed for java, and so doesn't play to any of Flash's strengths.

At present I'm in the hell that is depth sorting. It's not something I ever seem to do too well, just another black hole in my mind when it comes to coding, but this isn't the usual swapDepths based on the sprites y position. Nope, that would be far too simple. The game has bridges that you can walk over and under. And the baddies can walk over and under. And you can push crates ( You know the score by now ).

Not too harsh. But, and this it the beauty of it, all the sprites are offset on their y position by around 10 pixels ( ie, the image is placed at -10 on the y axis ). This was because in the original it allowed for simple depth sorting with some of the tiles in the game ( So the sprites wouldn't have to be behind certain tiles, so you don't need to worry about sorting for that ). Easy old school trick that surely could never come back to haunt you ( And no, that wasn't a pun ).

So you've got a bridge, and you put it in a higher layer than the sprites, so you can walk beneath it. When you have to walk over the bridge, simple and sly, just have a copy of the same sprite in a layer higher than that, and _visible=true and it's job done.
But, hang on, the sprites are offset. So although they're 32x32 pixels, the same as the tiles, they actually cover the tile above. Surely that means that walking infront of a bridge would lead to the sprites top 10 pixels ( Roughly a head's worth ) being obscured.

Ok, not a problem, we just check that and turn on our higher up copy of the sprite and it's all fixed. Internally every sprite has a zdepth var, so we know what "level" it's on, so you can walk over a bridge and a baddie walking beneath you can't kill you ( It wouldn't be the fairest of games otherwise ).
Where were we ? Oh yeah, at the foot of a bridge bump the sprites level to 1 and display the sprite in the top layer. Now if the sprite is to the left / right of the bridge we shouldn't do this, so we don't. I'm building up to the kicker here. Let's just push that crate along. Oh arse, it's over the bottom of a bridge, let's knock it's level to 1 and blah, blah, blah. The player's sprite whose just pushed it there though, he's still on layer 0, he doesn't know anything about the bridge. So what happens when he goes to push the crate, which is higher than he is ?

pm_bugGrab.png

There's the bridge, tinted orange so I can see it's in a higher layer. The crate which overlaps it tinted green, again so we can tell it's not in layer 0, but look at the Hector ( Our hero ), he's not green 'cause he knows no better.

This is part of why this is a "A difficult development process". There are way more joys that I could share, but I'll hold fire. No one wants to read about someone bitching about their job.

Squize.

Abuse of asBroadcast

How pure is pure oop, how usefull are design patterns and how to abuse asBroadcast?

Well, for the current game I'm bound to f8/AS2 because the client's audience is still mostly on f8 and the attempts to make them update the player greatly failed and resulted in a lot of "what is an update of the flash player", "what is a flash player" and "I don't know how" emails ...

The game currently uses my usual structure, that is a single class for the game and some classes for UI, sprites, tiles ... I usually made the game class "LMGame" (LM for the game's name) a singleton, but I wondered if that would be a good practice after all.
(You might guess it, this is a more or less philosophic question.)

I wanted to reduce refrences and singletons to a minimum. (Squize wrote about the problems earlier)

So far I came up with few different methods for accessing the LMGame class from various other classes during the game ...
If needed I pas a reference to the LMGame / needed class but you must admit that this feels rather clumsy.
For the Sprites however I didn't want pass a reference to the LMGame class just to say "Hello" or "I'm dead" ... so I tried a rather unusual way for sprite -> game communication:

While the game has a list of sprites and could call functions directly, I decided to rely heavily on asBroadcast.
I installed a stack (FIFO), to pass values if needed and tried if things were working like I expected ... and they did ... :)

A sprite is moved with this._asBroadcast.broadcastMessage("onTickEvent"); (from the LMGame class' onEnterFrame) and if a sprite dies it places it's id into the stack and calls this._asBroadcast.broadcastMessage("onSpriteDie"); (which is triggered by the LMGame class).

This might seem overly complicated but it really "looks" wonderfull in code and it saves a great deal of thinking, too.

As this is just a "try", I'm not sure if it's going to become very usefull, but I just like trying new "ideas" ...

nGFX

One for the road

Well with "The Game of Life" due to go live any day soon, I figured it's about time we wrapped up the blog posts for it.

Here's the final game, "Gift Shop"

GiftShopButton.png

That's just some of the items you'll have to pick from to ensure all your family recieve a holiday gift from you.

And on that note, that's it for the development posts for GOL. The next one will be a sexy little url, so after sticking with us for the past couple of months ( Amazing that it's been going that long ) we're almost there.
Rest assured that as soon as it's live you'll all be the first to know.

Ok, back to "Phantom Mansion" ( Now that sounds like another series of development posts ;) ).

Squize.

"Please sir, can I have some more?"

Of course you can, more cheeky grabs from GOL that is you little trickster.

Here's some action shots from "Souper Bowl", which is possibly the first time I've ever had to code drool for a game ( These firsts are getting rarer, you know you've hit a new low when you've coded a baby messing it's nappy ).

Souper Bowl, it's all it's feeding the homeless glory

Mmmm, look at those bowls of piping hot soup. It's making you hungry isn't it ? Hungry for a bit of Game of life action that is!

Soon, oh so soon.

Squize.

PS. That could well be the cheesiest, hard sell blog post I've ever done. Which is saying something.

 

I want to fly like an eagle ...

... Let my spirit carry me.

So this is the third game (yes, I know, there are currently only two (including this one), but it seems that Squize didn't post yesterday ... shish!)

You surely remember the time when you just walked up the diving platform, stood on the highest one and did a somersault, backwards ...
... and you surely noticed that each year you thought about "what can go wrong" a bit more.

Well, after a certain point you forget about the risks and you go hang gliding, High Jinx in our case or short HJ.

gol_hj_00.jpg

gol_hj_01.jpg

Distance is the key to get your blood flowing again, and of course you have to do some resource management to get as far as possible.

After all I enoyed doing HJ, hope you enjoy plaing it.

2 games left ...

nGFX

Almost at the money shot

Not posted many updates about "The Game of life" here for a while, so we're well overdue for a catch up.

My "Gift shop" game is done and dusted. It's only a straight forward Mastermind style game, but it plays pretty well and looks great too. I like it as part of the package because it's so different to everything else in there, a slow paced logic game ( Albeit still against the clock ). Fits in there well, and I think it achieves the projects umbrella aim of being able to target as many different players as possible ( Not everyone loves games which use the arrow keys ).

Olli's just finished his final game, currently called "The Day of the Triffids" ( Or Dot ), it's the exact opposite of Gift Shop. Really nice fast paced action using an asteroids style control system to control a lawn mower as you cut the grass and remove unwanted visitors.
I think it's everyone's new favorite game within the set, and a great one to finish on.

So after all this time, and blood and sweat and swearing, we're nearly there. There are some front-end alterations that I've got to make this evening, but purely visual stuff to update the existing images in line with the final ones, and we're ( Touch wood, and I don't mean that in a nob joke way ) gold.

Be so cool to see this bad boy live. Soon my beauties, soon.

Squize.

Time based movement and tracks/tiles ...

Long time no post, so I thought it might be the time to do so again ...

While still working on the last GOL game ("The Day of the Triffids"), my mind starts wondering off to the next big project, the "logimotion" game.

I do dimmly recall that when doing the Wintertales/Deserrunner game I said something about explanation, but I guess it somehow slipped through just waiting there to be recalled now ...

So here we go:

Time based movement and tracks/tiles ...

While doing the engine I came to the point where I had to move the sprite over the player created tracks, two ways came to mind:

a) write some fancy stuff for each tile, using the sprite and offset it's coords according to the need of the tile.
b) write some fancy stuff that works whth each tile, using some other approach.

I decided to try the latter one.

What bothered me with the first method was that I had to map out coordinates or tween the sprite along the tracks which somehow wasn't what I wanted.

The second method wasn't that clear. I needed to find a way to move the sprite from the starting point of the tile/track to it's end ... after a few pointless tries I thought that I could just do it time based instead of position based.
This proved to be a very easy and re-useable way.

dt_track_00.jpg
screenie of the car in motion, showing the track, too.

As the car isn't shown top/dow, there needed to be some sort of animation and we wanted to be able to move with different speeds, too.

My first task was to invent some sort of naming convention which helps me to sort the different tiles and tell the code *what* this tile does without adding to much fuzz to the map.

So I decided to use a for digit code like 0011 for a corner from west to south, giving each direction either 1 for "exit" and 0 for "no" exit.
Then I decided to use "easings" to move from the starting point of the track to end point of the track. Moving a stright line (0101, or from west to east) would just ease the x value linear in say 16 frames (and because I had 16 animation frames ... you guess right).

This is what I stored for the tile:

this._tile_array[22] = {sx: 1, sy: 1, t: TileEngineClass.TILE_TRACK, f: "t_0101", d: "0101"};

sx/sy: size
t: tile type
f: frame in the tile mc
d: direction information

And this is what the player sprite "knows":

this._track_array["0101"] = new Array();
this._track_array["0101"][1] = {sx: _x0, sy: _y1, ex: _x2, ey: _y1, fx: EaseUtil.easeLinear, fy: EaseUtil.easeLinear, nd: 1};
this._track_array["0101"][3] = {sx: _x2, sy: _y1, ex: _x0, ey: _y1, fx: EaseUtil.easeLinear, fy: EaseUtil.easeLinear, nd: 3};

sx/sy/ex/ey: start coords/end coords for the easing
fx/fy: easing method for x/y
nd: the new direction after reaching the end point, used for corners mainly.

The sprite knows which direction (0-3, according to the 4 digits of the name) it's moving, the animation it should use ("0101" + frame for the current time) and it's time.

If the sprite reaches the endpoint of the ease, I can look up the next tile in the map array (because if the direction of the next tile is 1, I take the next tile east of the current tile).
If the next tile is empty, well the player creashes.

Easy, isn't it?

Here's the data for a corner:

this._track_array["1100"] = new Array();
this._track_array["1100"][2] = {sx: _x1, sy: _y0, ex: _x2, ey: _y1, fx: EaseUtil.easeInSin, fy: EaseUtil.easeOutSin, nd: 1};
this._track_array["1100"][3] = {sx: _x2, sy: _y1, ex: _x1, ey: _y0, fx: EaseUtil.easeOutSin, fy: EaseUtil.easeInSin, nd: 0};

In order make it faster I just reduce the time needed to get from start to end, though it's a good idea to use something that can be devided by 2, so the animation isn't messed up

You can see it in action: here (German version, though)

Back to the Triffids ...
nGFX

"Some people are heroes. And some people jot down notes."
        -- (Terry Pratchett, The Truth (us, de))