In action
A little while ago, I was asked about what would be a good approach to creating an effect for a top-down game where coins would fly out of a smashed object. Not recalling any tutorials on the matter, I've made an example of this exact thing, and this is a post detailing everything related to such an effect.
Before we start
First things first, let me link you to the graphics used in this tutorial:
- Coin: the gold coin from "Animated coins" by Clint Bellanger.
-
Chest: the treasure chest from "Gold Treasure icons" by Clint Bellanger.
The "closed chest" version was done by Seki Znojemsky.
The "spritesheet" used here consists of ten 32x32 images and looks like the following:
Also, for clarity on axes, here I'm going to call "X" the axis that goes from left (-) to right (+), "Y" the one that goes from top to bottom, and "Z" the one that goes from bottom to top (opposite of Y):
(mouseover for animation)
Meet the coins
From left to right: coin, coin, coin, coin, and coin.
Let's talk about the items in videogames a little. Chances are that your game may have lots of them (either in terms of variety or volumes), and the individual value may not be exceptionally high (especially for "score" items). Thus there's sense of giving the player additional incentives of gathering them, even if just for shiny looks.
So let's take a look at some common concepts for making these more interesting:
Third axis
If your game is anything near the definition of "top-down", chances are that the playable field is technically flat. Or almost flat, aside of some exceptions. However, this doesn't mean that you can't add a bit of additional depth by giving the objects a "cosmetic" third axis. In a simple case that's means simply offsetting the vertical position of the object:
Shadows
As can be seen in the example above, just offsetting the vertical position of an object is not sufficient to achieve depth. You'll need something more, and that is shadows.
Your shadows can be sharp or smooth, circular or precise, but their important property is that they lie on the ground and allow the viewer to easily estimate how far from the ground the given object is.
The first coin shown has a basic (constant size) shadow. It does the job, but offers limited assistance in telling apart which object is casting the given shadow if there are multiple ones at one spot.
The shadow of the second coin grows smaller based on it's vertical position, in this case 12 / (1 + z / 20)
, where "12" is the base size of the shadow in pixels (when on the ground), and "z" is coin's vertical position. While this isn't how the shadows really work, the shadow gets proportionally smaller as the distance increases (1/2 at 20px, 1/3 at 40px, 1/4 at 60px, ...), and looks just good enough after minor tweaking.
The third coin's shadow is same as the second one's, but with a minor change - the shadow now "pulsates" a little (cosine function) to match up with the waving motion in the coin animation.
If your item animations do not include movements, you can make the items itself move upwards and downwards a few pixels.
This both makes the items look a bit more interesting and makes them easier to spot in the scenery.
Rendering order
Here's to another small-but-important thing - the drawing order. Chances are that you (or your engine\framework or preference) already have this sorted out, but just in case:
With the shown top-down[-ish] view, the objects are to be sorted based on their vertical coordinate - the lower the object's center [on the ground] is on the screen, the later it should be drawn.
In GameMaker you can accomplish this via depth = -y
; In Unity3d you can use Renderer.sortingOrder; If you're handling the things by yourself, you can just sort the array of game objects as you please.
Distance from the object to the ground doesn't need to have any influence on the drawing order.
Entity physics
Now, items bobbing and weaving are some good stuff, but what about the more important things? Like sliding. Or bouncing. So let's get to that too:
Z-axis physics
These are ridiculously simple - since the only thing that an entity can collide with on Z axis is ground, checking that is simply a matter of checking if it's Z fell below the value (in this case, 0):
// apply gravity if the entity is in the air: if (z > 0) zspeed -= gravity; // add speed to altitude: z += zspeed; // if the entity did hit the ground: if (z < 0) { // simulate a bounce (to avoid negative Z): z = -z; // if the entity was falling down, reduce the speed: if (zspeed < 0) zspeed = -zspeed * 0.6 - 0.7; // (handpicked constants) // if the speed is now below the threshold, snap the entity to the ground: if (zspeed < 1) { z = 0; zspeeed = 0; } }
XY plane physics
Having items bounce around already livens up the scene a little, but it could always do with a little more momentum. Depending on the tools used, you may already have this part covered for you, but just in case:
In the simplest situation, you would have two variables to hold the current speed (units per frame) for X and Y axes accordingly, add them to X\Y coordinate each frame, and apply friction:
// apply speed: x += xspeed; y += yspeed; // find speed vector length: var len = sqrt(xspeed * xspeed + yspeed * yspeed); if (len > 0) { // find the multiplier (new speed divided by current): var mul = max(len - friction, 0) / len; // apply the multiplier: xspeed *= mul; yspeed *= mul; }
The final result
And so, with all these things combined, you get the result just as shown in the beginning of this article:
Click to place chests; click chests to open them.
Downloads
- Haxe: gist · try.haxe
- GameMaker: GMZ
- JavaScript: Haxe-generated. Or just view the page source.
Have fun!
Coool!
Thank your the the Concept! Great read!!!!!
And to all. It is easy in Unity engine too.
Concept
https://i.imgur.com/YpoorK5.gif
Let chest give me more chests!
https://i.imgur.com/NFe5iSo.gif
Would love a unity tutorial :(
Me too, but apparently tutorials don’t write themselves
unity tutorial pls
Maybe at a later date, as the overhead of reinstalling Unity does not feel justified if the code is going to be much the same sans transform.position.x instead of x.
If what you are after is Z-ordering specifically, I think you can find talks/posts on how this was handled in Enter the Gungeon, which had a non-perspective camera look at the level at a slight angle and geometry stretched at two axes to compensate for view angle distortion.
from 2020 … is there any hope for a unity tutorial?
Despite the technological advancements, the tutorials still don’t write themselves, and although my posts are licensed permissively and people can translate them to other engines or languages, that also requires someone to put in the work.
Awesome!
The gmz download link does’nt work, can you please make an other link to it?
Fixed.
Thanks you very much :)
thank you very much this is super cool
Pingback: Understanding isometric grids
Super! Thanks!
So simple but yet so powerful. Thanks :-)