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...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
The "absolute edge" properties returns the absolute (also known as world coordinate) value of the edge of the camera's viewable area. It is one of four properties:
AbsoluteRightXEdge
AbsoluteLeftXEdge
AbsoluteTopYEdge
AbsoluteBottomYEdge
This property is similar to calling the "At" methods, such as AbsoluteRightXEdgeAt, but it assumes a Z value of 0. These properties can be more convenient than the "At" methods, especially for games which have the Camera's Orthogonal property set to true - which is the default.
The "absolute edge" values can be used to prevent the camera from viewing outside of the Camera bounds. Note that typical games use the CameraControllingEntity for camera positioning, so setting absolute edge values only applies if the camera is not controlled by a CameraControllingEntity instance.
If the Camera's Orthogonal property is set to true, then the "absolute edge" values can be set.
For example, to move the camera so that the coordinates (0,0) appear at the bottom left of the screen, the following code can be used:
The following code can be used to prevent the Camera from viewing outside of viewable bounds:
The AddLayer method allows the addition of Camera-specific Layers.
AddLayer() instantiates a new Layer and adds it to the Camera's internal list of Layers, at the end (to be drawn on top of all other contained Layers).
AddLayer(Layer layerToAdd)
adds an existing Layer instance to the calling Camera. The argument Layer should not already already be a part of any other Cameras or this method throws an exception.
The Camera class inherits from the PositionedObject class, so it can use the AttachTo function. For general information on AttachTo, see the PositionedObject.AttachTo page.
The simplest way to have the Camera follow an object is to attach the Camera to the object. However, if you do this, you will need to make sure to have the Camera's RelativeZ be a positive value so that the Camera isn't at the same Z value as the object it is attached to. For example, the following code attaches a Camera to a PlayerInstance - which is assumed to be a PositionedObject:
Attaching a Camera to another PositionedObject (like an Entity instance) is the easiest way to have the Camera follow on object; however, it is rather limited in its movement. Most modern, professional games do not attach the Camera to the player. The reason is this results in an unnatural form of movement. Rather, most modern games will do the following:
Perform smoothing in the movement - often the Camera may lag behind player actions
Looking ahead towards where the player is facing
Adjusting to prevent the "end of the world" from being seen
Scripted movement such as zooming out or moving on game events like when entering a new environment or when a boss appears
Therefore, attaching the Camera to an object is a good initial following implementation, but you should consider replacing this with a more advanced implementation as your game moves further along.
The CameraCullMode property controls how the Camera culls objects such as Sprites. The process of culling is the removal of objects from rendering calls. Culling can improve your game's performance by not drawing objects which are out of view. However, culling may not be desirable if your game supports a rotated camera.
By default, CameraCullMode is set to CameraCullMode.UnrotatedDownZ, which means that the Camera will not draw objects which are outside of the calculated view of an un-rotated camera. If your game requires a rotating camera (such as a 3D game), then you may need to set CameraCullMode to None
CameraCullMode only culls objects based on their angle relative to the camera. It does not affect drawing as related to distance. For more information on distance-based culling, see the FarClipPlane page.
UnrotatedDownZ (default) - use this if your game does not support a rotated camera
None - use this if your game supports a rotated camera
Camera-based culling is performed just before rendering, which means an object can be culled in one Camera and not in another. In other words, culling will work appropriately with multiple Cameras when using split screens.
FlatRedBall XNA assumes that the current scene is being viewed directly down the negative Z axis (the default). With this assumption the engine culls out Sprites which do not fall in this visible area. The following code creates 200 Sprites which extend down the positive X axis. Because of culling only a few are visible. The camera is rotated to view into the distance. Notice that as it views to the right, sprites are not drawn.
To fix this the Camera's CameraCullMode can be changed to None:
To "billboard" a Sprite means to adjust its rotation so that it is always facing the Camera. Billboarded sprites are only needed for games with a 3D camera. Note that billboarded sprites typically not used for UI because UI and HUD should be handled by Gum.
Games like Doom used a billboard effect on enemies and items. Mario 64 also used a billboard effect on its trees. This effect is evident when running around billboarded Sprites.
The AddSpriteToBillboard tells the calling Camera to hold a reference to the argument Sprite and adjust its rotation every frame so that it faces the Camera.
Billboarding is implemented by modifying the argument Sprite's Rotation values. Therefore, a billboarded Sprite cannot be rotated on its X or Y axes. In other words, billboarding overwrites RotationX and RotationY values. Changing any rotation or rotation velocity values on the X or Y will not have any impact on billboarded Sprites. Billboarded Sprites can still be rotated on the Z axis.
Both billboarding and attachments modify the rotation of PositionedObjects. To resolve this conflict, you are responsible for deciding which should take precedence. If you'd like the attachment to be dominant, you should not make a Sprite billboarded. If, on the other hand, you still want your Sprite to be billboarded, but it should have an attachment, set the ParentRotationChangesRotation property to false. For more information, see the ParentRotationChangesRotation article.
The AspectRatio of the camera is the ratio of width to height. Usually the AspectRatio will match the aspect ratio of the displayable area. For example, if the displayable area has a width of 800 pixels and a height of 600 pixels, then the aspect ratio should be 800/600, or 1.333. The AspectRatio of a Camera is used to set how wide the field of view should be. Since it is not an absolute value, but rather a ratio, changing a Camera's FieldOfView property will change the resulting viewable width. Of course, the actual AspectRatio value will be the same.
Note that the AspectRatio property is typically not modified in custom code. The most common way to control aspect ratio is by assigning the desird value in the FlatRedBall Editor's Display Settings.
The following code adds a Sprite then modifies the AspectRatio of the default Camera. This makes the regularly-circle graphic appear stretched out. Add the following code to Initialize after initializing FlatRedBall:
ClearsDepthBuffer determines whether the Camera clears the depth buffer and then writes/reads the depth buffer when performing rendering. By default this value is true, and it should be true in most cases except when a camera is used to render on top of other cameras, or for debugging purposes.
The "absolute edge" methods return the edge of the visible area at a given Z. There are four such methods:
AbsoluteRightXEdgeAt
AbsoluteLeftXEdgeAt
AbsoluteTopYEdgeAt
AbsoluteBottomYEdgeAt
The absolute functions take a single argument - the Z value where the absolute values should be calculated. The reason this is necessary is because 3D cameras (by definition) use perspective. Therefore, the edge of the Camera changes as you move further away from the Camera. If you are positioning an object along the edges of the Camera, you will most likely want to use the Z of the object you are positioning as the argument to absolute functions. For an example, see the code in the section below.
The following code creates four Circles. Each one is colored differently to help identify it.
The absolute edge values can be assigned if your Camera is 2D (Orthogonal = true). For example, the following code sets the Camera's top left corner to the origin. Keep in mind that positive Y still points up.
If your Camera's Orthogonal value is set to false, then setting any of the absolute values results in an exception being thrown.
Setting any othe absolute values ultimately assigns the Camera's X and Y properties. If your Camera is attached to another object or if you are using a CameraControllingEntity, then these position changes will be undone when updates are processed.
The edge values can be used to check if on screen. For example, the following code checks if a character's point is on screen. Since visual objects are usually larger than a single pixel, an additional buffer can be added.
Note that the buffer value above may be required if your object does not have a Width property (such as if your object is an entity). If your object has a Width and Height property, like a Sprite, you can use that value as shown in the following code:
If your Camera is attached to another object, you may need to call FlatRedBall.Camera.ForceUpdateDependencies before asking the Camera for its absolute edge values. For example:
The destination values represent the bounds that the Camera will draw to relative to the top-left of the window. By default the bounds are set to fill up the entire window. Changing these values will result in the area being drawn being smaller. These values can be used to implement a split-screen view. Since the default bounds of a Camera use the full screen, the DestinationRectangle can be used to get the resolution of your game. When setting the DestinationRectangle it is recommended that you use even values for all dimensions. In other words, the Width and Height of the rectangle should be even. Odd-sized DestinationRectangles can make pixel-perfect text render improperly.
The following code shows how changing the destination values impacts drawing. Notice that the background color of the Camera has been set to blue so that its drawn area can easily be identified.
The BackgroundColor property specifies what the background color will be cleared to every frame. To prevent the background from clearing every frame, set the Alpha of the BackgroundColor to 0. See more information below on this topic.
The following changes the BackgroundColor in response to user input. Add the following to your Screen's CustomActivity:
When a Camera is drawn, the first thing that is done is its DestinationRectangle is painted to the background color. If you have multiple Cameras which overlap and you'd like Cameras which are on top to not write over what's already been drawn by previous Cameras, you can set the BackgroundColor to a color that has an alpha of 0. BackgroundColor for any Cameras except the default one contained in the SpriteManager is transparent. You will need to change the background color if you are making a split-screen game to something no-transparent.
If you would like to draw to the screen before FlatRedBall draws, you can do so, but you must do the following:
Set the Camera's Color's Alpha to 0
Turn off RenderTargets.
FieldOfView represents the Y angle of view from the bottom of the screen to the top. The default value for FieldOfView is:
The following diagram shows a side-view of how FieldOfView changes what is shown on screen. A smaller field of view makes the view more narrow. This narrower view results in the appearance of "zooming in". Tools such as binoculars or telescopes provide a zoomed-in view by creating a very narrow field of view. The FieldOfView property is only effective if the Camera's property is false (the default value).
The DrawsWorld property controls whether the camera draws objects which are not on any and objects which are on that are not Camera-specific. Usually Cameras which are used to draw things in split-screen mode should have this property be true, while Cameras which are used to overlay things such as HUDs should usually set this to false.
The following example creates a situation where two Cameras are used. In this situation, the second Camera is used to draw HUD. The second Camera will not draw the underlying Sprite: Add the following using statement:
Add the following to Initialize after initializing FlatRedBall:
The DrawsToScreen property controls whether what the Camera draws is shown on screen. By default this property is true. This should be set to false if you are interested in obtaining the contents of the Camera (usually as a Texture) but you do not want these contents to be drawn to the screen. This property can also be set to false if you plan on drawing the contents to the screen manually instead of using FlatRedBall.
The following code sets DrawToScreen to false, gets the resulting render as a Texture2D, then renders this Texture2D using XNA's SpriteBatch class. Add the following at class scope:
Add the following to Initialize after initializing FlatRedBall:
Modify your Draw method so it looks like this:
The FarClipPlane value determines the maximum distance from the Camera that objects will be drawn. This value is relative to the Camera. In other words, if the FarClipPlane is 1000 and the Camera's Z is 100, then the furthest the Camera will draw is -900 assuming the Camera is looking down the negative Z axis (default in FlatRedBall XNA).
The following code increases the Camera's far clip plane to 2000:
Increasing the FarClipPlane allows the Camera to see further, but it also reduces the accuracy of the Z-Buffer. The larger the distance between the Camera's NearClipPlane and FarClipPlane, the more likely is. Therefore, if you are experiencing in your game, you should consider reducing the distance between the NearClipPlane and FarClipPlane if possible. If you are not using any Z-Buffered objects in your game, then you can increase the FarClipPlane without causing any graphical problems.
The ForceUpdateDependencies for the Camera performs all of the same functionality as the PositionedObject's ForceUpdateDependencies call, but it also does a few extra things. Specifically, it updates the mins and maxes of the camera, and recalculates its View and Project matrices. For information on ForceUpdateDependencies as it relates to PositionedObjects in general, see the PositionedObject's ForceUpdateDependencies page.
If you are writing a game where you need to perform logic based off of the Camera's position or edge values, then you need to call ForceUpdateDependencies prior to asking the Camera for any of these values if the Camera is attached to another object. Games often need to know a Camera's position in custom code. Consider the following examples:
You may be developing a top-down game which shows arrows on the edge of the screen to indicate where off-screen enemy units are located. The positioning of these units requires math using the Camera's position.
The calculation of the visible Sprites in a SpriteGrid requires up-to-date Camera position values.
Your game may be a 3D game which uses a 2D Layer for HUD. The 2D elements in your game may be based off of the 3D position of elements in the world (this is a more complex case).
If your Camera is attached to another object, you will need to call ForceUpdateDependencies to make sure that all values are up-to-date.
The order of calls matters in your game. The following code gives an example of how you would want to structure your Screen's CustomActivity if you plan on using the Camera's positioning:
As mentioned above, if you are translating between 3D and 2D coordiantes, you may still need to call ForceUpdateDepencies even if you are only updating the Camera's position manually. The reason for this is because you may end up using the Camera's matrices for calcualting the translations, and these are only updated when the Camera's dependencies are updated. Therefore, if you are experiencing unexpected behavior when translating between 3D and 2D (or 2D and 3D), then you should try calling ForceUpdateDependencies.
The DrawsShapes property can be used to control whether the Camera will render any shapes (such as Polygons and Circles). This is on by default, and can be turned off to hide all shape rendering.
Shapes are often used for collision, and their visible representation can be useful in debugging. Shapes can be easily turned off for non-debug builds as follows:
The GetViewport method can be used to get a reference to the current Microsoft.Xna.Framework.Graphics.Viewport with the calling Camera's properties applied.
The GetViewport method does the following:
It first grabs the GraphicsDevice's Viewport
It sets the Viewport's X, Y, Width, and Height
It returns the reference to the GraphicsDevice's Viewport
Therefore, if you call GetViewport on two different Cameras, you will have the same Viewport:
The IsSpriteInView method reports whether the argument Sprite is in view given the Camera's position, the Sprite's position, and the CameraCullMode. If the CameraCullMode is set to CameraCullMode.None then this value will always return true. If the CameraCullMode is set to CameraCullMode.UnrotatedDownZ then this will calculate whether the Sprite is in view or not. This function is intended to be used for culling, and it favors optimization over perfect accuracy.
The Main property provides access to the main Camera in FlatRedBall. This value is always valid, and represents the default view. Therefore, it can be used to modify the view.
To modify the X value of the Camera, you can use the Camera.Main property as follows:
The KeepSpriteInScreen method adjusts the absolute position of the argument Sprite so that it is fully in-view. This method makes a few assumptions:
The Camera is not rotated
The Sprite is in front of the Camera (has a smaller Z value than the Camera)
The following code creates a Sprite which is moved around the screen by the Keyboad with the arrow keys. Add the following using statement:
Add the following at class scope:
Add the following to Initialize after initializing FlatRedBall:
Add the following to Update:
As of the July 2010 release of FlatRedBall, the KeepSpriteInScreen method works properly even if the argument Sprite has a parent (a common setup when using Entities).
Each Camera has a list of Layers which can be used to draw objects which should only appear on one Camera. This is commonly used for HUD elements such as score and health. By default each Camera has one Layer (no code necessary to add this). Therefore, if using only one Layer, then no layer instantiation is necessary. To create additional layers, see the Camera's AddLayer method.
The following code creates two Sprites, each which represents a player. The code splits the view into two screens and adds a Text object displaying which player's view is shown on the Camera layer. Notice that only one Text appears in each camera although there are two Text objects. The bool value can be changed to compare the behavior of Camera-layered Text and regular Text.
The MaximumX, MaximumY, MinimumX, and MinimumY properties can set the minimum and maximum X and Y positional values for a given Camera. These properties can be used to create boundaries beyond which the camera cannot move. These are often used in games to keep the camera viewing the playable area and keep areas beyond the playable bounds from being viewed.
If you have a Camera which is part of an Entity then the Camera will be attached to that Entity (by default). The minimum and maximum values will prevent the Camera from moving behond the values you specify, but it will not prevent the parent Entity from moving beyond the bounds. In this situation it is advised to use your own custom min and max implementation.
The following code allows the user to move the camera with the arrow keys on the keyboard, but bounds the position of the Camera to the edges of the AxisAlignedRectangle created in the Initialize method.
Add the following to your Screen's CustomInitialize:
Add the following to Update
The OrthogonalHeight and OrthogonalWidth values control how many units tall and wide the view of the Camera can be seen. These values apply if the camera is 2D (if the Orthogonal value is set to true). If using Glue, the default setup is for a 2D camera. Orthogonal cameras are useful for creating 2D games, or for creating menu systems which work in pixels.
By default FlatRedBall games use a 2D camera with an OrthogonalWidth of 800 and OrthogonalHeight of 600. The following diagram can help visualize this configuration:
By default, FlatRedBall games have their resolution controlled by the Display Settings in the FlatRedBall Editor.
These values can be changed by typing new values in the Width and Height boxes or by using the dropdown to change both values.
The OrthogonalHeight and OrthogonalWidth values can be used to position an object at the edge of the screen. Keep in mind that a Camera's X and Y values represent the center of the screen, so the edges of the screen can be obtained by adding or subtracting half of the OrthogonalWidth or OrthogonalHeight.
The Camera's UsePixelCoordinates method sets the calling Camera's Orthogonal property to true and adjusts the pixel coordinates to the screen's resolution. In other words, if the screen is 800X600, calling UsePixelCoordinates sets the OrthogonalWidth to 800 and the OrthogonalHeight to 600.
OrthogonalWidth and OrthogonalHeight control how much of the world can be seen. For example, consider the following game level which is 3200x3200 pixels (zoomed down to fit on screen):
If this level were viewed with a camera with OrthogonalWidth of 800 and an OrthogonalHeight of 480, the red square represents the area that might be visible at one time:
The following image shows what this might look like in a FlatRedBall game:
When using a 3D camera (Orthogonal = false) the most common way to perform a "zoom in" is to adjust the Camera's Z value. When objects move closer to the Camera in a perspective view, they become larger. This is not the case when the Camera is Orthogonal. The following code adjusts the Camera's OrthogonalHeight and OrthogonalWidth (through the FixAspectRatioYConstant method) by using the up/down keys on the keyboard. Add the following to Initialize after initializing FlatRedBall:
Add the following to your Screen's CustomActivity:
Note that the code above adjusts OrthogonalHeight, then fixes the aspect ratio keeping the Y (height) constant. This code could also be written to adjust OrthogonalWidth and call FixAspectRatioXConstant
; however it's common to have OrthogonalHeight be the dominant axis since aspect ratio can vary widely on monitors.
OrthogonalWidth and OrthogonalHeight values control the area that a 2D camera (Orthogonal = true) can see. For more information see the .
Adjusts the Camera's OrthogonalWidth (if 2D) or AspectRatio (if 3D) to match the aspect ratio of the camera's DestinationRectangle.
The PositionRandomlyInView sets the Position of a PositionedObject randomly inside the view of the Camera calling the method. This can be used to quickly place one or more objects at a random position in the Camera's view and is commonly used in debugging and simple test applications.
The following code creates 100 Sprites and places them randomly in the Camera's view. All Sprites are between 20 and 60 units in front of the Camera. Add the following in Initialize after initializing FlatRedBall
The RelativeXEdgeAt and RelativeYEdgeAt methods can provide the distance in world coordinates from the center of the screen to the edge of the screen at a given Z position.
If your game is using a 3D camera, then objects in the game world are viewed with a 3D perspective. The result of having a perspective view is that objects which are far from the camera will appear smaller than objects which are close to the camera. The amount that is visible in the world is controlled by the Camera's FieldOfView property: Notice that the further away an object is from the camera (the further to the right on the picture above) the smaller portion of the visible area it will take. In other words,observe the redball Sprite in the image above. You'll notice that it takes up very little space relative to the view height (the distance between the top and the bottom lines). But what happens if the Sprite comes closer to the Camera? At this point the Sprite is so close that it touches the top and the bottom of the view boundaries. In other words, this would result in the Sprite being as large as the entire screen. It's important to notice that in world coordinates the Sprite actually didn't change size. Instead, it just changed how close it was to the Camera, making it appear larger. We can then apply this knowledge to draw another conclusion. When far away, the Sprite was very small. So small that we could have stacked numerous Sprites on top of each other. Let's say that the Sprite has a ScaleY of 1, meaning it is 2 units tall. If we were able to stack 5 Sprites on top of each other at the original distance, then we'd be able to approximate the view height to about 10 units:
But at a closer distance to the Camera, we can only fit one Sprite. That means that in the second image, the horizontal view height is only 2 units. This relationship of having a smaller view height (and width) holds linearly. That means that at two times the distance, the view height and width double. At half the distance the view height and width are also cut in half. To take it to the limits, that also means that at an infinite number of units away, the view is also infinitely wide and tall. That's not really practical, but it can help your realize that as you move far away from the Camera, more and more can be seen. The other end of the limit is at 0 units away from the Camera. At 0 units away (the point where the lines meet in our images above, the distance between the top and bottom line is 0. That means that at 0 units from the camera nothing is visible. Since RelativeXEdgeAt and RelativeYEdgeAt measure the distance from the center of the screen to the edge of the Screen (which is half of the distance from one edge to the other) then they also linearly follow this relationship. Therefore, if the Z value that you pass to these methods is further away, you will get a greater number, while if it's closer to the Camera you'll get a smaller number. Passing a Z value that is equal to the Camera's Z value will return a value of 0.
When the Camera shows a 3D view, then the minimum and maximum visible X an Y values depend on the distance away from the Camera. The following code uses the RelativeXEdgeAt and RelativeYEdgeAt to determine the distance of the edges of the screen relative to the center of the camera. These values are used to size a Sprite so it takes up the entire screen.
In general, the edges of the camera at a given Z can be found by the following code:
The Camera is a PositionedObject therefore it has a Position variable which works the same as the PositionedObject's Position variable. The default position for Cameras is:
Projects which have been created with the Wizard will have a CameraControllingEntity instance in the GameScreen. This instance automatically adjusts the position of the camera according to its own settings.
If your game includes a CameraControllingEntityInstance, then the Camera's position will automatically be determined by this object. If you would like to manually control the Camera, you can delete the CameraControllingEntityInstance from your game. For more information on how to use the CameraControllingEntity, see the CameraControllingEntity page.
The default (unrotated Camera) looks down the Z axis. This means that if you want the center of the screen to be at a certain coordinate, you simply need to set the Camera's X and Y value.
By default a TileMap's top-left corner will be positioned at X=0, Y=0. By default, the camera is centered at X=0, Y=0, so the top left of the map will appear in the center of the screen. For example, the following image shows how a level will appear in Tiled and in game:
One way to solve this problem is to change the Camera's X and Y values to be at the center of the tilemap. This can be adjusted by using the dimensions of the map, or arbitrarily by adding some constant value to the X and subtracting some value from the Y. For example, the following code will center on the map:
Now the Camera will be centered on the map as shown in the following image:
Changing the Z value of the Camera will make the camera move "forward" and "backward" in the world. This is a way to simulate zooming (technically "zooming" is accomplished by changing the Camera's FieldOfView). This will only work on 3D cameras. To make objects appear smaller, you will want to increase the Z value of the Camera. For example:
The Camera encapsulates functionality to simplify and control the display of a FlatRedBall application to the user. The camera controls view position, rotation, and background color. If the Camera is 3D, it can also control field of view, and viewable distance.
By default the camera in FlatRedBall looks down the negative Z axis. In other words negative Z points away from the camera. Increasing the Camera's Z moves it backwards while decreasing moves it forward. FlatRedBall uses a right handed coordinate system.
Of course, if the Camera is rotated, the forward and backward directions change. Most games can change camera properties through the . Alternatively, the Camera can be modified in code.
FlatRedBall projects automatically create a Camera which can be accessed by . The following code moves the Camera to X = 5:
For more information see the page. In most cases you will never need to create your own Camera - this one is the default camera that all single-Camera games use.
The camera inherits from the class so it shares the same interface for positioning, rotation, and attachment. Camera movement is not noticeable without something visible in the scene to compare the movement against. The following code can be added to a Screen such as an empty Screen created in the FlatRedBall Editor: Add the following using statements:
Replace CustomInitialize and CustomActivity with the following code:
FlatRedBall supports multiple cameras for different viewports (split screen). The following code creates a Sprite and views it from two different cameras. In Initialize
Every camera has a DestinationRectangle which defines where on the window it draws. When specifying the DestinationRectangle the top-left of the window is 0,0 and positive Y moves down. Assuming the window is 800 pixels wide and 600 pixels tall the following code creates a 50 pixel border around the DestinationRectangle:
For information about 2D coordinates and how to create 2D scenes, see the . To convert between world and pixel coordinates, see the .
For information on finding the absolute coordinates of the edges of the Camera, see the article.
For info on the see the .
For more information, see the page.
As explained in this tutorial the Camera's X and Y position are the center of the screen (unless the Camera is rotated). Therefore, to keep the Camera from viewing outside of a specific area, the visible width and height must be calculated. In other words, if the Camera should not be able to see anything to the left of X = 0, then the width of the Camera needs to be calculated, and the actual minimum X becomes
The SetBordersAtZ simplifies this process by doing the calculation of cameraWidthAtSomeZ automatically, and even updating mins and maxes if the Camera moves along the Z axis. The SetBordersAtZ sets the following Camera properties:
MinimumX
MinimumY
MaximumX
MaximumY
The SetBordersAtZ calculates what the minimum and maximum values need to be set at to keep the first four argument values as the visible borders at the Z value passed (fifth argument).
The following code prevents the user from viewing behind +/- 40 on the X and Y axes. Note that bounds will be exceeded if the field of view or aspect ratio is too large for the argument values. The Keyboard moves the Camera so the bounds can be tested. Add the following using statements:
Add the following to Initialize after initializing FlatRedBall:
Add the following to Update:
The Orthogonal setting controls whether the camera is using a perspective or orthogonal view. The following describes some differences between the two modes:
When the camera is in Orthogonal mode, the Z value of objects impacts drawing order. Objects with a larger Z value will be drawn in front of objects with a smaller Z value. Also, objects may disappear if they are moved too far away from the camera or if the objects have a Z value large enough to be placed behind the Camera. This is affected by the rotation of the camera. Camera Orthogonal can be set through the FlatRedBall Editor's Camera settings. For more information, see the .
By default the 2D camera in FlatRedBall will make objects such as sprites appear the same size on screen as the source texture. For example, the following screenshot shows the FlatRedBall icon (which is 85x88 pixels) drawn in a project with a default 2D camera:
Setting Camera.Main.Orthogonal = false results in the camera being 3D, drastically changing the size of the icon on screen:
This occurs because the size of the object now depends both on its Width and Height values, as well as the Z value of the camera. By default, the main camera has a Z value of 40. This can be changed in code. Increasing the Z value makes the camera move "backward", which allows it to see more of the sprite.
A 3D camera can be positioned so that objects at Z=0 appear the same size as on a 2D camera using GetZDistanceForPixelPerfect .
The Layers property contains all of the specific to this Camera. Layers which belong to a camera are drawn only on this camera. Camera-speicfic layers are useful when making split-screen games which should show visuals specific to one of the screens such as a player's HUD.
Cameras will have one Layer in the Layers property by default. This can be accessed in one of two ways:
or
Notice that the first Layer in Layers is equivalent to the Layer property.
This Layer is added for convenience, but it is not automatically used unless objects are placed on this Layer explicitly. In other words, objects (such as FlatRedBall Sprites) which are added to their respective managers are drawn unlayered by default. Note that this differs from Gum, where all objects are always added to a Layer.
For information on Zooming, see the .
The Camera class has a UpVector which is used to orient the Camera so that it is always tilted a particular way. UpVectors are very common in 3D games as they can help the player feel oriented. By default, the Camera's UpVector value is set to be the unit Y vector (0,1,0). The UpVector must be changed if you want the "up" direction to change. The most common situation this is needed is if the Camera needs to rotate on the Z axis (to change its RotationZ or RelativeRotationZ).
If you are working with the Camera class and expect modifying the Camera to rotate when you change its RotationMatrix or RotationZ, you may have been surprised to see that these properties do not modify the rotation of the Camera. As mentioned above, the reason for this is because the UpVector takes priority over the Camera's RotationMatrix. The reason for this is because in 3D games, the Camera may often end up with a rather complex RotationMatrix, and in many cases the expected behavior is to keep the Camera oriented so that it is not tilted. Simply setting the UpVector allows you to always guarantee that you will have a proper up vector without having to perform complex matrix math. In other words, if FlatRedBall were to not include an UpVector on the Camera, applying this functionality could be somewhat difficult. On the other hand, eliminating the UpVector functionality is very easy:
Orthogonal
Perspective (non-Orthogonal)
Moving objects further from the camera does not change their visible size
Moving objects further from the camera makes them appear smaller
Moving the Camera forward and backward does not create a "zoom" effect
Moving the Camera forward and backward does create a "zoom" effect
The camera uses the OrthogonalHeight and OrthogonalWidth properties to control the visible area.
The camera uses the FieldOfView property to control the visible area.
The UsePixelCoordinates method is an easy way to set up a traditional 2D camera. Using this method, world units can match up with pixel coordinates. Using the pixel as the unit is effective in pure 2D games where graphics are created to be drawn to-the-pixel. A camera which uses pixel coordinates is referred to as "pixel perfect". For more information on 2D games, see the 2D in FlatRedBall article. UsePixelCoordinates is a shortcut method which does the following:
It sets Orthogonal to true.
It sets OrthogonalHeight and OrthogonalWidth to match the screen's resolution.
The following code makes the camera a pure 2D camera. A Sprite using its Texture's dimensions for its scale is added to show the resolution. Add the following to Initialize after initializing FlatRedBall:
Standard Resolution (640 X 480)
High Definition 720 (1280 X 720)
High Definition 1080 (1920 X 1080)
If you are developing a 2D game, then you may be faced with the issue of resolution on the 360. If you set your Camera to use pixel coordinates, then the size of your objects on-screen will change depending on the resolution of the game. In other words, a Sprite which takes up the entire screen in standard resolution would take up a little more than half of the screen (vertically) if the user runs the game in high definition 720. Fortunately, the UsePixelCoordinates method provides an overload for changing the coordinate dimension of the screen. This means that you can code your game the same (or very close) for all resolutions if using the overload.
The following modifies the coordinates of the camera so that the entire redball.bmp Sprite takes up the screen. Add the following to Initialize after initializing FlatRedBall:
The UpdateViewProjectionMatrix updates the and properties according to the Camera's current state. This function is automatically called on all Cameras which are a part of FlatRedBall every frame prior to the frame being rendered, but if the and properties are needed after the Camera has been updated, then UpdateViewProjectionMatrix needs to be called.
The Camera's View property is a matrix which contains the "view" matrix commonly used when working with shaders. The View is internally calculated using the Matrix.CreateLookAt method. The View matrix is constructed using the Camera's absolute , its , and its .
The View matrix can be used when interacting with shaders. For example the following code demonstrates how to assign a BasicEffect's View using the Camera's View property:
The Camera object inherits from the PositionedObject class. Therefore, it can be rotated just like any other PositionedObject. For information on using rotation values on a PositionedObject in general, see the following pages:
By default the Camera will attempt to orient itself so that "up" is the Y vector (0,1,0). For more information see the .
The Camera can be rotated to be facing any direction. Keep in mind that many systems in FlatRedBall are designed to work in 2D, so making a game with a rotated Camera is more difficult. The following shows how to rotate the camera to simulate looking at an angle at a "floor" made up of the redball graphic. Add the following code to either Game1.cs's Initialize function, or your Screen's CustomInitialize function:
When programming on Windows, you have control of the "back buffer resolution". However, on the Xbox 360 the resolution is chosen by the user, either. Usually this is done through the switch on the video cable: Depending on the setting the user may be running the game in one of the following resolutions:
UsePixelCoordinates3D adjusts the Camera's Z value so that objects at the argument Z value will render pixel-perfect. In other words, the argument Z plane will behave as if the Camera was in 2D mode. This method still keeps the Camera in 3D mode, so perspective rules still apply.
The PixelsPerUnit method is a method that can be used to convert between world units and screen pixels. The PixesPerUnit method can be used if pixel coordinates are desired when the 3D camera is being used.
The most common usage of PixelsPerUnit is to convert from pixels to units. In other words, the most common usage is to obtain "world units per pixel". Once the number of world units is obtained per pixel, multiplying that value can be multiplied by the desired number of pixels. To convert "pixels per unit" to "units per pixels", we simply need to take the reciprocal. If you're not familiar with this math term, taking the reciprocal of a value is the same as dividing one by the value. The code for this is as follows:
The following code example creates a Sprite and scales it to the size of the entire screen. The default resolution is 800 X 600, so scaling the Sprite to this size will make the Sprite fill up the entire screen. Add the following to Initialize after initializing FlatRedBall:
Add the PixelsToUnits method at class scope:
This example creates a row of circles, each touching end-to-end, 32 pixels apart on a 3D camera. It uses PixelsPerUnitAt to size and space the circles. The following code can be placed in a screen's CustomInitialize method:
If you are using a 3D Camera, then the FieldOfView impacts the PixelsPerUnitAt method. PixelsPerUnitAt measures the number of pixels per world unit. In other words, the formula is: PixelsPerUnit = NumberOfPixels / NumberOfWorldUnits Therefore, increasing NumberOfWorldUnits will decrease the PixelsPerUnitAt. Increasing the FieldOfView will increase the number of visible world units, but will keep the NumberOfPixels constant. Therefore, a larger FieldOfView will decrease PixelsPerUnitAt
The resolution of the game impacts the PixelsPerUnitAt value. Increasing the resolution increases the NumberOfPixels in the formula above. Therefore, if your game runs at higher resolution, then the PixelsPerUnitAt will be larger. Keep in mind that by default the FlatRedBall Camera uses the same FieldOfView. This means that if your game increases its resolution, the PixelsPerUnitAt will increase. To be more specific, the PixelsPerUnitAt uses the resolution height. Therefore, changing the width of the application will not impact the PixelsPerUnitAt, but changing the height will.
The SetLookAtRotationMatrix method can be used to orient a camera so it is facing an object. This method of setting the rotation matrix can be easier to work with than calculating a rotation matrix yourself to accomplish a look-at.
The following code can be used to have a Camera look at a moving object called myEntity. This code assumes that myEntity is a valid Entity with a Position property.
The SetSplitScreenViewport method is a method which can be used to set the viewport (also known as the DestinationRectangle) to a value relative to the current game window. For example, using the SplitScreenViewport.TopHalf as the argument will set the calling Camera's DestinationRectangle so that it occupies the top-half of the game window regardless of its size. Once SetSplitScreenViewport is called, the camera that called the method will automatically change its DestinationRectangle if the game window resizes. This behavior will persist until the DestinationRectangle is manually changed. By default all Cameras will have have SetSplitScreenViewport called when created using the SplitScreenViewport.FullScreen value. In other words, this means that if the game window is resized, the Camera will automatically adjust to fit the screen.
The Camera will automatically adjust according to window resizing unless the destination rectangle is manually set. This can be done by setting any of the following properties:
Calling SetSplitScreenViewport will resume the automatic destination rectangle changing behavior.