-
Notifications
You must be signed in to change notification settings - Fork 137
Scene Guide
A Scene in Torque 2D follows the typical scene graph concept. It is the parent container for all scene object "nodes" (all classes including and derived from SceneObject - Sprite, TextSprite, Scroller, etc) that your game is built upon. You can abstract things in such a way that your entire game is contained within one Scene and you swap objects in and out as needed. Alternatively, you can use separate Scenes for each level in a platformer or splitting up the overworld from dungeons in a RPG, etc - and loading/unloading different Scenes as necessary.
Since all game objects need to be within a Scene, there are many "global" functions and roles that the Scene handles. The following sections will cover each role in more detail.
Physics
The Scene contains several methods that tie it to the physics simulation. The most important one allowing you to apply gravity to all "dynamic" body objects in the Scene. Gravity is just an easy to understand label though, you are not restricted to a constant force in the "down" direction. Gravity can be independently set in both the X and Y axis.
%scene = new Scene();
// Setting the gravity through the method
%scene.setGravity(0, -9.8);
// Setting the gravity through the field
%scene.Gravity = "0 -9.8";There are also options that let you set the number of iterations for position or velocity updates. See the Physics Guide for more details.
SceneObject Management
As a container that holds all the objects in the Scene, there are naturally several methods that let you add, get and remove scene objects within the Scene.
%scene = new Scene();
// Create an object
%object = new SceneObject();
// Add it to the scene
%scene.add(%object);
// Get the number of objects in the scene
%total = %scene.getCount();
// Get a list of object Ids that are currently in the scene
%list = %scene.getSceneObjectList();Asset Preloading
The Scene can also contain a list of asset Ids that will be preloaded when the Scene is loaded. This offers a degree of manual control over the asset system to help improve performance over the default, automatic loading and unloading of assets - in most cases using asset preloads is not necessary though.
%scene = new Scene();
// Add an asset to the preload list. This also loads the asset immediately.
%scene.addAssetPreload("ToyAssets:Tiles");
// Get the number of assets set to preload for this scene.
%total = %scene.getAssetPreloadCount();Joints
Also in a related role as the controller of the physics simulation, all Box2D joint creation, deletion, and manipulation are handled by the Scene. See the Joints Guide for more details on the methods available to join objects together.
Picking
This area is also very closely related to SceneObject management. The picking methods allow you to get all objects fall under a specific point, circle, box, or raycast. There are also a few filtering parameters available based on scene groups or layers, bounding boxes, or collision shapes.
// Find objects at coordinates 10, 10, with no scene group/layer filtering, and a collision pick mode.
MyScene.pickPoint("10 10", "", "", "collision");
// Find objects within a circle with a radius of 5 at coordinates 10, 10. No group/layer filtering, default mode oobb.
MyScene.pickCircle("10 10", 5);
// Find objects in scene group 3 within an 6x8 meter area at coordinates 10, 10. Pick mode is aabb.
MyScene.pickArea("10 10", "6 8", 3, "", "aabb");
// Find objects a ray crosses, from 0,0 to 20,20 (returns a list of object IDs).
MyScene.pickRay("0 0", "20 20");
// Like pickRay, but returns full collision detail for each object instead of just IDs.
MyScene.pickRayCollision("0 0", "20 20");pickPoint, pickCircle, pickArea, and pickRay each return a space-separated list of object IDs and accept optional sceneGroupMask, sceneLayerMask, and pickMode (any, aabb, oobb, or collision) arguments. pickRayCollision instead returns a block of collision detail for every object whose collision shape the ray crosses — object ID, contact point, normal, ray fraction, and shape index.
Debug Options
During development, there are many times where it is helpful to have visual aides which show objects bounding boxes, their collision shapes, joints, center of mass positions, or even metrics. This can be done at the Scene level to prevent turning on debug rendering on a tedious object-by-object basis. The following options are available for use: metrics, fps, controllers, joints, wireframe, aabb, oobb, sleep, collision, position, sort.
%scene = new Scene();
// Turn on debug rendering of collison shapes.
%scene.setDebugOn("collision");Layer Sorting
The sort mode for each scene layer is also defined through the Scene.
Behaviors
Scenes have the ability to be assigned and use behaviors.
A paused Scene stops simulating — nothing moves, nothing collides, no physics runs — but it carries on being drawn. That is exactly what you want behind a pause menu.
// Player hit Escape.
GameScene.setScenePause( true );
// ... show the menu, wait for them to pick Resume ...
GameScene.setScenePause( false );- setScenePause(%bool) - Pause or resume the Scene.
- getScenePause() - Whether it's currently paused.
Because the Scene is still drawn, your pause menu can sit on top of a frozen game rather than a blank screen.
How long the Scene has been running, in seconds, as a floating point number. This clock stops while the Scene is paused, so it measures time actually played rather than time since the level loaded — which is usually what you want for a speedrun timer or a "survive for 60 seconds" objective.
The gravity currently applied to everything in the Scene, as "x y". Set it with
setGravity, described above.
- getFPS() - The current average frames per second.
- getMinFPS() / getMaxFPS() - The worst and best averages seen so far.
getMinFPS() is the interesting one. Average frame rate can look fine while the game still
stutters; the minimum is where the stutter shows up.
- resetDebugStats() - Clears the minimum and maximum back to nothing, so you can measure one part of your game without earlier loading hitches dragging the numbers down.
setDebugOn (above) turns on the debug overlays — collision shapes, joints, AABBs and so
on.
- getDebugOn() - Which debug options are currently on, as a list of their names.
- setDebugSceneObject(%object) - Single out one object to report detailed metrics for, instead of the whole Scene.
- getDebugSceneObject() - Which object is being watched, or 0 if none is.
A Scene can list assets to load before it starts, so the game doesn't hitch the first time
each one is needed. addAssetPreload and getAssetPreloadCount are described above; the
rest of the family:
- getAssetPreload(%index) - The asset at a given position in the list. Numbered from 0.
- removeAssetPreload(%assetId) - Takes an asset off the list. Note this may unload the asset immediately if nothing else is using it.
- clearAssetPreloads() - Empties the list.
- isJoint(%jointId) - Whether a joint id is still valid. Worth checking before using a stored id, since the joint may have been deleted. See the Joints Guide.
- getControllers() - The Scene's controller set — the forces and effects applied to everything in the Scene, such as gravity wells or buoyancy.
- getLayerSortMode(%layer) - The render sort mode for one of the 32 layers.
- mergeScene(%scene) - Copies the entire contents of another Scene into this one. The other Scene is left alone; its objects are cloned, not moved. Useful for building a level out of pieces saved separately.
- setBatchingEnabled(%bool) / getBatchingEnabled() - Whether the renderer batches sprites together before drawing. On by default, and you should leave it on — it is a large performance win. Turning it off is a debugging measure.
- setIsEditorScene(%bool) - Marks the Scene as belonging to an editor rather than a running game. You won't need this unless you're building an editor of your own.
Using TorqueScript and the exposed fields or methods described in the previous section, you can programmatically create and configure a Scene. You can then export this type to a TAML file or even create a TAML file manually and read it into your game at an appropriate time.
Here is an example Scene TAML file in XML format:
<Scene
Name="GameScene" >
<Sprite
Image = "FillBattle:SixColors"
Frame = "0"
Size = "10 10"
Position = "44 30"
UseInputEvents = "1" >
<Sprite.Behaviors>
<ButtonBehavior />
</Sprite.Behaviors>
</Sprite>
</Scene>Depending on the amount of objects in your Scene when it is written out in TAML, the size of the file can become quite big.