Adventure Game Studio

AGS Support => Beginners' Technical Questions => Topic started by: rongel on Wed 18/11/2015 17:11:13

Title: Character turning and directions
Post by: rongel on Wed 18/11/2015 17:11:13
Hi! I'm having a problem with my character's turning. My first side way walk frame shows the character 2/3 sideways, so that the front of the body is also showing a bit. Much like in Indiana Jones and Monkey Island games. So the walk-loop is completely from the side, but when the character stops, he turns a bit to the "camera". This is the way i want it to be, it shows more of the characters face and looks nice. Now I would like to add the diagonal first frames as well, to get a nice smooth turning animation. But because the first frame in the side-loop isn't completely from left or right, the turning doesn't work smoothly. The cycle goes something like this when I turn from left to right:
left-upleft-up-upright-my standing still frame where the character is looking diagonally a bit down-left. So that frame pops up and looks annoying. This is complicated to describe, but I hope you got the idea.

So can I have both: a nice turning animation and still have my character to stop in 2/3 side way position after the loop, like in the LucasArts games. Can it be done without extensive, high-level coding? My current option is just to abandon the turning-option, which is a shame because it looks very good and works well otherwise. I have read through old posts but haven't found any resolution to this.
Title: Re: Character turning and directions
Post by: Retro Wolf on Wed 18/11/2015 17:39:12
You could use a separate idle view that works as soon as you stop walking.
Title: Re: Character turning and directions
Post by: rongel on Wed 18/11/2015 18:33:47
Thanks for the quick reply!
I need to test that idea, never thought of it. I'm a bit afraid that it will mess up my normal idle views (I haven't played around with those yet that much). I mean that can I still use another idle view when the character has been still few seconds?
Title: Re: Character turning and directions
Post by: Retro Wolf on Wed 18/11/2015 19:06:43
Set your idle view timer to 0 but have the first bunch of idle frames as him standing still (all same sprite), this is in front of your current idle view frames.
Title: Re: Character turning and directions
Post by: rongel on Wed 18/11/2015 20:29:10
Where the "player.SetIdleView"-command should be placed? I tried placing it to repeatedly_execute_always, where it seemed to work nicely. The transition to this new idle view was instant, but the game will only play the first frame. At game_start() it will play the following frames also, but it took a second or so for the view to switch to idle (even when the timer was set to 0), so it didn't look that nice...
Title: Re: Character turning and directions
Post by: Retro Wolf on Wed 18/11/2015 23:37:13
Hmm... it's been a while since I've used those commands, there may be more than one. You only need to set it once though, game start should be fine. Have you tried to set timer to 1? Can't use computer at the moment, so you might have to wait for someone else to help.
Title: Re: Character turning and directions
Post by: rongel on Thu 19/11/2015 06:24:03
I tried setting timer to 1, and -1 (and many other variations), but there was still the same annoying delay. Only when the command was in repeatedly execute, the transition was instant. If I remember right, the idle view frame delay was hard-coded, so could that be the issue? Have you used this method yourself before? Anyway, really appreciate the help, thanks!
Title: Re: Character turning and directions
Post by: Retro Wolf on Thu 19/11/2015 08:02:22
I've never done what you want your character to do personally, the possible solution just popped in my head. I'm going to try some experiments in AGS when I get the chance.

EDIT:
You're right there's a slight delay, my only guess is that the character is still in walking mode for a bit even though the character doesn't move. Just a guess. Sorry mate I'm a but stumped by it! Hopefully someone can step in and think of a workaround. Good luck with your project!
Title: Re: Character turning and directions
Post by: rongel on Thu 19/11/2015 13:09:01
Ok, for me the delay is just too long, it takes a second or longer before the idleview kicks in (if the command is not in repeatedly execute. I was just wondering how people overcome this, there must be many games that use sprites that are not standing exactly sideways when still, and use the turn character-option. But many thanks, your solution seemed to be quite close to working!
Title: Re: Character turning and directions
Post by: Khris on Thu 19/11/2015 13:57:35
Here's one way to do this:
1) put standing sideview frames in loops 1 and 2 so turning looks good
2) add another loop to your player's normalview (loop #8 for me), then add the two 2/3 sprites as first two frames (frame 0: left, frame 1: right)
3) go to GlobalScript.asc / repeatedly_execute and put this directly above it, outside the function:bool was_moving;
4) put this inside the function:  if (!player.Moving && was_moving) {
    if (player.Loop == 1 || player.Loop == 2) {
      player.Frame = player.Loop - 1;
      player.Loop = 8;
    }
  }
  was_moving = player.Moving;

