home *** CD-ROM | disk | FTP | other *** search
/ Delphi 5 for Professionals / DELPHI5.iso / AddOns / Components / TEECHART / Delphi1_And_Delphi2 / EXAMPLES / PACMAN / UPACMAN.PAS < prev    next >
Encoding:
Pascal/Delphi Source File  |  1998-10-24  |  26.5 KB  |  984 lines

  1. {**********************************************}
  2. {   TeePac a Pac-Man like Game                 }
  3. {   Copyright (c) 1996 by David Berneda        }
  4. {**********************************************}
  5. unit Upacman;
  6. {$P-}
  7.  
  8. interface
  9.  
  10. uses
  11.   SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls,
  12.   Forms, Dialogs, Teengine, Chart, ExtCtrls, StdCtrls, BubbleCh,
  13.   Series, Menus,IniFiles, Buttons,EditChar,CustEdit, teeprocs;
  14.  
  15. Const MaxMonsters=20;
  16.  
  17. type
  18.   TPacManDirection=(pdStop,pdLeft,pdRight,pdTop,pdBottom);
  19.   SetOfDirection=set of TPacManDirection;
  20.  
  21.   TTeePacForm = class(TForm)
  22.     Panel1: TPanel;
  23.     Chart1: TChart;
  24.     Walls: TBubbleSeries;
  25.     Label1: TLabel;
  26.     Label2: TLabel;
  27.     MainMenu1: TMainMenu;
  28.     File1: TMenuItem;
  29.     Open1: TMenuItem;
  30.     New1: TMenuItem;
  31.     Save1: TMenuItem;
  32.     N1: TMenuItem;
  33.     QuittAltX1: TMenuItem;
  34.     Options1: TMenuItem;
  35.     Help1: TMenuItem;
  36.     Zoomed1: TMenuItem;
  37.     N3Dimensions1: TMenuItem;
  38.     ShowAxis1: TMenuItem;
  39.     HowToPlay1: TMenuItem;
  40.     AboutTeeChart1: TMenuItem;
  41.     Label3: TLabel;
  42.     Label4: TLabel;
  43.     Chart2: TChart;
  44.     HorizBarSeries1: THorizBarSeries;
  45.     Panel2: TPanel;
  46.     Label5: TLabel;
  47.     Label6: TLabel;
  48.     OpenDialog1: TOpenDialog;
  49.     SaveDialog1: TSaveDialog;
  50.     Label7: TLabel;
  51.     Panel3: TPanel;
  52.     SpeedButton1: TSpeedButton;
  53.     SpeedButton2: TSpeedButton;
  54.     SpeedButton3: TSpeedButton;
  55.     SpeedButton4: TSpeedButton;
  56.     BitBtn1: TBitBtn;
  57.     SpeedButton5: TSpeedButton;
  58.     N2: TMenuItem;
  59.     Ranking1: TMenuItem;
  60.     BitBtn2: TBitBtn;
  61.     SpeedButton6: TSpeedButton;
  62.     SpeedButton7: TSpeedButton;
  63.     ShowLegend1: TMenuItem;
  64.     procedure FormShow(Sender: TObject);
  65.     function WallsGetPointerStyle(Sender: TChartSeries;
  66.       ValueIndex: Longint): TSeriesPointerStyle;
  67.     procedure Chart1UndoZoom(Sender: TObject);
  68.     procedure Zoomed1Click(Sender: TObject);
  69.     procedure ShowAxis1Click(Sender: TObject);
  70.     procedure N3Dimensions1Click(Sender: TObject);
  71.     procedure QuittAltX1Click(Sender: TObject);
  72.     procedure New1Click(Sender: TObject);
  73.     procedure HowToPlay1Click(Sender: TObject);
  74.     procedure AboutTeeChart1Click(Sender: TObject);
  75.     procedure Open1Click(Sender: TObject);
  76.     procedure Save1Click(Sender: TObject);
  77.     procedure FormClose(Sender: TObject; var Action: TCloseAction);
  78.     procedure SpeedButton1Click(Sender: TObject);
  79.     procedure SpeedButton2Click(Sender: TObject);
  80.     procedure SpeedButton3Click(Sender: TObject);
  81.     procedure SpeedButton4Click(Sender: TObject);
  82.     procedure BitBtn1Click(Sender: TObject);
  83.     procedure SpeedButton5Click(Sender: TObject);
  84.     procedure Ranking1Click(Sender: TObject);
  85.     procedure BitBtn2Click(Sender: TObject);
  86.     procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
  87.     procedure SpeedButton6Click(Sender: TObject);
  88.     procedure SpeedButton7Click(Sender: TObject);
  89.     procedure ShowLegend1Click(Sender: TObject);
  90.     procedure WallsAfterDrawValues(Sender: TObject);
  91.     procedure FormKeyDown(Sender: TObject; var Key: Word;
  92.       Shift: TShiftState);
  93.   private
  94.     { Private declarations }
  95.   public
  96.     { Public declarations }
  97.     Changed,
  98.     FirstKey,Zoomed:Boolean;
  99.     OldTime,IdleSpeed,Score,Lives:Longint;
  100.     ManDir:TPacManDirection;
  101.     CheckNewDirs:Boolean;
  102.     MonsterDir:Array[1..MaxMonsters] of TPacManDirection;
  103.     NumTargets:Longint;
  104.     TeeMap:TStringList;
  105.     Man:Longint;
  106.     OriginManX,OriginManY:Double;
  107.     { procedures }
  108.     Procedure Eated(ValueIndex:Longint);
  109.     Procedure EatedMonster(ValueIndex:Longint);
  110.     Function HorizWall(From:Longint; Const X:Double):Longint;
  111.     Function VertWall(From:Longint; Const Y:Double):Longint;
  112.     Function CrashDirection( From:Longint;
  113.                              ADir:TPacManDirection;
  114.                              Const tmpSpeed:Double):Longint;
  115.     Procedure MoveObject(From:Longint; ADir:TPacManDirection; Const Speed:Double);
  116.     Function RandomDir(Options:SetOfDirection):TPacManDirection;
  117.     procedure SetChartAxis;
  118.     Procedure CreateGame;
  119.     procedure CreateNewGame;
  120.     Procedure ChangeScore(NewScore:Longint);
  121.     Procedure ChangeLives(NewLives:Longint);
  122.     Procedure EndGame(Win:Boolean);
  123.     Procedure LoadGame(Const FileName:String);
  124.     Procedure SaveGame(Const FileName:String);
  125.     Procedure ProcessHit(FromObject,ToObject:Longint);
  126.     Procedure GuessMan;
  127.     procedure AppIdle(Sender: TObject; var Done: Boolean);
  128.     Function HorizVertWall( ListA,ListB:TChartValueList;
  129.                             From:Longint; Const num:Double ):Longint;
  130.   end;
  131.  
  132. Const AllDirections=[pdLeft,pdRight,pdTop,pdBottom];
  133.  
  134. var
  135.   TeePacForm: TTeePacForm;
  136.  
  137. implementation
  138.  
  139. {$R *.DFM}
  140. Uses UAbout,UTeeHelp,URankin,UDesign,TeCanvas
  141.      {$IFDEF WIN32}
  142.      ,Math 
  143.      {$ENDIF}
  144.      ;
  145.  
  146. { Default Map }
  147. {
  148.   x  =   Wall
  149.   o  =   Target (Money)
  150.   r  =   Red Monster
  151.   g  =   Green Monster
  152.   p  =   TeePac Man !!!
  153. }
  154. Const PacMap:Array[0..12] of String=
  155. (  'xxxxxxxxxxxxxxx',
  156.    'xoooooooooooxox',
  157.    'xoxxxoxoxoxxxox',
  158.    'xoooxoxoxooooox',
  159.    'xxxoxoxoxxxxxox',
  160.    'xoooxoxooooooox',
  161.    'xoxxrrrxxoxxxox',
  162.    'xoooxxxoooxooox',
  163.    'xxoooxoooxxoxxx',
  164.    'xooxxxxxooxooox',
  165.    'xoooxoxoooxoxox',
  166.    'xoxoopooxoxoxgx',
  167.    'xxxxxxxxxxxxxxx'
  168. );
  169.  
  170. { Color constants }
  171. const PacWallColor     =clTeal;
  172.       PacTargetColor   =clNavy;
  173.       PacManColor      =clYellow;
  174.       PacMonster1Color =clRed;
  175.       PacMonster2Color =clLime;
  176.  
  177.       PacManSpeed      =25;
  178.       PacMonsterSpeed  =25;
  179.       Radius           =50;
  180.  
  181. Procedure TTeePacForm.GuessMan;
  182. Var t:Longint;
  183. begin
  184.   for t:=0 to Walls.Count-1 do
  185.   if Walls.ValueColor[t]=PacManColor then
  186.   begin
  187.     Man:=t;
  188.     break;
  189.   end;
  190.   Walls.SwapValueIndex(Man,Walls.Count-1);
  191.   Man:=Walls.Count-1;
  192. end;
  193.  
  194. { This procedure CLEARS and RESETS the Game }
  195. Procedure TTeePacForm.CreateGame;
  196.  
  197.   Procedure ProcessMap(WallsOnly:Boolean);
  198.   Var t,tt,tmpX,tmpY:Longint;
  199.       MapChar:Char;
  200.       tmpSt:String;
  201.  
  202.       Procedure AddElement(Element:Longint);
  203.       begin
  204.         Walls.AddBubble(tmpX,tmpY,Radius,'',Element);
  205.       end;
  206.  
  207.   begin
  208.     for t:=TeeMap.Count-1 downto 0 do
  209.     begin
  210.       tmpY:=100*((TeeMap.Count-1-t))+Radius;
  211.       tmpSt:=TeeMap.Strings[t];
  212.       for tt:=1 to Length(tmpSt) do
  213.       begin
  214.         MapChar:=tmpSt[tt];
  215.         tmpX:=100*(tt-1)+Radius;
  216.         if WallsOnly then
  217.         begin
  218.           if MapChar='x' then AddElement(PacWallColor)
  219.           else
  220.           if MapChar='o' then
  221.           begin
  222.             Walls.AddBubble( tmpX,tmpY, Radius div 2, '', PacTargetColor);
  223.             Inc(NumTargets);
  224.           end;
  225.         end
  226.         else
  227.         Case MapChar of
  228.           'p': AddElement(PacManColor);
  229.           'r',
  230.           'g': if MapChar='r' then AddElement(PacMonster1Color)
  231.                               else AddElement(PacMonster2Color);
  232.         end;
  233.       end;
  234.     end;
  235.   end;
  236.  
  237. var t:Longint;
  238. begin
  239.   NumTargets:=0;
  240.   Walls.Clear;
  241.   Walls.XValues.Order:=loNone;
  242.   Walls.YValues.Order:=loNone;
  243.   Randomize;
  244.   TeeEraseBack:=False;
  245.   Zoomed:=False;
  246.   ChangeScore(0);
  247.   ChangeLives(4);
  248.   Label1.Caption:='0';
  249.   FirstKey:=True;
  250.   Walls.Pointer.InflateMargins:=False;
  251.   Walls.Squared:=False;
  252.   ProcessMap(True);
  253.   ProcessMap(False);
  254.   HorizBarSeries1.XValue[0]:=NumTargets;
  255.   ManDir:=pdStop;
  256.   GuessMan;
  257.   OriginManX:=Walls.XValue[Man];
  258.   OriginManY:=Walls.YValue[Man];
  259.   for t:=1 to MaxMonsters do MonsterDir[t]:=pdStop;
  260.   CheckNewDirs:=False;
  261. end;
  262.  
  263. { This procedure RESETS AND CREATES THE DEFAULT GAME }
  264. procedure TTeePacForm.CreateNewGame;
  265. var t:Longint;
  266. begin
  267.   TeeMap.Clear;
  268.   for t:=Low(PacMap) to High(PacMap) do TeeMap.Add(PacMap[t]);
  269.   CreateGame;
  270. end;
  271.  
  272. procedure TTeePacForm.FormShow(Sender: TObject);
  273. begin
  274.   OldTime:=0;
  275.   IdleSpeed:=100;
  276.   TeeMap:=TStringList.Create;
  277.   With Chart1 do
  278.   begin
  279.     ApplyZOrder:=False;
  280.     Legend.Visible:=False;
  281.     View3D:=True;
  282.     AxisVisible:=True;
  283.     BackColor:=clAqua;
  284.   end;
  285.   HorizBarSeries1.Clear;
  286.   HorizBarSeries1.Add(100,'',clTeeColor);
  287.   if ParamCount=1 then LoadGame(ParamStr(1));
  288.   if Walls.Count=0 then CreateNewGame;
  289.   Changed:=False;
  290.   Application.OnIdle:=AppIdle;
  291.   SpeedButton6.Down:=True;
  292.   SpeedButton7.Down:=True;
  293. end;
  294.  
  295. procedure TTeePacForm.AppIdle(Sender: TObject; var Done: Boolean);
  296. Var Hitted:Longint;
  297.  
  298.     Function OppositeDir(tmpDir:TPacManDirection):TPacManDirection;
  299.     begin
  300.       Case tmpDir of
  301.         pdLeft: result:=pdRight;
  302.         pdRight: result:=pdLeft;
  303.         pdTop: result:=pdBottom;
  304.       else
  305.         {pdBottom:} result:=pdTop;
  306.       end;
  307.     end;
  308.  
  309.   Procedure ProcessMonster(Monster:Longint; Var ADir:TPacManDirection);
  310.  
  311.     Function CheckDir(tmpDir:TPacManDirection):Boolean;
  312.     begin
  313.       result:=False;
  314.       if (tmpDir<>ADir) and (tmpDir<>OppositeDir(ADir)) then
  315.       begin
  316.         Hitted:=CrashDirection( Monster, tmpDir, PacMonsterSpeed);
  317.         if (Hitted=-1) or (Walls.ValueColor[Hitted]=PacTargetColor) then
  318.         begin
  319.           ADir:=tmpDir;
  320.           result:=True;
  321.         end;
  322.       end;
  323.     end;
  324.  
  325.     Function CheckAllDirections:Boolean;
  326.  
  327.       Procedure CheckCase(CaseNum:Longint);
  328.       begin
  329.         Case CaseNum of
  330.           0: result:= CheckDir(pdLeft) or
  331.                       CheckDir(pdRight) or
  332.                       CheckDir(pdTop) or
  333.                       CheckDir(pdBottom);
  334.           1: result:= CheckDir(pdRight) or
  335.                       CheckDir(pdTop) or
  336.                       CheckDir(pdBottom) or
  337.                       CheckDir(pdLeft);
  338.           2: result:= CheckDir(pdTop) or
  339.                       CheckDir(pdBottom) or
  340.                       CheckDir(pdLeft) or
  341.                       CheckDir(pdRight);
  342.           3: result:= CheckDir(pdBottom) or
  343.                       CheckDir(pdLeft) or
  344.                       CheckDir(pdRight) or
  345.                       CheckDir(pdTop);
  346.         end
  347.       end;
  348.  
  349.     var difx,dify:Double;
  350.     Begin
  351.       if Random(100)<15 then CheckCase(Random(4))
  352.       else
  353.       begin
  354.         difx:=Walls.XValue[Man]-Walls.XValue[Monster];
  355.         dify:=Walls.YValue[Man]-Walls.YValue[Monster];
  356.         if Abs(difx)<Abs(dify) then
  357.         begin
  358.           if difx>0 then CheckCase(1)
  359.                     else CheckCase(0);
  360.         end
  361.         else
  362.         begin
  363.           if dify>0 then CheckCase(2)
  364.                     else CheckCase(3);
  365.         end;
  366.       end;
  367.     end;
  368.  
  369.   Var tmpCol:Tcolor;
  370.   begin
  371.     Hitted:=CrashDirection( Monster, ADir, PacMonsterSpeed);
  372.     if Hitted<>-1 then tmpCol:=Walls.ValueColor[Hitted]
  373.                   else tmpCol:=-1;
  374.     if (Hitted=-1) or (tmpCol=PacTargetColor) then
  375.     begin
  376.       MoveObject(Monster,ADir,PacMonsterSpeed);
  377.       if CheckNewDirs then
  378.          if CheckAllDirections then CheckNewDirs:=False;
  379.     end
  380.     else
  381.     if Hitted=Man then ProcessHit(Monster,Man)
  382.     else
  383.     begin
  384.       if not CheckAllDirections then
  385.       begin
  386.         CheckNewDirs:=True;
  387.         ADir:=OppositeDir(ADir);
  388.       end;
  389.       Hitted:=CrashDirection( Monster, ADir, PacMonsterSpeed);
  390.       if (Hitted=-1) or (Walls.ValueColor[Hitted]=PacTargetColor) then
  391.          MoveObject(Monster,ADir,PacMonsterSpeed)
  392.     end;
  393.   end;
  394.  
  395. var NumMonster,t:Longint;
  396.     tmp:TColor;
  397. begin
  398.   if (GetTickCount-OldTime)>IdleSpeed then
  399.   begin
  400.     if not FirstKey then
  401.     begin
  402.       if ManDir<>pdStop then
  403.       begin
  404.         Hitted:=CrashDirection( Man, ManDir, PacManSpeed);
  405.         if Hitted=-1 then MoveObject(Man,ManDir,PacManSpeed)
  406.                      else
  407.                      begin
  408.                        if Walls.ValueColor[Hitted]=PacTargetColor then
  409.                           MoveObject(Man,ManDir,PacManSpeed)
  410.                        else
  411.                           ManDir:=pdStop;
  412.                        ProcessHit(Man,Hitted);
  413.                      end;
  414.       end;
  415.  
  416.  
  417.       NumMonster:=0;
  418.       for t:=0 to Walls.Count-1 do
  419.       begin
  420.         tmp:=Walls.ValueColor[t];
  421.         if (tmp=PacMonster1Color) or (tmp=PacMonster2Color) then
  422.         begin
  423.           Inc(NumMonster);
  424.           ProcessMonster(t,MonsterDir[NumMonster]);
  425.         end;
  426.       end;
  427.       IdleSpeed:=NumMonster*30;
  428.  
  429.       if Zoomed then SetChartAxis;
  430.     end;
  431.     OldTime:=GetTickCount;
  432.   end;
  433.   Done := FirstKey;
  434. end;
  435.  
  436. Function TTeePacForm.HorizVertWall( ListA,ListB:TChartValueList;
  437.                                     From:Longint; Const num:Double ):Longint;
  438. Var tmp0:Double;
  439.     tmp1:Double;
  440.  
  441.    Function Intersect(t:Longint):Boolean;
  442.    Var b0,b1:Double;
  443.    Begin
  444.      if Abs(num-ListB.Value[t])<Radius then
  445.      begin
  446.        b0:=ListA.Value[t]-Radius;
  447.        b1:=b0+2*Radius;
  448.        result:=(
  449.                 ((tmp0>b0) and (tmp0<b1)) or
  450.                 ((tmp1>b0) and (tmp1<b1)) or
  451.                 ((tmp0=b0) and (tmp1=b1))
  452.               );
  453.      end
  454.      else result:=False;
  455.    end;
  456.  
  457. Var t:Longint;
  458. begin
  459.   result:=-1;
  460.   tmp0:=ListA.Value[From]-Radius;
  461.   tmp1:=tmp0+2*Radius;
  462.   for t:=0 to Walls.Count-1 do
  463.   if t<>From then
  464.     if Intersect(t) then
  465.     begin
  466.       result:=t;
  467.       exit;
  468.     end;
  469. end;
  470.  
  471. { This Function returns the "hitted" object when moving horizontal }
  472. Function TTeePacForm.HorizWall( From:Longint; Const X:Double):Longint;
  473. begin
  474.   result:=HorizVertWall(Walls.YValues,Walls.XValues,From,X);
  475. end;
  476.  
  477. { This Function returns the "hitted" object when moving Vertical }
  478. Function TTeePacForm.VertWall( From:Longint; Const Y:Double):Longint;
  479. begin
  480.   result:=HorizVertWall(Walls.XValues,Walls.YValues,From,Y);
  481. end;
  482.  
  483. { This Function returns the minimum value between a and b }
  484. Function MinDouble(Const a,b:Double):Double;
  485. begin
  486.   if a<b then result:=a else result:=b;
  487. end;
  488.  
  489. { This method changes and repaints the SCORE }
  490. Procedure TTeePacForm.ChangeScore(NewScore:Longint);
  491. Begin
  492.   Score:=NewScore;
  493.   Label1.Caption:=IntToStr(Score);
  494. end;
  495.  
  496. { This method is called when PacMan EATS a Target object (Money) }
  497. Procedure TTeePacForm.Eated(ValueIndex:Longint);
  498. Begin
  499.   Walls.Delete(ValueIndex);
  500.   GuessMan;
  501.   ChangeScore(Score+5);
  502.   Dec(NumTargets);
  503.   { change the progress horiz bar chart }
  504.   HorizBarSeries1.XValue[0]:=NumTargets;
  505.   if NumTargets=0 then EndGame(True);
  506. end;
  507.  
  508. { This method changes and repaints the LIVES }
  509. Procedure TTeePacForm.ChangeLives(NewLives:Longint);
  510. Begin
  511.   Lives:=NewLives;
  512.   Label4.Caption:=IntToStr(Lives);
  513. end;
  514.  
  515. { This method is called when PacMan and Monster have collisioned }
  516. Procedure TTeePacForm.EatedMonster(ValueIndex:Longint);
  517. Begin
  518.   Walls.Delete(ValueIndex);
  519.   ChangeLives(Lives-1);
  520.   GuessMan;
  521.   ManDir:=pdStop;
  522.   Walls.XValue[Man]:=OriginManX;
  523.   Walls.YValue[Man]:=OriginManY;
  524.   if Lives=0 then EndGame(False);
  525. end;
  526.  
  527. Procedure TTeePacForm.ProcessHit(FromObject,ToObject:Longint);
  528. Var FromColor,ToColor:TColor;
  529. Begin
  530.   FromColor:=Walls.ValueColor[FromObject];
  531.   ToColor:=Walls.ValueColor[ToObject];
  532.   if ToColor=PacTargetColor then
  533.   begin
  534.     if FromColor=PacManColor then Eated(ToObject);
  535.   end
  536.   else
  537.   if (ToColor=PacMonster1Color) or
  538.      (ToColor=PacMonster2Color) then
  539.   begin
  540.     if FromColor=PacManColor then EatedMonster(ToObject);
  541.   end
  542.   else
  543.   if ToColor=PacManColor then
  544.      if FromColor<>PacManColor then EatedMonster(FromObject);
  545. end;
  546.  
  547. { This method handles the PacMan and Monsters movements }
  548. Function TTeePacForm.CrashDirection( From:Longint;
  549.                                 ADir:TPacManDirection;
  550.                                 Const tmpSpeed:Double):Longint;
  551. begin
  552.   result:=-1;
  553.   Case ADir of
  554.     pdLeft:  result:=HorizWall(From,Walls.XValue[From]-Radius-tmpSpeed);
  555.     pdRight: result:=HorizWall(From,Walls.XValue[From]+Radius+tmpSpeed);
  556.     pdTop:   result:=VertWall(From,Walls.YValue[From]+Radius+tmpSpeed);
  557.     pdBottom:result:=VertWall(From,Walls.YValue[From]-Radius-tmpSpeed);
  558.   end;
  559. end;
  560.  
  561. Procedure TTeePacForm.MoveObject(From:Longint; ADir:TPacManDirection; Const Speed:Double);
  562. begin
  563.   With Walls do
  564.   Case ADir of
  565.    pdleft:   XValues[From]:=XValue[From]-Speed;
  566.    pdright:  XValues[From]:=XValue[From]+Speed;
  567.    pdtop:    YValues[From]:=YValue[From]+Speed;
  568.    pdbottom: YValues[From]:=YValue[From]-Speed;
  569.   end;
  570.   Chart1.Invalidate;
  571. end;
  572.  
  573. { This method adjusts chart AXIS when in ZOOM mode }
  574. { The PacMan is always in the chart center }
  575. procedure TTeePacForm.SetChartAxis;
  576. Var X,Y:Double;
  577. begin
  578.   if Man<>-1 then
  579.   begin
  580.     X:=Walls.XValue[Man];
  581.     Chart1.BottomAxis.SetMinMax(X-Radius-350,X+Radius+350);
  582.     Y:=Walls.YValue[Man];
  583.     Chart1.LeftAxis.SetMinMax(Y-Radius-350,Y+Radius+350);
  584.   end;
  585. end;
  586.  
  587. { This function returns a random direction (Left, Right, Top or Bottom)  }
  588. Function TTeePacForm.RandomDir(Options:SetOfDirection):TPacManDirection;
  589. Begin
  590.   if Options=[] then result:=pdStop
  591.   else
  592.   Repeat
  593.     result:=TPacManDirection(Random(Ord(High(TPacManDirection))));
  594.   Until result in Options;
  595. end;
  596.  
  597. { This function returns the corresponding POINT STYLE }
  598. { for Walls and Targets.
  599.   Walls   = Rectangle
  600.   Targets = Ellipse
  601. }
  602. function TTeePacForm.WallsGetPointerStyle(Sender: TChartSeries;
  603.   ValueIndex: Longint): TSeriesPointerStyle;
  604. begin
  605.   if Sender.ValueColor[ValueIndex]=PacWallColor then result:=psRectangle
  606.                                                 else result:=psCircle;
  607. end;
  608.  
  609. { When user undos zoom with right mouse button }
  610. procedure TTeePacForm.Chart1UndoZoom(Sender: TObject);
  611. begin
  612.   Zoomed:=False;
  613. end;
  614.  
  615. { Toggle Zoom On/Off }
  616. procedure TTeePacForm.Zoomed1Click(Sender: TObject);
  617. begin
  618.   Zoomed1.Checked:=not Zoomed1.Checked;
  619.   Zoomed:=Zoomed1.Checked;
  620.   if Zoomed then
  621.   begin
  622.     SetChartAxis;
  623.   end
  624.   else
  625.   begin
  626.     Chart1.LeftAxis.Automatic:=True;
  627.     Chart1.BottomAxis.Automatic:=True;
  628.   end;
  629. end;
  630.  
  631. { Toggle View Axis On/Off }
  632. procedure TTeePacForm.ShowAxis1Click(Sender: TObject);
  633. begin
  634.   ShowAxis1.Checked:=not ShowAxis1.Checked;
  635.   Chart1.AxisVisible:=ShowAxis1.Checked;
  636. end;
  637.  
  638. { Toggle View 3D On/Off }
  639. procedure TTeePacForm.N3Dimensions1Click(Sender: TObject);
  640. begin
  641.   N3Dimensions1.Checked:=not N3Dimensions1.Checked;
  642.   Chart1.View3d:=N3Dimensions1.Checked;
  643. end;
  644.  
  645. { Bye, Bye !! }
  646. procedure TTeePacForm.QuittAltX1Click(Sender: TObject);
  647. begin
  648.   Close;
  649. end;
  650.  
  651. { Ask the user confirmation for a new game... }
  652. procedure TTeePacForm.New1Click(Sender: TObject);
  653. begin
  654.   if MessageDlg('Re-Start Game ?', mtConfirmation, [mbYes,mbNo],0)=mrYes then
  655.      CreateNewGame;
  656. end;
  657.  
  658. { Show Help Dialog }
  659. procedure TTeePacForm.HowToPlay1Click(Sender: TObject);
  660. begin
  661.   With TTeeHelp.Create(Self) do
  662.   try
  663.     ShowModal;
  664.   finally
  665.     Free;
  666.   end;
  667. end;
  668.  
  669. { Show About Dialog }
  670. procedure TTeePacForm.AboutTeeChart1Click(Sender: TObject);
  671. begin
  672.   With TAboutTeePac.Create(Self) do
  673.   try
  674.     ShowModal;
  675.   finally
  676.     Free;
  677.   end;
  678. end;
  679.  
  680. { Ask the User's Name when User Wins !!! }
  681. Procedure TTeePacForm.EndGame(Win:Boolean);
  682. var tmpSt:String;
  683. begin
  684.   FirstKey:=True;
  685.   if Win then
  686.   begin
  687.     tmpSt:='Me, the Winner';
  688.     if InputQuery('Congratulations !','Enter Your Name:',tmpSt) then
  689.     begin
  690.       with TIniFile.Create('teepac.ini') do
  691.       try
  692.         WriteString('Ranking',tmpSt,IntToStr(Score));
  693.       finally
  694.         Free;
  695.       end;
  696.     end;
  697.   end
  698.   else ShowMessage('Sorry. Try Again !');
  699.   CreateNewGame;
  700. end;
  701.  
  702. { Try to Open a stored Game }
  703. procedure TTeePacForm.Open1Click(Sender: TObject);
  704. begin
  705.   OpenDialog1.FileName:='';
  706.   if OpenDialog1.Execute then LoadGame(OpenDialog1.FileName);
  707. end;
  708.  
  709. { Try to Save the current Game to Disk }
  710. procedure TTeePacForm.Save1Click(Sender: TObject);
  711. begin
  712.   if SaveDialog1.FileName='' then SaveDialog1.FileName:='default.tee';
  713.   if SaveDialog1.Execute then SaveGame(SaveDialog1.FileName);
  714. end;
  715.  
  716. { Load a Game from Disk }
  717. Procedure TTeePacForm.LoadGame(Const FileName:String);
  718. var t:Longint;
  719.     tmpSt:String;
  720. begin
  721.   With TIniFile.Create(FileName) do
  722.   try
  723.     TeeMap.Clear;
  724.     for t:=0 to 100 do
  725.     begin
  726.       tmpSt:=ReadString('TeePacMap',IntToStr(t),'');
  727.       if tmpSt<>'' then
  728.          TeeMap.Add(tmpSt);
  729.     end;
  730.     Zoomed1.Checked:=ReadBool('TeePacOptions','Zoomed',False);
  731.     N3Dimensions1.Checked:=ReadBool('TeePacOptions','View3D',True);
  732.     ShowAxis1.Checked:=ReadBool('TeePacOptions','ShowAxis',True);
  733.     ShowLegend1.Checked:=ReadBool('TeePacOptions','ShowLegend',True);
  734.     CreateGame;
  735.   finally
  736.     Free;
  737.   end;
  738. end;
  739.  
  740. { Store a Game to Disk }
  741. Procedure TTeePacForm.SaveGame(Const FileName:String);
  742. var t:Longint;
  743. begin
  744.   With TIniFile.Create(FileName) do
  745.   try
  746.     EraseSection('TeePacMap');
  747.     for t:=0 to TeeMap.Count-1 do WriteString('TeePacMap',IntToStr(t),TeeMap[t]);
  748.     WriteBool('TeePacOptions','Zoomed',Zoomed1.Checked);
  749.     WriteBool('TeePacOptions','View3D',N3Dimensions1.Checked);
  750.     WriteBool('TeePacOptions','ShowAxis',ShowAxis1.Checked);
  751.     WriteBool('TeePacOptions','ShowLegend',ShowLegend1.Checked);
  752.     Changed:=False;
  753.   finally
  754.     Free;
  755.   end;
  756. end;
  757.  
  758. { Free allocated Map }
  759. procedure TTeePacForm.FormClose(Sender: TObject; var Action: TCloseAction);
  760. begin
  761.   Application.OnIdle:=nil;
  762.   TeeMap.Free;
  763. end;
  764.  
  765. procedure TTeePacForm.SpeedButton1Click(Sender: TObject);
  766. begin
  767.   Open1Click(Self);
  768. end;
  769.  
  770. procedure TTeePacForm.SpeedButton2Click(Sender: TObject);
  771. begin
  772.   Save1Click(Self);
  773. end;
  774.  
  775. procedure TTeePacForm.SpeedButton3Click(Sender: TObject);
  776. begin
  777.   New1Click(Self);
  778. end;
  779.  
  780. procedure TTeePacForm.SpeedButton4Click(Sender: TObject);
  781. begin
  782.   Zoomed1Click(Self);
  783.   SpeedButton4.Down:=Zoomed;
  784. end;
  785.  
  786. procedure TTeePacForm.BitBtn1Click(Sender: TObject);
  787. begin
  788.   EditChart(Self,Chart1);
  789.   Chart1.SetFocus;
  790. end;
  791.  
  792. procedure TTeePacForm.SpeedButton5Click(Sender: TObject);
  793. begin
  794.   ShowLegend1Click(Self);
  795.   SpeedButton5.Down:=Chart1.Legend.Visible;
  796. end;
  797.  
  798. { Show Ranking Dialog }
  799. procedure TTeePacForm.Ranking1Click(Sender: TObject);
  800. begin
  801.   With TTeeRanking.Create(Self) do
  802.   try
  803.     ShowModal;
  804.   finally
  805.     Free;
  806.   end;
  807. end;
  808.  
  809. { Show Map Designer Dialog }
  810. procedure TTeePacForm.BitBtn2Click(Sender: TObject);
  811. begin
  812.   With TTeeDesign.Create(Self) do
  813.   try
  814.     Memo1.Lines.Assign(TeeMap);
  815.     if ShowModal=mrOk then
  816.     begin
  817.       Changed:=True;
  818.       TeeMap.Assign(Memo1.Lines);
  819.       CreateGame;
  820.     end;
  821.   finally
  822.     Free;
  823.   end;
  824.   Chart1.SetFocus;
  825. end;
  826.  
  827. { Ask User confirmation to Close and Quit }
  828. procedure TTeePacForm.FormCloseQuery(Sender: TObject;
  829.   var CanClose: Boolean);
  830. begin
  831.   CanClose:=False;
  832.   if Changed then
  833.   begin
  834.     if MessageDlg('Game Changed. Do you want to save it ?',
  835.                   mtConfirmation,
  836.                   [mbYes,mbNo],0)=mrYes then
  837.     begin
  838.       if SaveDialog1.FileName='' then SaveDialog1.FileName:='default.tee';
  839.       if SaveDialog1.Execute then
  840.       begin
  841.         SaveGame(SaveDialog1.FileName);
  842.         CanClose:=True;
  843.       end
  844.     end
  845.     else Changed:=False;
  846.   end
  847.   else CanClose:=True;
  848. end;
  849.  
  850. procedure TTeePacForm.SpeedButton6Click(Sender: TObject);
  851. begin
  852.   ShowAxis1Click(Self);
  853.   SpeedButton6.Down:=Chart1.AxisVisible;
  854. end;
  855.  
  856. procedure TTeePacForm.SpeedButton7Click(Sender: TObject);
  857. begin
  858.   N3Dimensions1Click(Self);
  859.   SpeedButton7.Down:=Chart1.View3D;
  860. end;
  861.  
  862. { Toggle LEGEND on / off }
  863. procedure TTeePacForm.ShowLegend1Click(Sender: TObject);
  864. begin
  865.   ShowLegend1.Checked:=not ShowLegend1.Checked;
  866.   Chart1.Legend.Visible:=ShowLegend1.Checked;
  867. end;
  868.  
  869. { This method draws the PacMan FACE (Eyes and Mouth) }
  870. procedure TTeePacForm.WallsAfterDrawValues(Sender: TObject);
  871. var tmpx1,tmpy1,tmpx2,tmpy2:Longint;
  872.     HalfWidth3d,
  873.     HalfHeight3d:Longint;
  874.     x3,y3,x4,y4,xrad,yrad,xcen,ycen:Longint;
  875.  
  876.     Procedure DrawPie(SAngle,EAngle:Longint);
  877.     var SSin,SCos:Extended;
  878.     begin
  879.       SinCos(SAngle*pi/180.0,SSin,SCos);
  880.       x3:=xcen+round(xrad*Scos);
  881.       y3:=ycen+round(yrad*Ssin);
  882.       SinCos(EAngle*pi/180.0,SSin,SCos);
  883.       x4:=xcen+round(xrad*Scos);
  884.       y4:=ycen+round(yrad*Ssin);
  885.       With Chart1.Canvas do
  886.       begin
  887.         Pen.Style:=psSolid;
  888.         Pen.Color:=Chart1.BackColor;
  889.         Brush.Color:=Chart1.BackColor;
  890.         Brush.Style:=bsSolid;
  891.         Pie(tmpX1,tmpY1,tmpx2,tmpY2,x3,y3,x4,y4);
  892.         Pen.Color:=clBlack;
  893.         Pen.Style:=psSolid;
  894.         Pen.Width:=1;
  895.         MoveTo(xcen,ycen);
  896.         LineTo(x3,y3);
  897.         MoveTo(xcen,ycen);
  898.         LineTo(x4,y4);
  899.       end;
  900.     end;
  901.  
  902. var tmpx,tmpy,EyePos:Longint;
  903.     xx,yy:Double;
  904. begin
  905.     HalfWidth3d:=0{Chart1.SeriesWidth3d div 2};
  906.     HalfHeight3d:=0{Chart1.SeriesHeight3d div 2};
  907.     xx:=Walls.XValue[Man];
  908.     tmpx1:=Walls.CalcXPosValue(xx-Radius)+HalfWidth3d;
  909.     tmpx2:=Walls.CalcXPosValue(xx+Radius)+HalfWidth3d;
  910.     yy:=Walls.YValue[Man];
  911.     tmpy1:=Walls.CalcYPosValue(yy-Radius)-HalfHeight3d;
  912.     tmpy2:=Walls.CalcYPosValue(yy+Radius)-HalfHeight3d;
  913.     With Chart1.Canvas do
  914.     begin
  915.       xrad:=(tmpx2-tmpx1) div 2;
  916.       yrad:=(tmpy2-tmpy1) div 2;
  917.       xcen:=tmpx1+xrad;
  918.       ycen:=tmpy1+yrad;
  919.  
  920.       Case ManDir of
  921.         pdRight: DrawPie(345,15);
  922.         pdLeft:  DrawPie(165,195);
  923.         pdTop:   DrawPie(75,105);
  924.         pdBottom: DrawPie(255,285);
  925.         pdStop:  Begin
  926.                    Pen.Style:=psSolid;
  927.                    Pen.Color:=clBlack;
  928.                    MoveTo(xcen-(xrad div 2),ycen);
  929.                    LineTo(xcen+(xrad div 2),ycen);
  930.                  end;
  931.       end;
  932.  
  933.       Pen.Width:=2;
  934.       if ManDir=pdTop then EyePos:=-(yrad div 2)
  935.                       else EyePos:=+(yrad div 2);
  936.       tmpy:=ycen+EyePos;
  937.       if ManDir=pdStop then
  938.       begin
  939.         tmpx:=(xrad div 3);
  940.         MoveTo(xcen-tmpx,tmpy);
  941.         LineTo(xcen-tmpx,tmpy);
  942.         MoveTo(xcen+tmpx,tmpy);
  943.         LineTo(xcen+tmpx,tmpy);
  944.       end
  945.       else
  946.       begin
  947.         MoveTo(xcen+(xrad div 6),tmpy);
  948.         LineTo(xcen+(xrad div 6)-1,tmpy-1);
  949.       end;
  950.     end;
  951. end;
  952.  
  953. { When a key is pressed down...  }
  954. { PacMan is assigned a DIRECTION }
  955. { If we are beggining the game, Monsters are assigned a RANDOM DIRECTION }
  956. procedure TTeePacForm.FormKeyDown(Sender: TObject; var Key: Word;
  957.   Shift: TShiftState);
  958. Var OldDirection:TPacManDirection;
  959.     t,tmp:Longint;
  960. begin
  961.   if FirstKey then
  962.   begin
  963.     for t:=1 to MaxMonsters do MonsterDir[t]:=RandomDir(AllDirections);
  964.     FirstKey:=False;
  965.   end;
  966.   OldDirection:=ManDir;
  967.   Case Key of
  968.     VK_LEFT :  ManDir:=pdLeft;
  969.     VK_RIGHT:  ManDir:=pdRight;
  970.     VK_UP   :  ManDir:=pdTop;
  971.     VK_DOWN :  ManDir:=pdBottom;
  972.     Ord('Z'):  Zoomed1Click(Self);
  973.     Ord('3'):  N3Dimensions1Click(Self);
  974.     Ord('A'):  ShowAxis1Click(Self);
  975.   else
  976.     exit;
  977.   end;
  978.   tmp:=CrashDirection( Man, ManDir, PacManSpeed);
  979.   if (tmp<>-1) and (Walls.ValueColor[tmp]=PacWallColor) then
  980.      ManDir:=OldDirection;
  981. end;
  982.  
  983. end.
  984.