continuous scalling (right2left instead of top2bottom)?

Started by YotamElal, Sun 24/04/2005 13:10:30

Previous topic - Next topic

YotamElal

continuous scalling defualt is x% top to x% bottom.
my character is walking on a wall and I need him to be 80% on the left of the walkabel area and 100% on the right?
(instead of top to bottom)?

any ideas?

strazer

Try this:

Code: ags

// room script

// adjust these to your needs:
#define WALKABLEAREA_NUMBER 1
#define LEFT_EDGE 20
#define RIGHT_EDGE 150
#define SCALING_MIN 80
#define SCALING_MAX 100

function repeatedly_execute_always() {

  int scaling = SCALING_MIN + (((character[GetPlayerCharacter()].x - LEFT_EDGE) * (SCALING_MAX - SCALING_MIN)) / (RIGHT_EDGE - LEFT_EDGE));
  SetAreaScaling(WALKABLEAREA_NUMBER, scaling, scaling);

}


The formula could probably be streamlined a bit, I'm not too good with these things.
Any math wiz's please step in.

YotamElal

The game gives an error saying that the area scaling needs to be
between 5-200 in this line.

  int scaling = SCALING_MIN + (((character[GetPlayerCharacter()].x - LEFT_EDGE) * (SCALING_MAX - SCALING_MIN)) / (RIGHT_EDGE - LEFT_EDGE));
  SetAreaScaling(WALKABLEAREA_NUMBER, scaling, scaling);

YotamElal

My LEFT_EDGE is 261
My RIGHT_EDGE is 319
(the wall is on the right of the screen)
it give the error.

when I switched 261 with 319 it works but as if it were a wall on the left of the screen.
on the right of the wall my character gets smaller & on the left he gets bigger.
what do I need to change the code to make it work with a right wall?

THNX


Gilbert

What did you set for SCALING_MAX?
Like the error pointed out it must be <=200.

strazer

LEFT_EDGE and RIGHT_EDGE have to be the outermost edges of the walkable area.

If your character is able to walk outside this walkable area, try this:

Code: ags

//...

  if ((character[GetPlayerCharacter()].x >= LEFT_EDGE) && (character[GetPlayerCharacter()].x <= RIGHT_EDGE)) {
    int scaling = SCALING_MIN + (((character[GetPlayerCharacter()].x - LEFT_EDGE) * (SCALING_MAX - SCALING_MIN)) / (RIGHT_EDGE - LEFT_EDGE));
    SetAreaScaling(WALKABLEAREA_NUMBER, scaling, scaling);
  }

//...

Gilbert

Actually it's also possible that there are other walkable areas other than that one used for manual scaling, and are you sure that the character can't walk left past 261 and right past 319 ?

Strazers' code should work, or, if there're other areas that he can walk on you can also change the scaling code to only execute when the character's in that particular area:
if (GetWalkableAreaAt(character[GetPlayerCharacter()].x,character[GetPlayerCharacter()].y)==WALKABLEAREA_NUMBER) {
 int scaling = SCALING_MIN + (((character[GetPlayerCharacter()].x - LEFT_EDGE) * (SCALING_MAX - SCALING_MIN)) / (RIGHT_EDGE - LEFT_EDGE));
  SetAreaScaling(WALKABLEAREA_NUMBER, scaling, scaling);
}


strazer

GetWalkableAreaAt works with screen coordinates, so you may get problems in scrolling rooms. But either way should work.

Edit:

In general, has anyone tested if you can pass negative values for things that are left of the viewport and higher values for things that are right of the viewport to functions that expect screen coordinates?

YotamElal

THNKU both

The scaling is working on walls!

except for in a scrolling room, the right wall makes my character  tiny like 10% for some reason???

strazer

It works fine here (using my if-clause).

Which one of our suggestions have you used?
How big is the room?
What are your LEFT_EDGE etc. settings?

YotamElal

ok i tried your "if" to & it doesn't change the scaling with it.

before I tried with Gilbot's "if" & it worked but not in thescrolling room.

my scrypt
#define WALKABLEAREA_NUMBER 11
#define LEFT_EDGE 45
#define RIGHT_EDGE 0
#define SCALING_MIN 80
#define SCALING_MAX 100

#define WALKABLEAREA_NUMBER2 14
#define LEFT_EDGE2 504
#define RIGHT_EDGE2 545

if (GetWalkableAreaAt(character[GetPlayerCharacter()].x,character[GetPlayerCharacter()].y)==WALKABLEAREA_NUMBER) {
int scaling = SCALING_MIN + (((character[GetPlayerCharacter()].x - LEFT_EDGE) * (SCALING_MAX - SCALING_MIN)) / (RIGHT_EDGE - LEFT_EDGE));
SetAreaScaling(WALKABLEAREA_NUMBER, scaling, scaling); }
 
if (GetWalkableAreaAt(character[GetPlayerCharacter()].x,character[GetPlayerCharacter()].y)==WALKABLEAREA_NUMBER2) {
int scaling = SCALING_MIN + (((character[GetPlayerCharacter()].x - LEFT_EDGE2) * (SCALING_MAX - SCALING_MIN)) / (RIGHT_EDGE2 - LEFT_EDGE2));
SetAreaScaling(WALKABLEAREA_NUMBER2, scaling, scaling); }

room size 640 240
2 times my regular rooms (width)

...
Thanks

strazer

As I said, GetWalkableAreaAt works with screen coordinates, but Character.x are room coordinates, so try this:

