Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
The FRB Editor supports the creation and management of CollisionRelationship objects. This document covers the features provided by the FRB Editor, and explains common scenarios where you may need to interact with the CollisionsRelationships in code. Most cases can be handled by CollisionRelationships in the FRB Editor; however, more advanced situations can be handled in code. For information about creating and working with CollisionRelationships in code, see the CollisionManager page.
CollisionRelationships define how to respond when two types of objects collide (overlap). Examples of reactions to overlapping objects include:
A player must take damage when colliding with a bullet
A bullet must be destroyed when colliding with a wall
An enemy must be moved so that it doesn't overlap the same space as another enemy
A car must reduce its maximum speed when driving over grass
Even simple games will require multiple relationships, and larger games may include dozens of relationships. Glue makes the creation and management of these much simpler than management purely in code.
Collision relationships can be created between:
Lists of entities which implement ICollidable
Individual Entity instances which implement ICollidable
TileShapeCollections
ShapeCollections (regular, as opposed to TileShapeCollections)
All CollisionRelationships will at include at least one Entity or Entity list, so it is important to mark Entities which you intend to use in relationships as ICollidable. For information on ICollidable entities, see the ICollidable Entity page.
CollisionRelationships can be created a few ways. Typically collision relationships are added to a screen, such as a base GameScreen. In this example we will use a screen called GameScreen which already has a few objects:
PlayerList (a list of Player entities)
BulletList (a list of Bullet entities)
EnemyList (a list of Enemy entities)
SolidCollision (a TileShapeCollection)
Note that the TileShapeCollection may have its SetByDerived value set to true. This allows the creation of CollisionRelationships in a base Screen even though the TileShapeCollection is created in a derived Screen.
You can drag+drop one collidable object (such as a list) onto another collidable object (such as another list or a TileShapeCollection) so long as the two objects are in the same screen. This will create a CollisionRelationship between the two objects.
The Collision tab displays when a collidable object or list is selected
The image above displays the Collision tab for the BulletList. Notice that the BulletList can collide with any of the other collidable objects in the GameScreen including itself. Adding collision is easy - just click the Add button next to the object in the Collision tab to create a new relationship. For example, clicking on the Add button next to EnemyList creates a relationship between BulletList and EnemyList.
CollisionRelationships are regular Objects which can be created through the right-click menu. To create a CollisionRelationship through the right-click menu:
Right-click on a Screen's Objects
Select Add Object
Verify FlatRedBall or Custom Type is selected
Select the CollisionRelationship type
Click OK
In this case the newly-created CollisionRelationship will not yet reference any collidable objects in the screen, and the game will not compile until the objects in the relationship are set (as shown in the next section).
Once a CollisionRelationship is created, it can be edited by selecting it under the Screen's Objects folder and clicking the Collision tab.
A CollisionRelationship objects can be changed using the two drop-downs. Note that if the Auto-name Relationship checkbox is checked, the name of the relationship will automatically change when either of the two objects in the relationship changes. Of course, if you create CollisionRelationships using either the Add button or the drag-drop method, you do not need to set the object types.
Subcollision allows specifying a specific shape within a collidable entity to use when performing collision. This is useful if an entity includes multiple shapes, each for different purposes. For example, an enemy may have a circle for solid collision (preventing the enemy from walking through walls) but it may also have a line for line-of-sight collision. In this case, we do not want the line to collide against the walls, so we would specify that only the enemy's circle should collide with the walls. All available shapes for subcollisions appear in the Subcollision dropdowns for each object. Note that changing the subcollision will also rename the CollisionRelationship if the Auto-name Relationship option is checked.
Physics can be set up through the Collision tab which offers multiple options.
:
No Physics - Colliding objects will not automatically have their positions or velocities changed by the CollisionRelationship.
Move Collision - Colliding objects will be separated if a collision occurs using their relative mass values. The most common values for First Mass and Second Mass are 1, 1 if both objects have equal mass and 0, 1 if the first object should not be able to push the second (in the case of colliding against a solid TileShapeCollection)
First Mass - the mass of the first object in the relationship (the mass of enemies) relative to the mass of the second object. If this object should not be able to push the second object, it should have a mass of 0.
Second Mass - the mass of the second object relative to the first object. If this object should not be able to push the first object, it should have a mass of 0.
Move Soft Collision - Colliding objects will be separated, but gradually over time. This creates a "soft" feel, allowing objects to overlap and push each other around.
Bounce Collision - Colliding objects will be separated if a collision occurs. They will also have their velocity adjusted in response to the elasticity value. An elasticity value of 1 will preserve momentum. An elasticity of 0 will be an inelastic collision - where momentum is lost.
First Mass/Second Mass - see Move collision
Elasticity - A multiplier for an object's velocity when it collides. A value of 0 will absorb momentum. A value of 1 will preserve momentum. A value greater than 1 will add momentum.
Physics can also be applied using collision events if your game needs to customize the behavior when a collision occurs. For example, you may want the relaitive masses between entities to vary rather than always being fixed.
In some cases games will need to perform custom logic when a collision occurs. For example:
A Player entity takes damage when colliding with a bullet
The Bullet entity being destroyed when colliding with a wall
An Enemy entity's movement speed being slowed when colliding with mud TileShapeCollection
Certain objects should have different masses when performing collision.
Collision events can be created by dropping a CollisionRelationship on a Screen's Events folder.
For more information on FlatRedBall events, see the FlatRedBall Events page. Like all other events, collision events can be edited in code. In the example above, the GameScreen.Event.cs file now includes an function OnEnemyVsPlayerCollisionOccurred which is called whenever a collision occurs between an Enemy and Player instance. Make sure to add code to <YourGameScreen>.Event.cs and not the <YourScreen>.Genererated.Event.cs.
Notice that the CollisionRelationship used in this example is between a list of Enemies and a list of Players, but the event is raised for a single Enemy and a single Player. Since each enemy may collide with each player, the event method may get raised multiple times per frame. Every time the event is raised, the arguments tell you which two objects collided.
For example, in the code above, you could destroy either the enemy (which is called first) or the player (which is called second) in the event. To destroy the enemy, you can do the following code:
To identify which shapes an entity collided against in a TileShapeCollection, the LastCollisionAxisAlignedRectangles property can be used. For more information see the LastCollisionAxisAlignedRectangles page.
If all entity instances have the same mass, then you can set your collision relationship physics through the FlatRedBall Editor. If your game requires custom masses, then you can implement your own physics in the collision event.
For example, the following code would adjust the player's mass so that it is higher if the player is shooting. This makes the player harder to move when shooting.
CollisionRelationships created in Glue will be automatically managed and will automatically perform their every-frame logic. In some cases games need to manually perform collision logic. For example, a game may need to first reset variables on an entity before collision logic is performed for that frame. In that case, the CollisionRelationships created in Glue can be modified in the CustomInitialize method of the GameScreen. For example, to disable the EnemyListVsPlayerList CollisionRelationship, the following code can be used:
AxisAlignedRectangles are rectangular shapes which cannot be rotated. AxisAlignedRectangles can be used as collision objects. For information on using AxisAlignedRectangles in code, see the AxisAlignedRectangle code page.
To add an AxisAlignedRectangle to an entity:
Expand your entity
Right-click on the Objects item
Select "Add Object"
Enter the name "Collision"
Set the SourceType to "FlatRedBallType
Set the SourceClassType to "AxisAlignedRectangle"
The Circle object is commonly used for collision and as a placeholder graphic in game development. Circles can be added to entities which implement the ICollidable interface to act as the entity's collision shape.
To add a circle to an existing entity:
Expand the entity
Right-click on the entity's Objects folder
Select Add Object
Verify the FlatRedBall or Custom Type option is selected
Select Circle
Click OK
Circles can also be added to a new entity. To do this:
Right-click on Entities
Select Add Entity
Check the Circle option. Notice that this automatically checks the ICollidable check box.
The DestinationRectangle can be used to make a Layer only draw to part of a Screen. This is often referred to as "masking" or "creating a mask". The DestinationRectangle property in Glue functions the same as in code. For a technical discussion on destination rectangles for Layers, see this page.
The DestinationRectangle can control the area of the screen where a Layer is drawn. By default the DestinationRectangle is blank in Glue, meaning that the Layer will occupy the same area on screen as the main Camera.
This destination rectangle can be changed in Glue. To do this:
Right-click on "DestinationRectnagle" in Glue.
An option for "Use Custom Rectangle" should appear
Select this option and the Layer will be given a custom rectangle:
Now that the DestinationRectangle value is there, we can modify it easily by changing one of the four values, or by expanding the DestinationRectangle and modifying each value independently:
Consider a Sprite which takes up nearly the entire screen:
If this Sprite were put on the Layer, it would look like this:
Objects in Screens and Entities can be of type Camera. A Camera object will (by default) represent the main Camera (FlatRedBall.Camera.Main). If an object in an Entity is a Camera, then this will (by default) attach the main Camera to the Entity. If an object in a Screen is a Camera, then this object serves as an alias for FlatRedBall.Camera.Main, but no attachment occurs.
Cameras added to a Screen can be modified in the FlatRedBall Editor. By default, adding a Camera object to a Screen does not create a new Camera, but rather it provides access to the main Camera. For more information, see the IsNewCamera property below. To access the camera in a Screen:
Select the Screen to contain the object. To make changes for all levels, select the GameScreen.
Click the Add Object button to add a new object to the screen
Select Camera as the type and click OK
The new camera appears in the GameScreen. It can be modified to make changes to the game, including in edit mode. For example, the Background Color can be changed from Black to any desired color.
The IsNewCamera property is a property which only appears on objects which are of type Camera.
If this property is false (the default value) then the Camera object is assigned to the main Camera (FlatRedBall.Camera.Main).
If this property is true, Glue will create a new Camera instance. This is not often used but can be used for split-screen games.
If you are developing a game which requires logic for initializing or controlling the Camera then you may want to organize this code into an Entity. The Camera object facilitates setting this up in Glue. The process is as follows:
Create an Entity which will contain all of the logic. For example an Entity named CameraEntity
Right-click on the CameraEntity's objects and add a new object
Select Camera as the type
Now you can code logic in the CustomInitialize and CustomActivity of your CameraEntity.
The CameraControllingEntity provides a standardized way to control camera position in games which contain a moving character or which use Tiled for maps.
This page discusses working with the CameraControllingEntity in the FRB Editor. For information about how to work with it in code, see the CameraControllingEntity API Documentation.
If your game was created with the wizard, then your GameScreen has an instance called CameraControllingEntityInstance.
This instance targets the PlayerList (averages the position of all Players in the PlayerList) and will restrict the visible area to the Map object.
The Extra Map Padding property adds a number of pixels of offset between the edge of the actual map and the desired visible edge. A positive value adds padding, effective shrinking the available area that the camera can view. A negative value allows the camera to move outside of the map. Note that the property on the CameraControllingEntity is called Map since this is the most common type of object used to control bounds, but it doesn't have to be a map.
You can manually add a new instance to your game if you do not already have an instance in the GameScreen. Keep in mind this may have already been done for you if your game was created using the new project Wizard. To add a CameraControllingEntity to a game that has not used the Wizard:
Select your GameScreen
Select the Quick Actions tab
Click the Add Object to GameScreen button
Select the Camera Controlling Entity option
Click OK
Once you have created the instance, you can assign it the object to follow and the map to use as the visible bounds. To set which object the camera will follow:
Select the newly-created CameraControllingEntityInstance
Click the Variables tab
Select which object to follow in the Targets list. Notice that you can select entire lists of objects too, which will result in the CameraControllingEntity using the center position for all objects.
Similarly, the Map object can be set to control the visible bounds of the camera using the Map dropdown.
At runtime the Camera will automatically follow the target with no additional code required.
RenderTarget2D instances can be created in the FRB Editor. When created in the FRB editor, they have the following behavior:
They will automatically match the resolution of the screen
They will be cleaned up when the Screen is destroyed
For an example on using RenderTarget2Ds with FlatRedBall Layers, see the Layer RenderTarget page.
The AddToManagers property controls whether an object is added to its respective managers in generated code. In other words it controls whether the object is added to the FlatRedBall Engine or not. This value is true by default.
If an object is not added to managers, that means that the object will be instantiated, but it will not have any engine-provided behavior such as velocity, acceleration, rotational velocity, and attachments. Furthermore since the engine is responsible for rendering objects, any objects which have AddToManagers set to false will not be drawn.
If an object has its SetByDerived property set to true, then its AddToManagers is not generated. Typically SetByDerived is set to true if a derived screen or entity is responsible for instantiating an object. In such a situation, the derived screen is also responsible for adding the object to managers.
This behavior prevents both base and derived from adding the same object to managers, resulting in an object being updated or drawn twice per frame.
As mentioned above, AddToManagers is true by default, meaning any shape object (Circle, AxisAlignedRectangle, Polygon) will be added to the engine. This means that they will:
Be drawn by the engine
Have every-frame activity be applied automatically such as velocity, rotation, and rotational velocity
Both of these behaviors are usually not needed for shapes, especially when a game is nearing completion. Therefore, setting AddToManagers to false on shapes will generally result in improvement in your game's frame rate.
AddToManagers is usually left to its default value of true. Most objects will not need this value changed. However, this value may be set to true if your game requires that an object not be added to managers until after its container is created, or based off of a certain condition. For example, you may want to keep a character in a role playing game from appearing in a room until the player has completed a certain quest. Therefore, you may want to manually add the character instance in code in the Screen's CustomInitialize only if the user has completed the quest. Objects which are part of FlatRedBall managers have every-frame logic performed on them by the engine. Delaying or not adding an object to managers will improve performance slightly, and you may see a significant performance improvement in your game if you do not add objects which are not needed.
PositionedObjectLists (also referred to as lists) in the FlatRedBall Editor hold lists of objects which inherit from the PositionedObject type. Positioned objects include:
Any Entity (the most common types of lists)
Circles
AxisAlignedRectangles
Texts
Sprites
In code all of the objects mentioned above inherit from the FlatRedBall.PositionedObject class.
The most common place for lists is in GameScreen, although lists can exist in any screen and even in other entities.
As shown below, when an entity is created, the FlatRedBall suggests creating a list in GameScreen as well as adding a factory for the list. This configuration enables the following common and useful behaviors and relationships:
Entity lists automatically associated themselves with factories, so that creating a new instance through a factory in code results in the instance being added to the list.
Entity lists call Activity on all contained instances, keeping activity behavior consistent whether the instance is created in the FRB editor or at runtime (such as through a factory)
Entity lists automatically destroy all instances when the screen ends, making screen cleanup easy
By default the FRB Editor creates lists for newly-created entities if the default options are left unchanged. For example, the following animation shows the creation of an entity called Enemy which also results in an EnemyList added to GameScreen.
The FlatRedBall Editor provides a number of ways to create new lists.
If your game has a GameScreen, and if your GameScreen does not already contain a list for an entity, then the Quick Actions tab shows a button to add a list to the GameScreen. Clicking this button creates a new list in the GameScreen.
Entity lists can be created by right-click drag+dropping an entity into a screen. This is useful if you are adding lists of entities to screens other than the GameScreen.
PositionedObjectLists can also be created through the regular right-click menu in an screen or entity's Objects node:
Right-click on Objects
Select Add Object
Make sure FlatRedBall or Custom Type is selected
Select PositionedObjectList<T>
Select the type of list to create using the dropdown
Enter the name of the list
Once a list has been created, instances of the list's type can be added through the FRB Editor using a number of methods.
Option 1 - Drag+drop onto Screen, Objects folder or List
If a list contains a screen, it becomes the default container for newly-created instances that are added by drag+drop. For example, the following shows enemies being added to the EnemyList by drag+dropping an enemy on Level1, Level1's Objects folder, and directly on the EnemyList.
Option 2 - Right-click, Add Object
Objects can be directly added to the list by right-clicking on the list. Notice that the Add Object window restricts the types of entities which can be added to the types that are supported by the list. For example, the following animation shows how to add an Enemy to an Enemy list with the right-click menu.
If the list is of a base type, then the right-click option provides all available options for the list. For example, the following is a screenshot from a game which has multiple entity types inheriting from Enemy:
The CallActivity property controls whether the FRB Editor should generate Activity calls for a PositionedObjectList. By default this value is set to true. For example, the following shows a BulletList inside a screen which has its CallActivity set to true:
If this value is changed to false, then the Bullet instances inside of BulletList would not have their Activity (and CustomActivity) methods called automatically in generated code.
The most common reason to set this value to false is when dealing with derived entity lists. For example, consider a game which has a base Enemy entity as well as Skeleton entity which inherits from Enemy (Skeleton is an Enemy variant). If the game needs to perform custom logic on Skeleton instances then it may need both an EnemyList and SkeletonList in GameScreen.
In this case, Skeletons which are created through the Skeleton factory would be added to both the EnemyList and the SkeletonList. If both EnemyList and SkeletonList called Activity, then Skeleton instances would have activity called twice per frame. This can result in unexpected behavior such as movement logic being applied twice per frame.
If a derived entity type list is added to a screen through the quick action button, FlatRedBall automatically sets CallActivity to false.
If an entity list is added through the right-click option on a screen, FlatRedBall provides suggestions about whether to call Activity.
Sprites are used to render a texture to the screen. Sprites are one of the most common types of FlatRedBall objects. Examples of Sprites include:
Character graphics (static or animated)
Backgrounds
Particles
Bullets
Sprites are often contained in Entities or created in code as particles.
Many new developers confuse the terms Sprite and Texture so it's worth discussing the difference. A Sprite is an object that is added to an Entity which can display a texture or a portion of a texture. A Sprite can have a size, rotation, transparency, and a color tint.
A texture (technically a Texture2D) is an image which is usually loaded from a .png file. The texture has pixel data which is used by a Sprite to draw to the screen. A texture can contain a single image (such as a coin or bullet), or it can contain multiple images. When it contains multiple images it is often referred to as a sprite sheet.
You can think of the Sprite as something which displays texture data - like a digital picture frame. The texture is the picture that is being displayed in the digital picture frame.
When you are creating a new entity, you can check the option to add a Sprite in the Add Entity Window.
Right-click on the Entities folder
Select Add Entity
Check the Sprite option
Click OK
Sprites can be added to FlatRedBall screens or entities, although most games don't include Sprites directly in screens. To add a Sprite to an entity:
Create or select an existing entity or screen
Right-click on the Objects node
Select Add Object
Select the FlatRedBall or Custom Type category
Select the Sprite type
Click OK
Entities often contain a Sprite for their main visuals. Some entities may have multiple sprites for visuals. For example, an Enemy may have the main SpriteInstance for its body and a ShadowSprite for the shadow.
Sprites usually display textures, which are created from image files such as .png files. To add and display a texture on a Sprite:
Create a Sprite in a screen or entity as shown above
Find a .png which you would like to use
Drag+drop the .png file onto your screen or entity's Files folder in FlatRedBall
Select the Sprite in the same screen or entity with the newly-added file
Change its Texture property to the newly-added file
Sprites can display animations by referencing a .achx file.
To reference an Animation, the first step is to have a .achx file in the same Entity or Screen as your Sprite.
Once you have an .achx file, you can add the Animation by drag+dropping the .achx onto the Sprite.
Alternatively, you can change the Animation Chains property in the Variables tab.
Polygons can be added to screens and entities to create complex collision. Polygons will automatically be used in an entity's collisions if the entity is marked as ICollidable in Glue. For information on working with the Polygon object in code, see the Polygon class reference.
Polygons can be added to entities:
Select the entity which will have the Polygon
Select the Quick Actions tab
Click the Add Object button
Select the Polygon type
Click OK
If the containing Entity is an ICollidable, the Polygon will automatically be used when performing collision.
Polygons can be edited through the Points tab, which appears when selecting a Polygon.
A SoundEffectInstance is a sound effect which provides a number of properties which can be used to modify how the sound is played back - for example volume, pitch, and whether the sound is looping. If a SoundEffectInstance is playing, it cannot be played again until the sound ends, or until the SoundEffectInstance is explicitly stopped. This can give precise control over how many sounds are playing at one time.
To add a SoundEffectInstance to your project:
Make sure you have a Glue project with a Screen or Entity which will contain the SoundEffectInstance.
Add a new WAV file to your Screen or Entity. For more information, the .WAV file page.
Once the file has been added to Glue, you need to change the RuntimeType to SoundEffectInstance:
At this point the SoundEffectInstance will be available in code, but you cannot change any variables on the SoundEffectInstance. To do this:
Right-click on Objects
Select "Add Object"
Select the "From File" option
Select the .wav file you added as a file
Click OK
Select the newly-created object
Change "SourceName" to "Entire File (SoundEffectInstance)"
The Objects folder contains most visual and collidable game objects. Objects can be added to Screens and Entities, and when added through Glue, objects will automatically be managed. Objects can be grouped in one of three categories:
Instances of entities
Primitive types (such as FlatRedBall Sprite or Circle)
Objects obtained from a file
Entity instances can be created in Glue by drag+dropping an entity onto the Objects folder of a Screen or another entity.
Using the right mouse button when performing the drag+drop allows the selection of a single instance or a list.
Entities can also be added through the right-click menu.
Entities can also be added to screens or other instances of entities.
The Is2D option can be used to make a Layer use 2D coordinates. Layers which are 2D can be used even if the current Camera is in 3D. Layers which are 2D are often used to create HUDs and UI Screens.
For information on how to use Layers in code, see the Layer reference page.
The most common usage of the Is2D property is to create a 2D layer in a game which uses a 3D camera. Typically 3D games will have some type of 2D hud, so a 2D layer is needed to hold hud.
This example shows a simple setup where a 2D layer can be used on a 3D graphic. First, the game is set up to use a 3D camera.
Next, a Sprite is added to a GameScreen. It has the following variable values:
Texture = GroundTexture
Right Texture Pixel = 512
BottomTexturePixel = 512
Texture Address Mode = Wrap
Y = -10
Rotation X = 1.5708
The GameScreen has a layer named Layer2D for 2D objects.
Finally the GameScreen has a Text instance called GameOverText which has been placed on Layer2D.
The result is SpriteInstance is drawn in 3D, but the GameOverText is drawn and positioned in 2D.
Layers are a type of object which can be used to control the order in which visible objects in FlatRedBall are drawn. Most objects sort by their Z value. In other words, objects which are further from the Camera will draw behind objects which are closer to the Camera. Layers allow control over draw order without changing the Z of objects.
Layers are often used to draw certain categories of objects. For example, you may have regular game objects (such as trees, the ground, the sky), a Layer specifically for HUD elements (score, health, ammo), and another Layer for popup screens (pause screen, disconnected controller screen). Layers can also be used to draw visuals in 2D coordinates on top of a 3D Camera.
For a general tutorial on Layers in Glue, see the Using Layers Glue Tutorial page. For information on using Layers in code, see the Layer page.
To create a Layer in the FRB Editor:
Select a Screen or Entity which will contain the Layer. Usually Layers are added to Screens.
Click the Quick Actions tab
Click the Add Object button
Select Layer
Click OK
Layers are drawn in the same order that they are added in code. In other words, if Layer1 was added first, then Layer2, Layer1 would draw first, then Layer2 would be drawn on top of Layer1. Similarly, the order of Layers in Glue impacts the order that they are drawn. Layers draw top-to-bottom. Therefore, the first layer when looking at the list of elements in Glue will be drawn first, and any subsequent Layers will be drawn on top.
You can adjust the order of layers by right-clicking on a Layer and selecting one of the options to move it:
To add an object to a layer:
Make sure you have a Layer in the same Screen as your object
Drag+drop the object onto the layer
You can verify that the layer was changed by looking at the LayerOn property. Entity instances can be moved to a layer in code using the MoveToLayer function.
The FlatRedBall Editor supports creating objects of type ShapeCollection.
Note that entities which are created as ICollidable automatically have a ShapeCollection named Collision, and all shapes shapes are added to the default Collision shape collection. In this case you do not need to manually create a ShapeCollection. For more information, see the Implements ICollidable page.
To add a ShapeCollection:
Right-click on Objects under a Screen or Entity
Select Add Object
Verify that FlatRedBall or Custom Type is selected.
Select ShapeCollection
Click OK
Note that FlatRedBall also supports the .shcx file format, but this is no longer recommended. The PolygonEditor tool is no longer maintained, and the recommended approach is to add a ShapeCollection as shown above and to modify the shapes using FlatRedBall's LiveEdit.
ShapeCollections can have shapes added manually. The ShapeCollection serves as a "list" of shapes, but unlike normal lists, the ShapeCollection can contain multiple types of objects.
To add a new shape to the ShapeCollection:
Right-click on the ShapeCollection instance
Select Add Object
Select one of the shapes - notice that FlatRedBall filters the available types to the types allowed in a ShapeCollection.
Click OK
Your newly-created shape is added to ShapeCollection in the tree view.
For information on how to work with a ShapeCollection in code, see the ShapeCollection page.
The AttachToCamera property controls whether an object is attached to the Camera. HUD and UI elements are often attached to the Camera so that they stay in the same screen position when the Camera moves.
To attach an instance of an object to the Camera:
Select the instance under the "Object" tree item in a given Screen
Set the AttachToCamera property to true:
The AttachToCamera property is only available on objects which are contained in Screens. Objects which are contained in Entities do not have this property, and functionally AttachToCamera will always be false on objects in Entities. The reason for this is because even though this is something which is supported by the underlying FlatRedBall engine, it can result in confusing and difficult-to-debug behavior. Keeping all attachments to Camera at the Screen level makes it much easier to identify why an object is not behaving as you might expect.
The TileNodeNetwork object type is used to define the walkable areas in a level. Once a TileNodeNetwork is created it can be used for pathfinding for AI-controlled entities such as Enemies.
The FlatRedBall Editor supports the creation and population of TileNodeNetworks. Typically TileNodeNetworks are filled using tile maps. This section covers common ways to fill a TileNodeNetwork. We recommend using the GameScreen and Level approach, as this makes it easier to maintain games with multiple levels. Using this pattern, a TileNodeNetwork would be defined in the GameScreen:
Select the GameScreen
Click Add Object to GameScreen in the Quick Actions tab
Select TileNodeNetwork as the type
Enter a name for your TileNodeNetwork such as WalkingNodeNetwork
Click OK
Be sure to create the TileNodeNetwork in the GameScreen so it is included in all levels.
TileNodeNetworks (just like normal NodeNetworks) must have nodes and links to be used for pathfinding. Each node represents a point on the map where an entity can walk. These nodes are connected by links which indicate how an entity can walk.
We can create nodes and links for each level from the tiles in our Tiled map. We have two options for doing this:
By indicating that all empty tiles in a map should contain nodes
By using a dedicated tile for marking where entities can walk
The first option is easier because it works for many simple maps without any modifications. The second option provides more flexibility.
For simplicity we'll use the first approach (empty tiles):
Select the new TileNodeNetwork
Click on the TileNodeNetwork Properties tab
Click the From Layer option under the Creation Options category
Select your map and the layer. Typically this is Map and GameplayPlay layer.
Verify the All Empty option is selected
Optionally you may want to make the TileNodeNetwork visible so you can verify that it has been filled in:
Select the TileNodeNetwork
Click the Variables tab
Check the Visible checkbox
The game should display the node network wherever no tiles are present.
Some games include specific tiles for pathfinding rather than all empty tiles. The first step is to determine which tile to use as walkable tiles. Whichever tile is used should have its Class (or Type if using older versions of Tiled) specified in the tileset in Tiled.
Once this tile Type is set (and the .tsx is saved), this tile can be used to mark walkable areas in the map.
To use these tiles:
Select the TileNodeNetwork
Click the TileNodeNetwork Properties tab
Check the From Type property
Select the Source TMX File (usually Map)
Select the type for the tile you just saved. It should appear in the drop-down if the .tsx file has been saved.
The TileNodeNetwork will now place a node wherever the walkable tiles are present.
The AttachToContainer property sets whether a contained object attaches to the Entity that contains it. By default this property is set to true for all objects contained in an Entity.
This property will appear on all objects which can be attached to their containers in Glue.
AttachToContainer is only available on objects inside Entities.
The CallActivity property on an object determines if the object will have its CustomActivity (custom code) and Activity (generated code) methods called. This value defaults to true, which means that objects will have their Activity (and CustomActivity) called automatically.
CallActivity can be set to false to prevent generated code from automatically calling Activity on an object. This might be useful in a number of situations:
If a Screen has multiple lists of the same type (such as EnemyList), and if instances may exist in both lists. The primary list should have CallActivity set to true, while other lists should have this value set to false to prevent Activity from being called twice per frame.
If activity is never needed on an entity, and a large number of entities exist. Omitting activity calls may provide a small performance boost.
If entity activity is optional. This scenario is considered advanced, and is not recommended for most games. However, the flexibility exists.
PositionedObjectLists which are contained in Screens and Entities will call Activity on all contained instances. Setting CallActivity to false will disable this functionality.
FlatRedBall Text objects can be used to display information to the player such as current score or character dialog. Glue supports creating and editing Text objects in screens and entities.
To create a Text object in Glue:
Right-click on the Object item in a screen or entity
Select Add Object
Select the "FlatRedBall or Custom Type" option
Scroll down and select the "Text" type
Click OK
To see the Text object:
Select the Text object
Set its Display Text value to some value like "Hello"
Click the Preview checkbox in Glue
Since Text objects are usually used for game UI, the following properties are usually set in Glue:
Objects in Glue which reference files can either represent a part of a file (such as a Sprite in a Scene) or the entire file itself. Using the "entire file" option can make it easier to maintain as no changes are required on the Glue side when objects are added or removed from a file. The "entire file" option is often used in entities, which require files to be added as objects before they will show up in game.
The following steps can be used to create an entire file from a .emix (Emitter List) file. It assumes that the Entity already has an .emix file:
Right-click on Objects
Select "Add Object"
Select the "From File" option
Select the .emix file
Use the drop down to set the Source Name to "Entire File (EmitterList)"
Click OK
Objects using the "entire" option behave slightly differently than normal objects. If two named objects reference the same item in a file, then the Entity will receive two copies of that item. However, if one named object references the entire file, and another Entity references an item from inside that file, the second will reference an item in the first, instead of making its own copy. If this is confusing, let's take a look at an example. We'll start with an Entity called "Button" which has a Scene. This Scene may contain any number of objects - a frame for the Button, a highlight Sprite which turns on/off, a Text object, a drop shadow, and so on. Creating an object using "Entire File" is a quick way to see the entire Entity in game, but how do you add behavior to the Text object? The answer is, you can simply create a new object and have it reference the Text object in the Scene - Glue will not duplicate the object. In other words, your new object will reference the same Text object that is held inside the "Entire File" object. Now you can create variables and states using the new TextObject, and even use it in code.
If you open the generated code file you'll see that the TextObject comes from the EntireScene object:
For more information about working with textures, see the .
To add a new .achx file, see the page.
Sprites can automatically apply the collision from their AnimationChains to their parent Entity. For more information, see the page.
After setting up the object, you can modify the variables of the object in Glue. To do so, select the object and scroll to the "Unset Variables" category. These variables can also be set through code:
- Text objects are usually placed on a UI or HUD layer
- Text objects are usually displayed in a fixed position on screen
The ExposedInDerived property on an object allows an object to be accessible in a derived Entity. This is useful if a base Entity defines that an object must exist (such as an AxisAlignedRectangle in a collidable entity), but the entity modifies its values (such as a derived enemy entity modifying the size of its collision). Objects which are ExposedInDerived will appear as normal white entities in the tree view, and objects which are created as a result of setting ExposedInDerived to true appear as green in derived entities. The following image shows an AxisAlignedRectangleInstance in BaseEntity which has its ExposedInDerived set to true. The AxisAlignedRectangleInstance in DerivedEntity is green to indicate that it is created in the base entity.
Providing proper access to your objects can be a little complex at first, but it is the key to "scalability" (the property of being able to continually grow the size of your game while minimizing complexity). In short, there are three "levels" of access you can provide in Glue:
No access in derived elements (default)
ExposedInDerived set to true
SetByDerived set to true
If no access is given, then an Entity's objects will be hidden from derived Entities. This allows derived entities to simply inherit a "closed" object. It is rare to have a base entity that does not provide access to any of its contained objects to a derived entity, but this option exists in case you want to limit access to some. ExposedInDerived allows you to access and modify an existing Object in a derived Entity, but you do not have access to set it to something different. This is common for Entities which include lists that are to be populated by derived Entities. You can also do things like change properties on ExposedInDeived objects. SetByDerived allows you to completely change an Object in an derived Entity. In this case, the base entity simply defines that an object can exist but the derived entity is responsible for actually defining this object. This can be used if the derived entity will create the object conditionally, or based on some other file (such as obtaining a collision object from a Gum component).
The IncludeInIClickable property enables the exclusion of a shape from the IClickable interface checks. By default all shapes and Sprites added to an entity are checked in the HasCursorOver method. In other words, by default this property is set to true. This value can be set to false to exclude a shape from IClickable.
The HasPublicProperty variable on an Object controls whether the object can be accessed by code outside of an instance of the containing Entity. In other words, it controls whether the property created for an object is private or public. This value is false by default, but can be set to public if necessary.
The HasPublicProperty is by default false. It is usually set to true when dealing with objects which must expose certain objects to the Screen that contains them. Most commonly, objects need to expose their collision members so that the Screen that contains instances or lists of collidable objects can perform collision logic. If your code attempts to access an object from outside of an Entity but the object's HasPublicProperty is set to false, then you will see a compile error like:
The HasPublicProperty is only available on objects in their base definition. If an object is available in a derived Entity, but defined in the base Entity, the HasPublicProperty value can only be set in the base and not derived.
If an object is collidable, Glue displays a Collision tab. The following types can be collidable:
Collidable entity instances (like a single Player entity in a screen)
Collidable entity lists (like a list of Bullets in a screen)
TileShapeCollections (like SolidCollision in a screen)
ShapeCollection (like a ShapeCollection containing trigger zones for ending a level)
The following shows the Collision tab for a BulletList, which is a list of Bullets where the Bullet entity implements the ICollidable interface.
If the selected object is a list of collidables, then it can be partitioned. By default partitioning is turned off because incorrect values can cause collision to fail. However, partitioning is critical for games with a large number of objects such as Kosmo Squad.
If a list performs collision partitioning, Glue provides a number of options for partitioning, as shown in the following image:
Usually the answer is "yes, but maybe not now". Of course, for games with small numbers of objects it may not improve the game's performance much. Games with larger numbers of objects can improve performance by enabling partitioning, but partitioning can also introduce bugs so it's recommended to not turn on partitioning at the beginning of the development process unless you suspect that collision is already causing performance problems.
The Sort Axis is used to partition objects. In general we recommend leaving the Sort Axis to its default X value unless you are certain that your game will be distributed more along the Y axis than the X axis. If two lists collide against each other, then both lists must have the same sort axis. Therefore, sort axis is usually something you decide for your entire game rather than on a list-by-list basis.
This value indicates the maximum width or height of the entity in the current list. Keep in mind that entities in a list may or may not all be the same size. For example, you may have an EnemyList, but the Enemy instances inside the list may be of different size. The Partition Width/Height should be set to the largest possible width or height of any object in the list.
This option tells Glue whether to sort the list every frame for partitioning or not. If objects within the list can move (such as bullets), then sorting should happen every frame. If objects in a list cannot move (such as doors in a level) then sorting does not need to happen every frame.
LayerOn controls which layer an object is rendered to. By default the value is blank which means that it will be sorted with all other objects with no layer. This value can be changed on an object's Properties tab.
For an object to be on a Layer, a Layer must be defined in the same Screen/Entity that a given object is a part of. Once this occurs you can either use the LayerOn property to set the Layer, or you can drag+drop the object onto its desired Layer in the Glue UI.
The **LayerOn **property can be set to one of the following values:
<None> - Clears the LayerOn value
Under Everything (Engine Layer) - A layer automatically created by the FlatRedBall engine for objects which should be drawn under everything, including objects with no layer.
Layer Objects - Any Layer Object will appear in this list. If no Layers have been created in the current screen/entity, no layers will be shown here. The screenshot below shows LayerInstance, which is a Layer added to the SpriteEntity (shown in light green).
Top Layer (Engine Layer) - A layer automatically created by the FlatRedball engine for objects which should be drawn above everything, including all other layers.
At the time of this writing, only non-list objects can be added to layers. This is because lists do not have built-in support for layers in the FlatRedBall engine, and Glue is simply exposing default FlatRedBall object behavior for layering.
The IgnoresPausing property controls whether an object will be paused when the Screen it belongs to is paused. If this value is false, an object will behave the same whether the Screen is paused or not. This value can be assigned on individual instances or entire lists.
The IncludeInICollidable property controls whether an object is included in the container Entity's Collision ShapeCollection. By default this value is set to true, which means that any shape included in an ICollidable entity will be considered in collision. This can be set to false to exclude a Shape from the Collision ShapeCollection. Typically this value is set to false for shapes which should not be used for standard (solid) collision, such as line of sight collision.
For this example, consider an Entity named Enemy which has two shapes:
An AxisAlignedRectangle named Body
A Circle named DetectionCollision
In game, the entity may appear as shown in the following image:
In this example, the Body is used for collision against walls, the Player, and bullets. The DetectionCollision Circle is used to determine if an Enemy sees the Player. Therefore, we only want the DetectionCollision to be used in a special circumstance - a CollisionRelationship between Enemy and Player lists. Otherwise, the DetectionCollision should be excluded. The DetectionCollision can be excluded from default collision functions by setting the IncludeInICollidable to false.
By default collision relationships will not use the DetectionCollision. For example, the following collision relationship would not collide the enemy against the walls:
However, the following collision relationship would still detect collisions between the Enemy's DetectionCircle and the Player:
Notice that even though the DetectionCollision has its IncludeInICollidable set to false, collision relationships which explicitly reference this shape will still check collision.
The IsContainer property can be set to true to make a given object act as an alias for the containing Entity.
For a tutorial on how this works and why this is a good idea, see this link.
The Map object is a standard object created by the FlatRedBall Wizard. The Map object is defined in the GameScreen but is also available
Typically the Map object is a LayeredTileMap defined in the GameScreen and has its SetByDerived property to true.
If not using the wizard, the Map object is optionally created when adding a new GameScreen in a new project.
Using a Map object is recommended, whether it is created through the wizard or the Add Screen dialog.
Level screens should also have a Map object. Each Level screen will automatically have a Map object since the Map object in the GameScreen has its SetByDerived set to True. By default new levels will have a TMX object added automatically.
When using the default options, a new level will have a TMX file in the Files folder and a Map object in the Map folder.
Under the default setup (as set up by the new screen dialog), the Map object in the level will reference the TMX file.
If your game does not have the Map object assigned to a TMX file you may need to manually make the connection between the object and the file. This can happen if you delete the default TMX file, or if you are manually adding the TMX file at a later time. To assign the Map object to use the TMX file, drag+drop the TMX File onto the Map object in your Level screen.
The SourceFile sets the file that defines a given object.
If a file is added to a Screen, then it is automatically loaded when the Screen is loaded. If that file has a runtime representation, then the runtime representation is automatically created and added to the respective managers. For example, if a Tiled file (tmx) is added to a Screen, then the Tiled file is loaded and its runtime object (MapDrawableBatch) is added to the engine so that it will be drawn.
Therefore, for basic scenarios there is no need to create objects for a file - it will be fully functional just by being part of a Screen.
However, there are a number of situations where you may want to create an object that references the file - either in part or in whole. The following lists a few of these situations:
A Map object is usually added to GameScreen to allow TileShapeCollections and TileNodeNetwork to reference tile types and layers. This Map has its SourceFile set to the TMX in each level. This is automatically added when creating your project with the wizard.
A GumScreen object is usually added to GameScreen so that it can be added to a HudLayer. This is automatically added when creating your project with the wizard.
Individual layers within a tmx file can be referenced for custom game code, such as to reference tiles for logic not provided by entities or TileShapeCollections.
As mentioned above, adding an object that references a file does not create a copy of the object - rather it references the already-loaded file so that the object can be customized in the FRB Editor, refernced by other objects in the FRB Editor, or referenced in code in a type-safe way.
Objects in entities can also reference files, but these objects can create clones of the runtime object in the File. To understand why entities create clones, the first thing to remember is that files in both Screens and Entities create static objects in code.
For example, consider a file named TextureFile in the Enemy entity:
This file produces a static property in the Enemy class with the matching name.
Since the TextureFile (and all other files) are static, then all Enemy instances share the same File property. For file types which are often shared, such as Texture2Ds or SoundEffects, this behavior is convenient and sufficient for most games.
By contrast consider a type which has a runtime type, such as a Tiled file which loads into a MapDrawableBatch. If an entity references a TMX file, then it is likely that each instance of the Entity should have its own copy of a MapDrawableBatch. However, although this is likely, it is not guaranteed. Games may include references to files which may have runtime representatoins, but the game may not necessarily want this loaded and attached to the entity.
Objects which have their SourceFile set can control this behavior. To continue the TMX example, if no object is created, then the TMX is loaded into a MapDrawableBatch when the Entity is instantiated, but this loaded MapDrawableBatch does not get added to FlatRedBall. To have this MapDrawableBatch be drawn and attach to the entity, then an object must be created. By creating an object in an entity, this tells FlatRedBall that the game should create a copy of this MapDrawableBatch for each entity instance.
To create an object from a file, you can drag+drop the file onto the Objects folder.
You can inspect and change the properties on the object in the Properties tab after its creation.
You can identify whether an object is a clone of a file or a reference to a file by inspecting the generated code for the object. For example, the code above for the EntireFile in the Enemy class is assigned to a clone of the file as shown in the following screenshot of the Enemy.Generated.cs file:
If your game was created with the wizard and if you have a GameScreen, then your game likely has a Map object defined in the GameScreen which is set from file in the derived Level screens. Map is a particularly interesting use case of File objects because it is defined in a game screen but its SourceFile is set on the derived instance.
The Map object in the GameScreen has its source type set to FlatRedBall type. Notice that it also has its SetByDerived property set to true. This combination tells FlatRedBall that this object should be declared in the GameScreen, and that it can be referenced by other objects, but that ultimately it is up to derived classes (Level screens) to instantiate the Map object.
Each level also has access to the Map object in the FlatRedBall Editor. By default, these derived Level screens instantiate the Map object by referencing the entire TMX.
This split definition (declaration in the base, instantiation in the derived) provides both flexibility and reusability. Each level is free to load its own TMX file, but the shared GameScreen can use the Map to define TileShapeCollections for collision, TileNodeNetworks for pathfinding, and to provide map bounds for the CameraControllingEntityInstance.
Projects created by the FlatRedBall wizard automatically create a GameScreen which includes a matching Gum screen. This Gum screen is defined in a .gusx file which is added to the GameScreen's Files.
As mentioned earlier, the addition of the GameScreenGum file to the GameScreen in the FlatRedBall Editor is all that is needed to have the Gum screen render and be interactive when the game is running. However, if this object is to be customized in the FlatRedBall Editor, then it must be added as an object. By default this is added as an object named GumScreen.
The GumScreen object is created so that its layer can be set. For example, the following screenshot shows the GumScreen added to the HudLayer:
Alternatively, you can assign the Source properties on the map object:
The SourceFile property is a property which controls which file a given object is defined in. This value is only available if the object's is set to "File". If this value is available, then the drop-down lists all files in the containing Screen or Entity. The selected SourceFile determines the available .
The SetByDerived property enables base screens/entities to define objects which will be assigned (instantiated) in derived screens/entities. Keep in mind that both the base and derived Object type must be the same.
SetByDerived can be set to true in the following situations:
The object that you intend to create comes from a file that is defined in a derived class, such as the Map object in GameScreen
The object is not always present in all derived types, such as the presence of an optional Sprite on an entity
If your game was created using the new project wizard, then you probably have a GameScreen with a Map that has its SetByDerived as true.
In this case the GameScreen is defining that a Map object will exist, but the instantiation of the Map object should happen in derived (Level) screens. Typically this instantiation is done from a TMX file. In the following image, the Level1 Screen (which inherits from GameScreen) creates the Map using its Level1Map.tmx file.
If you set the SetByDerived property on an object to true, that means that generated code will not instantiate that object in the Screen or Entity that contains this Object. This Screen or Entity must be used as a base Screen or Entity to actually create an object. For example, consider an Entity called Character which contains a Sprite Object with SetByDerived set to true. The Sprite will not be created if you add an instance of Character to another Screen or Entity. The Character must be used as a base for another Entity (such as an Entity called "Monster").
If an object has SetByDerived marked as true, then FlatRedBall expects that this object must be instantiated in a derived class. Therefore, to prevent errors the code that is generated for the Screen or Entity is marked as abstract.
For example, a typical GameScreen in FlatRedBall is abstract because its Map object has the SetByDerived property to true. Your GameScreen.Generated.cs class header probably looks like the following code:
These two properties may seem similar but each is used in a different scenario. SetByDerived is used if you want the derived screen/entity to control the creation of the object, such as assigning an object to the result of loading a file. ExposedInDerived is used if you want the derived screen/entity to have access to the object so that its properties can be changed, but the object is still ultimately instantiated in the base.
The following shows how to create an Entity (Base) which defines a Sprite Object which will get SetByDerived. The Derived then re-defines the Sprite.
Right-click on the tree item
Select Add Entity
Name the entity Base
Check the Sprite checkbox to add a Sprite to the Base entity
Click OK
Right-click on the Entities tree item
Select Add Entity
Name the entity Derived
Click OK
Click the Properties tab on the newly-created Derived entity
Set the BaseEntity property Entities\Base
Base and Derived are bad names! This example uses the names "Base" and "Derived" to clearly indicate the relationship between two Entities. In an actual game, avoid using names like Base and Derived. You should always name your Entities in a way to indicate what they are in the context of your game (such as Character or Enemy or PlayerShip). However, if you intend to use an Entity as a base type, it is a good idea to append "Base" at the end of the name (such as EnemyBase).
Expand the Base entity
Select SpriteInstance (which was created earlier when the Sprite checkbox was checked)
Select the Properties tab
Set the SpriteObject's SetByDerived to True
FlatRedBall automatically adds a SpriteInstance to the Derived entity.
Notice that objects which have their SetByDerived property to true appear blue in the tree view window, and objects which have their base implementation marked as SetByDerived appear yellow.
At this point the Derived entity will automatically create a Sprite for you (since it is an object in Glue). You can select this Sprite and assign variables on it, just like any other Sprite.
By default SetByDerived applies to only one level of inheritance, rather than cascading down through all levels of inheritance. For example, consider an example with three entities:
Base
Middle (which inherits from Base)
Derived (which inherits from Middle)
If Base defines SpriteInstance, and SpriteInstance has its SetByDerived to true, then the assignment to SpriteInstance will be done in Middle, and Derived will not be able to re-assign Sprite. Notice in the image above that SpriteInstance does not appear in the Derived entity.
However, the SetByDerived property can be set on the Middle SpriteInstance, and it will be assignable in Derived.
The SourceType property determines the type of the Entity at the highest level. Changing the SourceType results in different options being available in the SourceClassType. Available SourceTypes are:
File
FlatRedBallType
Entity
Gum
Note that the same object in a base and derived screen may use different SourceTypes. For example, a Map object in GameScreen may use a FlatRedBallType, but each level uses File.
If an object's SourceType is File, then the object is defined by a file. If the object is created in a Screen, then the object is referencing either a part or the entirety of the file. If the object is an Entity then the object may be a reference to the file or a copy of the file if the file has a runtime type such as a Tiled TMX being loaded into a MapDrawableBatch.
A common example of an object which uses the File type is the Map object in derived levels.
For more information on File objects, see the SourceFile page.
FlatRedBallType means that the Object will be a standard FlatRedBall type such as Sprite, Circle, Layer, or PositionedObjectList. FlatRedBallType is usually used in the following situations:
An object which uses a FlatRedBall type (such as Sprite) but its definition is simple enough that it doesn't merit the creation of an entire file to define it. Glue can modify Object properties on FlatRedBall types through the object itself (it automatically exposes a small set of variables) or through tunneled variables.
An object which will be assigned to data from a file dynamically. This type may get set in reaction to a property being set on an Entity or Screen after initialization.
An object which will be assigned to a File in a derived Entity. The base Entity must define the type of the object, and using FlatRedBallType (along with the appropriate SourceType) can accomplish this.
The Entity SourceType identifies the Object as an instance of an Entity created in your project.