Manually changing the loop and frame like this is possible and shouldn't mess with anything else; AGS will simply overwrite it as soon as the IdleView kicks in or the player starts walking again.
Title: Re: Character turning and directions
Post by: Retro Wolf on Thu 19/11/2015 14:06:30
Damn I was trying some stuff with changing frames at one point! Nicely done Khris!
EDIT: And I missed "player.Moving" :-[
Title: Re: Character turning and directions
Post by: rongel on Thu 19/11/2015 14:44:25
Thanks, this sounds promising! Everything else looks good but, the code seems to mess the speech view, if the player starts to speak while standing sideways, game crashes. I created another loop 8 to speech view, but it just flips the frames, and also seems to flip the character in opposite direction. So is there a way to make the code not affect the speech views (and probably idleview also)?
Title: Re: Character turning and directions
Post by: rongel on Thu 19/11/2015 15:26:06
I think I got rid of the speech view problem, I edited the code to look like this:

Code (ags) Select
   if (!player.Moving && was_moving) {
    if (player.Loop == 1) {
      player.Frame = player.Loop - 1;
      player.Loop = 8;
    }
    if (player.Loop == 2) {
      player.Frame = player.Loop - 1;
      player.Loop = 9;
    }
  }
  was_moving = player.Moving;


Then I just added one more  loop to walk-views, so that each one has only one frame. Then added two speech-views to 8 and 9. It looks like it's working. It's weird but the nice smooth turning doesn't always happen, sometimes it seems the turning doesn't use all frames and i can see again the one frame in wrong place), then it starts to work again nicely. It's not a big problem, but just wondering what causes it.


EDIT:

Ok, noticed the problem. The character only turns smoothly and uses all the frames when he is already moving. If the character is standing still and I make him turn, it doesn't work, and I can see the problem frame again. So everything goes nicely only when he is walking already. I tried to edit the script but didn't get good results...
Title: Re: Character turning and directions
Post by: rongel on Thu 19/11/2015 17:29:27
AGS will simply overwrite it as soon as the IdleView kicks in or the player starts walking again.