if (GetWalkableAreaAt(character[GetPlayerCharacter()].x - GetViewportX(), character[GetPlayerCharacter()].y - GetViewportY()) == WALKABLEAREA_NUMBER) {

YotamElal

strazer ur the best!

It works good now! no more scalling problems!

SOLVED!

strazer

Glad I could help. :)

I think switching the LEFT_EDGE and RIGHT_EDGE values to reverse the scaling is a bit unintuitive, so I came up with this (just for reference):

Code: ags

// room script

// adjust these to your needs:
#define AREA_A_ID 1 // number of walkable area
#define AREA_A_LEFT_EDGE 0 // left edge always < right edge
#define AREA_A_RIGHT_EDGE 150
#define AREA_A_SCALING_LEFT 100 // switch these...
#define AREA_A_SCALING_RIGHT 50 // ...values to reverse scaling
#define AREA_A_CHARID GetPlayerCharacter() // or EGO or GUY etc.

function repeatedly_execute_always() {
  //...

  //--------------------------------------------------
  // Walkable area A horizontal scaling
  //--------------------------------------------------
  if ((character[AREA_A_CHARID].x >= AREA_A_LEFT_EDGE) && (character[AREA_A_CHARID].x) <= AREA_A_RIGHT_EDGE) { // if character is on walkable area A
    int scaling;
    if (AREA_A_SCALING_RIGHT > AREA_A_SCALING_LEFT) // if scaling left-to-right
      scaling = AREA_A_SCALING_LEFT + (((character[AREA_A_CHARID].x - AREA_A_LEFT_EDGE) * (AREA_A_SCALING_RIGHT - AREA_A_SCALING_LEFT)) / (AREA_A_RIGHT_EDGE - AREA_A_LEFT_EDGE));
    else // if scaling right-to-left
      scaling = AREA_A_SCALING_RIGHT + (((AREA_A_RIGHT_EDGE - character[AREA_A_CHARID].x) * (AREA_A_SCALING_LEFT - AREA_A_SCALING_RIGHT)) / (AREA_A_RIGHT_EDGE - AREA_A_LEFT_EDGE));
    SetAreaScaling(AREA_A_ID, scaling, scaling);
  }
  //--------------------------------------------------

  // Walkable area B etc.

  //...
}


Not using GetWalkableAreaAt makes it work with characters not on the screen (NPCs) as well.

Once AGS allows scaling characters directly, I'll come up with something more flexible. Unless of course horizontal scaling is implemented by then.

YotamElal

Strazer:

cool..

I won't need the code cuase I don't have NPCs that walk on walls...
& it's simpler to revers the LEFT_EDGE & RIGHT_EDGE for the second wall.

:o)

Thanks Again

BTW if you like solving problems what about trying to find a way to walk on cealings! (the walk point of the character is allways at the bottom so I can't find a way to do it) (but it's not that important, so only if you like solving problems)

strazer

QuoteI won't need the code cuase I don't have NPCs that walk on walls...
& it's simpler to revers the LEFT_EDGE & RIGHT_EDGE for the second wall.I won't

Yeah, I know, it was just for future reference in case someone else with a similar problem stumbles upon this thread.

Quote
BTW if you like solving problems what about trying to find a way to walk on cealings! (the walk point of the character is allways at the bottom so I can't find a way to do it)

Hm, how about this:

Make a view with vertically flipped frames of the player character's view and enter it in the walkable area's "Change player view while on this area", then

Code: ags

#define CEILING_ID 2 
#define CEILING_TOP_EDGE 202
#define CEILING_BOTTOM_EDGE 329
#define CEILING_SCALING_TOP 100 
#define CEILING_SCALING_BOTTOM 50 

function repeatedly_execute_always() {
  //...

  if (GetWalkableAreaAt(character[GetPlayerCharacter()].x - GetViewportX(), character[GetPlayerCharacter()].y - GetViewportY()) == CEILING_ID) {
    int scaling = CEILING_SCALING_BOTTOM + (((CEILING_BOTTOM_EDGE - character[GetPlayerCharacter()].y) * (CEILING_SCALING_TOP - CEILING_SCALING_BOTTOM)) / (CEILING_BOTTOM_EDGE - CEILING_TOP_EDGE));
    SetAreaScaling(CEILING_ID, scaling, scaling);

    int slot = GetGameParameter(GP_FRAMEIMAGE, character[GetPlayerCharacter()].view + 1, character[GetPlayerCharacter()].loop, character[GetPlayerCharacter()].frame);
    character[GetPlayerCharacter()].z = -((GetGameParameter(GP_SPRITEHEIGHT, slot, 0, 0) * scaling) / 100);
  }
  else character[GetPlayerCharacter()].z = 0;

  //...
}


I have no vertically flipped Roger sprites handy so I'm unable to check if it looks okay.

YotamElal

WOW thats amazing!
It works!

but,,,,...
I defined:
CEILING_SCALING_TOP 100
CEILING_SCALING_BOTTOM 80
but it shows the character about half the size of the defintions...
so if I tryed to change it to:
CEILING_SCALING_TOP 200
CEILING_SCALING_BOTTOM 100
It shows the character closer to the normal size.

I have no Idea what numbers to put in instead...
of 100 & 80 so can you either try and fix the code or instead tell me what numbers I should use?

strazer

Strange, it works fine here with 100 & 80.

Did you import the flipped sprites at the correct resolution ("Import for 640x400 resolution" checkbox)?
Can't think of anything else at the moment.

YotamElal



SMF spam blocked by CleanTalk