Urho2D includes 2D graphics and 2D physics.
A typical 2D game setup would consist of the following:
- Create an orthographic camera
- Create some sprites
- Use physics and constraints to interact with the scene
To use Urho2D we need to set camera to orthographic mode first; it can be done with following code:
// Create camera node node cameraNode = scene.CreateChild("Camera"); // Create camera var camera = cameraNode.CreateComponent<Camera>(); // Set camera orthographic camera.SetOrthographic(true); // Set camera ortho size (the value of PIXEL_SIZE is 0.01) camera.SetOrthoSize((float)graphics.Height * PIXEL_SIZE);
Urho2D provides a handful of classes for loading/drawing the kind of sprite required by your game. You can chose from animated sprites, 2D particle emitters and static sprites.
Workflow for creating animated sprites in Urho2D relies on Spriter (c). Spriter is a crossplatform tool for creating 2D animations. It comes both as an almost fully featured free version and a more advanced 'pro' version. Free version is available at http://www.brashmonkey.com/spriter.htm. To get started, scml files from bin/Data/Urho2D folder can be loaded in Spriter. Note that although currently Spriter doesn't support spritesheets/texture atlases, Urho2D does: you just have to use the same name for your scml file and your spritesheet's xml file (see Static sprites below for details on how to generate this file). Example 33_Urho2DSpriterAnimation is a good demonstration of this feature (scml file and xml spritesheet are both named 'imp' to instruct Urho2D to use the atlas instead of the individual files). You could remove every image files in the 'imp' folder and just keep 'imp_all.png' to test it out. However, keep your individual image files as they are still required if you want to later edit your scml project in Spriter.
- AnimationSet2D: a Spriter *.scml file including one or more animations. Each Spriter animation (Animation2D) contained in an AnimationSet2D can be accessed by its index and by its name (using AnimationSet2D.GetAnimation).
- AnimatedSprite2D: component used to display a Spriter animation (Animation2D) from an AnimationSet2D. Equivalent to a 3D AnimatedModel. Animation2D animations inside the AnimationSet2D are accessed by their name using AnimatedSprite2D.SetAnimation. Playback animation speed can be controlled using AnimatedSprite2D.Speed. Loop mode can be controlled using AnimatedSprite2D.SetLoopMode. You can use the default value set in Spriter (LM_DEFAULT) or make the animation repeat (LM_FORCE_LOOPED) or clamp (LM_FORCE_CLAMPED). One interesting feature is the ability to flip/mirror animations on both axes, using StaticSprite2D.FlipX, StaticSprite2D.FlipY, StaticSprite2D.SetFlip. Once flipped, the animation remains in that state until boolean state is restored to false. It is recommended to build your sprites centered in Spriter if you want to easily flip their animations and avoid using offsets for position and collision shapes.
- Animation2D: a Spriter animation from an AnimationSet2D. It allows readonly access to the SCML animation properties. For a demonstration, check examples 33_Urho2DSpriterAnimation and 24_Urho2DSprite.
ParticleEffect2D Holds the definition from a PEX file defining the behavior and texture of a 2D particle (ParticleEmitter2D). For an example, see bin/Data/Urho2D/greenspiral.pex.
ParticleEmitter2D: used to display a ParticleEffect2D. Equivalent to a 3D ParticleEmitter. For a demonstration, check example 25_Urho2DParticle.
Static sprites are built from single image files or from spritesheets/texture atlases. Single image files are loaded using Sprite2D class and spritesheets/texture atlases are loaded using SpriteSheet2D class. Both are rendered using StaticSprite2D class.
- Sprite2D: an image defined with texture, texture rectangle and hot spot.
- SpriteSheet2D: a texture atlas image (that packs multiple Sprite2D images).
- StaticSprite2D: used to display a Sprite2D. Equivalent to a 3D StaticModel.
You can assign a material to an image by creating a xml parameter file named as the image and located in the same folder. For example, to make the box sprite (bin/Data/Urho2D/Box.png) nearest filtered, create a file Box.xml next to it, with the following content:
<texture> <filter mode="nearest" /> </texture>
By default, sprite hotspot is centered, but you can choose another hotspot by setting the HotSpot property.
Background and layers
Finally, note that you can easily mix both 2D and 3D resources. 3D assets' position need to be slightly offset on the Z axis (z=1 is enough), Camera's position needs to be slightly offset (on the Z axis) from 3D assets' max girth and a Light is required.
Urho2D implements rigid body physics simulation using the Box2D library. You can refer to Box2D manual at http://box2d.org/manual.pdf for full reference.
Rigid Body Components
RigidBody2D is the base class for 2D physics object instance.
The avaialble rigid body types are defined in the BodyType2D enumeration, and they are Static, Dynamic and Kinematic. See the documentation for BodyType2D for more information.
Collision shapes components
Check Box2D manual - Chapter 4 Collision Module and Chapter 7 Fixtures for full reference.
Important: collision shapes must match your textures in order to be accurate.
You can use Tiled's objects to create your shapes (see Tile map objects). Or you can use tools like Physics Body Editor (https://code.google.com/p/box2d-editor/), RUBE (https://www.iforce2d.net/rube/), LevelHelper (http://www.gamedevhelper.com/levelhelper/), PhysicsEditor (http://www.codeandweb.com/physicseditor), ... to help you. Other interesting tool is BisonKick (https://bisonkick.com/app/518195d06927101d38a83b66/).
Fixtures and Collision Filtering
Box2D fixtures are implemented through the CollisionShape2D base class for 2D physics collision shapes.
Constraints ('joints' in Box2D terminology) are used to constrain bodies to an anchor point or between themselves.
See the documentation for Constraint2D for more information and details about the list of all the different kind of constraints
The following queries into the physics world are provided:
Unary geometric queries (queries on a single shape)
Shape point test: test if a point is inside a given plain shape and returns the body if true. Use GetRigidBody(). Point can be a Vector2 world position, or more conveniently you can pass screen coordinates when performing the test from an input (mouse, joystick, touch). Note that only plain shapes are supported, this test is not applicable to CollisionChain2D and CollisionEdge2D shapes.
Shape ray cast: returns the body, distance, point of intersection (position) and normal vector for the first shape hit by the ray. Use RaycastSingle().
World queries (see Box2D manual - Chapter 10 World Class)
Loading a TMX tile map file
A TMX file is loaded using TmxFile2D resource class and rendered using TileMap2D component class. You just have to create a TileMap2D component inside a node and then assign the tmx resource file to it.
var tileMapNode = scene.CreateChild("TileMap”);var tileMap = tileMapNode.CreateComponent<TileMap2D>();tileMap.tmxFile = cache.GetResource("TmxFile2D", "Urho2D/isometric_grass_and_water.tmx");
Note that: currently only XML Layer Format is supported (Base64 and CSV are not). In Tiled, go to Maps > Properties to set 'Layer Format' to 'XML'. if 'seams' between tiles are obvious then you should make your tilesets images nearest filtered (see Static sprites section above.)
TMX tile maps
Once a tmx file is loaded in Urho, use GetInfo() to access the map properties through TileMapInfo2D class.
A map is defined by its: orientation: Urho2D supports both orthogonal (flat) and isometric (strict iso 2.5D and staggered iso) tile maps. Orientation can be retrieved with orientation_ attribute (O_ORTHOGONAL for ortho, O_ISOMETRIC for iso and O_STAGGERED for staggered) width and height expressed as a number of tiles in the map: use width_ and height_ attributes to access these values width and height expressed in Urho2D space: use GetMapWidth() and GetMapHeight() to access these values which are useful to set the camera's position for example tile width and tile height as the size in pixels of the tiles in the map (equates to Tiled width/height * PIXEL_SIZE): use tileWidth_ and tileHeight_ attributes to access these values
Two convenient functions are provided to convert Tiled index to/from Urho2D space:
- TileIndexToPosition() to convert tile index to Urho position
- PositionToTileIndex() to convert Urho position to tile index (returns false if position is outside of the map)
You can display debug geometry for the whole tile map using DrawDebugGeometry().
TMX Tile Map Tilesets and Tiles.
A tile map is built from fixed-size sprites ('tiles', accessible from the Tile2D class) belonging to one or more 'tilesets' (=spritesheets).
Each tile is characterized by its: grid ID (ID in the tileset, from top-left to bottom-right): use GetGid() sprite/image (Sprite2D): use GetSprite() property: use HasProperty() and GetProperty() Tiles from a tileset can only be accessed from one of the layers they are 'stamped' onto, using GetTile() (see next section).
TMX Tile Map Layers
A tile map is composed of a mix of ordered layers. The number of layers contained in the tmx file is retrieved using GetNumLayers().
Accessing layers : from a TileMap2D component, layers are accessed by their index from bottom (0) to top using GetLayer() function.
A layer is characterized by its:
- name: currently not accessible
- width and height expressed as a number of tiles: use GetWidth() and GetHeight() to access these values
- type: retrieved using GetLayerType() (returns the type of layer, a TileMapLayerType2D: Tile=LT_TILE_LAYER, Object=LT_OBJECT_GROUP, Image=LT_IMAGE_LAYER and Invalid=LT_INVALID)
- custom properties : use HasProperty() and GetProperty() to check/access these values
Layer visibility can be toggled using SetVisible() (and visibility state can be accessed with IsVisible()). Currently layer opacity is not implemented. Use DrawDebugGeometry() to display debug geometry for a given layer.
By default, first tile map layer is drawn on scene layer 0 and subsequent layers are drawn in a 10 scene layers step. For example, if your tile map has 3 layers: bottom layer is drawn on layer 0 middle layer is on layer 10 top layer is on layer 20
You can override this default layering order by using SetDrawOrder(), and you can retrieve the order using GetDrawOrder().
You can access a given tile node or tileset's tile (Tile2D) by its index (tile index is displayed at the bottom-left in Tiled and can be retrieved from position using PositionToTileIndex()):
to access a tile node, which enables access to the StaticSprite2D component, for example to remove it or replace it, use GetTileNode()
to access a tileset's Tile2D tile, which enables access to the Sprite2D resource, gid and custom properties (as mentioned above), use GetTile()
An Image layer node or an Object layer node are accessible using GetImageNode() and GetObjectNode().
TMX Tile Map Objects
Tiled objects are wire shapes (Rectangle, Ellipse, Polygon, Polyline) and sprites (Tile) that are freely positionable in the tile map.
IMPORTANT: make sure that 'Rectangle' and 'Ellipse' objects' size is not zero, otherwise your whole scene won't render and you won't have any clue to debug (this is due to the fact that 'width' and 'height' fields are not saved in the tmx file when their value is zero).
Accessing Tiled objects : from a TileMapLayer2D layer, objects are accessed by their index using GetObject(). GetNumObjects() returns the number of objects contained in the object layer (tile and image layers will return 0 as they don't hold objects).
Use GetObjectType() to get the nature of the selected object (TileMapObjectType2D: OT_RECTANGLE for Rectangle, OT_ELLIPSE for Ellipse, OT_POLYGON for Polygon, OT_POLYLINE for PolyLine, OT_TILE for Tile and OT_INVALID if not a valid object).
Objects' properties (Name and Type) can be accessed using respectively GetName() and GetType(). Type can be useful to flag categories of objects in Tiled.
Except Tile, objects are not visible (although you can display them for debugging purpose using DrawDebugGeometry() at the level of the tile map or a given layer, as mentioned previously). They can be used:
- To easily design polygon sprites and Box2D shapes using the object's vertices: use GetNumPoints() to get the number of vertices and GetPoint() to iterate through the vertices
- As placeholders to easily set the position and size of entities in the world, using GetPosition() and GetSize()
- To display Tile objects as sprites
- To create a background from Tile sprites
Additionaly Sprite2D resource from a Tile object is retrieved using GetTileSprite().
If need be you can access the grid id (relative to the tilesets used) of a Tile object using GetTileGid().
|AnimatedSprite2D||Animated sprite component, it uses to play animation created by Spine (http://www.esotericsoftware.com) and Spriter (http://www.brashmonkey.com/).|
|AnimationSet2D||Spriter animation set, it includes one or more animations, for more information please refer to http://www.esotericsoftware.com and http://www.brashmonkey.com/spriter.htm.|
|BodyType2D||Rigid body type.|
|CollisionBox2D||2D box collision component.|
|CollisionChain2D||2D chain collision component.|
|CollisionCircle2D||2D circle collision component.|
|CollisionEdge2D||2D edge collision component.|
|CollisionPolygon2D||2D polygon collision component.|
|CollisionShape2D||2D collision shape component.|
|Constraint2D||2D physics constraint component.|
|ConstraintDistance2D||2D distance constraint component.|
|ConstraintFriction2D||2D friction constraint component.|
|ConstraintGear2D||2D gear constraint component.|
|ConstraintMotor2D||2D motor constraint component.|
|ConstraintMouse2D||2D mouse constraint component.|
|ConstraintPrismatic2D||2D prismatic constraint component.|
|ConstraintPulley2D||2D pulley constraint component.|
|ConstraintRevolute2D||2D revolute constraint component.|
|ConstraintRope2D||2D rope constraint component.|
|ConstraintWeld2D||2D weld constraint component.|
|ConstraintWheel2D||2D wheel constraint component.|
|CurveType||Curve type for the|
|Drawable2D||Base class for 2D visible components.|
|EmitterType2D||2D particle emitter types.|
|ParticleEffect2D||2D particle effect resource.|
|ParticleEmitter2D||2D particle emitter component.|
|PhysicsBeginContact2DEventArgs||Event arguments for the PhysicsWorld2D's PhysicsBeginContact2D event|
|PhysicsEndContact2DEventArgs||Event arguments for the PhysicsWorld2D's PhysicsEndContact2D event|
|PhysicsWorld2D||2D physics simulation world component. Should be added only to the root scene node.|
|Renderer2D||2D renderer component.|
|RigidBody2D||2D rigid body component.|
|Sprite2D||Sprite loaded from a file.|
|SpriteSheet2D||Sprite sheet - texture atlas image that packs multiple Sprite2D images.|
|StaticSprite2D||Static sprite renderer component.|
|Texture2D||2D texture resource.|
|TileMap2D||Tile map component.|
|TileMapLayer2D||Tile map component.|
|TileMapLayerType2D||Tile map layer type.|
|TileMapObject2D||Tile map object.|
|TileMapObjectType2D||Tile map object type.|
|TmxFile2D||Tile map file.|
|TmxImageLayer2D||Tmx image layer.|
|TmxObjectGroup2D||Tmx image layer.|
|TmxTileLayer2D||Tmx tile layer.|