So is the reason for turning not showing when still, that the character is not actually moving when he is turning? New loops 8 and 9 are still on and overwrite those turning frames. Only when the actual walking starts at frame 2, the loop stops? And when the player is walking already, turning works normally?
Title: Re: Character turning and directions
Post by: Khris on Thu 19/11/2015 17:46:49
Apparently AGS does not simply reset the loop :(
I played around with this and the only thing I got to work reliably is changing the entire view of the character to one that has changed standing frames, then resetting it to the walk view immediately before processing a WalkTo click.
So instead of all the Loop and Frame business, simply:
    player.ChangeView(STANDING);

As for resetting the view, this should ideally happen right before the character starts walking, no matter how it is told to walk.
Resetting it in on_mouse_click will work, but if you then put a blocking walk in some "interact with x" interaction, the view won't change back.
The only way I can see to fix this is to implement your own walking call:
// header
import void Go(this Character*, int x, int y, BlockingStyle blocking = eNoBlock, WalkWhere where = eWalkableAreas);
// script
void Go(this Character*, int x, int y, BlockingStyle blocking, WalkWhere where) {
  if (this.NormalView == STANDING) this.ChangeView(VIEW1);
  this.Walk(x, y, blocking, where);
}


Then in on_mouse_click / eButtonLeft:
    if (mouse.Mode == eModeWalkto) player.Go(mouse.x + GetViewportX(), mouse.y + GetViewportY());
    else ProcessClick(...);


I tested this with speech, and so far it seems to work.
Title: Re: Character turning and directions
Post by: rongel on Thu 19/11/2015 18:55:36
Wow, that's a lot of heavy coding!

I think I got it somewhat working using that, walking and turning seem nice now. I had couple of problems: I use BASS Lightweight template so does that cause problems? When I click to object with interactions, the player will walk there, and I don't want that. Is it a issue with mouse.Mode == eModeWalkto, all interactions except looking happen with left mouse button.

The other was with "else ProcessClick(...);". Maybe a dumb question but what are those three dots? AGS gave me an error with those, and I had to put some values there. But I have no idea what they should be.

Thanks!
Title: Re: Character turning and directions
Post by: valter on Fri 20/11/2015 07:45:36
Hello, have you found the solution to this latest questions?

ProcessClick (int x, int y, CursorMode)

If you look in the manual you can find a clear example.

Title: Re: Character turning and directions
Post by: Khris on Fri 20/11/2015 10:28:03
I didn't use the full line because the idea was to catch WalkTo clicks and handle them differently, so you were meant to keep your existing ProcessClick line. For the BASS template however, the proper place to insert the code is lines 45-48 of TwoClickHandler.asc:
      if (player.ActiveInventory == null)
      {
        ProcessClick(mouse.x, mouse.y, eModeWalkto);
      }


Just change it to:
      if (player.ActiveInventory == null)
      {
        player.Go(mouse.x + GetViewportX(), mouse.y + GetViewportY());
      }


The other part, meaning the import line and declaration for Go(), have to go inside TwoCLickHandler, too. Just add line 2 from the snippet anywhere to TwoClickHandler.ash, and lines 4-7 to the top of TwoClickHandler.asc (or put it above on_mouse_click).
Title: Re: Character turning and directions
Post by: rongel on Fri 20/11/2015 19:19:22
Thanks Khris for the clarification! I have a long travel ahead so can't test this now. This small problem with one frame in the wrong place is surprisingly difficult to fix, but I will test this soon. My back up plan is to use sideway-view when the character is facing right, left-turns works with my current frames (character turning seems to be hard-coded clock-wise). But I really hope this works and doesn't cause any other problems! 
Title: Re: Character turning and directions
Post by: rongel on Sat 21/11/2015 15:45:16
Ok, I hope you are patient with me! Almost got it working, my only problem seems to be that blocking actions are not showing up after the player has been put to STANDING view. For example, i click on a door, and the character just slides to it using STANDING view, my walk-animation (EGOWLK) doesn't play. Again, if the character is already walking when I click the door, the animation plays like it should. Otherwise the walking/turning is correct. I tested this also with an empty BASS template, and had the same effect. Here is my code, did I forgot something?

In GlobalScript.asc
Code (ags) Select
bool was_moving;
//----------------------------------------------------------------------------------------------------
// repeatedly_execute
//----------------------------------------------------------------------------------------------------
function repeatedly_execute()
{
  if (!player.Moving && was_moving) player.ChangeView(STANDING);
  was_moving = player.Moving;
}


In TwoClickHandler.ash
Code (ags) Select
// change this to the y position the mouse most be at to make the inventory GUI visible
#define INVENTORY_POPUP_POSITION 7
import void Go(this Character*, int x, int y, BlockingStyle blocking = eNoBlock, WalkWhere where = eWalkableAreas);


In TwoClickHandler.asc
Code (ags) Select
void Go(this Character*, int x, int y, BlockingStyle blocking, WalkWhere where) {
  if (this.NormalView == STANDING) this.ChangeView(EGOWLK);
  this.Walk(x, y, blocking, where);
}
//----------------------------------------------------------------------------------------------------
// on_mouse_click()
//----------------------------------------------------------------------------------------------------


Code (ags) Select
if (player.ActiveInventory == null) {
    //ProcessClick(mouse.x, mouse.y, eModeWalkto);
    player.Go(mouse.x + GetViewportX(), mouse.y + GetViewportY());
    }
    else
    {
      player.ActiveInventory = null;
      }
Title: Re: Character turning and directions
Post by: rongel on Sat 21/11/2015 16:36:52
Okay, I think I got the idea now. Of course the whole point was to make a custom walking command! So now instead of walk, I use Go. It looks like it's working, I will report if I stumble to problems. Really appreciate the help, thanks!
Title: Re: Character turning and directions
Post by: Khris on Sun 22/11/2015 12:57:09
Yes, I should've been clear about that; you can only use player.Go(). in your entire game, otherwise the view won't always get reset in time.