/// <summary> /// Create the body part entity. /// </summary> /// <param name="bodyEntity">The body entity that the torso belongs to.</param> /// <param name="bodyPart">The type of body part.</param> /// <param name="spriteType">The sprite type.</param> /// <param name="spriteFamily">The sprite family.</param> /// <param name="position">The world position of the body part.</param> /// <param name="collisionGroup">The collision group of the body part.</param> /// <param name="spriteVariation">The sprite variation.</param> /// <param name="isPhysical">Indicates whether the body part can collide with physics objects.</param> /// <returns>The body part entity and the component.</returns> private BodyPartInfo AssembleBodyPart( Entity bodyEntity, BodyPart bodyPart, string spriteType, string spriteFamily, Vector2 position, short collisionGroup, int spriteVariation = -1, bool isPhysical = true) { Entity entity = this.world.EntityManager.CreateEntity(); // Add the body part var bodyPartComponent = new BodyPartComponent(bodyEntity, bodyPart); this.world.EntityManager.AddComponent(entity, bodyPartComponent); // Add the sprite string spriteName = this.world.Resources.GetSpriteName("body", spriteType, spriteFamily, spriteVariation); this.world.EntityManager.AddComponent(entity, new SpriteComponent(spriteName)); Body body; if (isPhysical) { // Get the texture data for the sprite Rectangle rectangle = this.world.Resources.GetSpriteRectangle(spriteName); uint[] spriteData = new uint[rectangle.Width * rectangle.Height]; this.world.Resources.SpriteSheet.GetData(0, rectangle, spriteData, 0, spriteData.Length); // Create a polygon for the sprite texture Vertices vertices = PolygonTools.CreatePolygon(spriteData, rectangle.Width, true); // Scale the vertices from pixels to physics-world units var scale = new Vector2(Const.PixelsToMeters, -Const.PixelsToMeters); vertices.Scale(ref scale); // Partition into smaller polygons to split concave segments List<Vertices> convexVertices = BayazitDecomposer.ConvexPartition(vertices); // Create the body body = BodyFactory.CreateCompoundPolygon(this.world.Physics, convexVertices, 1.0f); } else { // Create a tiny rectangle since this isn't a physical body. A body is just created so that the body // part can be welded onto other parts body = BodyFactory.CreateRectangle(this.world.Physics, 0.001f, 0.001f, 1.0f); } body.IsStatic = false; body.CollisionGroup = collisionGroup; body.IsSensor = !isPhysical; // Add the physics component var physicsComponent = new PhysicsComponent(body); this.world.EntityManager.AddComponent(entity, physicsComponent); // Add the position component this.world.EntityManager.AddComponent(entity, new PositionComponent(body, position)); // Add the scale component this.world.EntityManager.AddComponent(entity, new ScaleComponent(Const.PixelsToMeters)); return new BodyPartInfo(entity, bodyPartComponent, physicsComponent); }
/// <summary> /// Initializes a new instance of the BodyPartInfo class. /// </summary> /// <param name="entity">The body part entity.</param> /// <param name="bodyPartComponent">The body part component.</param> /// <param name="physicsComponent">The physics component.</param> public BodyPartInfo(Entity entity, BodyPartComponent bodyPartComponent, PhysicsComponent physicsComponent) { this.Entity = entity; this.BodyPartComponent = bodyPartComponent; this.PhysicsComponent = physicsComponent; }
/// <summary> /// Create a terrain entity from a bitmap image. /// </summary> /// <param name="world">The world context.</param> /// <param name="x">The top-left X position in world-coordinates.</param> /// <param name="y">The top-left Y position in world-coordinates.</param> /// <param name="scale">The scale ratio for the terrain.</param> /// <param name="isCollidable">Indicates whether the terrain can be collided with.</param> /// <param name="terrainBitmapName">The name of the terrain bitmap.</param> /// <param name="currentTime">The current time used as the terrain creation time.</param> /// <returns>The entity.</returns> public Entity CreateTerrain( WorldContext world, float x, float y, float scale, bool isCollidable, string terrainBitmapName, TimeSpan currentTime) { Entity entity = world.EntityManager.CreateEntity(); // Load the terrain texture Texture2D texture = world.Resources.Load<Texture2D>(terrainBitmapName); // Create the terrain quad tree var terrainFactory = new TerrainFactory(); ClipQuadTree<TerrainData> terrainQuadTree = terrainFactory.CreateTerrainQuadTree(texture, currentTime); // Build the path nodes from the terrain quad tree var pathBuilder = new PathBuilder(terrainQuadTree, 30, 5); Dictionary<Point, LinkedPathNode> pathNodes = pathBuilder.BuildPathNodes(); // Create the terrain component var cTerrain = new TerrainComponent(terrainQuadTree, isCollidable, pathNodes); // Create the physics body. Initially this has no fixtures, as those are populated dynamically var body = new Body(world.Physics); var cPhysics = new PhysicsComponent(body); // Add components to entity world.EntityManager.AddComponent(entity, cTerrain); world.EntityManager.AddComponent(entity, cPhysics); world.EntityManager.AddComponent(entity, new PositionComponent(body, new Vector2(x, y))); world.EntityManager.AddComponent(entity, new ScaleComponent(scale)); return entity; }