Adventure Game Studio

AGS Support => Beginners' Technical Questions => Topic started by: joelphilippage on Sat 11/08/2007 15:18:07

Title: Seprate Head and body
Post by: joelphilippage on Sat 11/08/2007 15:18:07
Hello. I am trying to get a character who's head and body are seprate so he can talk while walking.
The script I have is fairly simple and works well but it seems like the head moves slightly slower than the body.
here is the code I put in repeatedly execute:
cRus.x = cEgo.x;
cRus.y = cEgo.y - 32;
if (cEgo.Loop == 0){
  cRus.Loop = 0;
}
if (cEgo.Loop == 1){
  cRus.Loop = 1;
}
if (cEgo.Loop == 2){
  cRus.Loop = 2;
}
if (cEgo.Loop == 3){
  cRus.Loop = 3;
  }

Rus is the head character and ego is the body.
Title: Re: Seprate Head and body
Post by: GarageGothic on Sat 11/08/2007 15:26:55
Sadly, this is due to the way the character walking/animation system works. I've had problems with it too. It would seem that the character moves in-between you getting his coordinates/viewframe info and that the graphics are actually drawn.

One alternative is using a dummy character for the body, applying the x, y, view, loop and frame of the (invisible) player character to him every frame. These would then be identical to the settings for the head.
You could also look into the function Character.FollowCharacter and its FOLLOW_EXACTLY property.

Title: Re: Seprate Head and body
Post by: joelphilippage on Sat 11/08/2007 15:42:09
Ok I have tried making an invisible character to connect them. I am using the same script except Ego is now the invisible player and I added this to the end:
cBod.FollowCharacter(cEgo, FOLLOW_EXACTLY, 0);
Bod is the body character.
The problem is that the body wont animate when walking.
[edit]
Never Mind.
I went back to my original plan and set the game speed to 100 then turned down the speed of everything else.
Now the only problem is that when the room scrolls the head sort of has a tearing effect.
Title: Re: Seprate Head and body
Post by: GarageGothic on Sat 11/08/2007 16:22:38
Setting the game speed too fast might not be the best idea since not everybody's computers can keep up the rate of 100fps.

The suggestions I gave were to be read as two independent pieces of advice.

1) You turn the player invisible. Then have two characters, cBody and cEgo, that get their x and y coordinates, along with view, loop and frame set to match the invisible character in repeatedly_execute_always.

or:

2) Using cHead.FollowCharacter(cEgo, FOLLOW_EXACTLY, 0); to have a static head move around with the player character.
Title: Re: Seprate Head and body
Post by: joelphilippage on Sat 11/08/2007 16:36:06
Ok I tried your first suggestion and it works great. the only problem is the tearing it gets when the screen scrolls. Is there a way to fix this?
Title: Re: Seprate Head and body
Post by: GarageGothic on Sat 11/08/2007 16:40:24
You can try to set System.VSync to true and see if it changes anything.
Title: Re: Seprate Head and body
Post by: joelphilippage on Sat 11/08/2007 16:43:28
Nope doesn't change anything. Also how do I get the head to be talking and animating but still have the character be able to move. cRus.BackgroundSay wont work because it doesn't play the talking animation.
Title: Re: Seprate Head and body
Post by: GarageGothic on Sat 11/08/2007 17:12:03
Tearing is a known problem in scrolling rooms. If vsync doesn't help I don't have any other suggestions.

As for talking animations, you'll have to start and stop the head animating manually. The problem is that Say is blocking, so whenever that is used, the walk animation will freeze. You'd be best off scripting your own version of the Say command, that starts the head animating, displays the text (possibly by using SayBackground or your own overlay), then stops the head animating when the text disappears (handy to know, the text stays for ((StrLen(text) / game.text_speed) + 1) * GetGameSpeed() loops).
Title: Re: Seprate Head and body
Post by: Khris on Sat 11/08/2007 17:38:36
Just wanted to point out that this:
if (cEgo.Loop == 0){
  cRus.Loop = 0;
}
if (cEgo.Loop == 1){
  cRus.Loop = 1;
}
if (cEgo.Loop == 2){
  cRus.Loop = 2;
}
if (cEgo.Loop == 3){
  cRus.Loop = 3;
  }


is the same as
cRus.Loop=cEgo.Loop;

No, duh! ;)
Title: Re: Seprate Head and body
Post by: joelphilippage on Sat 11/08/2007 18:33:24
Ok I have written the script for the function and am getting the error "undifined symbol StrLen" on the line about setting the timer.
function speak(String message){
  cRus.Animate(cEgo.Loop, 4, eRepeat, eNoBlock, eForwards);
  cRus.SayBackground(message);
  SetTimer(2, ((StrLen(String message) / game.text_speed) + 1) * GetGameSpeed() loops);
}

function repeatedly_execute() {
  if (IsTimerExpired(2)){
  cRus.UnlockView();
}
}
Title: Re: Seprate Head and body
Post by: Lt. Smash on Sat 11/08/2007 18:43:59
StrLen must be defined inside that function or globally at top of global script or in script header otherwise StrLen can't be found.

String StrLen=...;
Title: Re: Seprate Head and body
Post by: Khris on Sat 11/08/2007 18:57:05
No, StrLen is old code. Use "message.Length" instead.
Title: Re: Seprate Head and body
Post by: joelphilippage on Sat 11/08/2007 19:06:41
Ok I got it to work using this:
SetTimer(2, ((StrLeng.Length/game.text_speed) + 1)*GetGameSpeed());
I still don't know how I could fix the tearing effect on the character when the room scrolls but it's fine for now. If anyone knows please tell me.
Title: Re: Seprate Head and body
Post by: Lt. Smash on Sat 11/08/2007 19:48:08
Quote from: KhrisMUC on Sat 11/08/2007 18:57:05
No, StrLen is old code. Use "message.Length" instead.
Oh, yes. Didn't know that.
Title: Re: Seprate Head and body
Post by: jetxl on Sun 12/08/2007 01:04:30
Quote from: joelphilippage on Sat 11/08/2007 19:06:41
I still don't know how I could fix the tearing effect on the character when the room scrolls but it's fine for now. If anyone knows please tell me.
I alone know.

I got sick of the strobe effect when the character walks in a scrolling room.
So I use this in Global script repeatedly_execute

//THIS IS OLD CODE 4 OLD SKOOL PEEPS
  if(character[GetPlayerCharacter()].x>GetViewportX()+200){
    SetViewport(GetViewportX()+1,GetViewportY());
  }
  if(character[GetPlayerCharacter()].x<GetViewportX()+120){
  SetViewport(GetViewportX()-1,GetViewportY());
  }

And just watch how smoothly the character walks.
I'm convinced that this is a step closer to make dual sprite animations smooth too.

Now you know it too.
Title: Re: Seprate Head and body
Post by: monkey0506 on Sun 12/08/2007 02:47:10
Quote from: jetxl on Sun 12/08/2007 01:04:30//THIS IS OLD CODE 4 OLD SKOOL PEEPS

// N3\/\/ SK00L
  int viewportX = GetViewportX();
  if ((player.x >= (viewportX + ((System.ViewportWidth / 3) * 2))) && (viewportX + System.ViewportWidth < Room.Width)) SetViewport(viewportX + 1, GetViewportY());
  else if ((player.x <= (viewportX + (System.ViewportWidth / 3))) && (viewportX)) SetViewport(viewportX - 1, GetViewportY());


:P