home *** CD-ROM | disk | FTP | other *** search
- unit MChSprt;
-
- {
- Real Time Scaleable Sprites
- Components
- for
- Borland Delphi
-
- Copyright 1995 by
- Marek A. Chmielowski
- All rights reserved
-
- These components and source code is released to the public domain under the condition
- that it will not be used for commercial or "For Profit" ventures.
- This code can be copied, used, and distributed freely providing that it is NOT
- modified, no fee is charged, and it is not used in a package for which a charge
- is made.
-
- Please do NOT distribute components or source code if you altered them -
- EVEN IF THIS IS ONLY BUG CORRECTION.
- Let me know about the problem and the solution and I will implement it in the
- next version (may be it will be the next version).
- My e-mail:
- 76360,2775@compuserve.com
-
- If you would like to use this component for shareware or commercial application
- please contact me first by mail:
-
- Marek Chmielowski
- 5/56 Kozia St.
- Warsaw 00-070
- Poland
- or
-
- Marek Chmielowski
- 10005 Broad St.
- Bethesda, MD 20814
- USA
-
-
- }
-
- interface
-
- uses
- SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls,
- Forms, Dialogs, ExtCtrls, Buttons, StdCtrls, MChSpBg;
-
- type
- TMChSprite = class;
-
- TSprPosFunc = function(AtTime: TDateTime):TPoint;
- TSprOnBorder = procedure(AtTime: TDateTime);
- TSprOnCollide = procedure(SprCollided: TMChSprite; AtTime: TDateTime);
- TSprNoCollide = procedure(AtTime: TDateTime);
-
- TMChSprite = class(TGraphicControl)
- { Public declarations or Published if $M+ }
- private
- { Private declarations }
- PSpriteMgr: TMChSpriteBgr;
- FSprMgrSet: Boolean;
- FSprBitmapOrig: TBitmap;
- FSprTrColor: TColor;
- FSprBitmap, FSprMask: TBitmap;
- FSprBitSet: Boolean;
- FSprSet: Boolean;
- FSprOnCanvas: Boolean;
- FSprInBuf: Boolean;
- FSprToShow: Boolean;
- FSprRepaint: Boolean;
- FSprRunning: Boolean;
- FSprPaused: Boolean;
- FSprCruise: Boolean;
- FSprFrom: TPoint;
- FSprDest: TPoint;
- FSprNextPos: TPoint;
- FSprMoved: Boolean;
- FSprCurrentRect: TRect;
- FSprDirty: TDirtyReg;
- FSprTimeToRun: TDateTime;
- FSprHideAfter: Boolean;
- FSprTimeRunning: TDateTime;
- FSprTimeStarted: TDateTime;
- FSprTimeUpdated: TDateTime;
- FSprMoveVect: TPoint;
- FSprPosFunc: TSprPosFunc;
- FSprIndex: Cardinal;
- FSprDragable: Boolean;
- FSprScaleX: double;
- FSprScaleY: double;
- FSprRescale: Boolean;
- FSprRefX: Integer;
- FSprRefY: Integer;
- FSprColliding: Boolean;
- FSprCollisionMask: Boolean;
- FSprRadiusX: Integer;
- FSprRadiusY: Integer;
- FSprGuessBgr: Boolean;
- procedure SprSetBitmap(Bitmap: TBitmap; trColor: TColor);
- procedure SprMakeMask(trColor: TColor);
- procedure SprReplTrCl(trColor: TColor);
- function SprMakeVect(From, Dest: TPoint):TPoint;
- procedure SprGuessSpriteMgr;
- procedure SprFreeNotOrig;
- protected
- { Protected declarations }
- procedure SprFree;
- public
- { Public declarations }
- FSprOnCollide: TSprOnCollide;
- FSprOnBorder: TSprOnBorder;
- FSprNoCollide: TSprNoCollide;
- constructor Create(AOwner: TComponent); override;
- destructor Destroy; override;
- procedure SprInit;
- procedure SprSetMgr(BgrMgr: TMChSpriteBgr);
- procedure SprUnSetMgr;
- procedure SprSetBitmapOrig(Bitm: TBitmap);
- procedure SprRenewBitmap;
- procedure SprSetTrColor(trColor: TColor);
- procedure SprShowAt(Dest: TPoint);
- procedure SprShowPaused(Dest: TPoint);
- procedure SprShowAtTime(JTime: TDateTime);
- procedure SprShowOn;
- procedure SprHide;
- procedure SprHideTmp;
- procedure SprStop;
- function SprDesiredPos(AtTime: TDateTime):TPoint;
- procedure SprGoTo(Dest: TPoint; TimeToRunSec: TDateTime);
- procedure SprGo(From, Dest: TPoint; TimeToRunSec: TDateTime);
- procedure SprRun(From,Dest: TPoint; TimeToRunSec: TDateTime);
- procedure SprCruise(TimeToRunSec: TDateTime);
- procedure SprMoveTo(Dest: TPoint);
- function SprGetDirty: TDirtyReg;
- function SprGetDirtyAndClear: TDirtyReg;
- function SprHitTest(ScrP: TPoint): Boolean;
- function SprHitAt(ScrP: TPoint): TPoint;
- procedure SprSetScale(NewScale: double);
- procedure SprSetScaleX(NewScaleX: double);
- procedure SprSetScaleY(NewScaleY: double);
- procedure SprSetRef(NewRef: TPoint);
- procedure SprSetRefX(NewRefX: Integer);
- procedure SprSetRefY(NewRefY: Integer);
- function SprRefToLeftTop(ScrP: TPoint): TPoint;
- function SprLeftTopToRef(ScrP: TPoint): TPoint;
- function SprCheckCollision(TestSpr: TMChSprite; AtTime: TDateTime): Boolean;
- function SprCheckBorders(AtTime: TDateTime): Boolean;
- property SprPosFunc: TSprPosFunc read FSprPosFunc write FSprPosFunc;
- property SprMask: TBitmap read FSprMask;
- property SprBitmap: TBitmap read FSprBitmap;
- property SprFrom: TPoint read FSprFrom;
- property SprDest: TPoint read FSprDest;
- property SprNextPos: TPoint read FSprNextPos;
- property SprCurrentRect: TRect read FSprCurrentrect;
- property SprInBuf: Boolean read FSprInBuf;
- property SprOnCanvas: Boolean read FSprOnCanvas;
- property SprRepaint: Boolean read FSprRepaint write FSprRepaint;
- property SprIndex: Cardinal read FSprIndex write FSprIndex;
- property SprOnCollide: TSprOnCollide read FSprOnCollide write FSprOnCollide;
- property SprOnBorder: TSprOnBorder read FSprOnBorder write FSprOnBorder;
- property SprNoCollide: TSprNoCollide read FSprNoCollide write FSprNoCollide;
- property SprTimeUpdated: TDateTime read FSprTimeUpdated;
- property SprTimeStarted: TDateTime read FSprTimeStarted;
- property SprPaused: Boolean read FSprPaused write FSprPaused;
- property SprCollisionMask: Boolean read FSprCollisionMask write FSprCollisionMask;
- published
- { Published declarations - can be only class type or properties }
- property Visible;
- property Height default 1;
- property Width default 1;
- property Left;
- property Top;
- property SprSpriteBitmap: TBitmap read FSprBitmapOrig write SprSetBitmapOrig;
- property SprTrColor: TColor read FSprTrColor write SprSetTrColor;
- property SprHideAfter: Boolean read FSprHideAfter write FSprHideAfter default False;
- property SprScaleX: double read FSprScaleX write SprSetScaleX;
- property SprScaleY: double read FSprScaleY write SprSetScaleY;
- property SprRefX: Integer read FSprRefX write SprSetRefX;
- property SprRefY: Integer read FSprRefY write SprSetRefY;
- property SprColliding: Boolean read FSprColliding write FSprColliding;
- property SprRadiusX: Integer read FSprRadiusX write FSprRadiusX;
- property SprRadiusY: Integer read FSprRadiusY write FSprRadiusY;
- property SprGuessBgr: Boolean read FSprGuessBgr write FSprGuessBgr default False;
- property SprDragable: Boolean read FSprDragable write FSprDragable default False;
- end;
-
- procedure Register;
-
- implementation
-
- procedure Register;
- begin
- RegisterComponents('Samples', [TMChSprite]);
- end;
-
- constructor TMChSprite.Create(AOwner: TComponent);
- begin
- inherited Create(AOwner);
- Visible:=False;
- FSprBitmapOrig:=TBitmap.Create;
- FSprCurrentRect:=Rect(Left,Top,Left+Width,Top+Height);
- FSprTimeStarted:=time;
- FSprNextPos:=Point(Left,Top);
- FSprGuessBgr:=True;
- FSprScaleX:=1.0;
- FSprScaleY:=1.0;
- end;
-
- destructor TMChSprite.Destroy;
- begin
- SprFree;
- inherited Destroy;
- end;
-
- procedure TMChSprite.SprFreeNotOrig;
- begin
- try
- if FSprRunning then SprStop;
- if FSprOnCanvas then SprHide;
- FSprMask.Free;
- FSprBitmap.Free;
- finally
- FSprBitSet:=False;
- end;
- end;
-
- procedure TMChSprite.SprFree;
- begin
- SprFreeNotOrig;
- FSprBitmapOrig.Free;
- end;
-
- procedure TMChSprite.SprInit;
- begin
- if not FSprMgrSet then SprGuessSpriteMgr;
- if not FSprBitSet then SprRenewBitmap;
- FSprSet:=True;
- end;
-
- procedure TMChSprite.SprSetMgr(BgrMgr: TMChSpriteBgr);
- begin
- PSpriteMgr:=BgrMgr;
- FSprMgrSet:=True;
- SprInit;
- end;
-
- procedure TMChSprite.SprUnSetMgr;
- begin
- if FSprRunning then SprStop;
- SprHide;
- SprHideTmp;
- FSprDirty.Old:=FSprCurrentRect;
- FSprDirty.New:=NulRect;
- FSprOnCanvas:=False;
- PSpriteMgr.BgrUpdateDirtyReg(SprGetDirty);
- PSpriteMgr:=nil;
- FSprIndex:=0;
- FSprMgrSet:=False;
- FSprSet:=False;
- end;
-
- procedure TMChSprite.SprGuessSpriteMgr;
- var
- i: Cardinal;
- begin
- if not FSprGuessBgr then Exit;
- if Parent.ComponentCount>0 then
- begin
- for i:=0 to Parent.ComponentCount-1 do
- begin
- if Parent.Components[i] is TMChSpriteBgr then
- begin
- PSpriteMgr:=(Parent.Components[i] as TMChSpriteBgr);
- FSprMgrSet:=True;
- Break;
- end;
- end;
- end;
- end;
-
- procedure TMChSprite.SprMakeMask(trColor: TColor);
- var
- ColTestBitm1,ColTestBitm2: TBitmap;
- trColorInv: TColor;
- begin
- { Used to find result of xor for colors on actual bitmap }
- ColTestBitm1 := TBitmap.Create;
- ColTestBitm1.width := 1;
- ColTestBitm1.height:=1;
- ColTestBitm2 := TBitmap.Create;
- ColTestBitm2.width := 1;
- ColTestBitm2.height:=1;
- ColTestBitm1.Canvas.Pixels[0,0]:=trColor;
- ColTestBitm2.Canvas.CopyMode:=cmSrcInvert;
- ColTestBitm2.Canvas.Draw(0,0,ColTestBitm1);
- trColorInv:=ColTestBitm2.Canvas.Pixels[0,0];
- ColTestBitm1.free;
- ColTestBitm2.free;
- with SprMask.Canvas do
- begin
- { Does NOT work well due to color mapping }
- {Brush.Color:= ((trColor xor clWhite) and $00FFFFFF)
- or (trColor and $0F000000);}
- Brush.Color:= trColorInv;
- BrushCopy( Rect(0,0,SprMask.Width,SprMask.Height),
- FSprBitmap,
- Rect(0,0,FSprBitmap.Width,FSprBitmap.Height),
- trColor);
- CopyMode:=cmSrcInvert; { src xor Dest) }
- Draw(0,0,FSprBitmap);
- end;
- end;
-
- procedure TMChSprite.SprReplTrCl(trColor: TColor);
- begin
- with FSprBitmap.Canvas do
- begin
- CopyMode:=cmSrcCopy;
- Brush.Color:= clBlack;
- BrushCopy( Rect(0,0,FSprBitmap.Width,FSprBitmap.Height),
- FSprBitmap,
- Rect(0,0,FSprBitmap.Width,FSprBitmap.Height),
- trColor);
- end;
- end;
-
- procedure TMChSprite.SprSetBitmap(Bitmap: TBitmap; trColor: TColor);
- begin
- if not FSprMgrSet then SprGuessSpriteMgr;
- try
- SprFreeNotOrig;
- FSprTrColor:=trColor;
- if not Bitmap.Empty then
- begin
- Width :=Bitmap.Width;
- Height:=Bitmap.Height;
- FSprBitmap := TBitmap.Create;
- FSprMask := TBitmap.Create;
- FSprBitmap.Width := Bitmap.Width;
- FSprBitmap.Height := Bitmap.Height;
- FSprMask.Width := Bitmap.Width;
- FSprMask.Height := Bitmap.Height;
- FSprBitmap.Canvas.Draw(0,0,Bitmap);
- SprMakeMask(trColor);
- SprReplTrCl(trColor);
- FSprScaleX:=1.0;
- FSprScaleY:=1.0;
- FSprRefX:=Width div 2;
- FSprRefY:=Height div 2;
- FSprRadiusX:=Width div 2;
- FSprRadiusY:=Height div 2;
- FSprCurrentRect:=Rect(Left,Top,Left+Width,Top+Height);
- FSprNextPos:=Point(Left+round(FSprRefX*FSprScaleX),Top+round(FSprRefY*FSprScaleY));
- FSprBitSet:=True;
- end;
- except
- SprFreeNotOrig;
- end;
- end;
-
- procedure TMChSprite.SprSetTrColor(trColor: TColor);
- begin
- FSprTrColor:=trColor;
- SprRenewBitmap;
- end;
-
- procedure TMChSprite.SprRenewBitmap;
- begin
- SprSetBitmap(FSprBitmapOrig,FSprTrColor);
- end;
-
- procedure TMChSprite.SprSetBitmapOrig(Bitm: TBitmap);
- begin
- Width :=Bitm.Width;
- Height:=Bitm.Height;
- FSprBitmapOrig.Width := Bitm.Width;
- FSprBitmapOrig.Height := Bitm.Height;
- FSprBitmapOrig.Canvas.Draw(0,0,Bitm);
- SprRenewBitmap;
- end;
-
- procedure TMChSprite.SprHide;
- begin
- if FSprOnCanvas then
- begin
- FSprToShow:=False;
- end;
- end;
-
- procedure TMChSprite.SprHideTmp;
- begin
- if not FSprMgrSet then SprGuessSpriteMgr;
- if FSprInBuf then PSpriteMgr.BgrEraseBufRect(FSprCurrentRect);
- FSprInBuf:=False;
- end;
-
- procedure TMChSprite.SprStop;
- begin
- FSprCruise:=False;
- if FSprRunning then
- begin
- if FSprHideAfter then SprHide;
- FSprRunning:=False;
- end;
- end;
-
- function TMChSprite.SprGetDirty: TDirtyReg;
- begin
- SprGetDirty:=FSprDirty;
- end;
-
- function TMChSprite.SprGetDirtyAndClear: TDirtyReg;
- begin
- SprGetDirtyAndClear:=FSprDirty;
- FSprDirty.Old:=NulRect;
- FSprDirty.New:=NulRect;
- end;
-
- procedure TMChSprite.SprMoveTo(Dest: TPoint);
- begin
- FSprCruise:=False;
- if FSprRunning then SprStop;
- SprHide;
- FSprNextPos:=Dest;
- FSprTimeUpdated:=time;
- FSprMoved:=True;
- FSprTimeUpdated:=time;
- end;
-
- procedure TMChSprite.SprShowOn;
- begin
- if FSprMoved then SprShowAT(FSprNextPos)
- else SprShowAT(SprLeftTopToRef(Point(Left,Top)));
- end;
-
- procedure TMChSprite.SprShowAt(Dest: TPoint);
- begin
- FSprCruise:=False;
- if not FSprSet then SprInit;
- if FSprRunning then SprStop;
- FSprNextPos:=Dest;
- FSprMoved:=True;
- FSprToShow:=True;
- FSprTimeUpdated:=time;
- end;
-
-
- procedure TMChSprite.SprShowPaused(Dest: TPoint);
- begin
- if not FSprSet then SprInit;
- FSprNextPos:=Dest;
- FSprMoved:=True;
- FSprToShow:=True;
- FSprTimeUpdated:=time;
- end;
-
- procedure TMChSprite.SprShowAtTime(JTime: TDateTime);
- var
- RcOld: TRect;
- Stationary: Boolean;
- NewPos: TPoint;
- begin
- if not FSprSet then SprInit;
- if FSprToShow then
- begin
- RcOld:=FSprCurrentRect;
- FSprTimeRunning:=JTime-FSprTimeStarted;
- NewPos:= SprDesiredPos(JTime);
- if FSprMoved then FSprMoved:=False;
- if FSprOnCanvas and ((Left+SprRefX)=NewPos.x) and ((Top+SprRefY)=NewPos.y) and (not FSprRescale) then
- Stationary:=True
- else
- begin
- Stationary:=False;
- Left:=SprRefToLeftTop(NewPos).x;
- Top :=SprRefToLeftTop(NewPos).y;
- Width :=round(SprBitmap.Width *FSprScaleX);
- Height:=round(SprBitmap.Height*FSprScaleY);
- FSprCurrentRect:=Rect(Left,Top,Left+Width,Top+Height);
- FSprRescale:=False;
- FSprNextPos:=NewPos;
- FSprTimeUpdated:=JTime;
- end;
- {
- PSpriteMgr.BgrScreenBuf.Canvas.CopyMode:=cmSrcAnd;
- PSpriteMgr.BgrScreenBuf.Canvas.StretchDraw(FSprCurrentRect,FSprMask);
- PSpriteMgr.BgrScreenBuf.Canvas.CopyMode:=cmSrcPaint;
- PSpriteMgr.BgrScreenBuf.Canvas.StretchDraw(FSprCurrentRect,FSprBitmap);
- }
- PSpriteMgr.BgrScreenBufStretchMaskPaint(FSprCurrentRect,FSprMask,FSprBitmap);
- FSprInBuf:=True;
- if not Stationary then
- begin
- if FSprOnCanvas then FSprDirty.Old:=RcOld;
- FSprDirty.New:=FSprCurrentRect;
- end
- else if SprRepaint then FSprDirty.New:=FSprCurrentRect;
- FSprOnCanvas:=True;
- if FSprHideAfter and (FSprTimeToRun>0) and ((JTime-FSprTimeStarted)>FSprTimeToRun) then
- begin
- FSprToShow:=False;
- end;
- end
- else
- begin
- if FSprOnCanvas then
- begin
- FSprDirty.Old:=FSprCurrentRect;
- FSprDirty.New:=NulRect;
- FSprOnCanvas:=False;
- end
- else
- begin
- if FSprRunning and not FSprToShow then
- begin
- FSprTimeRunning:=JTime-FSprTimeStarted;
- NewPos:= SprDesiredPos(JTime);
- if FSprMoved then FSprMoved:=False;
- Left:=SprRefToLeftTop(NewPos).x;
- Top :=SprRefToLeftTop(NewPos).y;
- Width :=round(SprBitmap.Width *FSprScaleX);
- Height:=round(SprBitmap.Height*FSprScaleY);
- FSprCurrentRect:=Rect(Left,Top,Left+Width,Top+Height);
- FSprNextPos:=NewPos;
- FSprTimeUpdated:=JTime;
- end;
- end;
- end;
- end;
-
- procedure TMChSprite.SprGoTo(Dest: TPoint; TimeToRunSec: TDateTime);
- begin
- SprGo(SprLeftTopToRef(Point(Left,Top)),Dest,TimeToRunSec);
- end;
-
- procedure TMChSprite.SprGo(From, Dest: TPoint; TimeToRunSec: TDateTime);
- begin
- FSprCruise:=False;
- if not FSprSet then SprInit;
- if FSprRunning then SprStop;
- FSprFrom:=From;
- FSprDest:=Dest;
- FSprTimeToRun:=TimeToRunSec/60.0/60.0/24.0;
- FSprMoveVect:=SprMakeVect(FSprFrom,FSprDest);
- FSprTimeStarted:=time;
- FSprToShow:=True;
- FSprRunning := True;
- end;
-
- procedure TMChSprite.SprCruise(TimeToRunSec: TDateTime);
- begin
- if not FSprSet then SprInit;
- if FSprRunning then SprStop;
- FSprTimeToRun:=TimeToRunSec/60.0/60.0/24.0;
- FSprTimeStarted:=time;
- FSprCruise:=True;
- FSprToShow:=True;
- FSprRunning := True;
- end;
-
- procedure TMChSprite.SprRun(From,Dest: TPoint; TimeToRunSec: TDateTime);
- var
- SNew : TBitmap;
- RcOld,RcB: TRect;
- PosNew:TPoint;
- i:cardinal;
- Done: Boolean;
- WasOnCanvas: Boolean;
-
- begin
- if not FSprSet then SprInit;
- if FSprRunning then SprStop;
- WasOnCanvas:=FSprOnCanvas;
- if FSprOnCanvas then SprHide;
- if FSprOnCanvas or FSprInBuf then
- begin
- PSpriteMgr.BgrAppIdle(Self,Done);
- PSpriteMgr.BgrUpdateDirtyRegToCanvas(DirtyReg(NulRect,FSprCurrentRect));
- end;
- PSpriteMgr.BgrPause:=True;
- if (not FSprRunning) and (not FSprInBuf) and (not FSprOnCanvas) then
- begin
- SNew:=TBitmap.Create;
- SNew.Width:=Width;
- SNew.Height:=Height;
- SNew.Canvas.CopyMode:=cmSrcCopy;
- RcB:=Rect(0,0,Width,Height);
- FSprFrom:=From;
- FSprDest:=Dest;
- FSprTimeToRun:=TimeToRunSec/60.0/60.0/24.0;
- FSprMoveVect:=SprMakeVect(FSprFrom,FSprDest);
- Left:=SprRefToLeftTop(From).x;
- Top :=SprRefToLeftTop(From).y;
- FSprCurrentRect:=Rect(Left,Top,Left+Width,Top+Height);
- FSprNextPos:=From;
- FSprMoved:=False;
- FSprTimeStarted:=time;
- FSprRunning:=True;
- repeat
- RcOld:=FSprCurrentRect;
- FSprTimeRunning:=time-FSprTimeStarted;
- PosNew:=SprDesiredPos(time);
- if FSprMoved then FSprMoved:=False;
- Left:=SprRefToLeftTop(PosNew).x;
- Top :=SprRefToLeftTop(PosNew).y;
- FSprCurrentRect:=Rect(Left,Top,Left+Width,Top+Height);
- FSprNextPos:=PosNew;
- {SNew.Canvas.CopyRect(RcB,PSpriteMgr.BgrScreenBuf.Canvas,FSprCurrentRect);}
- PSpriteMgr.BgrScreenBufGetRect(RcB,SNew,FSprCurrentRect);
- {
- PSpriteMgr.BgrScreenBuf.Canvas.CopyMode := cmSrcAnd;
- PSpriteMgr.BgrScreenBuf.Canvas.Draw(Point(Left,Top),FSprMask);
- PSpriteMgr.BgrScreenBuf.Canvas.CopyMode := cmSrcPaint;
- PSpriteMgr.BgrScreenBuf.Canvas.Draw(Point(Left,Top),FSprBitmap);
- }
- PSpriteMgr.BgrScreenBufDrawMaskPaint(Point(Left,Top),FSprMask,FSprBitmap);
- FSprInBuf:=True;
- {SprUpdateDirtyReg(RcOld,FSprCurrentRect);}
- PSpriteMgr.BgrUpdateDirtyRegToCanvas(DirtyReg(RcOld,FSprCurrentRect));
- {
- PSpriteMgr.BgrScreenBuf.Canvas.CopyMode := cmSrcCopy;
- PSpriteMgr.BgrScreenBuf.Canvas.Draw(Left,Top,SNew);
- }
- PSpriteMgr.BgrScreenBufDrawRect(Point(Left,Top),SNew);
- FSprInBuf:=False;
- until FSprTimeRunning>=FSprTimeToRun;
- if SprHideAfter then PSpriteMgr.BgrUpdateDirtyReg(DirtyReg(NulRect,FSprCurrentRect))
- {PSpriteMgr.SprUpdateDirtyReg(NulRect,FSprCurrentRect)}
- else
- begin
- {
- PSpriteMgr.BgrScreenBuf.Canvas.CopyMode := cmSrcAnd;
- PSpriteMgr.BgrScreenBuf.Canvas.Draw(Left,Top,FSprMask);
- PSpriteMgr.BgrScreenBuf.Canvas.CopyMode := cmSrcPaint;
- PSpriteMgr.BgrScreenBuf.Canvas.Draw(Left,Top,FSprBitmap);
- }
- PSpriteMgr.BgrScreenBufDrawMaskPaint(Point(Left,Top),FSprMask,FSprBitmap);
- FSprInBuf:=True;
- FSprOnCanvas:=False;
- FSprToShow:=True;
- end;
- FSprRunning:=False;
- FSprNextPos:=PosNew;
- PSpriteMgr.BgrPause:=False;
- if WasOnCanvas and not SprHideAfter then
- begin
- SprShowAt(FSprNextPos);
- end;
- SNew.Free;
- end;
- end;
-
- function TMChSprite.SprMakeVect(From, Dest: TPoint):TPoint;
- begin
- SprMakeVect:=Point( Dest.x-From.x, Dest.y-From.y );
- end;
-
- function TMChSprite.SprDesiredPos(AtTime: TDateTime):TPoint;
- var
- RTime: TDateTime;
- begin
- RTime:=AtTime-FSprTimeStarted;
- if (not FSprRunning) then
- begin
- if not FSprMoved then SprDesiredPos:=SprLeftTopToRef(Point(Left,Top))
- else
- begin
- SprDesiredPos:=SprNextPos;
- end;
- end
- else
- begin
- if FSprCruise and (FSprTimeToRun>=0) and (RTime>FSprTimeToRun) then FSprCruise:=False;
- if FSprCruise and Assigned(FSprPosFunc) and ((FSprTimeToRun<0) or (RTime<FSprTimeToRun)) then
- begin
- if FSprPaused then
- begin
- FSprPosFunc(AtTime);
- SprDesiredPos:=SprNextPos;
- end
- else SprDesiredPos:=FSprPosFunc(AtTime);
- end
- else
- begin
- if FSprPaused then SprDesiredPos:=SprNextPos
- else
- begin
- if RTime<=0 then
- SprDesiredPos:=SprFrom
- else
- if (FSprTimeToRun>0) and (RTime<FSprTimeToRun) then
- SprDesiredPos:=Point(
- FSprFrom.x+trunc(RTime/FSprTimeToRun*FSprMoveVect.x),
- FSprFrom.y+trunc(RTime/FSprTimeToRun*FSprMoveVect.y) )
- else
- SprDesiredPos:=SprDest;
- end;
- end;
- end;
- end;
-
- function TMChSprite.SprHitTest(ScrP: TPoint): Boolean;
- var
- PTmp, PTmp2: TPoint;
- begin
- SprHitTest:=False;
- if (FSprOnCanvas) and (InRect(ScrP, FSprCurrentRect) ) then
- begin
- if (SprScaleX<>0) and (SprScaleY<>0) then
- begin
- PTmp:=Point(ScrP.x-left-round(SprScaleX*SprRefX),ScrP.y-Top-round(SprScaleY*SprRefY));
- PTmp2:=Point( round(PTmp.x/abs(SprScaleX))+SprRefX,round(PTmp.y/abs(SprScaleY))+SprRefY );
- if (FSprMask.Canvas.Pixels[PTmp2.x,PTmp2.y]=clBlack) and
- (FSprBitmap.Canvas.Pixels[PTmp2.x,PTmp2.y]<>clBlack) then
- SprHitTest:=True;
- end
- else
- begin
- SprHitTest:=True;
- end;
- end;
- end;
-
- function TMChSprite.SprHitAt(ScrP: TPoint): TPoint;
- var
- PTmp, PTmp2: TPoint;
- begin
- if SprHitTest(ScrP) then
- begin
- PTmp:=Point(ScrP.x-left-round(SprScaleX*SprRefX),ScrP.y-Top-round(SprScaleY*SprRefY));
- PTmp2:=Point( round(PTmp.x),round(PTmp.y) );
- SprHitAt:=PTmp2;
- end
- else
- SprHitAt:=NulPoint;
- end;
-
- procedure TMChSprite.SprSetScaleX(NewScaleX: double);
- begin
- FSprScaleX:=NewScaleX;
- FSprRescale:=True;
- FSprMoved:=True;
- end;
-
- procedure TMChSprite.SprSetScaleY(NewScaleY: double);
- begin
- FSprScaleY:=NewScaleY;
- FSprRescale:=True;
- FSprMoved:=True;
- end;
-
- procedure TMChSprite.SprSetScale(NewScale: double);
- begin
- FSprScaleX:=NewScale;
- FSprScaleY:=NewScale;
- FSprRescale:=True;
- FSprMoved:=True;
- end;
-
- procedure TMChSprite.SprSetRefX(NewRefX: Integer);
- begin
- FSprRefX:=NewRefX;
- FSprRescale:=True;
- FSprMoved:=True;
- end;
-
- procedure TMChSprite.SprSetRefY(NewRefY: Integer);
- begin
- FSprRefY:=NewRefY;
- FSprRescale:=True;
- FSprMoved:=True;
- end;
-
- procedure TMChSprite.SprSetRef(NewRef: TPoint);
- begin
- FSprRefX:=NewRef.x;
- FSprRefY:=NewRef.y;
- FSprRescale:=True;
- FSprMoved:=True;
- end;
-
- function TMChSprite.SprRefToLeftTop(ScrP: TPoint): TPoint;
- begin
- SprRefToLeftTop:=Point(ScrP.x-round(SprScaleX*SprRefX),ScrP.y-round(SprScaleY*SprRefY));
- end;
-
- function TMChSprite.SprLeftTopToRef(ScrP: TPoint): TPoint;
- begin
- SprLeftTopToRef:=Point(ScrP.x+round(SprScaleX*SprRefX),ScrP.y+round(SprScaleY*SprRefY));
- end;
-
- function TMChSprite.SprCheckCollision(TestSpr: TMChSprite; AtTime: TDateTime): Boolean;
- var
- TestPos, MyPos: TPoint;
- Dist, MyRad, TestRad, alpha: double;
- begin
- SprCheckCollision:=False;
- if FSprColliding and TestSpr.SprColliding then
- begin
- MyPos:=SprDesiredPos(AtTime);
- TestPos:=TestSpr.SprDesiredPos(AtTime);
- if (abs(MyPos.x-TestPos.x)<=(abs(SprScaleX*SprRadiusX)+abs(TestSpr.SprScaleX*TestSpr.SprRadiusX))) and
- (abs(MyPos.y-TestPos.y)<=(abs(SprScaleY*SprRadiusY)+abs(TestSpr.SprScaleY*TestSpr.SprRadiusY))) then
- begin
- if (SprRadiusX<0) and (TestSpr.SprRadiusX<0) then SprCheckCollision:=True
- else
- begin
- Dist:=sqrt( (1.0*(MyPos.x-TestPos.x))*(1.0*(MyPos.x-TestPos.x))+
- (1.0*(MyPos.y-TestPos.y))*(1.0*(MyPos.y-TestPos.y))+1.0e-6 );
- if abs(MyPos.x-TestPos.x)<1 then alpha:=0 else
- alpha:=arctan( abs( (MyPos.y-TestPos.y)/(MyPos.x-TestPos.x) ) );
- MyRad := sqrt( abs(SprScaleX*SprRadiusX)*sin(alpha)*abs(SprScaleX*SprRadiusX)*sin(alpha)+
- abs(SprScaleY*SprRadiusY)*cos(alpha)*abs(SprScaleY*SprRadiusY)*cos(alpha) );
- TestRad:= sqrt( abs(TestSpr.SprScaleX*TestSpr.SprRadiusX)*sin(alpha)*
- abs(TestSpr.SprScaleX*TestSpr.SprRadiusX)*sin(alpha)+
- abs(TestSpr.SprScaleY*TestSpr.SprRadiusY)*cos(alpha)*
- abs(TestSpr.SprScaleY*TestSpr.SprRadiusY)*cos(alpha) );
- if Dist<MyRad+TestRad then SprCheckCollision:=True;
- end;
- end;
- end;
- end;
-
- function TMChSprite.SprCheckBorders(AtTime: TDateTime): Boolean;
- var
- TestPos, MyPos: TPoint;
- Dist, MyRad, TestRad, alpha: double;
- begin
- SprCheckBorders:=False;
- if FSprColliding then
- begin
- MyPos:=SprDesiredPos(AtTime);
- if (MyPos.x-abs(SprScaleX*SprRadiusX)<=0) or
- (MyPos.x+abs(SprScaleX*SprRadiusX)>=PSpriteMgr.ClientWidth) or
- (MyPos.y-abs(SprScaleY*SprRadiusY)<=0) or
- (MyPos.y+abs(SprScaleY*SprRadiusy)>=PSpriteMgr.ClientHeight) then
- SprCheckBorders:=True;
- end;
- end;
-
- end.
-