Smoother scaling

Started by Sughly, Mon 05/04/2021 09:10:47

Previous topic - Next topic

Sughly

Hi - I'm working on a game with walkable areas that are quite thin and isometric, and am finding the continuous scaling option a little clunky for this as it applies quite significant shifts in scaling as the player walks left to right (difference between top pixel and bottom pixel of the area isn't very high, but there needs to be a fair difference in scaling from far left of screen to far right). I found a super old module that can shift the angle of scaling, making it scale from left to right rather than top to bottom (link here), but it doesn't seem to run right now (could just be me being dull) and was just curious if there was already something like this in the updated engine?

Posted in Beginner's since I suppose this could very well be a simple reply! Bit old and rusty on this engine :~(

Snarky

#1
I don't think left-to-right scaling is built into the engine, but it's not too difficult to implement (untested code, may have bugs):

Code: ags
void SidewaysScale(this Character*,  int xLeft, int xRight, int scaleLeft, int scaleRight)
{
  float weight = IntToFloat(this.x-xLeft)/IntToFloat(xRight-xLeft); // How far along we are from left to right, scaled from 0.0 to 1.0
  int scale = FloatToInt((1.0-weight)*IntToFloat(scaleLeft)+weight*IntToFloat(scaleRight),eRoundNearest);
  this.ManualScaling = true;
  this.Scaling = scale;
}

function late_repeatedly_execute_always()
{
  // For every character in the game...
  for(int i=0; i<Game.CharacterCount; i++)
  {
    Character* c = character[i];
    // If the character is in the relevant walkable area...
    if(c.Room == player.Room && GetWalkableAreaAt(c.x - Game.Camera.X, c.y - Game.Camera.Y) == SCALING_AREA_ID)
    {
      // Do the sideways scaling
      c.SideWaysScale(SCALING_AREA_LEFT_X, SCALING_AREA_RIGHT_X, SCALING_AREA_LEFT_SCALE, SCALING_AREA_RIGHT_SCALE);
    }
  }
}


(If you're using an older version of AGS, use GetViewportX() and GetViewportY() instead of Game.Camera.X and Game.Camera.Y.)

Here, all the SCALING_AREA constants are numbers you need to set for the particular walkable area you want to do this sideways scaling. (If you're doing it for many walkable areas, you'll probably want to create some sort of array.)

Sughly

Thanks for the help Snarky! I'm not even pretending that I know half of what's going on in this, but I'm getting an error on line 4 there  - Type mismatch, cannot convert 'float' to 'int'...

I appreciate the help!

Snarky

Oh yeah, scaleRight needed to be wrapped in an IntToFloat(). I've edited the code accordingly.

The idea is simply to take a weighted average of the left-hand scale and the right-hand scale factors, with the relative weights depending on how far along from left to right the character is. (So at the left edge the scale is 1*leftScale + 0*rightScale = leftScale, at the halfway point it's 0.5*leftScale + 0.5*rightScale, and at the right edge it's 0*leftScale + 1*rightScale = rightScale.)

The late_repeatedly_execute_always() function simply goes through all the characters in the game each screen update, checks if they are on this walkable area, and if so, applies the scaling. (One thing that is missing here is to turn off manual scaling if they aren't on the area in question. This means they won't respond to built-in scaling after crossing the area, so we'll need to fix that later.)

SMF spam blocked by CleanTalk