Game Development Community

Moving the camera

by Tim Doty · in Torque Game Builder · 03/05/2005 (7:33 am) · 21 replies

Effect I'm wanting to achieve: player can move around window, but camera scrolls to prevent movement off window.

Planned method: set world limit for player with NULL and a callback to a function setting camera velocity appropriately.

Problem: I can't find a way to set camera velocity. I could extrapolate a position, set a target, start the camera move and have the movement interpolated but that seems like a lot of work to get back to the same place.

What am I missing?
Page «Previous 1 2
#1
03/05/2005 (10:56 am)
Tim, actually the best way to do this is probably to "fake" it. What that means is that the camera stays stationary. Everything else scrolls by... the background (fxScroller2D, bunch of sprites, or tiles, etc), the enemies or what have you, etc. Then you can just set the appropriate world limits for player-controlled objects. This gives the appearance of motion (it is, actually, equivalant to moving the camera around, just easier, and this way you don't need to define a huge world space, so it's better).

Make sense? Let us know if you need more detail.
#2
03/05/2005 (11:24 am)
Robert, by sorted out as it scrolls, do you mean making it so the enemies are removed when they go beyond the screen?

If so, you can use the setworldlimits method with the KILL parameter, as in the tutorial. Or, you could avoid the memory thrashing (deleting an enemy, spawning a new one) and when an enemy goes off-screen, just re-position it elsewhere. Or, if you want your player character to be able to move back and forth in a level (while the enemies stay in place), you can just set-up the whole level at once and not remove enemies except when they actually die.

Let me know if I understood the question correctly. :)
#3
03/05/2005 (11:28 am)
@Tim: Don't forget that you can mount the camera to any T2D object, even use forces. You can also restrict the view so a larger region and the camera will never view outside of it which is important if you want your player to be able to move there and the camera is mounted to it.

- Melv.
#4
03/05/2005 (3:39 pm)
@Josh: well, I must be missing something because it seems to me that it would be easier to move the camera, even with the extrapolation/interpolation. Otherwise I have to scroll the tiles and scroll every object. In the context of the game I'm envisioning the map is large but not huge and there wouldn't be spawning.

@Melv: Thanks, I'll try that tomorrow (I'm one of the crazies whose still actually running games twice a week and I've got to get ready for tonight ;^)

Just to try and make sure I'm being clear about the effect, its of a "lazy camera" where the player isn't always centered in the screen so it gives the illusion of moving around the world rather than moving the world around the player.
#5
03/05/2005 (11:41 pm)
Tim, yeah, it depends on how your world is set-up. If you want a large, non-repeating level that scroll at different speeds according to player movement and persist off-screen positions, then moving the camera and player through the world is probably the best choice. If you want something like the example shooter where things scroll at a fixed rate and there's no sense of off-screen object state, etc, then faking it by scrolling the bg and world objects is typically the best way to go.
#6
03/06/2005 (2:14 am)
... also, you can mount the camera with a force rather than it being rigid so that it slowly tracks the object and will lag behind dependant upon the force you use.

Failing that, you can always track the camera yourself when the player moves, possibly using a schedule. You can position the camera system instantly or tell it to interpolate either using a linear/sigmoid interpolation all done by T2D. Might way to take a look at the fxSceneWindow2D reference.

- Melv.
#7
03/06/2005 (12:33 pm)
One question about mounting a camera to the player with a force... when the player reaches the edge of the map (usually they start at one), typically the player can move around the scene nad the camera remains stationary until the player moves so far to the side of the screen where the world continues and then begins tracking player. In effect, the camera tracks the player unless the camera's view space will go beyond the edge of the map. Is there an easier way to handle this?
#8
03/06/2005 (12:48 pm)
@Seth: I'm not sure now whether you want to restrict the camera or not now. As I mentioned in my post "19:28", you can restrict the view to a larger region to the camera doesn't go outside of it. By default, this restriction isn't there.

"setViewLimitOn()" and "setViewLimitOff()".

Make sense?

- Melv.
#9
03/06/2005 (12:49 pm)
Ah duh. Sorry for the noise.
#10
03/06/2005 (12:51 pm)
No problem. :)

- Melv.
#11
03/06/2005 (1:08 pm)
@Melv: Thanks! I'd missed being able to mount with a force and that does *exactly* what I want. Now its just a matter of playing with the force number.

@Seth: well, due to your "noise" Melv pointed out the setViewLimitOn() which was the next capability I was going to look for.

I knew from the get-go that T2D was powerful, but I'm getting a better idea of just how powerful it is the more I get to play with it.
#12
03/06/2005 (2:53 pm)
Cool Tim. :)

- Melv.
#13
03/10/2005 (4:37 pm)
Okay, I've done some testing and as far as I can tell the force applied to the mount is the same no matter what value is specified. Test consisted of changing the mount force number and racing the camera to the edge of the screen. I tried mount force values from 0 (supposed to be a rigid mount) to 0.1 to 100000.
#14
03/10/2005 (6:25 pm)
@Melv: About setViewLimitOn, I can't figure out how to get it working properly.

sceneWindow2D.setCurrentCameraPosition( "0 0 100 76" );
sceneWindow2D.mount($player, "0 0", 100);

sceneWindow2D.setViewLimitOn(-50, -38, 50, 38);
sceneWindow2D.setViewLimitOn(0, 0, 100, 76);
...

