Seprate Head and body

Started by joelphilippage, Sat 11/08/2007 15:18:07

Previous topic - Next topic

joelphilippage

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:
Code: ags
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.



GarageGothic

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.


joelphilippage

#2
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:
Code: ags
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.



GarageGothic

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.

joelphilippage

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?



GarageGothic

You can try to set System.VSync to true and see if it changes anything.

joelphilippage

#6
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.



GarageGothic

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).

Khris

Just wanted to point out that this:
Code: ags
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
Code: ags
cRus.Loop=cEgo.Loop;


No, duh! ;)

joelphilippage

#9
Ok I have written the script for the function and am getting the error "undifined symbol StrLen" on the line about setting the timer.
Code: ags
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();
}
}



Lt. Smash

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=...;

Khris

No, StrLen is old code. Use "message.Length" instead.

joelphilippage

Ok I got it to work using this:
Code: ags
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.



Lt. Smash

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.

jetxl

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
Code: ags

//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.

monkey0506

Quote from: jetxl on Sun 12/08/2007 01:04:30
Code: ags
//THIS IS OLD CODE 4 OLD SKOOL PEEPS

Code: ags
// 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

SMF spam blocked by CleanTalk