Room size

Started by ld-airgrafix, Wed 19/02/2020 11:40:51

Previous topic - Next topic

ld-airgrafix

Im experimenting with the engine and trying different room sizes. I would prefer a room thats bigger than view size, but when character moves together with camera, its really jerky, and not smooth. Is there anything i can do to improve this?

TheManInBoots

#1
Hi ld-airgrafix,
Try eri0o's module
https://www.adventuregamestudio.co.uk/forums/index.php?topic=57489.msg636611488#msg636611488

And I think there are already some threads on smooth camera movement in the forum.

fernewelten

Quote from: ld-airgrafix on Wed 19/02/2020 11:40:51
but when character moves together with camera, its really jerky, and not smooth. Is there anything i can do to improve this?

The fundamental reason is that the character's movement is jerky. It must be because the character can only move when the animation frame changes. (This is an effect that can be turned off in the Editor, but you'd usually not want to because it helps to prevent the character from slithering.) If the camera isn't locked to positions that are set manually, it moves with the character, and so it is jerky, too.

You can take control of the camera in the event repeatedly_execute or repeatedly_execute_always and see to it  that it only changes at most by a few pixels per call of that event. That's what I did for my game Mamma Mia Winter Ice Cream Mayhem. That game features fast movements when Jake starts up the ice cream maker, and I found that the jerky camera movements make the player giddy.

I'd post the code I used here, but that game was coded in AGS 3.4.1, and the respective concepts and functions have changed name and semantics in the meantime.

Crimson Wizard

#3
Quote from: fernewelten on Wed 19/02/2020 17:01:31
You can take control of the camera in the event repeatedly_execute or repeatedly_execute_always and see to it  that it only changes at most by a few pixels per call of that event.

For the latest version of AGS I suggest using late_repeatedly_execute_always, because it's called after game logic update, but before drawing, so you will be always in sync with, for example, player character position.

Quote from: fernewelten on Wed 19/02/2020 17:01:31
I'd post the code I used here, but that game was coded in AGS 3.4.1, and the respective concepts and functions have changed name and semantics in the meantime.

For camera movement inside the room the differences are trivial, and it's mostly a matter of replacing one function or property name with another in most cases.

ld-airgrafix

Quote from: TheManInBoots on Wed 19/02/2020 15:27:01
Hi ld-airgrafix,
Try eri0o's module
https://www.adventuregamestudio.co.uk/forums/index.php?topic=57489.msg636611488#msg636611488

And I think there are already some threads on smooth camera movement in the forum.
Thank you so much for this, it works really well and smooth. This engine continues to surprise me daily

eri0o

Depending on what you want to accomplish, you can solve by simply using:

Code: ags
function late_repeatedly_execute_always(){ 
  Game.Camera.SetAt(player.x, player.y);
}


The reason is as following:

Quote from: Crimson Wizard on Wed 19/02/2020 17:38:40
For the latest version of AGS I suggest using late_repeatedly_execute_always, because it's called after game logic update, but before drawing, so you will be always in sync with, for example, player character position.

Laura Hunt

#6
Quote from: eri0o on Thu 20/02/2020 12:00:24
Depending on what you want to accomplish, you can solve by simply using:

Code: ags
function late_repeatedly_execute_always(){ 
  Game.Camera.SetAt(player.x, player.y);
}



Hmmm what if I wanted the viewport to move "on rails", so to say? i.e., imagine I have a line defined by two points: (a, b) and (c, d) and I want the camera to move with the player but also be restricted to moving ONLY along this axis so it doesn't bob all over the place (think for example a long corridor in iso perspective). Would that be feasible? (in 3.4.3, since I don't think I'll switch to 3.5 for this game)

eri0o

Yes, you project the player position in that line and set camera position to that point.

Laura Hunt

#8
Quote from: eri0o on Thu 20/02/2020 12:42:14
Yes, you project the player position in that line and set camera position to that point.

By "project" do you mean taking the player position, throwing a perpendicular from there to the rail/central axis and setting the viewport to the intersection point?

