Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /* #############################################################################
- *
- * Copyright (C) 2011 Scott Franks
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy of
- * this software and associated documentation files (the "Software"), to deal in
- * the Software without restriction, including without limitation the rights to
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
- * of the Software, and to permit persons to whom the Software is furnished to do
- * so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- ############################################################################# */
- using System;
- using System.IO;
- using FarseerPhysics.Common;
- using FarseerPhysics.Common.Decomposition;
- using FarseerPhysics.Common.PolygonManipulation;
- using FarseerPhysics.Dynamics;
- using FarseerPhysics.Factories;
- using Microsoft.Xna.Framework;
- using Microsoft.Xna.Framework.Graphics;
- using Ruminate.GUI.Framework;
- using Ruminate.Utils;
- using TiledLib;
- namespace Ruminate.Engine2D {
- /// <summary>
- /// Extensions to the TiledLib library by Nick Gravelyn
- /// </summary>
- public static class TiledLibExtentions {
- /// <summary>
- /// Renders the entire map and then saves it to disk as a .png
- /// </summary>
- /// <param name="map">The Map to save to disk.</param>
- /// <param name="device">The Games current device.</param>
- /// <param name="fileName">The location to save the current file.</param>
- public static void SaveAsPng(this Map map, GraphicsDevice device, string fileName) {
- var width = map.Width * map.TileWidth;
- var height = map.Height * map.TileHeight;
- var baker = new TextureBaker(device, new Vector2(width, height), RenderState.Tile);
- map.Draw(baker);
- using (var stream = new FileStream(fileName, FileMode.Create)) {
- baker.GetTexture().SaveAsPng(stream, width, height);
- }
- }
- /// <summary>
- /// Performs a basic rendering of a the specified layer in the map.
- /// </summary>
- /// <param name="map">The Map containing the layer to draw.</param>
- /// <param name="spriteBatch">The SpriteBatch to use to render the map.</param>
- /// <param name="layerName">The name of the layer to draw.</param>
- public static void DrawLayer(this Map map, SpriteBatch spriteBatch, string layerName) {
- var area = new Rectangle(0, 0, map.Width * map.TileWidth, map.Height * map.TileHeight);
- map.DrawLayer(spriteBatch, area, layerName);
- }
- /// <summary>
- /// Draws a layer of the map defined in world space (pixel) coordinates.
- /// </summary>
- /// <param name="map">The Map containing the layer to draw.</param>
- /// <param name="spriteBatch">The SpriteBatch to use to render the map.</param>
- /// <param name="viewArea">The area of the map to draw in world coordinates.</param>
- /// <param name="layerName">The name of the layer to draw.</param>
- public static void DrawLayer(this Map map, SpriteBatch spriteBatch, Rectangle viewArea, string layerName) {
- if (spriteBatch == null) {
- throw new ArgumentNullException("spriteBatch");
- }
- switch (map.Orientation) {
- case Orientation.Orthogonal:
- // figure out the min and max tile indices to draw
- var minX = Math.Max((int)Math.Floor((float)viewArea.Left / map.TileWidth), 0);
- var maxX = Math.Min((int)Math.Ceiling((float)viewArea.Right / map.TileWidth), map.Width);
- var minY = Math.Max((int)Math.Floor((float)viewArea.Top / map.TileHeight), 0);
- var maxY = Math.Min((int)Math.Ceiling((float)viewArea.Bottom / map.TileHeight), map.Height);
- foreach (var l in map.Layers) {
- if (!l.Visible) { continue; }
- if (l.Name.Equals(layerName)) { continue; }
- var tileLayer = l as TileLayer;
- if (tileLayer == null) { continue; }
- for (var x = minX; x < maxX; x++) {
- for (var y = minY; y < maxY; y++) {
- var tile = tileLayer.Tiles[x, y];
- if (tile == null) { continue; }
- var destination = new Rectangle(
- x * map.TileWidth - viewArea.Left,
- y * map.TileHeight - tile.Source.Height + map.TileHeight - viewArea.Top,
- map.TileWidth,
- map.TileHeight);
- tile.DrawOrthographic(spriteBatch, destination, tileLayer.Opacity, l.LayerDepth);
- }
- }
- }
- break;
- default:
- throw new NotSupportedException("TileLib does not have built in support for rendering isometric tile maps.");
- }
- }
- /// <summary>
- /// Converts a the specified layer of the map into a polygon body for use in the
- /// Farseer Physics Engine. Requires that you set the ConvertUnits.DisplayUnitToSimUnitRatio
- /// to an appropriate value for your game. Defaults to 100px = 1m.
- /// </summary>
- /// <param name="map">The Map containing the later to convert to a Body.</param>
- /// <param name="device">The graphics device of the current Game.</param>
- /// <param name="world">The world to add the created body to.</param>
- /// <param name="meterInPixels">The number of pixels equivalent to 1 Body unit.</param>
- /// <param name="layer">The name of the Layer to convert to a Body.</param>
- /// <returns>The body created and added to the world.</returns>
- public static Body LayerToBody(this Map map, GraphicsDevice device, World world, float meterInPixels, string layer) {
- //Pixel size of the map
- var width = map.Width * map.TileWidth;
- var height = map.Height * map.TileHeight;
- //Create the baker
- var baker = new TextureBaker(
- device,
- new Vector2(width, height),
- RenderState.Tile);
- //Render the map to a texture
- map.Draw(baker);
- var polygonTexture = baker.GetTexture();
- //Get the data from the texture
- var data = new uint[polygonTexture.Width * polygonTexture.Height];
- polygonTexture.GetData(data);
- //Create a poly from the texture
- var verts = PolygonTools.CreatePolygon(data, polygonTexture.Width, true);
- //These 2 seem to work the best with tile maps
- verts = SimplifyTools.CollinearSimplify(verts);
- verts = SimplifyTools.DouglasPeuckerSimplify(verts, 0f);
- var list = BayazitDecomposer.ConvexPartition(verts);
- var vertScale = new Vector2(1f / meterInPixels);
- foreach (var vertices in list) {
- vertices.Scale(ref vertScale);
- }
- //Create a body from the poly
- var body = BodyFactory.CreateCompoundPolygon(world, list, 1);
- return body;
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment