Example #1
0
        /// <summary>
        /// Builds entities based on tilemap, and tiles provided and splits them up into the chunks passed
        /// </summary>
        /// <param name="perChunkTileAmount">Number of tiles per chunk</param>
        public void Build(Point perChunkTileAmount)
        {
            bool AddedTileForChunkFix = false;

            if (this.tiles.FindAll(e => e.Position3D.X == 0 && e.Position3D.Y == 0 && e.Position3D.Z == 0).Count == 0)
            {
                this.tiles.Add(new Tile(Point.Zero, new Point3D(0, 0, 0)));
                AddedTileForChunkFix = true;
            }

            chunkLayers = new List <int>();
            foreach (Tile tile in this.tiles)
            {
                if (!chunkLayers.Contains(tile.Position3D.Z))
                {
                    chunkLayers.Add(tile.Position3D.Z);
                }
            }
            chunkLayers.Sort((t1, t2) => { return(t1 - t2); });

            totalMapSize = this.TotalMapSize();
            totalChunks  = new Point3D(
                Math.Max((int)Math.Ceiling((double)totalMapSize.X / (perChunkTileAmount.X * this.tileSize.X)), 1),
                Math.Max((int)Math.Ceiling((double)totalMapSize.Y / (perChunkTileAmount.Y * this.tileSize.Y)), 1),
                chunkLayers.Count
                );
            chunkSize = perChunkTileAmount * this.tileSize;
            chunks    = new Texture2D[totalChunks.X, totalChunks.Y, totalChunks.Z];

            foreach (Tile tile in this.tiles)
            {
                if (AddedTileForChunkFix && tile.Position3D.X == 0 && tile.Position3D.Y == 0 && tile.Position3D.Z == 0)
                {
                    AddedTileForChunkFix = false;
                    continue;
                }

                Point3D chunkIndex = Point3D.FromPoint((tile.Position * tileSize) / chunkSize);
                chunkIndex.Z = chunkLayers.FindIndex(x => x == tile.Position3D.Z);
                Rectangle chunkRect  = new Rectangle((chunkIndex * chunkSize).ToPoint(), chunkSize);
                Color[]   tileColors = new Color[this.tileSize.X * this.tileSize.Y];
                this.tileset[tile.SourcePosition.X, tile.SourcePosition.Y].GetData <Color>(tileColors, 0, tileColors.Length);

                if (chunks[chunkIndex.X, chunkIndex.Y, chunkIndex.Z] == null)
                {
                    chunks[chunkIndex.X, chunkIndex.Y, chunkIndex.Z] = new Texture2D(Global.GraphicsDevice, chunkSize.X, chunkSize.Y);
                }

                Rectangle relativeTileRect = new Rectangle((tile.Position * this.tileSize) - chunkRect.Location, this.tileSize);
                chunks[chunkIndex.X, chunkIndex.Y, chunkIndex.Z].SetData <Color>(0, relativeTileRect, tileColors, 0, this.tileSize.X * this.tileSize.Y);
            }


            for (int x = 0; x < totalChunks.X; x++)
            {
                for (int y = 0; y < totalChunks.Y; y++)
                {
                    for (int z = 0; z < totalChunks.Z; z++)
                    {
                        if (chunks[x, y, z] == null)
                        {
                            continue;
                        }

                        TileGroupEntities.Add(new Entity(entity => {
                            entity.Origin       = Vector2.Zero;
                            entity.Position     = new Vector2(x * chunkSize.X, y * chunkSize.Y);
                            entity.SortingLayer = chunkLayers[z];
                            entity.AddComponent(new Drawable()).Run <Drawable>(component => {
                                component.Texture2D = chunks[x, y, z];
                            });
                        }));
                    }
                }
            }
        }