private ClipQuadTree<TerrainData>[] GetTerrainInView( TerrainComponent cTerrain, Vector3 translation, Vector3 scale, int widthPadding, int heightPadding) { var rect = new Rectangle( cTerrain.Terrain.Bounds.X - (int)translation.X - widthPadding, cTerrain.Terrain.Bounds.Y - (int)translation.Y - heightPadding, (int)Math.Ceiling(this.graphics.Viewport.Width / scale.X) + widthPadding, (int)Math.Ceiling(this.graphics.Viewport.Height / scale.Y) + heightPadding); return cTerrain.Terrain.GetNodesIntersecting(rect).ToArray(); }
/// <summary> /// Draw the TerrainComponent sprites. /// </summary> /// <param name="spriteBatch">The sprite batch.</param> /// <param name="cameraTranslateX">The camera x translation value.</param> /// <param name="cameraTranslateY">The camera y translation value.</param> /// <param name="cameraScaleX">The camera x scale value.</param> /// <param name="cameraScaleY">The camera y scale value.</param> private void DrawTerrainComponents( SpriteBatch spriteBatch, Matrix transform, ClipQuadTree<TerrainData>[] terrainBlocks, TerrainComponent cTerrain) { // Begin the sprite batch with the camera transform spriteBatch.Begin(SpriteSortMode.Deferred, null, SamplerState.PointClamp, null, null, null, transform); foreach (ClipQuadTree<TerrainData> terrainBlock in terrainBlocks) { // Don't draw anything if no terrain exists here TerrainMaterial material = terrainBlock.Data.Material; if (material == TerrainMaterial.None) { continue; } // Calculate the bounds of this terrain block in on-screen coordinates var screenBounds = new Rectangle( terrainBlock.Bounds.X, terrainBlock.Bounds.Y, terrainBlock.Bounds.Length, terrainBlock.Bounds.Length); // Tile the terrain within the bounds this.DrawTiledTerrain(spriteBatch, material, screenBounds); } // Draw fringe sprites for each terrain block foreach (ClipQuadTree<TerrainData> terrainBlock in terrainBlocks) { // Don't draw anything if no terrain exists here TerrainMaterial material = terrainBlock.Data.Material; if (material == TerrainMaterial.None) { continue; } // Draw the fringe tiles this.DrawTerrainFringe(spriteBatch, material, terrainBlock.Bounds, cTerrain.PathNodes); } /* // DEBUG: Draw path components Texture2D debugTexture = new Texture2D(this.graphics, 1, 1); debugTexture.SetData<Color>(new Color[] { Color.White }); foreach (PathComponent path in this.EntityManager.GetComponents(typeof(PathComponent))) { for (int i = 0; i < path.Nodes.Length - 1; i++) { PathNode p1 = path.Nodes[i]; PathNode p2 = path.Nodes[i + 1]; int width = Math.Abs(p2.X - p1.X); if (width == 0) width = 1; int height = Math.Abs(p2.Y - p1.Y); if (height == 0) height = 1; spriteBatch.Draw( debugTexture, new Rectangle(p1.X, p1.Y, width, height), (p1.Type == PathNodeType.Normal) ? Color.Red : Color.Yellow); } } */ spriteBatch.End(); }
private void CreateTestPath(WorldContext world, TerrainComponent terrain, Point start, Point goal) { var testEntity = world.EntityManager.CreateEntity(); // Create the path finder var pathFinder = new PathFinder(terrain); // Find the nodes along the path PathNode[] path; if (pathFinder.FindPath(start, goal, 1, 1, out path)) { // Create the path component world.EntityManager.AddComponent(testEntity, new PathComponent(path)); } }
/// <summary> /// Draw the game. /// </summary> /// <param name="spriteBatch">The sprite batch.</param> /// <param name="cameraTranslateX">The camera x translation value.</param> /// <param name="cameraTranslateY">The camera y translation value.</param> /// <param name="cameraScaleX">The camera x scale value.</param> /// <param name="cameraScaleY">The camera y scale value.</param> private void DrawGame( SpriteBatch spriteBatch, Matrix terrainTransform, Matrix spriteTransform, ClipQuadTree<TerrainData>[] terrainBlocks, TerrainComponent cTerrain) { // Draw the terrain this.DrawTerrainComponents(spriteBatch, terrainTransform, terrainBlocks, cTerrain); // Draw the sprites this.DrawSpriteComponents(spriteBatch, spriteTransform); }
/// <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; }