Load scml-File with SpriterDotNet for MonoGame 3.8

Hi,

i want to load a scml-file created with Spriter. I use monogame 3.8 and it will be no problem to don’t use the conten-pipline for this, but i don’t know how to do it.

Has anyone done this and can trigger me to the right way to do?

Best regards,
Volker

I’ve never worked with Spriter or the scml file format, but they seem to have full documention on the file spec including pseudo code at ScmlReference

Since it looks like the scml file is just XML you could look into deserializing it using the System.Xml namespace stuff

1 Like

Thank you! I will have a look at it.

I got it working. For all who maybe need this here is a quick info of what i did:

  • declare all things we need:
    private readonly List animators = new List();
    private MonoGameAnimator animator;
    public static readonly Config SpriterConfig = new Config
    {
    MetadataEnabled = true,
    EventsEnabled = true,
    PoolingEnabled = true,
    TagsEnabled = true,
    VarsEnabled = true,
    SoundsEnabled = false
    };
    Spriter spriter;

  • in LoadContent():
    var sdata = File.ReadAllText(“Content/GreyGuy/player.scml”);
    var rootFolder = “GreyGuy”;

          spriter = SpriterReader.Default.Read(sdata);
          
          DefaultProviderFactory<ISprite, SoundEffect> factory = new DefaultProviderFactory<ISprite, SoundEffect>(SpriterConfig, true);
          if (spriter != null)
          {
              foreach(SpriterFolder folder in spriter.Folders) 
              {
                  if (spriter.Atlases != null && spriter.Atlases.Length > 0)
                  {
                      // AddAtlasFolder(folder, factory, spriter);  // I don't use SpriteAtlas so you have to write your own function here
                  }
                  else
                  {
                      AddRegularFolder(folder, rootFolder, factory, spriter);
                  }
              }
          }           
          
    
          Stack<SpriteDrawInfo> drawInfoPool = new Stack<SpriteDrawInfo>();
    
          foreach (SpriterEntity entity in spriter.Entities)
          {
              var animator = new MonoGameAnimator(entity, factory, drawInfoPool);
              animators.Add(animator);
              animator.Position = new Vector2(100, 400);
          }
    
          animator = animators.First();
          animator.Play("walk");
          animator.Position = new Vector2(400, 400);
    
  • The AddRegularFolder()-function:
    private void AddRegularFolder(SpriterFolder folder, string rootFolder, DefaultProviderFactory<ISprite, SoundEffect> factory, Spriter spriter)
    {
    contentHelper = new ContentHelper(GraphicsDevice, Content);
    contentHelper.OpenZipArchive();

          foreach (SpriterFile file in folder.Files)
          {
              if (file.Type == SpriterFileType.Sound)
              {
                  string path = rootFolder + "/" + file.Name;
                  SoundEffect sound = contentHelper.LoadSoundFX(path);
                  factory.SetSound(spriter, folder, file, sound);
              }
              else
              {
                  string path = rootFolder + "/" + file.Name.Replace(".png", ".p4");
                  Texture2D texture = contentHelper.loadTexture2D(path);
                  TextureSprite sprite = new TextureSprite(texture);
                  file.Name = file.Name.Substring(0, file.Name.LastIndexOf(".") - 1);
                  factory.SetSprite(spriter, folder, file, sprite);
              }
          }
    
          contentHelper.CloseZipArchive();
      }
    

As i use my own content-pipe based on a zip-file, i have to include it here, so the contentHelper is my own solution, you have to put yours into here.

  • Update()
    float deltaTime = gameTime.ElapsedGameTime.Ticks / (float)TimeSpan.TicksPerMillisecond;
    animator.Update(deltaTime);

  • Draw()
    _spriteBatch.Begin(SpriteSortMode.BackToFront);
    animator.Draw(_spriteBatch);
    _spriteBatch.End();

Best regards
Volker

2 Likes