home *** CD-ROM | disk | FTP | other *** search
/ Monster Media 1994 #1 / monster.zip / monster / PROG_GEN / TCYBER.ZIP / CFSPRITE.PAS < prev    next >
Pascal/Delphi Source File  |  1994-01-15  |  12KB  |  557 lines

  1. {
  2. Turbo Vision CyberTools 1.0
  3. (C) 1994 Steve Goldsmith
  4. All Rights Reserved
  5.  
  6. Character Sprite objects using non-modal dialogs.  Broadcast cmAnimate to
  7. update and draw sprites.
  8. }
  9.  
  10. unit CFSprite;
  11.  
  12. {$I APP.INC}
  13.  
  14. interface
  15.  
  16. uses
  17.  
  18.   Objects, App, Views, Dialogs, Drivers, CFCmds, ColorSel;
  19.  
  20. type
  21.  
  22.   PBackView = ^TBackView;
  23.   TBackView = object (TView)
  24.     procedure Draw; virtual;
  25.   end;
  26.  
  27.   PSpriteView = ^TSpriteView;
  28.   TSpriteView = object (TView)
  29.     FrameSize,
  30.     FramePos,
  31.     EndPos,
  32.     PalIndex : byte;
  33.     Dir : TPoint;
  34.     SpriteStr : PString;
  35.     constructor Init (var Bounds : TRect; S : PString; D : TPoint);
  36.     procedure CalcMove; virtual;
  37.     procedure Draw; virtual;
  38.   end;
  39.  
  40.   PAniDlg = ^TAniDlg;
  41.   TAniDlg = object (TDialog)
  42.     AniFlag : boolean;
  43.     AniGroup : PGroup;
  44.     constructor Init (T : string);
  45.     procedure InitSprites; virtual;
  46.     procedure DrawSprites; virtual;
  47.     function GetPalette: PPalette; virtual;
  48.     procedure HandleEvent(var Event: TEvent); virtual;
  49.   end;
  50.  
  51.   PUfoView = ^TUfoView;
  52.   TUfoView = object (TSpriteView)
  53.     procedure CalcMove; virtual;
  54.   end;
  55.  
  56.   PBombView = ^TBombView;
  57.   TBombView = object (TSpriteView)
  58.     procedure CalcMove; virtual;
  59.   end;
  60.  
  61.   PExpView = ^TExpView;
  62.   TExpView = object (TSpriteView)
  63.     procedure CalcMove; virtual;
  64.   end;
  65.  
  66.   PUfoDlg = ^TUfoDlg;
  67.   TUfoDlg = object (TAniDlg)
  68.     Ufo : PUfoView;
  69.     Bomb : PBombView;
  70.     Exp : PExpView;
  71.     procedure InitSprites; virtual;
  72.     procedure DrawSprites; virtual;
  73.   end;
  74.  
  75.   PShipView = ^TShipView;
  76.   TShipView = object (TSpriteView)
  77.     procedure CalcMove; virtual;
  78.   end;
  79.  
  80.   PShotView = ^TShotView;
  81.   TShotView = object (TSpriteView)
  82.     procedure CalcMove; virtual;
  83.   end;
  84.  
  85.   PShipDlg = ^TShipDlg;
  86.   TShipDlg = object (TAniDlg)
  87.     Ship : PShipView;
  88.     Shot : PShotView;
  89.     procedure InitSprites; virtual;
  90.     procedure DrawSprites; virtual;
  91.   end;
  92.  
  93. const
  94.  
  95.   {dialog palette additions for animation}
  96.   CAniColor = #$00#$00#$00#$00#$00#$00#$00;
  97.   CAniPal   = #136#137#138#139#140#141#142;
  98.  
  99.   {frame sequences using character value.  animate.cgf or compatible}
  100.   {character patterns must be loaded into font used for text}
  101.   invSprite  : string[12] = #128#129#32#130#131#132#133#134#135#136#137#138;
  102.   ufoSprite  : string[6]  = #139#140#32#141#142#143;
  103.   bombSprite : string[4]  = #144#145#146#147;
  104.   expSprite  : string[18] = #148#148#148#148#149#149#149#149#150#150#150#150#149#149#149#149#148#148#148#148;
  105.   shipSprite : string[12] = #151#152#32#153#154#155#156#157#158#159#160#161;
  106.   shotSprite : string[4]  = #162#163#164#165;
  107.  
  108. implementation
  109.  
  110. {TBackView}
  111.  
  112. procedure TBackView.Draw;
  113.  
  114. var
  115.  
  116.   Buf : TDrawBuffer;
  117.  
  118. begin {animation group background}
  119.   MoveChar (Buf[0],' ',GetColor (33),Size.X);
  120.   WriteLine (0,0,Size.X,Size.Y,Buf)
  121. end;
  122.  
  123. {TSpriteView}
  124.  
  125. constructor TSpriteView.Init (var Bounds : TRect; S : PString; D : TPoint);
  126.  
  127. begin
  128.   inherited Init (Bounds);
  129.   SpriteStr := S;      {sprite sequence string}
  130.   Dir := D;            {x and y direction}
  131.   FrameSize := Size.X; {characters used in frame}
  132.   FramePos := 1;       {start with first frame}
  133.   EndPos := Length (SpriteStr^)-FrameSize+1 {last frame}
  134. end;
  135.  
  136. procedure TSpriteView.CalcMove;
  137.  
  138. begin {default calc uses desending invaders logic which restart at top}
  139.   if Dir.X > 0 then           {when they reach the bottom}
  140.   begin                       {see if x dir = 1 (moving left)}
  141.     if FramePos < EndPos then {if not last frame then inc for next}
  142.       Inc (FramePos,FrameSize)
  143.     else
  144.     begin                     {if last frame then move sprite x dir chrs}
  145.       Origin.X := Origin.X+Dir.X;
  146.       FramePos := 1
  147.     end
  148.   end
  149.   else
  150.     if Dir.X < 0 then
  151.     begin
  152.       if FramePos > 1 then
  153.         Dec (FramePos,FrameSize)
  154.       else
  155.       begin
  156.         Origin.X := Origin.X+Dir.X;
  157.         FramePos := EndPos
  158.       end
  159.     end;
  160.   if Origin.X > Owner^.Size.X then {boundry checking logic}
  161.   begin
  162.     FramePos := EndPos;
  163.     Origin.X := Owner^.Size.X;
  164.     Dir.X := -1;
  165.     Inc (Origin.Y);
  166.     if Origin.Y > Owner^.Size.Y then
  167.       Origin.Y := 0
  168.   end
  169.   else
  170.     if Origin.X < -Size.X  then
  171.     begin
  172.       FramePos := 1;
  173.       Origin.X := -Size.X;
  174.       Dir.X := 1;
  175.       Inc (Origin.Y);
  176.       if Origin.Y > Owner^.Size.Y then
  177.         Origin.Y := 0
  178.     end
  179. end;
  180.  
  181. procedure TSpriteView.Draw;
  182.  
  183. var
  184.  
  185.   Buf : TDrawBuffer;
  186.   X : byte;
  187.  
  188. begin {draw current frame}
  189.   for X := 0 to Size.X-1 do
  190.     MoveChar(Buf[X],SpriteStr^[FramePos+X],GetColor (PalIndex),1);
  191.   WriteLine (0,0,Size.X,1,Buf)
  192. end;
  193.  
  194. {TAniDlg}
  195.  
  196. constructor TAniDlg.Init (T : string);
  197.  
  198. var
  199.  
  200.   R : TRect;
  201.   BackView : PBackView;
  202.  
  203. begin
  204.   R.Assign (0,0,45,10);
  205.   inherited Init (R,T);
  206.  
  207.   R.Assign(32, 1, 43, 3);
  208.   Insert(New(PButton, Init(R, '~A~nimate', cmAniOn, bfNormal)));
  209.   R.Assign(32, 3, 43, 5);
  210.   Insert(New(PButton, Init(R, '~S~top', cmAniOff, bfNormal)));
  211.   R.Assign(32, 5, 43, 7);
  212.   Insert(New(PButton, Init(R, '~C~lose', cmClose, bfDefault)));
  213.  
  214.   R.Assign (2,1,31,9);
  215.   AniGroup := New (PGroup, Init (R));
  216.   AniGroup^.GetExtent (R);
  217.   BackView := New (PBackView, Init (R));
  218.   AniGroup^.Insert (BackView);
  219.   InitSprites;             {initilize sprites}
  220.   Insert (AniGroup);
  221.   Palette := dpBlueDialog; {use blue dialog}
  222.   AniFlag := true          {turn animation on}
  223. end;
  224.  
  225. procedure TAniDlg.InitSprites;
  226.  
  227. var
  228.  
  229.   X, Y : byte;
  230.   B, R : TRect;
  231.   P : TPoint;
  232.   SV : PSpriteView;
  233.  
  234. begin {default to using two rows of invaders}
  235.   AniGroup^.GetBounds (B);
  236.   P.X := 1;
  237.   P.Y := 0;
  238.   for Y := 0 to 1 do
  239.     for X := 0 to 5 do
  240.     begin
  241.       R.Assign (X*3+B.A.X,Y*2+B.A.Y,X*3+B.A.X+3,Y*2+B.A.Y+1);
  242.       SV := New (PSpriteView, Init (R,@invSprite,P));
  243.       SV^.PalIndex := 34;
  244.       AniGroup^.Insert (SV)
  245.     end
  246. end;
  247.  
  248. procedure TAniDlg.DrawSprites;
  249.  
  250. procedure DrawSpr (P : PView); far;
  251.  
  252. begin
  253.   if TypeOf (P^) = TypeOf (TSpriteView) then
  254.     PSpriteView (P)^.CalcMove;
  255.   P^.DrawView
  256. end;
  257.  
  258. begin {update and draw all sprites in group}
  259.   AniGroup^.Lock;
  260.   AniGroup^.ForEach (@DrawSpr);
  261.   AniGroup^.Unlock
  262. end;
  263.  
  264. function TAniDlg.GetPalette: PPalette;
  265.  
  266. const
  267.  
  268.   CNewBlueDialog = CBlueDialog+CAniPal;
  269.   CNewCyanDialog = CCyanDialog+CAniPal;
  270.   CNewGrayDialog = CGrayDialog+CAniPal;
  271.   P: array[dpBlueDialog..dpGrayDialog] of string[Length(CNewBlueDialog)] =
  272.   (CNewBlueDialog, CNewCyanDialog, CNewGrayDialog);
  273.  
  274. begin  {defines additional colors for animation starting at dialog palette index 33}
  275.   GetPalette := @P[Palette];
  276. end;
  277.  
  278. procedure TAniDlg.HandleEvent(var Event: TEvent);
  279.  
  280. begin
  281.   inherited HandleEvent(Event);
  282.   case Event.What of
  283.     evCommand:
  284.     begin {process commands}
  285.       case Event.Command of
  286.         cmClose  : Close;
  287.         cmAniOn  : AniFlag := true;
  288.         cmAniOff : AniFlag := false
  289.       else
  290.         Exit
  291.       end;
  292.       ClearEvent (Event)
  293.     end;
  294.     evBroadcast :
  295.     begin {process broadcasts}
  296.       case Event.Command of
  297.         cmAnimate : if AniFlag then
  298.                       DrawSprites
  299.       else
  300.         Exit
  301.       end;
  302.       ClearEvent (Event)
  303.     end
  304.   end
  305. end;
  306.  
  307. {TUfoView}
  308.  
  309. procedure TUfoView.CalcMove;
  310.  
  311. begin {logic for ufo starting at random y axis and moving horz}
  312.   if Dir.X > 0 then
  313.   begin
  314.     if FramePos < EndPos then
  315.       Inc (FramePos,FrameSize)
  316.     else
  317.     begin
  318.       Origin.X := Origin.X+Dir.X;
  319.       FramePos := 1
  320.     end
  321.   end
  322.   else
  323.     if Dir.X < 0 then
  324.     begin
  325.       if FramePos > 1 then
  326.         Dec (FramePos,FrameSize)
  327.       else
  328.       begin
  329.         Origin.X := Origin.X+Dir.X;
  330.         FramePos := EndPos
  331.       end
  332.     end;
  333.   if Origin.X > Owner^.Size.X then
  334.   begin
  335.     FramePos := EndPos;
  336.     Origin.X := Owner^.Size.X;
  337.     Dir.X := -1;
  338.     Origin.Y := Random (Owner^.Size.Y)
  339.   end
  340.   else
  341.     if Origin.X < -Size.X then
  342.     begin
  343.       FramePos := 1;
  344.       Origin.X := -Size.X;
  345.       Dir.X := 1;
  346.       Origin.Y := Random (Owner^.Size.Y)
  347.     end
  348. end;
  349.  
  350. {TBombView}
  351.  
  352. procedure TBombView.CalcMove;
  353.  
  354. begin {logic for decending bomb that hides when it hits bottom}
  355.   if State and sfVisible = sfVisible then
  356.   begin
  357.     if FramePos < EndPos then
  358.       Inc (FramePos,FrameSize)
  359.     else
  360.     begin
  361.       Origin.Y := Origin.Y+Dir.Y;
  362.       FramePos := 1
  363.     end
  364.   end
  365. end;
  366.  
  367. {TExpView}
  368.  
  369. procedure TExpView.CalcMove;
  370.  
  371. begin {logic for updating frames without moving}
  372.   if State and sfVisible = sfVisible then
  373.   begin
  374.     if FramePos < EndPos then
  375.       Inc (FramePos,FrameSize)
  376.     else
  377.       Hide
  378.   end
  379. end;
  380.  
  381.  
  382. {TUfoDlg}
  383.  
  384. procedure TUfoDlg.InitSprites;
  385.  
  386. var
  387.  
  388.   B, R : TRect;
  389.   P : TPoint;
  390.  
  391. begin
  392.   GetBounds (B);
  393.   P.X := 0;
  394.   P.Y := 1;
  395.   R.Assign (B.A.X+1,B.A.Y,B.A.X+2,B.A.Y+1);
  396.   Bomb := New (PBombView, Init (R,@bombSprite,P));
  397.   Bomb^.PalIndex := 36;
  398.   Bomb^.Hide;
  399.   AniGroup^.Insert (Bomb);
  400.   P.X := 0;
  401.   P.Y := 0;
  402.   Exp := New (PExpView, Init (R,@expSprite,P));
  403.   Exp^.PalIndex := 37;
  404.   Exp^.Hide;
  405.   AniGroup^.Insert (Exp);
  406.   P.X := 1;
  407.   P.Y := 0;
  408.   R.Assign (B.A.X+1,B.A.Y,B.A.X+4,B.A.Y+1);
  409.   Ufo := New (PUfoView, Init (R,@ufoSprite,P));
  410.   Ufo^.PalIndex := 35;
  411.   AniGroup^.Insert (Ufo)
  412. end;
  413.  
  414. procedure TUfoDlg.DrawSprites;
  415.  
  416. begin
  417.   AniGroup^.Lock;
  418.   if (Random (20) = 0) and {randomly drop bombs}
  419.   (Bomb^.State and sfVisible = 0) then
  420.   begin
  421.     Bomb^.Origin.X := Ufo^.Origin.X;
  422.     Bomb^.Origin.Y := Ufo^.Origin.Y;
  423.     Bomb^.Show
  424.   end;
  425.   if (Bomb^.State and sfVisible = sfVisible) and
  426.   (Bomb^.Origin.Y = AniGroup^.Size.Y) then
  427.   begin {if bomb hits bottom then explode!}
  428.     Exp^.Origin.X := Bomb^.Origin.X;
  429.     Exp^.Origin.Y := Bomb^.Origin.Y-1;
  430.     Exp^.FramePos := 1;
  431.     Bomb^.Hide;
  432.     Exp^.Show
  433.   end;
  434.   Ufo^.CalcMove;
  435.   Bomb^.CalcMove;
  436.   Exp^.CalcMove;
  437.   AniGroup^.Last^.DrawView;
  438.   Ufo^.DrawView;
  439.   Bomb^.DrawView;
  440.   Exp^.DrawView;
  441.   AniGroup^.Unlock
  442. end;
  443.  
  444. {TShipView}
  445.  
  446. procedure TShipView.CalcMove;
  447.  
  448. begin {logic that randomly moves ship in horz dir}
  449.   if Random (50) = 0 then
  450.     Dir.X := 1
  451.   else
  452.     if Random (50) = 0 then
  453.       Dir.X := -1
  454.     else
  455.       if Random (50) = 0 then
  456.         Dir.X := 0;
  457.   if Dir.X > 0 then
  458.   begin
  459.     if FramePos < EndPos then
  460.       Inc (FramePos,FrameSize)
  461.     else
  462.     begin
  463.       Origin.X := Origin.X+Dir.X;
  464.       FramePos := 1
  465.     end
  466.   end
  467.   else
  468.     if Dir.X < 0 then
  469.     begin
  470.       if FramePos > 1 then
  471.         Dec (FramePos,FrameSize)
  472.       else
  473.       begin
  474.         Origin.X := Origin.X+Dir.X;
  475.         FramePos := EndPos
  476.       end
  477.     end;
  478.   if Origin.X > Owner^.Size.X then
  479.   begin
  480.     FramePos := EndPos;
  481.     Origin.X := Owner^.Size.X;
  482.     Dir.X := -1
  483.   end
  484.   else
  485.     if Origin.X < -Size.X then
  486.     begin
  487.       FramePos := 1;
  488.       Origin.X := -Size.X;
  489.       Dir.X := 1
  490.     end
  491. end;
  492.  
  493. {TShotView}
  494.  
  495. procedure TShotView.CalcMove;
  496.  
  497. begin {logic for vert moving shot}
  498.   if FramePos < EndPos then
  499.     Inc (FramePos,FrameSize)
  500.   else
  501.   begin
  502.     Origin.Y := Origin.Y+Dir.Y;
  503.     FramePos := 1
  504.   end;
  505.   if Origin.Y < 0 then
  506.     Hide
  507. end;
  508.  
  509. {TShipDlg}
  510.  
  511. procedure TShipDlg.InitSprites;
  512.  
  513. var
  514.  
  515.   B, R : TRect;
  516.   P : TPoint;
  517.  
  518. begin
  519.   AniGroup^.GetBounds (B);
  520.   P.X := 1;
  521.   P.Y := 0;
  522.   R.Assign (B.A.X+1,B.B.Y-2,B.A.X+4,B.B.Y-1);
  523.   Ship := New (PShipView, Init (R,@shipSprite,P));
  524.   Ship^.PalIndex := 38;
  525.   AniGroup^.Insert (Ship);
  526.   P.X := 0;
  527.   P.Y := -1;
  528.   R.Assign (B.A.X+1,B.A.Y,B.A.X+2,B.A.Y+1);
  529.   Shot := New (PShotView, Init (R,@shotSprite,P));
  530.   Shot^.PalIndex := 39;
  531.   Shot^.Hide;
  532.   AniGroup^.Insert (Shot)
  533. end;
  534.  
  535. procedure TShipDlg.DrawSprites;
  536.  
  537. begin
  538.   AniGroup^.Lock;
  539.   if (Random (10) = 0) and {randomly shoot}
  540.   (Shot^.State and sfVisible = 0) and
  541.   (Ship^.FramePos = 1)then
  542.   begin
  543.     Shot^.Origin.X := Ship^.Origin.X;
  544.     Shot^.Origin.Y := Ship^.Origin.Y-1;
  545.     Shot^.FramePos := 1;
  546.     Shot^.Show
  547.   end;
  548.   Ship^.CalcMove;
  549.   Shot^.CalcMove;
  550.   AniGroup^.Last^.DrawView;
  551.   Ship^.DrawView;
  552.   Shot^.DrawView;
  553.   AniGroup^.Unlock
  554. end;
  555.  
  556. end.
  557.