scaling individual loops/frames?

Started by Goldmund, Mon 22/03/2010 10:51:14

Previous topic - Next topic

Goldmund

Hilfe!

After completing many-framed animations in my game I've noticed that the character is much bigger in her front loop than in left/right ones.
It's not that I'm lazy - it's just resizing them (and drawing transparency around the silhouttes) would take a lot, a big fat lot of time.
Is there a way to use some scripting magic, I wonder, to make certain loops ALWAYS scaled some percent less than other loops? Or a way to resize frames in engine?

To the rescue, oh please!

Calin Leafshade

can't you just use an if?

something like

Code: ags

if (cEgo.Loop == 1) cEgo.Scaling = 95;
else cEgo.Scaling = 100;


Sorry dont have AGS with me so i dunno the actual property

Khris

Yep, set player.ManualScaling to true, then put that in rep_ex_always.
You can also use GetScalingAt(player.x, player.y) to calculate the scaling in case you're using continuous scaling.

Goldmund

Thanks! I've tried that trick with rep_exec, but the thing is that I also want different walking area scaling to work in all different rooms; I made it so that it always takes away a point or two from scaling if the character's in a certain loop, but it comes off jerky, even though my comp is quite fast -- the character is displayed in the walking area scaling first, for an eyeblink, and then goes to the scaling diminished by the script.

I'd need something faster or radical - like, a command to automatically shrink a number of sprites.

Dualnames

Quote from: Goldmund on Mon 22/03/2010 17:28:31
Thanks! I've tried that trick with rep_exec, but the thing is that I also want different walking area scaling to work in all different rooms; I made it so that it always takes away a point or two from scaling if the character's in a certain loop, but it comes off jerky, even though my comp is quite fast -- the character is displayed in the walking area scaling first, for an eyeblink, and then goes to the scaling diminished by the script.

I'd need something faster or radical - like, a command to automatically shrink a number of sprites.

There's a module called DistortChar. Very handy! It can 'change' the sprites frames of all loops of a view for the duration of the whole game, just by simple command at the game start.

I also use the Manual Scaling command but use it on the repeatedly_execute_always. It works fine there, I also but the scaling thing to run once before each room fade-in.
Worked on Strangeland, Primordia, Hob's Barrow, The Cat Lady, Mage's Initiation, Until I Have You, Downfall, Hunie Pop, and every game in the Wadjet Eye Games catalogue (porting)

Shane 'ProgZmax' Stevens

Take your original sprites, resize them, re-import.  Done.

Goldmund

Quote from: Dualnames on Mon 22/03/2010 20:46:46
There's a module called DistortChar. Very handy! It can 'change' the sprites frames of all loops of a view for the duration of the whole game, just by simple command at the game start.

Thanks! I took a look at it, I need to experiment more, but maybe it can help me.

Quote from: ProgZmax on Fri 26/03/2010 08:12:51
Take your original sprites, resize them, re-import.  Done.

If you haven't read my first post, ignore the sentence below.
If you have - take your advice, unzip your pants, bend over and let your imagination do the rest.

GarageGothic

#7
Quote from: Goldmund on Mon 22/03/2010 17:28:31the character is displayed in the walking area scaling first, for an eyeblink, and then goes to the scaling diminished by the script.

Make the real character invisible and pass it's coordinates and viewframe to a visible dummy character in the rep_exec_always, use ManualScaling to set the size to the invisible character's scaling, BUT with a conditional that modifies the scaling for the problematic loops.

e.g.

Code: ags
function repeatedly_execute_always() {
  cDummy.x = player.x;
  cDummy.y = player.y;
  cDummy.LockViewFrame(player.View, player.Loop, player.Frame);
  if (cDummy.Loop == 2) cDummy.Scaling = 90*player.Scaling/100; //reduce to 90% of actual character scale
  else cDummy.Scaling = player.Scaling;
  }

function game_start() {
  cDummy.ManualScaling = true;
  player.Transparency = 100; 
  }


(not tested)

Edit: Changed (cDummy.View = player.View) etc. to LockViewFrame for shorter code, I don't think it makes any difference but maybe you will need to call cDummy.UnlockView() right before the LockViewFrame call.

Goldmund

You are amazing!  :o

Thanks a million! Works brilliantly. No UnlockView needed.

You see, after a while of celebrating I've tried to improve on your solution: let's make it that the player character is visible and manually scaled only and make it's scaling based on the invisible Dummy automatic scaling, and it failed (jerking big/small) again. I wonder why, the mechanics should be the same.


Kweepa

#9
Here's an alternative method, as long as you're not planning to resize the character again based on area scaling (which would result in an ugly double scaling):

DynamicSprite *gSpriteBuffer[1000];
int gSpriteBufferSize = 0;

function ResizeViewLoopByPercentage(int view, int loop, int percentage)
{
  int frame = 0;
  int numFrames = Game.GetFrameCountForLoop(view, loop);
  while (frame < numFrames)
  {
    ViewFrame *viewFrame = Game.GetViewFrame(view, loop, frame);
    DynamicSprite *ds = DynamicSprite.CreateFromExistingSprite(viewFrame.Graphic);
    ds.Resize((percentage*ds.Width)/100, (percentage*ds.Height)/100);
    viewFrame.Graphic = ds.Graphic;
    gSpriteBuffer[gSpriteBufferSize] = ds;
    gSpriteBufferSize++;
    frame++;
  }
}

// in game_start, for example
  ResizeViewLoopByPercentage(VIEW1, 2, 90);


[EDIT] Using GetFrameCountForLoop as suggested by GG
Unfortunately you need to pass the number of frames in the loop since I don't think there's an accessor (monkey?).
Still waiting for Purity of the Surf II