I can't find a variation that works. Think typical Mario. I was thinking that if I mounted the camera to the center of the player but set the limit, then it would correctly handle the character being at the bottom of the screen while walking, but when flying or something and there's room around the world, that the camera would center on the character. However, it centers on him anyway. Not sure how to use this properly.
#15
03/11/2005 (1:24 am)
@Tim: I'll check that out but I'm sure it's working. It's on the list though.

@Seth: A little explanation might help...

Be careful of the different between "setCurrentCameraPosition" and "setCurrentCameraArea". The "position" one allows you to specify a centered coord and a width/height. The "area" one allows you to specify the area directly in (minX/minY/maxX/maxY).

A hint here is to look at the debug-info panel which always shows you the area (in world-units) that you're viewing as well as the zoom level.

The "setViewLimitOn()" function takes (minX/minY/maxX/maxY) which defines the maximum rectangular area in the world that the camera will view so your second-command doesn't look good for what you need but your first one looks much better.

The problem with the first one though is that you've effectively locked your camera in place because it cannot move anywhere, even if it is mounted to an object. If you wanted the camera to move upwards then you need to give it a little scope to do so. Using your example coordinates, use something like the following ...
sceneWindow2D.setCurrentCameraPosition( "0 0 100 76" );
sceneWindow2D.mount($player, "0 0", 100);
sceneWindow2D.setViewLimitOn(-50, -100, 50, 38);

Notice that the camera is now free to move all the way up to "-100" but before it was already at "-38" and couldn't go anywhere.

Think of the "setViewLimitOn" as something similar to the "setWorldLimit" function.

Not sure if I've explained that well?

- Melv.
#16
03/18/2005 (6:43 am)
@Tim: I've finally worked my way through the bugs-list to your bug report here with regards to the mount-force used when mounting the window to an object but unfortunately, under repeated tests, I cannot find a problem.

Here's one of the pieces of code that I used to try to duplicate the problem...
%sprite = new fxStaticSprite2D() { scenegraph = t2dSceneGraph; };
%sprite.setSize( 5 );
%sprite.setImageMap( ggLogoImageMap );
%sprite.setWorldLimit( bounce, "-50 -30 50 30" );
%sprite.setImpulseForcePolar( 30, 300 );
sceneWindow2D.mount( %sprite, "0 0", 2 );

If you could provide me more information regarding the problem then I might be able to find what exactly is going wrong. I would ask that you do this urgently if you would like to see the fix in the next update.

Thanks for your help,

- Melv.
#17
03/18/2005 (3:51 pm)
@Melv: Thanks for taking a look! Based on your code it would seem to me that you are limiting the sprite to bouncing within the map, although I am rather tired and could easily be misinterpreting.

Because a few things have changed with the code since I was last testing this I started retesting and noticed a couple of things. Originally I tested forces of 0, 0.1, 1, 10 (I think) and certainly up to the ridiculous 100000. All had the same behavior. The code roughly looked like this:

$player = new fxStaticSprite2D() { scenegraph = t2dSceneGraph; };
  $player.setSize("7.5 15");
...  
  sceneWindow2D.mount($player,"0 0",1,true);

What I would do is start from a certain position and move (using setImpulseForcePolar repeatedly via key press) in a straight line. The sprite would exit the visible portion of the screen at the same place no matter what force number I used, including 0 which the documentation says should rigid lock it to the sprite.

Thing is, since you can't reproduce this I set about using my current code (which, among other things, uses a different zoom level). With a force of 100 or 1000 the camera did not budge. With a force of 2 it definitely followed the sprite better. With a force of 0 it does appear to be rigidly mounted (excepting where it can't because of setting the camera to not show past the map edges).

Because the current code base is using Bryan Edds OO resource I'm technically not using the same executable, but I don't see why that would matter (given the resource applied). Unfortunately it looks like I don't have a backup of the old project before making all the new changes.

So the short of it is that I can't seem to reproduce the same problem, but there does seem to be an issue with very high force numbers. At my resolutions, etc., I noticed trouble at around 14 and it pretty much quit working at 20.

As it basically seems to be working I guess just take it off your list. I'm not sure what happened before but I don't even have the identical code to try that out.
#18
03/19/2005 (2:28 am)
@Tim: Well the reason I'm very confident with the camera mounting code is that it has been used agressively in the "Grav" demo and we've not encountered any problem. If you come across the same problem again then please let me know.

Thanks and good luck!

- Melv.
#19
03/30/2005 (3:13 pm)
Hmz... i am thinking of stuff like a sideview based game (like Commander Keen etc) or a top-view game (like that cewl tank game with squashing people in it :D ). Seems like this mounting to the "player object" makes scrolling on a map easy using the camera.

Is it possible to stop the camera from following the player when he reaches the "border" of the map? My guess is that i should check if a "near border" tile is colliding with the player and dismount the camera ?

Greetz,

:: EeKay ::
#20
03/30/2005 (3:22 pm)
You mean to avoid showing off-map areas? Not a problem:

// Position camera, set zoom, set map limit
  sceneWindow2D.setCurrentCameraPosition( "0 0 160 120" );
  sceneWindow2D.setViewLimitOn("-375 -375 375 375");
  sceneWindow2D.setCurrentCameraZoom(0.5);

The setViewLimitOn() tells the camera what the viewable boundaries are.
Page «Previous 1 2