示例#1
0
 public Sprite(SpriteFrameset frames)
 {
     m_CurrentFrame = 0;
     m_FrameTime    = 0.0;
     m_FrameCount   = 0;
     Frames         = frames;
 }
示例#2
0
        public void Load(DomNode data, string fileName)
        {
            SpriteLibrary.FramesetData        framesetData;
            SpriteLibrary.FrameData           frameData, quadFrameData;
            List <SpriteLibrary.FrameData>    framesData    = new List <SpriteLibrary.FrameData>();
            List <SpriteLibrary.FramesetData> framesetsData = new List <SpriteLibrary.FramesetData>();
            List <QuadSorter.Quad>            quads         = new List <QuadSorter.Quad>();

            QuadSorter.Quad             quad;
            int                         frameIndex = 0, framesetIndex, width, height;
            Dictionary <string, Bitmap> bitmaps = new Dictionary <string, Bitmap>();
            string                      bitmapPath;
            Bitmap                      bitmap;
            BitmapFile                  bitmapFile;
            Texture                     texture;
            float                       quadWidth, quadHeight;
            bool                        quadFound;

            // load xml and related bitmaps
            foreach (DomNode node in data)
            {
                if (!node.Name.Equals("frameset", StringComparison.OrdinalIgnoreCase))
                {
                    GameDebugger.Log(LogLevel.Notice, "Skipping node '{0}' since 'frameset' is expected", node.Name);
                    continue;
                }
                framesetData = new SpriteLibrary.FramesetData();

                if (node.Attributes["id"].Equals(""))
                {
                    throw new UserFriendlyException("Cannot load sprite library since one or more framesets have no 'id' attribute.", "There are errors in game data files.");
                }
                framesetData.Id = node.Attributes["id"];

                bitmapPath = null;
                if (!node.Attributes["imgRel"].Equals(""))
                {
                    bitmapPath = node.Attributes["imgRel"].RelativeTo(fileName);
                }
                else if (!node.Attributes["img"].Equals(""))
                {
                    bitmapPath = node.Attributes["img"].ToPath();
                }
                if (bitmapPath != null)
                {
                    if (!bitmaps.TryGetValue(bitmapPath, out bitmap))
                    {
                        bitmapFile = GameFile.LoadFile <BitmapFile>(bitmapPath);
                        bitmap     = bitmapFile.Bitmap;
                        bitmaps.Add(bitmapPath, bitmap);
                    }
                    framesetData.Bitmap = bitmap;
                }

                foreach (DomNode child in node)
                {
                    if (!child.Name.Equals("frame", StringComparison.OrdinalIgnoreCase))
                    {
                        GameDebugger.Log(LogLevel.Notice, "Skipping node '{0}' since 'frame' is expected", child.Name);
                        continue;
                    }
                    frameData = new SpriteLibrary.FrameData();

                    bitmapPath = null;
                    if (!child.Attributes["imgRel"].Equals(""))
                    {
                        bitmapPath = child.Attributes["imgRel"].RelativeTo(fileName);
                    }
                    else if (!child.Attributes["img"].Equals(""))
                    {
                        bitmapPath = child.Attributes["img"].ToPath();
                    }
                    if (bitmapPath != null)
                    {
                        if (!bitmaps.TryGetValue(bitmapPath, out bitmap))
                        {
                            bitmapFile = GameFile.LoadFile <BitmapFile>(bitmapPath);
                            bitmap     = bitmapFile.Bitmap;
                            bitmaps.Add(bitmapPath, bitmap);
                        }
                        frameData.Bitmap = bitmap;
                    }
                    else
                    {
                        if (framesetData.Bitmap == null)
                        {
                            throw new UserFriendlyException("Cannot load sprite library since one or more frames have no 'img' attribute.", "There are errors in game data files.");
                        }
                        frameData.Bitmap = framesetData.Bitmap;
                    }

                    if (!child.Attributes["id"].Equals(""))
                    {
                        frameData.Id = child.Attributes["id"];
                    }
                    if (!child.Attributes["x"].Equals(""))
                    {
                        frameData.X = int.Parse(child.Attributes["x"]);
                    }
                    if (!child.Attributes["y"].Equals(""))
                    {
                        frameData.Y = int.Parse(child.Attributes["y"]);
                    }
                    if (!child.Attributes["u"].Equals(""))
                    {
                        frameData.U = int.Parse(child.Attributes["u"]);
                    }
                    if (!child.Attributes["v"].Equals(""))
                    {
                        frameData.V = int.Parse(child.Attributes["v"]);
                    }
                    if (!child.Attributes["width"].Equals(""))
                    {
                        frameData.Width = int.Parse(child.Attributes["width"]);
                    }
                    if (!child.Attributes["height"].Equals(""))
                    {
                        frameData.Height = int.Parse(child.Attributes["height"]);
                    }
                    if (!child.Attributes["duration"].Equals(""))
                    {
                        frameData.Duration = child.Attributes["duration"].ToDouble(0.1);
                    }
                    if (!child.Attributes["next"].Equals(""))
                    {
                        frameData.NextFrame = child.Attributes["next"].ToInt32(0);
                    }
                    if (!child.Attributes["event"].Equals(""))
                    {
                        frameData.Event = child.Attributes["event"];
                    }

                    if (frameData.Width <= 0)
                    {
                        frameData.Width = frameData.Bitmap.Width;
                    }
                    if (frameData.Height <= 0)
                    {
                        frameData.Height = frameData.Bitmap.Height;
                    }

                    framesetData.Frames.Add(frameData);
                    framesData.Add(frameData);

                    quadWidth  = (float)(frameData.Width + 2);                    // 2 is the padding of 1 px from every side
                    quadHeight = (float)(frameData.Height + 2);
                    quadFound  = false;

                    // we need only unique pictures so we will check every quad already added
                    foreach (QuadSorter.Quad q in quads)
                    {
                        if (q.Width == quadWidth && q.Height == quadHeight)
                        {
                            quadFrameData = ((List <SpriteLibrary.FrameData>)q.Data)[0];
                            if (quadFrameData.Bitmap == frameData.Bitmap && quadFrameData.U == frameData.U && quadFrameData.V == frameData.V)
                            {
                                // same width, height, u, v and bitmap ... this frame is not the first to use that graphic
                                ((List <SpriteLibrary.FrameData>)q.Data).Add(frameData);
                                quadFound = true;
                                break;
                            }
                        }
                    }
                    if (!quadFound)
                    {
                        quad      = new QuadSorter.Quad();
                        quad.Data = new List <SpriteLibrary.FrameData>();
                        ((List <SpriteLibrary.FrameData>)quad.Data).Add(frameData);
                        quad.Width  = quadWidth;
                        quad.Height = quadHeight;
                        quads.Add(quad);
                    }
                }
                framesetsData.Add(framesetData);
            }

            // sort and build containers
            QuadSorter sorter = new QuadSorter(quads, 256f, 256f);

            // create textures
            frameIndex = 0;
            foreach (QuadSorter.QuadContainer container in sorter.Containers)
            {
                width         = Texture.ConvertToSuitableDimension((int)container.Width);
                height        = Texture.ConvertToSuitableDimension((int)container.Height);
                bitmap        = new Bitmap(width, height, 4);
                bitmap.Format = BitmapFormat.BGRA;
                foreach (QuadSorter.Quad q in container.Quads)
                {
                    frameData = ((List <SpriteLibrary.FrameData>)q.Data)[0];
                    bitmap.CopyPixels(frameData.Bitmap, (int)q.X + 1, (int)q.Y + 1, frameData.U, frameData.V, frameData.Width, frameData.Height);
                }

                /*
                 * // Uncomment this block if the sprite managing algorithm needs debugging
                 * bitmapFile = new BitmapFile();
                 * bitmapFile.Bitmap = bitmap;
                 * bitmapFile.Save(String.Format("test/spltex-{0}.png", frameIndex++));
                 */

                texture = new Texture(bitmap.Width, bitmap.Height, bitmap.Pixels, TextureMinFilter.Nearest, TextureMagFilter.Nearest);
                Textures.Add(texture);

                foreach (QuadSorter.Quad q in container.Quads)
                {
                    foreach (FrameData fd in (List <FrameData>)q.Data)
                    {
                        fd.Frame = new SpriteFrame(fd.Id, new Image(texture, (int)q.X + 1, (int)q.Y + 1, fd.Width, fd.Height, fd.X, fd.Y), fd.Duration, fd.NextFrame, fd.Event);
                    }
                }
            }

            framesetIndex = 0;
            foreach (FramesetData fsdata in framesetsData)
            {
                List <SpriteFrame> frames = new List <SpriteFrame>();
                frameIndex = 0;
                foreach (FrameData fdata in fsdata.Frames)
                {
                    fdata.Frame.Index = frameIndex++;
                    frames.Add(fdata.Frame);
                }
                SpriteFrameset frameset = new SpriteFrameset(fsdata.Id, frames);
                frameset.Index = framesetIndex++;
                Framesets.Add(frameset.Id, frameset);
            }
        }