
Hey, I am starting to play around with Sprite Stacking in AGS. Has someone ever done this here?
Sliced.ash
// new module header
#define MAX_SLICED_OBJECTS 32
#define MAX_OVERLAYS 2048
#define OVERLAYS_STEP 32
managed struct SlicedObject {
import void Set(float x, float y, float z, int graphic_first_slice, int graphic_last_slice);
import static SlicedObject* Create(float x, float y, float z, int graphic_first_slice, int graphic_last_slice); // $AUTOCOMPLETEIGNORESTATIC$
writeprotected int GraphicFirstSlice, GraphicLastSlice, SliceRange, SliceWidth, SliceHeight;
writeprotected float X, Y, Z;
};
struct SlicedWorld{
import void AddSlicedObject(int x, int y, int z, int graphic_first_slice, int graphic_last_slice);
import void Render(float angle_radians = 0.0);
protected SlicedObject* SlicedObjects[MAX_SLICED_OBJECTS];
protected int ObjectCount;
protected Overlay* Overlays[MAX_OVERLAYS];
};
Sliced.asc
// new module script
// -- SLICED OBJECT --
void SlicedObject::Set(float x, float y, float z, int graphic_first_slice, int graphic_last_slice)
{
this.X = x;
this.Y = y;
this.Z = z;
this.GraphicFirstSlice = graphic_first_slice;
this.GraphicLastSlice = graphic_last_slice;
this.SliceRange = graphic_last_slice - graphic_first_slice;
this.SliceWidth = Game.SpriteWidth[graphic_first_slice];
this.SliceHeight = Game.SpriteHeight[graphic_first_slice];
}
static SlicedObject* SlicedObject::Create(float x, float y, float z, int graphic_first_slice, int graphic_last_slice)
{
SlicedObject* sobj = new SlicedObject;
sobj.Set(x, y, z, graphic_first_slice, graphic_last_slice);
return sobj;
}
// -- SLICED WORLD --
void SlicedWorld::AddSlicedObject(int x, int y, int z, int graphic_first_slice, int graphic_last_slice)
{
SlicedObject* sobj = SlicedObject.Create(IntToFloat(x), IntToFloat(y), IntToFloat(z), graphic_first_slice, graphic_last_slice);
this.SlicedObjects[this.ObjectCount] = sobj;
this.ObjectCount++;
}
void SlicedWorld::Render(float angle_radians)
{
float pre_cos = Maths.Cos(angle_radians);
float pre_sin = - Maths.Sin(angle_radians);
for(int i=0; i<this.ObjectCount; i++)
{
SlicedObject* sobj = this.SlicedObjects[i];
int overlay_id_start = i*OVERLAYS_STEP;
int slice_range = sobj.SliceRange;
for(int j=0; j<slice_range; j++) {
int overlay_id = overlay_id_start + j;
if(this.Overlays[overlay_id] == null || !this.Overlays[overlay_id].Valid) {
this.Overlays[overlay_id] = Overlay.CreateRoomGraphical(0, 0, sobj.GraphicFirstSlice + j);
}
Overlay* ovr = this.Overlays[overlay_id];
float dist = IntToFloat(j) + sobj.Z;
float lx = dist * pre_cos;
float ly = dist * pre_sin;
ovr.X = FloatToInt(sobj.X - lx);
ovr.Y = FloatToInt(sobj.Y - ly);
ovr.Rotation = Maths.RadiansToDegrees(angle_radians);
}
}
}
Usage code
#define SPR_BARREL 1
#define SPR_BARREL_LAST 8
#define SPR_CHAIR 9
#define SPR_CHAIR_LAST 19
#define SPR_CHEST 20
#define SPR_CHEST_LAST 30
SlicedWorld sWorld;
function room_AfterFadeIn()
{
}
function room_Load()
{
sWorld.AddSlicedObject(32, 32, 0, SPR_BARREL, SPR_BARREL_LAST);
sWorld.AddSlicedObject(64, 32, 0, SPR_BARREL, SPR_BARREL_LAST);
sWorld.AddSlicedObject(64, 96, 0, SPR_CHAIR, SPR_CHAIR_LAST);
sWorld.AddSlicedObject(128, 96, 0, SPR_CHAIR, SPR_CHAIR_LAST);
sWorld.AddSlicedObject(200, 48, 0, SPR_CHEST, SPR_CHEST_LAST);
sWorld.AddSlicedObject(230, 48, 0, SPR_CHEST, SPR_CHEST_LAST);
sWorld.AddSlicedObject(160, 96, 0, SPR_CHEST, SPR_CHEST_LAST);
sWorld.AddSlicedObject(32, 111, 0, SPR_CHEST, SPR_CHEST_LAST);
}
float angl;
function room_RepExec()
{
angl += 0.0125;
sWorld.Render(angl);
}
So far my code and usage is like so, but I am not sure on this design. Any ideas?
(link to above project zip file to download)