示例#1
0
文件: TileMap.cs 项目: tipfom/quasi_
        public void Serialize(Stream stream, IEntitySerializer serializer)
        {
            using (BinaryWriter writer = new BinaryWriter(stream, Encoding.UTF8, true)) {
                bool is32bit = (Size.Area >= Math.Pow(2, 16));

                // write header
                writer.Write(HEADER);
                writer.Write(VERSION);

                // write data
                writer.Write(is32bit);
                writer.Write((short)Width);
                writer.Write((short)Height);
                writer.Write((short)SpawnPoint.X);
                writer.Write((short)SpawnPoint.Y);

                /////////////////////////////////////////////////////////////////////////////////////////
                // compress mapdata
                int[] currenttile = { -1, -1, -1 };  // current tile of each layer
                Dictionary <int, List <int>[]> startpoints = new Dictionary <int, List <int>[]>( );

                for (int y = 0; y < Height; y++)
                {
                    for (uint x = 0; x < Width; x++)
                    {
                        for (int layer = 0; layer < 3; layer++)
                        {
                            // go through each layer
                            if (currenttile[layer] != Data[x, y, layer])
                            {
                                // if tile changed
                                if (!startpoints.ContainsKey(Data[x, y, layer]))
                                {
                                    startpoints.Add(Data[x, y, layer], new List <int> [3]);

                                    startpoints[Data[x, y, layer]][0] = new List <int>( );
                                    startpoints[Data[x, y, layer]][1] = new List <int>( );
                                    startpoints[Data[x, y, layer]][2] = new List <int>( );
                                }
                                // remember startingpoint
                                // invert the y axis
                                startpoints[Data[x, y, layer]][layer].Add((int)(y * Width + x));
                                currenttile[layer] = Data[x, y, layer];
                            }
                        }
                    }
                }

                Action <int> WriteInt;
                if (is32bit)
                {
                    WriteInt = (value) => { writer.Write((int)value); }
                }
                ;
                else
                {
                    WriteInt = (value) => { writer.Write((short)value); }
                };

                /////////////////////////////////////////////////////////////////////////////////////////
                // write mapdata
                foreach (var tileentry in startpoints)
                {
                    WriteInt(tileentry.Key + 1); // tileid
                    for (int layer = 0; layer < 3; layer++)
                    {
                        tileentry.Value[layer].Sort( );
                        for (int i = 0; i < tileentry.Value[layer].Count; i++)
                        {
                            WriteInt(tileentry.Value[layer][i] + 1);
                        }
                        WriteInt(0);
                    }
                }
                WriteInt(0);

                //////////////////////////////////////////////////////////////////////////////////////////
                // write tiles
                byte[] tilesraw = JsonConvert.SerializeObject(Tiles).Compress( ).Encode( );
                writer.Write((short)tilesraw.Length);
                writer.Write(tilesraw);

                // write texturename
                writer.Write(Texture);

                // write info
                writer.Write(Creator);
                writer.Write(Name);
                writer.Write(Gravity.X);
                writer.Write(Gravity.Y);

                // estimated entity count
                writer.Write((short)Entities.Count);
                // write entities
                for (int i = 0; i < Entities.Count; i++)
                {
                    // id
                    writer.Write((int)serializer.GetID(Entities[i]));
                    // pos
                    writer.Write(Entities[i].Transform.Center.X);
                    writer.Write(Entities[i].Transform.Center.Y);
                    // data
                    foreach (Tuple <DataID, DataType, object> data in serializer.GetData(Entities[i]))
                    {
                        // data id
                        writer.Write((int)data.Item1);
                        // data type
                        writer.Write((byte)data.Item2);
                        // the data itself
                        switch (data.Item2)
                        {
                        case DataType.Boolean:
                            writer.Write((bool)data.Item3);
                            break;

                        case DataType.BooleanArray:
                            writer.WriteArray((bool[] )data.Item3);
                            break;

                        case DataType.Byte:
                            writer.Write((byte)data.Item3);
                            break;

                        case DataType.ByteArray:
                            writer.WriteArray((byte[] )data.Item3);
                            break;

                        case DataType.SByte:
                            writer.Write((sbyte)data.Item3);
                            break;

                        case DataType.SByteArray:
                            writer.WriteArray((sbyte[] )data.Item3);
                            break;

                        case DataType.Short:
                            writer.Write((short)data.Item3);
                            break;

                        case DataType.ShortArray:
                            writer.WriteArray((short[] )data.Item3);
                            break;

                        case DataType.UShort:
                            writer.Write((ushort)data.Item3);
                            break;

                        case DataType.UShortArray:
                            writer.WriteArray((ushort[] )data.Item3);
                            break;

                        case DataType.Int:
                            writer.Write((int)data.Item3);
                            break;

                        case DataType.IntArray:
                            writer.WriteArray((int[] )data.Item3);
                            break;

                        case DataType.UInt:
                            writer.Write((uint)data.Item3);
                            break;

                        case DataType.UIntArray:
                            writer.WriteArray((uint[] )data.Item3);
                            break;

                        case DataType.Long:
                            writer.Write((long)data.Item3);
                            break;

                        case DataType.LongArray:
                            writer.WriteArray((long[] )data.Item3);
                            break;

                        case DataType.ULong:
                            writer.Write((ulong)data.Item3);
                            break;

                        case DataType.ULongArray:
                            writer.WriteArray((ulong[] )data.Item3);
                            break;

                        case DataType.Float:
                            writer.Write((float)data.Item3);
                            break;

                        case DataType.FloatArray:
                            writer.WriteArray((float[] )data.Item3);
                            break;

                        case DataType.Double:
                            writer.Write((double)data.Item3);
                            break;

                        case DataType.DoubleArray:
                            writer.WriteArray((double[] )data.Item3);
                            break;

                        case DataType.Decimal:
                            writer.Write((decimal)data.Item3);
                            break;

                        case DataType.DecimalArray:
                            writer.WriteArray((decimal[] )data.Item3);
                            break;

                        case DataType.Vector2:
                            writer.Write((Vector2)data.Item3);
                            break;

                        case DataType.Vector2Array:
                            writer.WriteArray((Vector2[] )data.Item3);
                            break;

                        case DataType.String:
                            writer.Write((string)data.Item3);
                            break;

                        case DataType.StringArray:
                            writer.WriteArray((string[] )data.Item3);
                            break;
                        }
                    }
                    // end
                    writer.Write((int)DataID.End);
                }
                writer.Write((int)EntityID.End);
            }
        }