home *** CD-ROM | disk | FTP | other *** search
/ CD Actual Thematic 25: Programming / pc_actual_25.iso / Delphi / TeeChartPro / TeeChart5Delphi5Eval.exe / %MAINDIR% / Examples / Features / Game_PacMan.pas < prev    next >
Encoding:
Pascal/Delphi Source File  |  2001-09-10  |  25.6 KB  |  944 lines

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