home *** CD-ROM | disk | FTP | other *** search
/ Chip: Shareware for Win 95 / Chip-Shareware-Win95.bin / ostatni / delphi / delphi2 / wowsrc.exe / SSSPRITE.PAS < prev    next >
Pascal/Delphi Source File  |  1995-11-07  |  12KB  |  414 lines

  1. {               //SleepingSheep Sprite Engine//
  2. This unit is desined to work under normal windows3.1(non-WinG).
  3. Ver. 0.2.0 11/5/95
  4. 1995 All Copy Rights Reserved by Koji Yamashita, Sleeping Sheep Ltd. Co.}
  5. unit Sssprite;
  6.  
  7. interface
  8.  
  9. uses
  10.   SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls,
  11.   Forms, Dialogs;
  12.  
  13. const
  14.   MaxSegment = 7;
  15.   MaxOffset = 7;
  16.   VirtualWorkSpaceWidth = 64;
  17.   VirtualWorkSpaceHeight = 64;
  18.  
  19. type
  20.   SegmentIndexRange = 0..MaxSegment;
  21.   OffsetIndexRange = 0..MaxOffset;
  22.   AnimationFileArray = array [0..MaxSegment, 0..MaxOffset] of TBitmap;
  23.  
  24. {TSprite is a new object, which has TBitmap as its direct parent.}
  25.   TSprite = class(TBitmap)
  26.     {users are not allowed to access this part}
  27.     private
  28.       SpriteFiles: AnimationFileArray;
  29.       MaskedFiles: AnimationFileArray;
  30.       SaveSpace: TBitmap;
  31.       {refer to the procedure TSprite.Create}
  32.       SegmentIndex: SegmentIndexRange;
  33.       OffsetIndex: OffsetIndexRange;
  34.       XPosition: integer;
  35.       YPosition: integer;
  36.       DisplayOn: boolean;
  37.  
  38.       function SpriteToWorkSpace(var Sprite: TSprite): boolean;
  39.       function SaveSpaceToWorkSpace(var Sprite: TSprite): boolean;
  40.       function FindEmptyOffset(Sprite: TSprite; Segment: integer;
  41.         var Offset: integer): boolean;
  42.     {users are free to use these procedures}
  43.     public
  44.       procedure CreateSprite(var Sprite: TSprite; SpriteFileName: string;
  45.         MaskedFileName: string);
  46.       {!!DELETE EACH SPRITES, WHEN THEY ARE NO MORE INUSE!!}
  47.       procedure DeleteSprite(var Sprite: TSprite);
  48.       procedure SetPosition(var Sprite: TSprite; X: integer; Y: integer);
  49.       procedure CheckPosition(Sprite: TSprite; var X: integer; var Y: integer);
  50.       procedure MoveSprite(var Sprite: TSprite;
  51.         XMove: integer; YMove: integer);
  52.       procedure AddAnimation(Sprite: TSprite; SpriteFileName: string;
  53.         MaskedFileName: string; Segment: integer);
  54.       Procedure AnimateForwardSprite(var Sprite: TSprite;
  55.         WithinSegment: boolean);
  56.       procedure TurnOnOffSprite(var Sprite: TSprite; Switch: boolean);
  57.       procedure SetSegment(var Sprite: TSprite; DesiredSegment: integer);
  58.       procedure IncOffset(var Sprite: TSprite);
  59.       procedure IncSegment(var Sprite: TSprite);
  60.     end;
  61.  
  62.  
  63. procedure InitializeScreen (SpriteScreen: TCanvas; CanvasWidth: integer;
  64.   CanvasHeight: integer; BackGroundFile: string);
  65. {!!DON'T FORGET TO TERMINATE SPRITE AT THE END OF YOUR APPLICATIONS!!}
  66. procedure TerminateScreen;
  67. procedure DisplaySprite(Sprite: TSprite; X: integer; Y: integer);
  68. procedure RefreshScreen;
  69.  
  70. implementation
  71.  
  72. var
  73.    BackGroundBitmap: TBitmap;
  74.    WorkSpace: TBitmap;
  75.    OutputSpace: TCanvas;
  76.    OutputWidth: integer;
  77.    OutputHeight: integer;
  78.    OutputSpaceActive: boolean;
  79.  
  80. procedure InitializeScreen(SpriteScreen: TCanvas;
  81.   CanvasWidth: integer;CanvasHeight: integer; BackGroundFile: string);
  82. begin
  83.   OutputSpaceActive := True;
  84.   OutputSpace := SpriteScreen;
  85.   OutputWidth := CanvasWidth;
  86.   OutputHeight := CanvasHeight;
  87.  
  88.   BackGroundBitmap := TBitmap.Create;
  89.   BackGroundBitmap.LoadFromFile(BackGroundFile);
  90.  
  91.   WorkSpace := TBitmap.Create;
  92.   WorkSpace.Canvas.CopyMode := cmSrcCopy;
  93.   WorkSpace.Width := CanvasWidth + 128;
  94.   WorkSpace.Height := CanvasHeight + 128;
  95.   WorkSpace.Canvas.StretchDraw(rect(-VirtualWorkSpaceWidth,
  96.     -VirtualWorkSpaceHeight, CanvasWidth + VirtualWorkSpaceWidth,
  97.     CanvasHeight + VirtualWorkSpaceHeight), BackGroundBitmap);
  98.  
  99.   OutputSpace.CopyMode := cmSrcCopy;
  100.   OutputSpace.CopyRect(rect(0, 0, WorkSpace.Width, WorkSpace.Height),
  101.     WorkSpace.Canvas, rect(0, 0, WorkSpace.Width, WorkSpace.Height));
  102. end;
  103.  
  104. procedure RefreshScreen;
  105. begin
  106.   if OutputSpaceActive then
  107.   begin
  108.     OutputSpace.CopyMode := cmSrcCopy;
  109.     OutputSpace.Draw(0, 0,
  110.       WorkSpace);
  111.   end;
  112. end;
  113.  
  114. procedure TSprite.CreateSprite(var Sprite: TSprite; SpriteFileName: string;
  115.   MaskedFileName: string);
  116. var
  117.   Test: boolean;
  118.   Index1, Index2: integer;
  119. begin
  120.   Sprite := TSprite.Create;
  121.   Sprite.SaveSpace := TBitmap.Create;
  122.   for Index1 := 0 to 7 do
  123.   begin
  124.     for Index2 := 0 to 7 do
  125.     begin
  126.       Sprite.SpriteFiles[Index1, Index2] := TBitmap.Create;
  127.       Sprite.MaskedFiles[Index1, Index2] := TBitmap.Create;
  128.     end;
  129.   end;
  130.   Sprite.SpriteFiles[0,0].LoadFromFile(SpriteFileName);
  131.   Sprite.MaskedFiles[0,0].LoadFromFile(MaskedFileName);
  132.   {animation Segment/Offset Index: [<Segment>, <Offset>]}
  133.   Sprite.SegmentIndex := 0;
  134.   Sprite.OffsetIndex := 0;
  135.   Sprite.DisplayOn := False;
  136. end;
  137.  
  138. procedure TerminateScreen;
  139. begin
  140.   BackGroundBitmap.Free;
  141.   WorkSpace.Free;
  142.   OutputSpaceActive := False;
  143. end;
  144.  
  145. procedure Tsprite.DeleteSprite(var Sprite: TSprite);
  146. var
  147. Index1, Index2: integer;
  148. begin
  149.   Sprite.Free;
  150.   Sprite.SaveSpace.Free;
  151.   for Index1 := 0 to 7 do
  152.   begin
  153.     for Index2 := 0 to 7 do
  154.     begin
  155.       Sprite.SpriteFiles[Index1, Index2].Free;
  156.       Sprite.MaskedFiles[Index1, Index2].Free;
  157.     end;
  158.   end;
  159. end;
  160.  
  161. procedure TSprite.SetPosition(var Sprite: TSprite; X: integer; Y: integer);
  162. var
  163.   Test: boolean;
  164. begin
  165.   MoveSprite(Sprite, X - Sprite.XPosition, Y - Sprite.YPosition);
  166. end;
  167.  
  168. procedure TSprite.TurnOnOffSprite(var Sprite: TSprite; Switch: boolean);
  169. begin
  170.   Sprite.DisplayOn := Switch;
  171. end;
  172.  
  173. function TSprite.SaveSpaceToWorkSpace(var Sprite: TSprite): boolean;
  174. begin
  175.   {add a programmer-protect function here-- Empty(SaveSpace)-> Cancel}
  176.   with Sprite do
  177.   begin
  178.     if DisplayOn then
  179.     begin
  180.       WorkSpace.Canvas.CopyMode := cmSrcCopy;
  181.       WorkSpace.Canvas.CopyRect(
  182.         rect(XPosition, YPosition, XPosition + Width, YPosition + Height),
  183.         SaveSpace.Canvas,
  184.         rect(0, 0, Width, Height));
  185.     end;
  186.   end;
  187. end;
  188.  
  189. function TSprite.SpriteToWorkSpace(var Sprite: TSprite): boolean;
  190. begin
  191.   {if Sprite is out from WorkSpace then Cancel it}
  192.   with Sprite do
  193.   begin
  194.     if DisplayOn then
  195.     begin
  196.       if (XPosition < -VirtualWorkSpaceWidth) or
  197.         (XPosition > WorkSpace.Width - Width) or
  198.         (YPosition < -VirtualWorkSpaceHeight) or
  199.         (YPosition > WorkSpace.Height - Height) then
  200.       begin
  201.         SpriteToWorkSpace := False;
  202.       end
  203.       else
  204.       begin
  205.         Width := SpriteFiles[SegmentIndex, OffsetIndex].Width;
  206.         Height := SpriteFiles[SegmentIndex, OffsetIndex].Height;
  207.         {save WorkSpace, which will be modified, to SaveSpace}
  208.         SaveSpace.Width := Width;
  209.         SaveSpace.Height := Height;
  210.         SaveSpace.Canvas.CopyMode := cmSrcCopy;
  211.         SaveSpace.Canvas.CopyRect(rect(0, 0, Width, Height),
  212.           WorkSpace.Canvas,
  213.           rect(XPosition, YPosition, XPosition + Width, YPosition + Height));
  214.         {modify the WorkPlace by MaskedFile}
  215.         WorkSpace.Canvas.CopyMode := cmSrcAnd;
  216.         WorkSpace.Canvas.CopyRect(
  217.           rect(XPosition, YPosition, XPosition + Width, YPosition + Height),
  218.           MaskedFiles[SegmentIndex, OffsetIndex].Canvas,
  219.           rect(0,0, Width, Height));
  220.         {modify the WorkSpace by SpriteFile}
  221.         WorkSpace.Canvas.CopyMode := cmSrcInvert;
  222.         WorkSpace.Canvas.CopyRect(
  223.           rect(XPosition, YPosition, XPosition + Width, YPosition + Height),
  224.           SpriteFiles[SegmentIndex, OffsetIndex].Canvas,
  225.           rect(0,0, Width, Height));
  226.       end;
  227.     end;
  228.   end;
  229. end;
  230.  
  231. procedure DisplaySprite(Sprite: TSprite; X: Integer; Y: Integer);
  232. var
  233. LTX, LTY, RBX, RBY: integer;
  234. begin
  235.   with Sprite do
  236.   begin
  237.     if DisplayOn then
  238.     begin
  239.       OutputSpace.CopyMode := cmSrcCopy;
  240.       if (Width > abs(X)) and (Height > abs(Y)) then
  241.       begin
  242.         if X >= 0 then
  243.         begin
  244.           LTX := XPosition - abs(X);
  245.           RBX := XPosition + Width;
  246.         end;
  247.         if Y >= 0 then
  248.         begin
  249.           LTY := YPosition - abs(Y);
  250.           RBY := YPosition + Height;
  251.         end;
  252.         if X < 0 then
  253.         begin
  254.           LTX := XPosition;
  255.           RBX := XPosition + Width + abs(X);
  256.         end;
  257.         if Y < 0 then
  258.         begin
  259.           LTY := YPosition;
  260.           RBY := YPosition + Height +abs(Y);
  261.         end;
  262.         OutputSpace.CopyRect(
  263.           rect(LTX, LTY, RBX, RBY),
  264.           WorkSpace.Canvas,
  265.           rect(LTX, LTY, RBX, RBY));
  266.       end
  267.       else
  268.       begin
  269.         OutputSpace.CopyRect(
  270.           rect(XPosition - X, YPosition - Y,
  271.           XPosition + Width, YPosition + Height),
  272.           WorkSpace.Canvas,
  273.           rect(XPosition - X, YPosition - Y,
  274.           XPosition + Width, YPosition + Height));
  275.         OutputSpace.CopyRect(
  276.           rect(XPosition, YPosition, XPosition + Width, YPosition + Height),
  277.           WorkSpace.Canvas,
  278.           rect(XPosition, YPosition, XPosition + Width, YPosition + Height));
  279.       end;
  280.     end;
  281.   end;
  282. end;
  283.  
  284. procedure TSprite.MoveSprite(var Sprite: TSprite;
  285.   XMove: integer; YMove: integer);
  286. var
  287.   Test: boolean;
  288. begin
  289.   Test := SaveSpaceToWorkSpace(Sprite);
  290.   Sprite.XPosition := Sprite.XPosition + XMove;
  291.   SPrite.YPosition := Sprite.YPosition + YMove;
  292.   Test := SpriteToWorkSpace(Sprite);
  293.   DisplaySprite(Sprite, XMove, YMove);
  294. end;
  295.  
  296. procedure TSprite.CheckPosition(Sprite: TSprite; var X:
  297.   integer; var Y: integer);
  298. begin
  299.   X := Sprite.XPosition;
  300.   Y := SPrite.YPosition;
  301. end;
  302.  
  303. procedure TSprite.AddAnimation(Sprite: TSprite; SpriteFileName: string;
  304.   MaskedFileName: string; Segment: integer);
  305. var
  306.   Test: boolean;
  307.   Offset: integer;
  308. begin
  309.   Test := FindEmptyOffset(Sprite, Segment, Offset);
  310.   if test then
  311.   begin
  312.     Sprite.SpriteFiles[Segment, Offset].LoadFromFile(SpriteFileName);
  313.     Sprite.MaskedFiles[Segment, Offset].LoadFromFile(MaskedFileName);
  314.   end;
  315. end;
  316.  
  317. {this function is to find the youngest available Offset with in a segment}
  318. function TSprite.FindEmptyOffset(Sprite: TSprite; Segment: integer;
  319.   var Offset: integer): boolean;
  320. begin
  321.   FindEmptyOffset := False;
  322.   Offset := MaxOffset;
  323.   if Sprite.SpriteFiles[Segment, 0].Empty then
  324.   begin
  325.     Offset := 0;
  326.     FindEmptyOffset := True;
  327.   end
  328.   else
  329.   begin
  330.     while Sprite.SpriteFiles[Segment, Offset].Empty and (Offset > 0) do
  331.       begin
  332.         Offset := Offset - 1;
  333.         FindEmptyOffset := True;
  334.       end;
  335.     Offset := Offset + 1;
  336.   end;
  337. end;
  338.  
  339. {this function is to animate the sprite}
  340. procedure TSprite.AnimateForwardSprite(var Sprite: TSprite;
  341.   WithinSegment: boolean);
  342. begin
  343.   if WithinSegment then
  344.   begin
  345.     IncOffset(Sprite);
  346.   end
  347.   else
  348.   begin
  349.     IncOffset(Sprite);
  350.     if Sprite.OffsetIndex = 0 then
  351.     begin
  352.       IncSegment(Sprite);
  353.     end;
  354.   end;
  355. end;
  356.  
  357. {this function is to increment offset No. within segment}
  358. procedure TSprite.IncOffset(var Sprite: TSprite);
  359. begin
  360.   with Sprite do
  361.   begin
  362.     if OffsetIndex = MaxOffset then
  363.     begin
  364.       OffsetIndex := 0;
  365.     end
  366.     else
  367.     begin
  368.       OffsetIndex := OffsetIndex + 1;
  369.       if SpriteFiles[SegmentIndex, OffsetIndex].Empty then
  370.       begin
  371.         OffsetIndex := 0;
  372.       end;
  373.     end;
  374.   end;
  375. end;
  376.  
  377. {this function is to increment segment No.}
  378. procedure TSprite.IncSegment(var Sprite: TSprite);
  379. begin
  380.   with Sprite do
  381.   begin
  382.     if SegmentIndex = MaxSegment then
  383.     begin
  384.       SegmentIndex := 0;
  385.     end
  386.     else
  387.     begin
  388.       SegmentIndex := SegmentIndex + 1;
  389.       if SpriteFiles[SegmentIndex, OffsetIndex].Empty then
  390.       begin
  391.         SegmentIndex := 0;
  392.       end;
  393.     end;
  394.   end;
  395. end;
  396.  
  397. procedure TSprite.SetSegment(var Sprite: TSprite; DesiredSegment: integer);
  398. begin
  399.   with Sprite do
  400.   begin
  401.     if DesiredSegment > MaxSegment then
  402.     begin
  403.     end
  404.     else
  405.     begin
  406.       if not(SpriteFiles[DesiredSegment, OffsetIndex].Empty) then
  407.       begin
  408.         SegmentIndex := DesiredSegment;
  409.       end;
  410.     end;
  411.   end;
  412. end;
  413. end.
  414.