Problem with character scaling

Started by beomoud, Wed 21/01/2009 03:00:24

Previous topic - Next topic

beomoud

Ok, this has been a problem to me for a long time. In my game i need to use a function to control my character's and my npcs' scaling. It goes like this:

function my_race_scaling() {
  if (race ==1) {
    player.ManualScaling = true;
    player.Scaling = (GetScalingAt(player.x, player.y) *70)/100;
    player.z = -10;
  }
  else if (race ==2) {
    player.ManualScaling = true;
    player.Scaling = (GetScalingAt(player.x, player.y) *130)/100;
    player.z = -10;
  }
  else if (race ==0) {
    player.ManualScaling = true;
    player.Scaling = (GetScalingAt(player.x, player.y) *100)/100;
    player.z = -10;
  }
}

It works out smoothly, the only problem is when my character (or NPCs) get close to the edges of my Walkable area in that room and particularly around sharp edges they lose their scaling for a moment and appear much bigger than they would, in their sprites full size which is much bigger than any scaling you get in that room, keep in mind that i use continuous scaling. That looks bad when it happens. I use the upper function in the repeatedly execute function. Any ideas how to solve my problem and what i have done wrong? Would you do it any better?

Thanks...  :)

Gilbert

Hmmm, I'm not quite sure, but at sharp edges of a walkable area it may be possible that the character somehow walks past the area and rests in a non-walkable area where scaling is not defined (maybe for just one split frame or two).

My suggestion is that you may try to add a GUI for debug purpose, with two labels on it, which are updated in repeatedly_execute[_always]() with the information of the walkable area he's currently on and the current scaling (via GetWalkableAreaAt(player.x, player.y) and player.Scaling). Monitor the values when odd things happen and see if you can have any idea form them.

beomoud

problem fixed...i used a function from an old post and it works out fine, i'm sorry to have bothered you. here it goes:

function Scale(this Character*, int factor) {
  if (this.Room != player.Room) return;
  if (!this.ManualScaling) this.ManualScaling = true;
  int s = (GetScalingAt(this.x, this.y) * factor)/100;
  if (s<1) s = 1;
  if (s>200) s = 200;
  this.Scaling = s;
}

Thanks, you may delete this post now....

Fritzi

I don't see how the new function can give a different result, the only
difference is a couple of checks which should not influence the cases
beomoud describes.... Can anyone explain?

Gilbert

Well, there are restrictions on the range of scaling (1% to 200%) and I don't know what will happen if you supply an out-of-range parameter to the function, so the checkings are to ensure that the scale paramenter is within the range. I don't know whether his original problem was caused by this though.

Khris

Maybe it's because my code doesn't set .ManualScaling to true every game loop.
Beomoud's would get out of bounds if a race 2 char gets to a wa scaling of ~155, don't know what values he's using though.

beomoud

It does keep doing it but not so often anymore. The function i was using before for my NPCs was:

function race_scaling(int scaled) {
  character[scaled].ManualScaling = true;
  character[scaled].Scaling = (GetScalingAt(character[scaled].x, character[scaled].y) *(person[scaled].race_multiplier))/100;
  character[scaled].z = -10;
}

I don't get it, is there a problem with the way the engine detects the walkable areas?

Pumaman

As Gilbert says, the X/Y co-ordinates of the player are not guaranteed to always be over a walkable area, since when the character is walking around the corner or along the edge of a walkable area they may briefly slip outside the area while doing so.

Therefore, you cannot guarantee that GetWalkableAreaAt/GetScalingAt will work correctly when using a moving character's X/Y co-ordinates. You would need to wrap it in a custom function that checked a couple of pixels in each direction if the GetWalkableAreaAt returned 0.

Of course, the usual solution to this that I would suggest is checking the character's Scaling property instead of using GetScalingAt -- however in this case because you're changing the Scaling property it won't work.

beomoud

I tried that... i tried adding the GetWalkableAreaAt condition, i checked a few pixels around the player but nothing changes. It seems like it finds the walkable area under the player but it reads the scaling property as 0. Isn't there a way to manually scale a character correctly? How is it normally done? This is my only big problem. I forgot to mention that i run this function in repeatedly execute where every game cycle the character scaled is a different one (it cycles among the characters in the game...). Any ideas? Even if when the character loses his scaling the wrong scaling was close to the right one so that this wasn't so obvious that would be enough for me... Can someone test any of these?

Pumaman

Can you upload some sort of sample game that demonstrates this problem?

beomoud

this is a game sample, not just the compiled. i have circled some of the problem areas. just walk close to the limits of the walkable area, you will see the problem

http://www.easy-share.com/1903572559/test.zip

SSH

I suggest remembering the previous scaling, and checking what walkable area is under the character: if none, then use the previous scaling, if there is one then apply your formula as usual.
12

beomoud

#12
I already tried that using arrays for every character, it just seems to recognize the walkable area as 1 but still  gets the wrong scaling. But i kind of fixed it in another way, i used to call the player's function every game cycle, now that i put him with the rest of the characters every second it doesn't do it any more except from very rarely, i guess it's good enough. thank you...

SSH

Well, since the scaling is just dependent on the Y value of the char, why not just work it out manually, rather than using AGS's getscaling function?

scaling = (((max_scale-min_scale)/(max_y-min_y)) * (char.y-min_y)) + min_scale;
12

beomoud

By the way what would max_y and max_x represent. And what would max_scale and min_scale be, cause the engine doesn't provide you with the max and min scaling parameters of the room i would have to define those values in every room wouldn't i?

Pumaman

Quote from: beomoud on Mon 09/02/2009 00:24:21
this is a game sample, not just the compiled. i have circled some of the problem areas. just walk close to the limits of the walkable area, you will see the problem

http://www.easy-share.com/1903572559/test.zip

Ok, I've taken a look at this. The cause of the problem is the fact that GetWalkableAreaAt takes screen co-ordinates, not room co-ordinates, and this is a scrolling room.

I tried replacing this line:

if (GetWalkableAreaAt(this.x, this.y) != 0){

with this:

if (GetWalkableAreaAt(this.x - GetViewportX(), this.y - GetViewportY()) != 0){

and that seems to resolve the problem.

beomoud

Thanks a lot. I really needed that fix.  :)

SMF spam blocked by CleanTalk