123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341 |
- {
- * Copyright (c) 2012 Andrey Kemka
- *
- * This software is provided 'as-is', without any express or
- * implied warranty. In no event will the authors be held
- * liable for any damages arising from the use of this software.
- *
- * Permission is granted to anyone to use this software for any purpose,
- * including commercial applications, and to alter it and redistribute
- * it freely, subject to the following restrictions:
- *
- * 1. The origin of this software must not be misrepresented;
- * you must not claim that you wrote the original software.
- * If you use this software in a product, an acknowledgment
- * in the product documentation would be appreciated but
- * is not required.
- *
- * 2. Altered source versions must be plainly marked as such,
- * and must not be misrepresented as being the original software.
- *
- * 3. This notice may not be removed or altered from any
- * source distribution.
- }
- unit zglSpriteEngine;
- {$I zglCustomConfig.cfg}
- {$IFDEF FPC}
- {$MODE DELPHI}
- {$ENDIF}
- interface
- uses
- {$IFDEF USE_ZENGL_STATIC}
- zgl_main,
- zgl_fx,
- zgl_sprite_2d,
- zgl_textures
- {$ELSE}
- zglHeader
- {$ENDIF}
- ;
- type
- zglCSprite2D = class;
- zglCSEngine2D = class;
- zglCSEngine2D = class
- protected
- FCount : Integer;
- FList : array of zglCSprite2D;
- procedure SortByLayer( iLo, iHi : Integer );
- procedure SortByID( iLo, iHi : Integer );
- function GetSprite( ID : Integer ) : zglCSprite2D;
- procedure SetSprite( ID : Integer; Sprite : zglCSprite2D );
- public
- destructor Destroy; override;
- function AddSprite : Integer; overload; virtual;
- function AddSprite( Texture : zglPTexture; Layer : Integer ) : zglCSprite2D; overload; virtual;
- procedure AddSprite( Sprite : zglCSprite2D; Layer : Integer ); overload; virtual;
- procedure DelSprite( ID : Integer ); virtual;
- procedure ClearAll; virtual;
- procedure Draw; virtual;
- procedure Proc; virtual;
- property Count: Integer read FCount;
- property List[ID : Integer]: zglCSprite2D read GetSprite write SetSprite;
- end;
- zglCSprite2D = class
- protected
- public
- ID : Integer;
- Manager : zglCSEngine2D;
- Texture : zglPTexture;
- Kill : Boolean;
- Layer : Integer;
- X, Y : Single;
- W, H : Single;
- Angle : Single;
- Frame : Single;
- Alpha : Integer;
- FxFlags : LongWord;
- constructor Create( _Manager : zglCSEngine2D; _ID : Integer ); virtual;
- destructor Destroy; override;
- procedure OnInit( _Texture : zglPTexture; _Layer : Integer ); virtual;
- procedure OnDraw; virtual;
- procedure OnProc; virtual;
- procedure OnFree; virtual;
- end;
- implementation
- destructor zglCSEngine2D.Destroy;
- begin
- ClearAll();
- end;
- procedure zglCSEngine2D.SortByLayer( iLo, iHi : Integer );
- var
- lo, hi, mid : Integer;
- t : zglCSprite2D;
- begin
- lo := iLo;
- hi := iHi;
- mid := FList[ ( lo + hi ) shr 1 ].Layer;
- repeat
- while FList[ lo ].Layer < mid do INC( lo );
- while FList[ hi ].Layer > mid do DEC( hi );
- if lo <= hi then
- begin
- t := FList[ lo ];
- FList[ lo ] := FList[ hi ];
- FList[ hi ] := t;
- INC( lo );
- DEC( hi );
- end;
- until lo > hi;
- if hi > iLo Then SortByLayer( iLo, hi );
- if lo < iHi Then SortByLayer( lo, iHi );
- end;
- procedure zglCSEngine2D.SortByID( iLo, iHi : Integer );
- var
- lo, hi, mid : Integer;
- t : zglCSprite2D;
- begin
- lo := iLo;
- hi := iHi;
- mid := FList[ ( lo + hi ) shr 1 ].ID;
- repeat
- while FList[ lo ].ID < mid do INC( lo );
- while FList[ hi ].ID > mid do DEC( hi );
- if Lo <= Hi then
- begin
- t := FList[ lo ];
- FList[ lo ] := FList[ hi ];
- FList[ hi ] := t;
- INC( lo );
- DEC( hi );
- end;
- until lo > hi;
- if hi > iLo Then SortByID( iLo, hi );
- if lo < iHi Then SortByID( lo, iHi );
- end;
- function zglCSEngine2D.GetSprite( ID : Integer ) : zglCSprite2D;
- begin
- Result := FList[ ID ];
- end;
- procedure zglCSEngine2D.SetSprite( ID : Integer; Sprite : zglCSprite2D );
- begin
- FList[ ID ] := Sprite;
- end;
- function zglCSEngine2D.AddSprite : Integer;
- begin
- if FCount + 1 > Length( FList ) Then
- SetLength( FList, FCount + 16384 );
- Result := FCount;
- INC( FCount );
- end;
- function zglCSEngine2D.AddSprite( Texture : zglPTexture; Layer : Integer ) : zglCSprite2D;
- var
- id : Integer;
- begin
- id := AddSprite();
- FList[ id ] := zglCSprite2D.Create( Self, id );
- Result := FList[ id ];
- Result.OnInit( Texture, Layer );
- end;
- procedure zglCSEngine2D.AddSprite( Sprite : zglCSprite2D; Layer : Integer );
- var
- id : Integer;
- begin
- if not Assigned( Sprite ) Then exit;
- id := AddSprite();
- FList[ id ] := Sprite;
- FList[ id ].Manager := Self;
- FList[ id ].ID := id;
- FList[ id ].OnInit( Sprite.Texture, Layer );
- end;
- procedure zglCSEngine2D.DelSprite( ID : Integer );
- var
- i : Integer;
- begin
- if ( ID < 0 ) or ( ID > FCount - 1 ) or ( FCount = 0 ) Then exit;
- FList[ ID ].Free;
- for i := ID to FCount - 2 do
- begin
- FList[ i ] := FList[ i + 1 ];
- FList[ i ].ID := i;
- end;
- DEC( FCount );
- end;
- procedure zglCSEngine2D.ClearAll;
- var
- i : Integer;
- begin
- for i := 0 to FCount - 1 do
- FList[ i ].Destroy();
- SetLength( FList, 0 );
- FCount := 0;
- end;
- procedure zglCSEngine2D.Draw;
- var
- i : Integer;
- s : zglCSprite2D;
- begin
- i := 0;
- while i < FCount do
- begin
- s := FList[ i ];
- s.OnDraw();
- if s.Kill Then
- DelSprite( s.ID )
- else
- INC( i );
- end;
- end;
- procedure zglCSEngine2D.Proc;
- var
- i, a, b, l : Integer;
- s : zglCSprite2D;
- begin
- i := 0;
- while i < FCount do
- begin
- s := FList[ i ];
- s.OnProc();
- if s.Kill Then
- DelSprite( s.ID )
- else
- INC( i );
- end;
- if FCount > 1 Then
- begin
- l := 0;
- for i := 0 to FCount - 1 do
- begin
- s := FList[ i ];
- if s.Layer > l Then l := s.Layer;
- if s.Layer < l Then
- begin
- SortByLayer( 0, FCount - 1 );
- // TODO: provide parameter for enabling/disabling stable sorting
- l := FList[ 0 ].Layer;
- a := 0;
- for b := 0 to FCount - 1 do
- begin
- s := FList[ b ];
- if ( l <> s.Layer ) Then
- begin
- SortByID( a, b - 1 );
- a := b;
- l := s.Layer;
- end;
- if b = FCount - 1 Then
- SortByID( a, b );
- end;
- for a := 0 to FCount - 1 do
- FList[ a ].ID := a;
- break;
- end;
- end;
- end;
- end;
- constructor zglCSprite2D.Create( _Manager : zglCSEngine2D; _ID : Integer );
- begin
- Manager := _Manager;
- ID := _ID;
- OnInit( nil, 0 );
- end;
- destructor zglCSprite2D.Destroy;
- begin
- OnFree();
- end;
- procedure zglCSprite2D.OnInit( _Texture : zglPTexture; _Layer : Integer );
- begin
- Texture := _Texture;
- Layer := _Layer;
- X := 0;
- Y := 0;
- if Assigned( Texture ) Then
- begin
- W := Round( ( Texture.FramesCoord[ 1, 1 ].X - Texture.FramesCoord[ 1, 0 ].X ) * Texture.Width );
- H := Round( ( Texture.FramesCoord[ 1, 0 ].Y - Texture.FramesCoord[ 1, 2 ].Y ) * Texture.Height );
- end else
- begin
- W := 0;
- H := 0;
- end;
- Angle := 0;
- Frame := 1;
- Alpha := 255;
- FxFlags := FX_BLEND;
- end;
- procedure zglCSprite2D.OnDraw;
- begin
- asprite2d_Draw( Texture, X, Y, W, H, Angle, Round( Frame ), Alpha, FxFlags );
- end;
- procedure zglCSprite2D.OnProc;
- begin
- end;
- procedure zglCSprite2D.OnFree;
- begin
- end;
- end.
|