Shane 'ProgZmax' Stevens

#10
QuoteIf you have - take your advice, unzip your pants, bend over and let your imagination do the rest.

Hostile much?  Don't take your laziness out on me.  My suggestion was perfectly valid and doesn't involve any unnecessary workaround scripting to compensate for something you should have done right in the first place.  I mean, seriously...using a script to resize a few sprites in game because you can't be bothered to spend 5 minutes resizing them in just about any paint program?

Kweepa

What if he rescaled all the sprites to 90%, and then decided that perhaps 92% would have been better? :'(
Why do you care how he develops his game anyway?
Still waiting for Purity of the Surf II

Shane 'ProgZmax' Stevens

You're right, how silly of me to make a valid suggestion and then be insulted for it.

GarageGothic

#13
Quote from: Goldmund on Fri 26/03/2010 20:54:23You are amazing!  :o

Thanks, I know! (and modest too  ;D)

Kidding aside, I'm happy it worked. The benefit of this method compared to the DistortChar module and Steve's script is that it uses AGS' built-in character scaling instead of resized DynamicSprites, so they keep their alpha channel (if 32-bit color) and don't bloat savegame size. Also, I guess anti-aliased scaling might look slightly more consistent since it doesn't get resized with nearest-neighbour first.

Quotelet's make it that the player character is visible and manually scaled only and make it's scaling based on the invisible Dummy automatic scaling, and it failed (jerking big/small) again. I wonder why, the mechanics should be the same.

I've encountered variants of this problem in several different contexts, and I *think* what happens is that the character animates and gets drawn at the end of the game loop and thus the changes you made are overridden  by the built-in animation system. The main reason for using a dummy that doesn't move or animate by itself is to make sure that their sprite only gets updated when we do so manually. If you turn the actual player character visible and keep the dummy visible too, you will notice that the dummy usually lags a frame behind, creating a sort of tracer effect.

Quote from: SteveMcCrea on Fri 26/03/2010 21:50:04Unfortunately you need to pass the number of frames in the loop since I don't think there's an accessor (monkey?).

Game.GetFrameCountForLoop(int view, int loop)

Goldmund

ProgZmax:

Firstly, your suggestion wasn't valid.
I've presented a technical problem: how to resize individual loops without having to resize sprites.
Your answer: resize sprites.
Was it helpful? No.
Was it an answer to the question posed in the thread? No.
Was the person asking for help unaware of this possibility? No, and you knew it.
Was it prickly? Yeah.

Secondly, I don't have to explain myself, but since you're so interested in my vices and strength of my character, I will: it's not five minutes. We're talking about something like 15-20 minutes for a single frame, because I need to redraw transparencies. Multiply by three sets of clothes, picking up anims, crouching anims, etc. Having to work for my family sustenance, caring for a small child AND trying to finish my game makes time precious.
And it makes one less patient with smartasses. :-)

Steve:
your script blows my mind ;-) No, but the main problem was that it should also react to walking area scaling. I can't really tell what your solution does, the script's too advanced -- it resizes the sprites at the start of the game? If so, will the automatic area scaling work with them? That's what I need...

GarageGothic:
I see, so the player's automatic scaling runs first, and then we have rep_exec.
It's dummy for me, then!
Thanks again.

Dualnames

Goldmund (remaining off-topic) I don't think ProgZ offered a smartass advice at any point. Nor he is a smartass. He just knows a way not to do this technically 100% but actually solve the problem without scripting a code.
Worked on Strangeland, Primordia, Hob's Barrow, The Cat Lady, Mage's Initiation, Until I Have You, Downfall, Hunie Pop, and every game in the Wadjet Eye Games catalogue (porting)

Snarky

Quote from: Goldmund on Sat 27/03/2010 08:51:28
Secondly, I don't have to explain myself, but since you're so interested in my vices and strength of my character, I will: it's not five minutes. We're talking about something like 15-20 minutes for a single frame, because I need to redraw transparencies. Multiply by three sets of clothes, picking up anims, crouching anims, etc.

It's not clear to me why you can't simply take each frame you have in its final form and resize that. The transparencies should work out correctly on their own, with no need to redraw anything. If the problem was that the sprites are resized from a bigger original, and resizing them again would reduce the quality, that's fair enough, but then resizing them in AGS wouldn't get around the problem.

Anything that a fixed scaling in AGS gets you, you should be able to get by pre-scaling in Photoshop or whatever. And since you can do the scaling with a macro and batch-process all the images automatically (in IrfanView if you don't have Photoshop), it should literally be only five minutes regardless of how many loops and frames we're talking about.

Goldmund

Dualnames:

well maybe I have emotional intelligence of a retard, but for me there's no doubt that Progz was being haughty for one reason or another.

Snarky:

Alas, not so!

Before:


After resizing:


Ryan Timothy B

#18
Resize to nearest neighbor that way you won't have the AA resizing of Bilinear/Bicubic.

It may have certain side effects where the pupil or such detail may actually be omitted, but it'll certainly do the same with DirectDraw.

edit: but obviously you know how to resize to nearest neighbor, since your posted image appears to be 12x12 pixels - which leaves me confused as to why you posted a scaled down image with the AA residuals of Bilinear/Bicubic resizing.  Or you simply don't like the effects of Nearest Neighbor resizing, which I can understand.

Goldmund

Heh, no, I didn't know that about the nearest neighbour!

It doesn't seem to leave AA, as you say.

It does look uglier, though; for example, an eye seems to be closed, nose bit distorted etc.

Using this script I can have the 100% view in-game, at least, but it's great that now I know this way of resizing! Thanks.

SMF spam blocked by CleanTalk