If it's that, it's easy to visualize, but I have no idea how I would go about doing that with actual math... (especially considering that in iso perspective, perpendicular does not mean "90 degrees"). Hmm, something to think about, but at least I know how to approach the problem now!

eri0o

#9
I think you need to make one of the positions of the line your origin point. So you need another vector to have the player position translated to this new origin. Then you need to normalize the line vector, so you have 0-1 x,y normalized vector. Then you do the dot product of this normalized vector of the line by the one of the translated player position. There may be some wrong stuff in this ...

I have some (UNTESTED!) math code here that may be useful : https://www.adventuregamestudio.co.uk/forums/index.php?topic=57516.0

If using above, try using Vec3.Project() and use Vec3 with z= 0. I am not sure if this will work, but I imagine yes.

Laura Hunt

Quote from: eri0o on Thu 20/02/2020 12:57:23
I think you need to make one of the positions of the line your origin point. So you need another vector to have the player position translated to this new origin. Then you need to normalize the line vector, so you have 0-1 x,y normalized vector. Then you do the dot product of this normalized vector of the line by the one of the translated player position. There may be some wrong stuff in this ...

I have some (UNTESTED!) math code here that may be useful : https://www.adventuregamestudio.co.uk/forums/index.php?topic=57516.0

If using above, try using Vec3.Project() and use Vec3 with z= 0. I am not sure if this will work, but I imagine yes.



This feels WAY over my head right now, I'll try to take a look later at home and see if I can wrap my head around it. Thanks for all the resources in any case, hope I can put all this to good use :)

fernewelten

Quote from: eri0o on Thu 20/02/2020 12:00:24
Depending on what you want to accomplish, you can solve by simply using:
Code: ags
function late_repeatedly_execute_always(){ 
  Game.Camera.SetAt(player.x, player.y);
}


Only, of course, then the camera movement is just as jerky as before because it mimics the jerky player movement exactly. So you'd rather need some logic such as "The ideal camera position is the player position. If that is farther away from the actual camera position than 3 pixels, then set the camera position to the actual position minus or plus 3 pixels, as the case may be. Otherwise, set the camera position to the ideal position." That's the gist of what I coded in Mamma Mia.

Laura Hunt

Quote from: fernewelten on Wed 19/02/2020 17:01:31
I'd post the code I used here, but that game was coded in AGS 3.4.1, and the respective concepts and functions have changed name and semantics in the meantime.

I'm still using 3.4.3 for my game and don't plan on switching to 3.5. Would appreciate seeing your code if you don't mind :)

Crimson Wizard

#13
@LauraHunt

If your camera rail is matching one of the base axis (X or Y), then it's a trivial matter of using one character's coordinate and a fixed rail coordinate:

Code: ags

function late_repeatedly_execute_always(){ 
  Game.Camera.SetAt(player.x, RAIL_Y);
}


or in 3.4.3 terms:

Code: ags

function late_repeatedly_execute_always(){ 
  SetViewport(player.x, RAIL_Y);
}


(Above does not accomodate for smoothness problem, naturally, so any solution to that has to be added as a pre- or post- calculation)


Of course this is the most primitive case. If your rail is an arbitrary line, then you have to use 2D vector math.
In this case your should probably create a line coming from the character's position and parallel to one of the base axes (e.g. Y), and find a point of intersection between that line and your "rail".

Laura Hunt

Quote from: Crimson Wizard on Thu 20/02/2020 13:44:14
Of course this is the most primitive case. If your rail is an arbitrary line, then you have to use 2D vector math.
In this case your should probably create a line coming from the character's position and parallel to one of the base axes (e.g. Y), and find a point of intersection between that line and your "rail".

Yeah like I said, the tough part about it is that we're using isometric perspective, so the math gets more complicated that I expected. We'll see what we do in the end... I was curious about if and how it could be done, but the effort might just not be worth it.

Crimson Wizard

