private Rectangle GetTilesetTileSourceRect(TmxTilesetTile tile, TmxTileset tileset) { int x = tile.Id % tileset.Columns.Value; int y = tile.Id / tileset.Columns.Value; return(new Rectangle(x * tileset.TileWidth, y * tileset.TileHeight, tileset.TileWidth, tileset.TileHeight)); }
/// <summary> /// Initializes a new instance of the <see cref="TilesetTile" /> class. /// </summary>> /// <param name="tmxTilesetTile">The TMX parsed tileset tile.</param> /// <param name="tileset">The associated tileset</param> public TilesetTile(TmxTilesetTile tmxTilesetTile, Tileset tileset) { this.Tileset = tileset; this.ID = tmxTilesetTile.Id; this.Probability = tmxTilesetTile.Probability; this.Properties = new Dictionary <string, string>(tmxTilesetTile.Properties); this.TerrainEdges = new List <TilesetTerrain>(); if (tmxTilesetTile.BottomRight != null) { this.BottomRight = this.Tileset.Terrains[tmxTilesetTile.BottomRight.Name]; this.TerrainEdges.Add(this.BottomRight); } if (tmxTilesetTile.BottomLeft != null) { this.BottomLeft = this.Tileset.Terrains[tmxTilesetTile.BottomLeft.Name]; this.TerrainEdges.Add(this.BottomLeft); } if (tmxTilesetTile.TopRight != null) { this.TopRight = this.Tileset.Terrains[tmxTilesetTile.TopRight.Name]; this.TerrainEdges.Add(this.TopRight); } if (tmxTilesetTile.TopLeft != null) { this.TopLeft = this.Tileset.Terrains[tmxTilesetTile.TopLeft.Name]; this.TerrainEdges.Add(this.TopLeft); } }
private GameObject CreateTile(TmxTileset tileset, TmxTilesetTile tile, Transform2 transform) { var entity = Entity.Create($"Tile {tile.Id}", transform) .Add((o, r) => new Texture(r.LoadTexture(tileset.TileSource, o), new SpriteSheetRectangle(tile.Id, tileset.Columns, tileset.TileWidth, tileset.TileHeight, tileset.Spacing).Get())); return(tile.CollisionBoxes.Any() ? WithBoxColliders(tile, entity) : entity); }
private GameObject WithBoxColliders(TmxTilesetTile tile, GameObject entity) { //TODO: allow multiple boxes var box = tile.CollisionBoxes.First(); return(entity.Add(new Collision()) .Add(new BoxCollider( new Transform2( entity.World.Location + box.Location.ToVector2(), new Size2(box.Width, box.Height))))); }
private TiledTile ParseTile(TmxTileset tileset, TmxTilesetTile tilesetTile) { string texture = GetTilesetTexture(tileset); Rectangle sourceRectangle = GetTilesetTileSourceRect(tilesetTile, tileset); TiledTile tiledTile = new TiledTile(); tiledTile.Initialize(tilesetTile, 0, texture, sourceRectangle); return(tiledTile); }
public void Initialize(TmxTilesetTile tile, float drawPriority, string textureName, Rectangle sourceRectangle) { this.tilesetId = tile.Id; this.drawPriority = drawPriority; this.textureName = textureName; this.sourceRectangle = sourceRectangle; this.type = tile.Type; properties = tile.Properties; }
private Texture2D RenderChunk(Vector2 position) { GraphicsDevice gDevice = worldRenderer.Game.GraphicsDevice; var renderTarget = new RenderTarget2D(gDevice, chunkSize, chunkSize, false, gDevice.PresentationParameters.BackBufferFormat, DepthFormat.None, 0, RenderTargetUsage.PreserveContents); gDevice.SetRenderTarget(renderTarget); gDevice.Clear(Color.Transparent); // Render tiles spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.AlphaBlend, SamplerState.PointWrap, null, null); var world = worldRenderer.World; var tileWidth = world.Map.TileWidth; var tileHeight = world.Map.TileHeight; foreach (var layer in world.Map.Layers) { if (!layer.Visible || layer.Opacity == 0f || layer.Type != TmxLayerType.Tile) { continue; } for (int y = getYStart(position.Y, chunkSize); y < getYEnd(position.Y, chunkSize); ++y) { for (int x = getXStart(position.X, chunkSize); x < getXEnd(position.X, chunkSize); ++x) { float absX = (x * tileWidth) - position.X; // Negate the position so we render them inside the texture. Remember, we're drawing them to a texture and not the screen. float absY = (y * tileHeight) - position.Y; var tileGid = layer.Data[x + (y * world.Width)]; if (tileGid == 0) { continue; } TmxTilesetTile tileInfo = world.Map.FindTileInfo(tileGid); spriteBatch.Draw(tileInfo.Tileset.Texture, new Vector2(absX, absY), tileInfo.SubRectangle, Color.White); } } } spriteBatch.End(); gDevice.SetRenderTarget(null); return(renderTarget); }
private Collision GetCollisionType(TmxTilesetTile collisionTile) { string collisionType; if (!collisionTile.Properties.TryGetValue("Collision", out collisionType)) { return(Collision.Solid); } if (collisionType == "Water") { return(Collision.Water); } else { return(Collision.Solid); } }
private TileType GetTilesetTileType(TmxTileset tileset, int id) { TmxTilesetTile tilesetTile = TileForId(tileset, id); if (tilesetTile == null || !tilesetTile.Properties.ContainsKey("type")) { throw new Exception($"Tile {id} has no type."); } var typeString = tilesetTile.Properties["type"]; if (Enum.TryParse <TileType>(typeString, true, out var type)) { return(type); } throw new Exception($"Tile type {typeString} is not valid."); }
private void CreateCollisionObject(MapCell cell, TmxTilesetTile tileResult, out bool customCollisionSize) { TmxObjectGroup.TmxObject tmxObject = null; for (int objectGroupCount = 0; objectGroupCount < tileResult.ObjectGroups.Count; objectGroupCount++) { for (int objectCount = 0; objectCount < tileResult.ObjectGroups.Count; objectCount++) { tmxObject = tileResult.ObjectGroups[objectGroupCount].Objects[objectCount]; } } cell.passable = false; GameObject collisionObject = new GameObject(cell.position);//cell.position.X / 32 == 33 && cell.position.Y / 32 == 29 if (debugTileset) { collisionObject.AddLight(new LightSource(70, Color.White)); } if (tmxObject != null) { customCollisionSize = true; collisionObject.position += new Vector2((float)tmxObject.X, (float)tmxObject.Y); collisionObject.size = new Vector2((float)tmxObject.Width, (float)tmxObject.Height); } else { customCollisionSize = false; } string tag = tileResult.Properties["Tag"]; if (tag != "") { collisionObject.tags.Add(tag); } collisionObjectList.Add(collisionObject); }
WorldTileEntity ProcessTmxLayerTile(TmxLayerTile tmxLayerTile, TmxTileset tmxTileset) { WorldTileEntity tile = new WorldTileEntity { SpriteSheetFrame = Math.Max(-1, tmxLayerTile.Gid - tmxTileset.FirstGid) }; if (tile.SpriteSheetFrame < 0) { return(tile); } TmxTilesetTile tmxTilesetTile = tmxTileset.Tiles.FirstOrDefault(x => x.Id == tile.SpriteSheetFrame); if (tmxTilesetTile == null) { return(tile); } string objectId = string.Empty; string terrainId = string.Empty; if (tmxTilesetTile.Properties.ContainsKey("ObjectId")) { tile.ObjectId = tmxTilesetTile.Properties["ObjectId"]; } if (tmxTilesetTile.Properties.ContainsKey("TerrainId")) { tile.TerrainId = tmxTilesetTile.Properties["TerrainId"]; } tile.ObjectId = string.IsNullOrWhiteSpace(objectId) ? tile.ObjectId : objectId; tile.TerrainId = string.IsNullOrWhiteSpace(terrainId) ? tile.TerrainId : terrainId; return(tile); }
//private Layer collisionLayer; // Construct a TiledLib.Map from a TmxReader.map public Map(ContentManager content, string mapName) { string mapPath = AppDomain.CurrentDomain.BaseDirectory + "Content/" + mapName + ".tmx"; TmxMap tmx = new TmxMap(mapPath); Version = new Version(tmx.Version); switch (tmx.Orientation) { case TmxMap.OrientationType.Isometric: Orientation = Orientation.Isometric; break; case TmxMap.OrientationType.Orthogonal: Orientation = Orientation.Orthogonal; break; case TmxMap.OrientationType.Staggered: throw new Exception( "TiledLib doesn't support maps with Staggered " + "orientation."); } Width = tmx.Width; Height = tmx.Height; TileWidth = tmx.TileWidth; TileHeight = tmx.TileHeight; Properties = new PropertyCollection(); foreach (KeyValuePair <string, string> kvp in tmx.Properties) { Properties.Add(kvp); } // Create a list for our tiles List <Tile> tiles = new List <Tile>(); Tiles = new Collection <Tile>(tiles); // Read in each TileSet foreach (TmxTileset ts in tmx.Tilesets) { string tilesetName = ts.Name; Texture2D texture = content.Load <Texture2D>(ts.Image.Source); bool collisionSet = ts.Properties.ContainsKey("CollisionSet") && ts.Properties["CollisionSet"] == "True" ? true : false; /* TODO: Add this intelligence to TiledSharp. * If the texture is bigger than a individual tile, infer all the * additional tiles that must be created. */ if (texture.Width > ts.TileWidth || texture.Height > ts.TileHeight) { // Deconstruct tileset to individual tiles int id = 0; for (int y = 0; y < texture.Height / ts.TileHeight; y++) { for (int x = 0; x < texture.Width / ts.TileWidth; x++) { Rectangle source = new Rectangle( x * ts.TileWidth, y * ts.TileHeight, ts.TileWidth, ts.TileHeight ); Color[] collisionData = null; bool[] collisionBitData = null; PropertyCollection props = new PropertyCollection(); TmxTilesetTile tsTile = ts.Tiles.Find(i => i.Id == id); if (tsTile != null) { foreach (KeyValuePair <string, string> kvp in tsTile.Properties) { props.Add(kvp); // Inherit tilesets collision bool collidable = collisionSet; if (kvp.Key == "CollisionSet") { // Allow override per tile if (kvp.Value == "True") { collidable = true; } else { collidable = false; } } if (collidable) { int numOfBytes = ts.TileWidth * ts.TileHeight; collisionData = new Color[numOfBytes]; collisionBitData = new bool[numOfBytes]; texture.GetData <Color>( 0, source, collisionData, 0, numOfBytes ); for (int col = 0; col < numOfBytes; col++) { if (collisionData[col].A > 0) { collisionBitData[col] = true; } } collisionData = null; } } } Tile t = new Tile( texture, source, props, collisionBitData ); while (id >= tiles.Count) { tiles.Add(null); } tiles.Insert(id + ts.FirstGid, t); id++; } } } } // Process Map Items (layers, objectgroups, etc.) List <Layer> layers = new List <Layer>(); Layers = new Collection <Layer>(layers); foreach (TmxLayer l in tmx.Layers) { Layer layer = null; PropertyCollection props = new PropertyCollection(); foreach (KeyValuePair <string, string> kvp in l.Properties) { props.Add(kvp); } layer = new TileLayer( l.Name, tmx.Width, // As of TiledQT always same as layer. tmx.Height, // As of TiledQT always same as layer. l.Visible, (float)l.Opacity, props, this, l.Tiles ); layers.Add(layer); namedLayers.Add(l.Name, layer); } foreach (TmxObjectGroup og in tmx.ObjectGroups) { Layer layer = null; PropertyCollection props = new PropertyCollection(); foreach (KeyValuePair <string, string> kvp in og.Properties) { props.Add(kvp); } List <MapObject> objects = new List <MapObject>(); // read in all of our objects foreach (TmxObjectGroup.TmxObject i in og.Objects) { Rectangle objLoc = new Rectangle( i.X, i.Y, i.Width, i.Height ); List <Point> objPoints = new List <Point>(); if (i.Points != null) { foreach (Tuple <int, int> tuple in i.Points) { objPoints.Add(new Point(tuple.Item1, tuple.Item2)); } } PropertyCollection objProps = new PropertyCollection(); foreach (KeyValuePair <string, string> kvp in i.Properties) { objProps.Add(kvp); } objects.Add( new MapObject( i.Name, i.Type, objLoc, objPoints, objProps) ); } layer = new MapObjectLayer( og.Name, tmx.Width, tmx.Height, og.Visible, (float)og.Opacity, props, objects ); layers.Add(layer); namedLayers.Add(og.Name, layer); } }
public TileMap(string path, bool debugTileset = false) { this.debugTileset = debugTileset; tmxMap = new TmxMap(path); config = new TmxMap("Maps\\" + configName + ".tmx"); // 1. intialize tilesets = new Texture2D[tmxMap.Tilesets.Count]; for (int i = 0; i < tmxMap.Tilesets.Count; i++) { string name = Path.GetFileNameWithoutExtension(tmxMap.Tilesets[i].Image.Source); tilesets[i] = (Game.content.Load <Texture2D>("Textures\\Tilesets\\" + name)); tilesets[i].Name = name; } this.width = tmxMap.Width; //todo: /32 this.height = tmxMap.Height; for (int counter = 0; counter < tmxMap.Layers.Count; counter++) { layers.Add(new Layer()); } mapRect = new Rectangle(0, 0, width * Tile.size, height * Tile.size); // 2. build blank map, or if you want - intializing all layers foreach (Layer layer in layers) { for (int y = 0; y < height; y++) { //create new row MapRow newRow = new MapRow(); //add to its columns new cells for (int x = 0; x < width; x++) { newRow.Columns.Add(new MapCell()); } //add the new row to the current layer layer.Rows.Add(newRow); } } // 3. add map design for (int layersCounter = 0; layersCounter < layers.Count; layersCounter++) { Layer layer = layers[layersCounter]; for (int y = 0; y < height; y++) { MapRow row = layer.Rows[y]; for (int x = 0; x < width; x++) { MapCell cell = row.Columns[x]; int currentCell = y * (height) + x; TmxLayerTile tmxCell = tmxMap.Layers[layersCounter].Tiles[currentCell]; //texture and tileset if (tmxCell.Gid == 0) { cell.empty = true; } cell.texture = tmxCell.Gid; cell.tileset = tilesets[0]; int tilesSoFar = tmxMap.Tilesets[0].Tiles.Count; for (int tilesetsCounter = 0; tilesetsCounter < tmxMap.Tilesets.Count - 1; tilesetsCounter++) { if (tmxCell.Gid > tilesSoFar) { cell.texture = tmxCell.Gid - tilesSoFar; cell.tileset = tilesets[tilesetsCounter + 1]; } tilesSoFar += tmxMap.Tilesets[tilesetsCounter + 1].Tiles.Count; } //position cell.position = new Vector2(tmxCell.X * Tile.size, tmxCell.Y * Tile.size); //if autotile if (FindTileset(cell.tileset.Name).Properties["Autotile"] == "true") { cell.autotile = true; } //tile properties TmxTilesetTile tileResult = GetMapTile(cell); if (tileResult != null) { //collision if (tileResult.Properties["Passable"] == "X") { CreateCollisionObject(cell, tileResult, out cell.customCollisionSize); } //height if (tileResult.Properties["Height"] == "1") { cell.high = true; highCells.Add(cell); } else { mapCellsList.Add(cell); } //tags string tag = tileResult.Properties["Tag"]; if (tag != "") { cell.tags.Add(tag); } } } } } //check for autotiles for (int layersCounter = 0; layersCounter < layers.Count; layersCounter++) { Layer layer = layers[layersCounter]; for (int y = 1; y < height - 1; y++) { MapRow row = layer.Rows[y]; for (int x = 1; x < width - 1; x++) { MapCell cell = row.Columns[x]; int currentCell = y * (height) + x; TmxLayerTile tmxCell = tmxMap.Layers[layersCounter].Tiles[currentCell]; //same layer collision if (layersCounter == 0) //do it for just one time { if (CheckLayersPassableTag(tmxMap, y, x)) { List <GameObject> SameLayerCollisionList = collisionObjectList.FindAll(collisionObject => collisionObject.position == cell.position); foreach (GameObject gameObject in SameLayerCollisionList) { collisionObjectList.Remove(gameObject); } } } //check for autotiles if (cell.autotile) { if (row.Columns[x - 1].autotile && row.Columns[x + 1].autotile) { if (layer.Rows[y - 1].Columns[x].autotile && layer.Rows[y + 1].Columns[x].autotile) { //corners //upper left if (!layer.Rows[y - 1].Columns[x - 1].autotile) { cell.autotileCorner = MapCell.Corner.topLeft; } //upper right else if (!layer.Rows[y - 1].Columns[x + 1].autotile) { cell.autotileCorner = MapCell.Corner.topRight; } //lower left else if (!layer.Rows[y + 1].Columns[x - 1].autotile) { cell.autotileCorner = MapCell.Corner.bottomLeft; } //lower right else if (!layer.Rows[y + 1].Columns[x + 1].autotile) { cell.autotileCorner = MapCell.Corner.bottomRight; } //center } else { //down link if (layer.Rows[y - 1].Columns[x].autotile) { cell.texture += cell.tilesetWidth; } //up link if (layer.Rows[y + 1].Columns[x].autotile) { cell.texture -= cell.tilesetWidth; } } } else if (row.Columns[x - 1].autotile) { //right link if (layer.Rows[y - 1].Columns[x].autotile) { //down link cell.texture += cell.tilesetWidth; } if (layer.Rows[y + 1].Columns[x].autotile) { //up link cell.texture -= cell.tilesetWidth; } cell.texture++; } else if (row.Columns[x + 1].autotile) { //left link if (layer.Rows[y - 1].Columns[x].autotile) { //down link cell.texture += cell.tilesetWidth; } if (layer.Rows[y + 1].Columns[x].autotile) { //up link cell.texture -= cell.tilesetWidth; } cell.texture--; } } } } } }
public void Build() { Dictionary <string, List <Vertex> > vertices = new Dictionary <string, List <Vertex> >(); foreach (var tile in layer.Tiles) { if (tile.Gid == 0) { continue; } // Find the corresponding tileset TmxTileset tileset = null; foreach (var ts in map.Tilesets) { if (tile.Gid >= ts.FirstGid && tile.Gid < ts.FirstGid + ts.TileCount) { tileset = ts; break; } } if (tileset == null) { continue; } if (!vertices.ContainsKey(tileset.Image.Source)) { vertices.Add(tileset.Image.Source, new List <Vertex>()); } var vertexList = vertices[tileset.Image.Source]; // Prepare the vertices Vertex tl = new Vertex(new Vector2f((float)(layer.OffsetX ?? 0) + tile.X * tileset.TileWidth, (float)(layer.OffsetY ?? 0) + tile.Y * tileset.TileHeight)); Vertex bl = new Vertex(new Vector2f(tl.Position.X, tl.Position.Y + tileset.TileHeight)); Vertex br = new Vertex(new Vector2f(tl.Position.X + tileset.TileWidth, tl.Position.Y + tileset.TileHeight)); Vertex tr = new Vertex(new Vector2f(tl.Position.X + tileset.TileWidth, tl.Position.Y)); // Find the tile in the tileset int lid = tile.Gid - tileset.FirstGid; TmxTilesetTile tsTile = null; foreach (var tsTileCheck in tileset.Tiles) { if (tsTileCheck.Id == lid) { tsTile = tsTileCheck; break; } } // Do animations if (tsTile != null && tsTile.AnimationFrames != null && tsTile.AnimationFrames.Count != 0) { var anim = new AnimIndex(); anim.whichTex = tileset.Image.Source; anim.vertexOffset = vertexList.Count; anim.tile = tile; anim.tileset = tileset; anim.tsTile = tsTile; anim.animInfo = tsTile.AnimationFrames; anims.Add(anim); lid = GetAnimationFrame(tsTile.AnimationFrames); } // Do texture coordinates UpdateTexCoords(tile, tileset, lid, ref tl, ref bl, ref br, ref tr); // Add vertices to the layer for rendering vertexList.Add(tl); vertexList.Add(bl); vertexList.Add(br); vertexList.Add(tr); } this.vertices.Clear(); foreach (var vertexList in vertices) { this.vertices.Add(vertexList.Key, vertexList.Value.ToArray()); } }