Game Development Community

Saving your CompositeSprites using Taml

by Lukas Joergensen · in Torque 2D Professional · 05/27/2014 (2:21 am) · 3 replies

Hey guys! I just started using T2D yesterday, and wanted to share the technique I've been using for persisting my levels (which are stored in CompositeSprites).

I've created a new "Persistence" module, which handles the loading and saving of levels.
I have a "LevelFillBehavior" which you just add to the CompositeSprite and then it can be saved and loaded.
if (!isObject(LevelFillBehavior))
{
   %template = new BehaviorTemplate(LevelFillBehavior);
   %template.addBehaviorField(GridSize, "The size of the board", int, 15);
   %template.addBehaviorField(LevelFile, "The level file", "default", "default.level.taml");
}

//-----------------------------------------------------------------------------

function LevelFillBehavior::onBehaviorAdd(%this)
{
   %this.Load();
}

function LevelFillBehavior::Save(%this)
{
   %Level = new SimGroup() {
      Size = %this.GridSize;
      Default = BlueCrystal;
   };
   %Positions = new SimGroup();
   %Level.add(%Positions);
   for(%x = 0; %x < %this.GridSize; %x++)
   {
      for(%y = 0; %y < %this.GridSize; %y++)
      {
         %point = new SimObject();
         %point.Position = %x SPC %y;
         %this.owner.SelectSprite(%point.Position);
         %image = %this.owner.getSpriteImage();
         %frame = %this.owner.getSpriteImageFrame();
         %found = false;
         for(%i = 0; %i < Tiles.getCount(); %i++)
         {
            %type = Tiles.getObject(%i);
            if(%type.Image $= %image
               && %type.Frame $= %frame)
               {
                  %point.Type = %type.getName();
                  %found = true;
                  break;
               }
         }
         if(!%found)
         {
            %point.Type = %Level.Default;
         }
         %Positions.add(%point);
      }
   }
   TamlWrite(%Level, %this.LevelFile);
}

function LevelFillBehavior::Load(%this)
{
   if(!isFile(%this.LevelFile))
    return;
   %level = TamlRead(%this.LevelFile);
   
   // Iterate over all the sprites
   for(%x = 0; %x < %level.Size; %x++)
   {
      for(%y = 0; %y < %level.Size; %y++)
      {
         // Pick a random number from 0 to 5.
         //  This will equal the frame number from the ImageAsset.
         %Tile = %level.getObject(0).getObject((%x*%level.Size)+%y);
         
         // Add a sprite (aka "tile")
         %this.owner.addSprite(%Tile.Position);
         
         // Assign it an ImageAsset and a random frame
         %this.owner.setSpriteImage(%Tile.Type.Image, %Tile.Type.Frame);
      }
   }
}

Notice how it saves the sprites as objects from the "Tiles" groups, which is a Taml file that I have written like this:
<SimGroup
   Name="Tiles" >
   <ScriptObject
      Name="BlueCrystalTile"
      Image="ToyAssets:TD_Crystal_blueSprite"
      Frame="0" />
</SimGroup>

Which allows me to easily maintain a list of available tiles.

To save the composite sprite you simply run the method:
TileBoard.getBehavior(LevelFillBehavior).save();

The result is a file that looks like this:
<SimGroup
    Default="BlueCrystal"
    Size="15">
    <SimGroup>
        <SimObject
            Position="0 0"
            Type="RedCrystalTile" />
    </SimGroup>
</SimGroup>

#1
05/27/2014 (4:35 am)
There's probably some pretty cool uses for your system but I can't help but wonder, why not use TamlWrite(MyCompositeSprite, %this.filename); and TamlRead(%this.filename);?
#2
05/27/2014 (6:19 am)
@Simon originally because I wanted to compile the list of Tiles into the file as well. I seperated it, but decided to keep it this way for future customization purposes (like setting specific settings on individual sprites like "blocking")

Using TamlWrite would only preserve the sprites themselves.
Granted for the above use case it doesn't make much sense :P
#3
05/27/2014 (7:00 am)
Thanks for the clarification! Makes sense