Scaling actors

In a point and click adventure game there are many rooms in which the actor’s distance to the ‘camera’ is more or less the same everywhere he goes.
But there might be rooms where perspective is important. Think long hallways, large outside areas, huge room, weird camera angles, etc.
Look at the picture below. These are a few examples of area’s where the actor can move closer to and further away from the camera:


When you play these games (Day of the Tentacle, Indiana Jones and the Fate of Atlantis, and Monkey Island II) these areas feel very natural. How the actor scales and moves depending on the location feels just right (most of the time).

What is it that it feels natural? And how do you implement this?First thing you notice when you walk around these areas is that the actors scales down or up depending on how ‘far away’ the character is. Its size matches the surroundings where he walks.
But scaling alone is not enough. You also have to adjust the vertical and horizontal walking speed. If you don’t adjust that speed, and the actor is half its normal size because it’s far away, then the speed in which he walks seems ridiculous fast.

So when implementing this adapting behavior, you have to adjust 3 variables: size of the actor, horizontal speed, and vertical speed. It is necessary to adjust both vertical and horizontal speed, because depending on the room, you need different walking speeds in different areas. These values might be different from room to room, especially when your game has a very cartoonish style with weird deformations and perspectives (like Day of the Tentacle).

Allright, let’s implement this. How do we know what size and speed the actor needs? How can we define this in our room?
There are several ways to accomplish this. Probably more than the 3 I’ll mention here:

1. Scaling using the Y axis
Using this method you just scale the actor down when it goes up on the screen. In many rooms this is sufficient. When the character walks into the distance, most of the time it is also going up on the screen. This is the easiest implementation. Just add a scale factor to the Y position on the screen. And also scale the vertical and horizontal movement speed.
Pros: Very easy to implement. Probably sufficient for most rooms.
Cons: It limits the type of rooms you can create, because you can’t create a room with different scaling factors on the same y-axis.

2. Scaling using walkboxes
This can only be used when you use walkboxes, or polygons to define the walkable area. If you build a walkable area using walkboxes/polygons, you can add a scale factor to each vertex of the walkbox/polygon and interpolate that scale factor depending on the position the actor is inside that walkbox/polygon. With this you can create a very exact scaling (depending on how detailed your walkable area is), but it can be very time consuming to adjust all the scale factors on all the vertices.
Pros: Easy to implement. It allows for many different styles of rooms.
Cons: Time consuming to edit and maintain

3. Use alpha value for scale factor
This is the method we use for now and it suits our needs. For this method we create an extra bitmap image for each room that needs actor scaling. That bitmap is only painted in the walkable area. The transparency (alpha value) of each pixel defines the scale factor used. So when the actor is walking around we know exactly on which pixel he is in the bitmap (the bitmap is obviously not shown. It’s only loaded in memory). So we can scale the actor and its movement according to the alpha value of the pixel.
Using tools like Adobe Photoshop it is easy to create a gradient bitmap where the transparency gradually increases.
Pros: Very easy to implement. It allows for many different styles of rooms.
Cons: Not necessarily easy to create for everyone

Let’s look at a simple example created using our own engine:
(disclaimer: crappy programmer art and a stolen character sprite)

Here we see a room with a deep hallway and some stairs. The actor scales down when he walks down the hallway further away from the ‘camera’. He scales up when he gets closer. When he walks up the stairs, he only scales down a little bit (barely noticeable).

Using method 1, scaling on the y-axis, would not work here, because our character would scale down a huge amount when walking up the stairs.
In our engine we use method 3. That means we have a bitmap for the background, and another bitmap for the scaling using transparency. This can be seen here:

And combined with the background:

You can see the transparency increases down the hallway. And it increases only a little going up the stairs.

Our engine loads this bitmap in memory when the room is loaded. When the actor walks around the room, the engine knows on which position it walks on the background bitmap, so it also know which pixel to pick from the bitmap in memory. Then we use ‘alpha value’ of that pixel to determine the scale factor.

Which scale factor you need depends on the room, and it’s a lot of trial and error to get it just right in the room.

Of course there are other ways to accomplish this, and ours may not even be the best way. But it works for us, and might work for you.

That’s it for now. If you have any questions, please leave a comment.

2 thoughts on “Scaling actors

  1. Hi there, I made a Adventure game engine from scratch and it’s interesting to see how different ppl attack these kind of problems.

    To solve this (scaling) I’ve used a pivot system. I calculate a lerp between the firs pivot higher and lower the scaling target. each pivot has a “scale value”. the X speed is calculated based on high of actor * max_speed. and the Y speed is calculated based on the diference in size of these pivots and how “close” they are.

    Example: if the pivots are really close but the diference in high is big, that means that the perspective angle is really low. so if the character moves only a few pixels up, in reallity is going very far away and should take a long time.

    I can put many pivots on each screen if the perspective is curved.

    If the room is warped from right to left, I can put different pivots that “activates” another set of pivots that work best on that place of the screen.

    The workflow is really fast because is visual and integrated with the room customization part of the engine.

    I don’t know if this helps at all, I’m just giving my “perspective” on the matter 😀

    1. That sounds really interesting and very flexible.

      It might be complicated to set up a scene that way, but when it’s well integrated in the room editor, that shouldn’t be a problem.

      Thanks for sharing!
      If you have a website/blog/source where you explain it in more detail, I’m happy to include a link here.

Leave a Reply