#15
Quote from: Laura Hunt on Thu 20/02/2020 13:57:15
Yeah like I said, the tough part about it is that we're using isometric perspective, so the math gets more complicated that I expected. We'll see what we do in the end... I was curious about if and how it could be done, but the effort might just not be worth it.

It takes relatively small effort, the hardest part is to find necessary formulas in a book of vector algebra :)

PS. I don't remember this by heart, unfortunately

Laura Hunt

Quote from: Crimson Wizard on Thu 20/02/2020 14:06:48
Quote from: Laura Hunt on Thu 20/02/2020 13:57:15
Yeah like I said, the tough part about it is that we're using isometric perspective, so the math gets more complicated that I expected. We'll see what we do in the end... I was curious about if and how it could be done, but the effort might just not be worth it.

It takes relatively small effort, the hardest part is to find a vector algebra book with formulas :)

Would you believe that I actually studied three years of Engineering and there was a time when I owned those kind of books and actually knew how to do all this stuff? Then I dropped out and switched to Philosophy, sigh. Not that I regret it, but I miss doing complex math and stuff. I felt, like, smart. Who cares about Heidegger now.

(ok, the thread is officially derailed now. Sorry, back to the subject at hand! :sealed:)


eri0o

#17
Code: ags

int _rail_0x,_rail_0y,_rail_1x,_rail_1y;

/// define a rail line (a,b) to (c,d) on room load
void SetRail(int a, int b, int c, int d){
  _rail_0x = a;
  _rail_0y = b;
  _rail_1x = c;
  _rail_1y = d;
}

function late_repeatedly_execute_always(){ 
  Vec3* vp = Vec3.Create(IntToFloat(player.x), IntToFloat(player.y));

  // We want a line from (a,b) to (c,d), so we are going to initialize two vectors from origin 0,0 to each point.
  Vec3* vl0 = Vec3.Create(IntToFloat(_rail_0x), IntToFloat(_rail_0y));
  Vec3* vl1 = Vec3.Create(IntToFloat(_rail_1x), IntToFloat(_rail_1y));

  // We are going to use (a,b) as origin for both the player and the line
  Vec3* vl = vl1.Sub(vl0);
  Vec3* vp_l0 = vp.Sub(vl0);

  // We need to project the player position on the line
  Vec3* vprojected = vl.Project(vp_l0); //not sure if reverse

  // We need to bring back to the 0,0 origin
  Vec3* vcam = vprojected.Add(vl0);

  // Let's force the camera on this point
  Game.Camera.SetAt(FloatToInt(vcam.x), FloatToInt(vcam.y));
}


Using the library I linked above, I think this is the code (typed in my phone, may have mistakes). I haven't tested the code, so not sure if it works. I added comments to clarify the intention.

Spoiler
[close]

Laura Hunt

#18
I'm still wondering if this couldn't be done with simple linear algebra? We need to consider that because this is isometric perspective, I already have the angle and thus the slope of the line. If the angle of our perspective is 30 degrees, then m = tan 30?

Now with just one point of the rail and knowing the slope, I can have its equation: y - a = m(x - b)

Then I would define a second line the same way, but with the reverse slope value and using the player position as my reference point. This is the line that goes from the player to the rail.

And finally, I just need to find the intersection between these two equations (there has to be a formula, right?) which would give me the point where I need to place the viewport.

I've just looked up a lot of these things real quick so I might be off in places, but I think the idea seems solid? (Of course, there would be a lot of additional calculations to acommodate the "inverted" Y axis and the fact that the viewport position is set using its top left corner rather than its center!)

TheManInBoots

Quote from: ld-airgrafix on Thu 20/02/2020 09:08:33
Quote from: TheManInBoots on Wed 19/02/2020 15:27:01
Hi ld-airgrafix,
Try eri0o's module
https://www.adventuregamestudio.co.uk/forums/index.php?topic=57489.msg636611488#msg636611488

And I think there are already some threads on smooth camera movement in the forum.
Thank you so much for this, it works really well and smooth. This engine continues to surprise me daily
You welcome :)

SMF spam blocked by CleanTalk