tappytux: A very large rework of the software architecture, removing various hacks and improving the general architecture

git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@2150 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
sekelsenmat
2011-11-16 21:54:32 +00:00
parent c1bf1dd46a
commit 3bc96963bc
6 changed files with 272 additions and 270 deletions

View File

@ -6,6 +6,7 @@ object formTappyTuxGame: TformTappyTuxGame
Caption = 'Tappy Tux' Caption = 'Tappy Tux'
ClientHeight = 425 ClientHeight = 425
ClientWidth = 621 ClientWidth = 621
OnClose = FormClose
OnCreate = FormCreate OnCreate = FormCreate
OnShow = FormShow OnShow = FormShow
Position = poDesktopCenter Position = poDesktopCenter
@ -105,39 +106,4 @@ object formTappyTuxGame: TformTappyTuxGame
ReadOnly = True ReadOnly = True
TabOrder = 4 TabOrder = 4
end end
object GameOver: TToggleBox
Left = 240
Height = 64
Top = 152
Width = 172
Caption = 'Game Over'#13#10'Continue?'
Checked = True
Color = clRed
Enabled = False
State = cbChecked
TabOrder = 5
Visible = False
end
object Yes: TButton
Left = 240
Height = 30
Top = 216
Width = 80
Caption = 'Yes'
Color = clRed
OnClick = YesClick
TabOrder = 6
Visible = False
end
object No: TButton
Left = 336
Height = 30
Top = 219
Width = 76
Caption = 'No'
Color = clRed
OnClick = NoClick
TabOrder = 7
Visible = False
end
end end

View File

@ -18,17 +18,15 @@ type
TformTappyTuxGame = class(TForm) TformTappyTuxGame = class(TForm)
btnExit: TButton; btnExit: TButton;
Answer: TEdit; Answer: TEdit;
No: TButton;
Yes: TButton;
Level: TEdit; Level: TEdit;
Score: TEdit; Score: TEdit;
Lives: TEdit; Lives: TEdit;
LabelLevels: TLabel; LabelLevels: TLabel;
LabelScore: TLabel; LabelScore: TLabel;
LabelLives: TLabel; LabelLives: TLabel;
GameOver: TToggleBox;
procedure btnExitClick(Sender: TObject); procedure btnExitClick(Sender: TObject);
procedure AnswerKeyPress(Sender: TObject; var Key: char); procedure AnswerKeyPress(Sender: TObject; var Key: char);
procedure FormClose(Sender: TObject; var CloseAction: TCloseAction);
procedure FormCreate(Sender: TObject); procedure FormCreate(Sender: TObject);
procedure FormShow(Sender: TObject); procedure FormShow(Sender: TObject);
procedure NoClick(Sender: TObject); procedure NoClick(Sender: TObject);
@ -65,12 +63,17 @@ procedure TformTappyTuxGame.AnswerKeyPress(Sender: TObject; var Key: char);
begin begin
if Key = #13 then if Key = #13 then
begin begin
GetCurrentModule().Answered(); GetCurrentModule().Answered(Answer.Text);
formTappyTuxGame.Answer.Clear; formTappyTuxGame.Answer.Clear;
end; end;
end; end;
procedure TformTappyTuxGame.FormClose(Sender: TObject;
var CloseAction: TCloseAction);
begin
GetCurrentModule().EndGame();
end;
procedure TformTappyTuxGame.FormCreate(Sender: TObject); procedure TformTappyTuxGame.FormCreate(Sender: TObject);
begin begin
// Creation of internal components // Creation of internal components
@ -91,9 +94,6 @@ end;
procedure TformTappyTuxGame.NoClick(Sender: TObject); procedure TformTappyTuxGame.NoClick(Sender: TObject);
begin begin
GetCurrentModule().EndGame();
Close;
formConfig.Show;
end; end;
@ -103,13 +103,8 @@ begin
end; end;
procedure TformTappyTuxGame.YesClick(Sender: TObject); procedure TformTappyTuxGame.YesClick(Sender: TObject);
var
i: Integer;
begin begin
GetCurrentModule().StartNewGame(formConfig.comboSound.ItemIndex,
formConfig.comboMusic.ItemIndex,
formConfig.comboLevel.ItemIndex,
formConfig.ltbWordlist.ItemIndex);
end; end;

View File

@ -5,9 +5,9 @@ unit mod_tappymath;
interface interface
uses uses
Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls, Classes, SysUtils, Types, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls,
// LCL // LCL
ExtCtrls, ExtCtrls, LCLIntf, LCLType,
// TappyTux // TappyTux
tappyconfig, tappydrawer, tappymodules; tappyconfig, tappydrawer, tappymodules;
@ -16,7 +16,6 @@ type
{ TTappyMath } { TTappyMath }
TTappyMath = class(TTappyModule) TTappyMath = class(TTappyModule)
private private
gameScore : Integer; gameScore : Integer;
gameLives : Integer; gameLives : Integer;
@ -30,7 +29,6 @@ type
count : Integer; count : Integer;
timerMath : TTimer; timerMath : TTimer;
procedure HandleOnTimer(Sender: TObject); procedure HandleOnTimer(Sender: TObject);
public public
constructor Create; override; constructor Create; override;
destructor Destroy; override; destructor Destroy; override;
@ -38,14 +36,16 @@ type
procedure TranslateTextsToPortuguese; override; procedure TranslateTextsToPortuguese; override;
procedure StartNewGame(SndFX: Integer; Music: Integer; Level: Integer; QuestionList: Integer); override; procedure StartNewGame(SndFX: Integer; Music: Integer; Level: Integer; QuestionList: Integer); override;
procedure CreateQuestion(); override; procedure CreateQuestion(); override;
procedure Answered(); override; function GetFallingDurationFromLevel: Integer;
procedure Answered(AText: string); override;
procedure EndGame(); override; procedure EndGame(); override;
procedure GameWon(); override;
procedure GameLost(); override;
procedure ProcessFallingTextEnd(); override;
end; end;
implementation implementation
uses gameplayform;
{ TTappyMath } { TTappyMath }
procedure TTappyMath.HandleOnTimer(Sender: TObject); procedure TTappyMath.HandleOnTimer(Sender: TObject);
@ -54,62 +54,8 @@ var
j: Integer; j: Integer;
frequency: Integer; frequency: Integer;
snowmanWrong: TFallingText; snowmanWrong: TFallingText;
lAnimation: TTappyTuxAnimation;
begin begin
i:= 0;
j:= vTappyTuxDrawer.GetAnimationCount - 1;
while (i<= j) do
begin
if vTappyTuxDrawer.GetAnimation(i).InheritsFrom(TFallingText) then
begin
if (vTappyTuxDrawer.GetAnimation(i).Caption = 'OK!') then
begin
if (vTappyTuxDrawer.GetAnimation(i).Value = '1') then
begin
vTappyTuxDrawer.RemoveAnimation(i);
i := i - 1;
end;
if (vTappyTuxDrawer.GetAnimation(i).Value = '0') then vTappyTuxDrawer.GetAnimation(i).Value := '1';
end;
if (vTappyTuxDrawer.GetAnimation(i).Caption = 'Oh-oh!') then
begin
vTappyTuxDrawer.RemoveAnimation(i);
gameLives := gameLives - 1;
formTappyTuxGame.Lives.Text := IntToStr(gameLives);
CreateQuestion();
if gameLives <= 0 then EndGame();
i := i - 1;
end;
end;
i := i + 1;
j := vTappyTuxDrawer.GetAnimationCount - 1;
end;
i:= 0;
j:= vTappyTuxDrawer.GetAnimationCount - 1;
while (i<= j) do
begin
if vTappyTuxDrawer.GetAnimation(i).InheritsFrom(TFallingText) then
begin
if ((vTappyTuxDrawer.GetAnimation(i).Position.y >= 270) AND (vTappyTuxDrawer.GetAnimation(i).Caption <> 'Oh-oh!')) then
begin
snowmanWrong := TFallingText.Create;
snowmanWrong.IsInfinite := False;
snowmanWrong.StartPoint := vTappyTuxDrawer.GetAnimation(i).Position;
snowmanWrong.EndPoint := vTappyTuxDrawer.GetAnimation(i).Position;
snowmanWrong.Position := vTappyTuxDrawer.GetAnimation(i).Position;
snowmanWrong.LoadImageFromPng(vTappyTuxConfig.GetResourcesDir() + 'images' + PathDelim + 'sprites' + PathDelim + 'snowmanwrong.png');
snowmanWrong.caption:= 'Oh-oh!';
snowmanWrong.value:= '0';
vTappyTuxDrawer.AddAnimation(snowmanWrong);
vTappyTuxDrawer.RemoveAnimation(i);
i := i -1;
end;
end;
i := i + 1;
j := vTappyTuxDrawer.GetAnimationCount - 1;
end;
frequency := 60; frequency := 60;
count := count + 1; count := count + 1;
if count >= frequency then if count >= frequency then
@ -118,8 +64,7 @@ begin
CreateQuestion(); CreateQuestion();
end; end;
vTappyTuxDrawer.HandleAnimationOnTimer(); vTappyTuxDrawer.HandleAnimationOnTimer(timerMath.Interval);
end; end;
constructor TTappyMath.Create; constructor TTappyMath.Create;
@ -159,7 +104,7 @@ var
begin begin
count := 0; count := 0;
timerMath.Enabled := True; timerMath.Enabled := True;
timerMath.Interval:= 500; timerMath.Interval:= 100;
gameScore := 0; gameScore := 0;
gameLives := 5; gameLives := 5;
gameLevel := Level+1; gameLevel := Level+1;
@ -170,13 +115,9 @@ begin
if (Music = 1) then gameMusic := false; if (Music = 1) then gameMusic := false;
gameSLevel := gameLevel; gameSLevel := gameLevel;
formTappyTuxGame.Answer.ReadOnly := false; UpdateLevel(gameLevel);
formTappyTuxGame.GameOver.Visible := false; UpdateScore(gameScore);
formTappyTuxGame.Yes.Visible := false; UpdateLives(gameLives);
formTappyTuxGame.No.Visible := false;
formTappyTuxGame.Level.Text := IntToStr(gameLevel);
formTappyTuxGame.Score.Text := IntToStr(gameScore);
formTappyTuxGame.Lives.Text := IntToStr(gameLives);
// Animations Creation // Animations Creation
lTuxAnimation := TTappySpriteAnimation.Create; lTuxAnimation := TTappySpriteAnimation.Create;
@ -267,7 +208,8 @@ begin
end; end;
snowmanAnimation.StartPoint := Point(xAux, 5); snowmanAnimation.StartPoint := Point(xAux, 5);
snowmanAnimation.EndPoint := Point(xAux, 100); snowmanAnimation.EndPoint := Point(xAux, 270);
snowmanAnimation.StepCount := GetFallingDurationFromLevel();
snowmanAnimation.IsInfinite:= false; snowmanAnimation.IsInfinite:= false;
snowmanAnimation.LoadImageFromPng(vTappyTuxConfig.GetResourcesDir() + 'images' + PathDelim + 'sprites' + PathDelim + 'snowman.png'); snowmanAnimation.LoadImageFromPng(vTappyTuxConfig.GetResourcesDir() + 'images' + PathDelim + 'sprites' + PathDelim + 'snowman.png');
//snowmanAnimation.caption:= gameQuestionList[random(gameQuestionList.Count - 1)]; //snowmanAnimation.caption:= gameQuestionList[random(gameQuestionList.Count - 1)];
@ -278,21 +220,21 @@ begin
0: begin 0: begin
questionType[2] := random(21); questionType[2] := random(21);
questionType[3] := random(21); questionType[3] := random(21);
snowmanAnimation.value := IntToStr(questionType[2] + questionType[3]); snowmanAnimation.value := (questionType[2] + questionType[3]);
snowmanAnimation.caption := IntToStr(questionType[2])+' + ' +IntToStr(questionType[3]); snowmanAnimation.caption := IntToStr(questionType[2])+' + ' +IntToStr(questionType[3]);
end; end;
1: begin 1: begin
questionType[2] := random(21); questionType[2] := random(21);
questionType[3] := random(questionType[2]); questionType[3] := random(questionType[2]);
snowmanAnimation.value := IntToStr(questionType[2] - questionType[3]); snowmanAnimation.value := (questionType[2] - questionType[3]);
snowmanAnimation.caption := IntToStr(questionType[2])+' - ' +IntToStr(questionType[3]); snowmanAnimation.caption := IntToStr(questionType[2])+' - ' +IntToStr(questionType[3]);
end; end;
2: begin 2: begin
questionType[2] := random(11); questionType[2] := random(11);
questionType[3] := random(11); questionType[3] := random(11);
snowmanAnimation.value := IntToStr(questionType[2] * questionType[3]); snowmanAnimation.value := (questionType[2] * questionType[3]);
snowmanAnimation.caption := IntToStr(questionType[2])+' x ' +IntToStr(questionType[3]); snowmanAnimation.caption := IntToStr(questionType[2])+' x ' +IntToStr(questionType[3]);
end; end;
@ -302,43 +244,55 @@ begin
end; end;
procedure TTappyMath.Answered; function TTappyMath.GetFallingDurationFromLevel: Integer;
begin
case gameLevel of
1: Result := 25000;
2: Result := 20000;
3: Result := 15000;
4: Result := 10000;
else
Result := 7000;
end;
end;
procedure TTappyMath.Answered(AText: string);
var var
i: Integer; i: Integer;
j: Integer; j: Integer;
snowmanRight: TFallingText; snowmanRight: TFallingText;
lAnimation: TTappyTuxAnimation;
begin begin
i:= 0; i:= 0;
j:= vTappyTuxDrawer.GetAnimationCount - 1; j:= vTappyTuxDrawer.GetAnimationCount - 1;
while (i<= j) do while (i<= j) do
begin begin
if vTappyTuxDrawer.GetAnimation(i).InheritsFrom(TFallingText) then lAnimation := vTappyTuxDrawer.GetAnimation(i);
if lAnimation is TFallingText then
begin begin
if (vTappyTuxDrawer.GetAnimation(i).value = formTappyTuxGame.Answer.Text) then if TFallingText(lAnimation).value = StrToInt(AText) then
begin begin
gameScore := gameScore +1; gameScore := gameScore +1;
gameLevel := (gameScore div 20) + gameSLevel; gameLevel := (gameScore div 20) + gameSLevel;
formTappyTuxGame.Score.Text := IntToStr(gameScore); UpdateScore(gameScore);
formTappyTuxGame.Level.Text := IntToStr(gameLevel); UpdateLevel(gameLevel);
snowmanRight := TFallingText.Create; snowmanRight := TFallingText.Create;
snowmanRight.IsInfinite := False; snowmanRight.IsInfinite := False;
snowmanRight.StartPoint := vTappyTuxDrawer.GetAnimation(i).Position; snowmanRight.StartPoint := vTappyTuxDrawer.GetAnimation(i).Position;
snowmanRight.EndPoint := vTappyTuxDrawer.GetAnimation(i).Position; snowmanRight.EndPoint := vTappyTuxDrawer.GetAnimation(i).Position;
snowmanRight.Position := vTappyTuxDrawer.GetAnimation(i).Position; snowmanRight.Position := vTappyTuxDrawer.GetAnimation(i).Position;
snowmanRight.caption:= 'OK!'; snowmanRight.StepCount := 2000;
snowmanRight.value:= '0';
snowmanRight.LoadImageFromPng(vTappyTuxConfig.GetResourcesDir() + 'images' + PathDelim + 'sprites' + PathDelim + 'snowmanright.png'); snowmanRight.LoadImageFromPng(vTappyTuxConfig.GetResourcesDir() + 'images' + PathDelim + 'sprites' + PathDelim + 'snowmanright.png');
snowmanRight.caption:= 'OK!';
snowmanRight.ProcessOnEnd := False;
vTappyTuxDrawer.AddAnimation(snowmanRight); vTappyTuxDrawer.AddAnimation(snowmanRight);
vTappyTuxDrawer.RemoveAnimation(i); vTappyTuxDrawer.RemoveAnimation(i);
i := i - 1; i := i - 1;
CreateQuestion;
end; end;
end; end;
i := i + 1; i := i + 1;
j := vTappyTuxDrawer.GetAnimationCount - 1; j := vTappyTuxDrawer.GetAnimationCount - 1;
end; end;
end; end;
procedure TTappyMath.EndGame; procedure TTappyMath.EndGame;
@ -350,16 +304,6 @@ var
exitBtn: TButton; exitBtn: TButton;
begin begin
timerMath.Enabled := False; timerMath.Enabled := False;
formTappyTuxGame.Answer.ReadOnly := true;
//gameOverScreen := TTappySpriteAnimation.Create;
//gameOverScreen.IsInfinite := True;
//gameOverScreen.StartPoint := Point(90, 150);
//gameOverScreen.EndPoint := gameOverScreen.StartPoint;
//SetLength(gameOverScreen.Bitmaps, 1);
//gameOverScreen.Bitmaps[0] := TPortableNetworkGraphic.Create;
//gameOverScreen.Bitmaps[0].LoadFromFile(vTappyTuxConfig.GetResourcesDir() + 'images' + PathDelim + 'sprites' + PathDelim + 'gameover.png');
//vTappyTuxDrawer.AddAnimation(gameOverScreen);
i:= 0; i:= 0;
j:= vTappyTuxDrawer.GetAnimationCount - 1; j:= vTappyTuxDrawer.GetAnimationCount - 1;
@ -368,10 +312,39 @@ begin
vTappyTuxDrawer.RemoveAnimation(i); vTappyTuxDrawer.RemoveAnimation(i);
j := vTappyTuxDrawer.GetAnimationCount - 1; j := vTappyTuxDrawer.GetAnimationCount - 1;
end; end;
end;
formTappyTuxGame.GameOver.Visible := true; procedure TTappyMath.GameWon;
formTappyTuxGame.Yes.Visible := true; var
formTappyTuxGame.No.Visible := true; lRes: Integer;
begin
timerMath.Enabled := False;
// Now check what the user desires to do
lRes := Application.MessageBox(
'Congratulations, you have won the game =D Would you like to play again?', '', MB_YESNO);
if lRes = ID_YES then RestartGame()
else EndGame();
end;
procedure TTappyMath.GameLost;
var
lRes: Integer;
begin
timerMath.Enabled := False;
// Now check what the user desires to do
lRes := Application.MessageBox(
'Unfortunately you have lost =P Would you like to play again?', '', MB_YESNO);
if lRes = ID_YES then RestartGame()
else EndGame();
end;
procedure TTappyMath.ProcessFallingTextEnd;
begin
gameLives := gameLives - 1;
UpdateLives(gameLives);
if gameLives <= 0 then GameLost();
end; end;
initialization initialization

View File

@ -5,9 +5,13 @@ unit mod_tappywords;
interface interface
uses uses
Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls, fpSound, Classes, SysUtils,
//
FileUtil,
//
fpSound,
// LCL // LCL
ExtCtrls, IntfGraphics, ExtCtrls, IntfGraphics, LCLType, Forms, Controls, Graphics, Dialogs, StdCtrls,
// TappyTux // TappyTux
tappyconfig, tappydrawer, tappymodules; tappyconfig, tappydrawer, tappymodules;
@ -16,7 +20,6 @@ type
{ TTappyWords } { TTappyWords }
TTappyWords = class(TTappyModule) TTappyWords = class(TTappyModule)
private private
gameScore : Integer; gameScore : Integer;
gameLives : Integer; gameLives : Integer;
@ -27,6 +30,7 @@ type
gameQuestionList : TStringList; gameQuestionList : TStringList;
count : Integer; count : Integer;
timerWords: TTimer; timerWords: TTimer;
NewQuestionFrequency: Integer;
procedure HandleOnTimer(Sender: TObject); procedure HandleOnTimer(Sender: TObject);
public public
constructor Create; override; constructor Create; override;
@ -35,92 +39,37 @@ type
procedure TranslateTextsToPortuguese; override; procedure TranslateTextsToPortuguese; override;
procedure StartNewGame(SndFX: Integer; Music: Integer; Level: Integer; QuestionList: Integer); override; procedure StartNewGame(SndFX: Integer; Music: Integer; Level: Integer; QuestionList: Integer); override;
procedure createQuestion(); override; procedure createQuestion(); override;
procedure Answered(); override; function GetFallingDurationFromLevel: Integer;
procedure Answered(AText: string); override;
procedure EndGame(); override; procedure EndGame(); override;
procedure GameWon(); override;
procedure GameLost(); override;
procedure ProcessFallingTextEnd(); override;
end; end;
var var
backgroundMusic: TSoundDocument; backgroundMusic: TSoundDocument;
startupSound: TSoundDocument; startupSound: TSoundDocument;
implementation implementation
uses gameplayform;
{ TTappyWords } { TTappyWords }
procedure TTappyWords.HandleOnTimer(Sender: TObject); procedure TTappyWords.HandleOnTimer(Sender: TObject);
var var
i: Integer; i: Integer;
j: Integer; j: Integer;
frequency: Integer;
snowmanWrong: TFallingText; snowmanWrong: TFallingText;
begin begin
i:= 0; // Periodically create new questions
j:= vTappyTuxDrawer.GetAnimationCount - 1; count := count + timerWords.Interval;
while (i<= j) do if count >= NewQuestionFrequency then
begin
if vTappyTuxDrawer.GetAnimation(i).InheritsFrom(TFallingText) then
begin
if (vTappyTuxDrawer.GetAnimation(i).Caption = 'OK!') then
begin
if (vTappyTuxDrawer.GetAnimation(i).Value = '1') then
begin
vTappyTuxDrawer.RemoveAnimation(i);
i := i - 1;
end;
if (vTappyTuxDrawer.GetAnimation(i).Value = '0') then vTappyTuxDrawer.GetAnimation(i).Value := '1';
end;
if (vTappyTuxDrawer.GetAnimation(i).Caption = 'Oh-oh!') then
begin
vTappyTuxDrawer.RemoveAnimation(i);
gameLives := gameLives - 1;
formTappyTuxGame.Lives.Text := IntToStr(gameLives);
CreateQuestion();
if gameLives <= 0 then EndGame();
i := i - 1;
end;
end;
i := i + 1;
j := vTappyTuxDrawer.GetAnimationCount - 1;
end;
i:= 0;
j:= vTappyTuxDrawer.GetAnimationCount - 1;
while (i<= j) do
begin
if vTappyTuxDrawer.GetAnimation(i).InheritsFrom(TFallingText) then
begin
if ((vTappyTuxDrawer.GetAnimation(i).Position.y >= 270) AND (vTappyTuxDrawer.GetAnimation(i).Caption <> 'Oh-oh!')) then
begin
snowmanWrong := TFallingText.Create;
snowmanWrong.IsInfinite := False;
snowmanWrong.StartPoint := vTappyTuxDrawer.GetAnimation(i).Position;
snowmanWrong.EndPoint := vTappyTuxDrawer.GetAnimation(i).Position;
snowmanWrong.Position := vTappyTuxDrawer.GetAnimation(i).Position;
snowmanWrong.caption:= 'Oh-oh!';
snowmanWrong.value:= '0';
snowmanWrong.LoadImageFromPng(vTappyTuxConfig.GetResourcesDir() + 'images' + PathDelim + 'sprites' + PathDelim + 'snowmanwrong.png');
vTappyTuxDrawer.AddAnimation(snowmanWrong);
vTappyTuxDrawer.RemoveAnimation(i);
i := i -1;
end;
end;
i := i + 1;
j := vTappyTuxDrawer.GetAnimationCount - 1;
end;
frequency := 60;
count := count + 1;
if count >= frequency then
begin begin
count := 0; count := 0;
CreateQuestion(); CreateQuestion();
end; end;
vTappyTuxDrawer.HandleAnimationOnTimer(); vTappyTuxDrawer.HandleAnimationOnTimer(timerWords.Interval);
end; end;
constructor TTappyWords.Create; constructor TTappyWords.Create;
@ -129,8 +78,10 @@ begin
timerWords := TTimer.Create(nil); timerWords := TTimer.Create(nil);
timerWords.Enabled := False; timerWords.Enabled := False;
timerWords.Interval := 1000; timerWords.Interval := 100;
timerWords.OnTimer := @HandleOnTimer; timerWords.OnTimer := @HandleOnTimer;
NewQuestionFrequency := 5000;
end; end;
destructor TTappyWords.Destroy; destructor TTappyWords.Destroy;
@ -159,7 +110,7 @@ var
begin begin
count := 5; count := 5;
timerWords.Enabled := True; timerWords.Enabled := True;
timerWords.Interval:= 500; timerWords.Interval := 100;
gameScore := 0; gameScore := 0;
gameLives := 5; gameLives := 5;
gameLevel := Level+1; gameLevel := Level+1;
@ -175,13 +126,9 @@ begin
gameQuestionList.LoadFromFile(vTappyTuxConfig.GetResourcesDir() + 'images'+PathDelim+'modules'+PathDelim+'tappywords'+PathDelim+'0.txt'); gameQuestionList.LoadFromFile(vTappyTuxConfig.GetResourcesDir() + 'images'+PathDelim+'modules'+PathDelim+'tappywords'+PathDelim+'0.txt');
//gameQuestionList.LoadFromFile('C:/'+IntToStr(QuestionList)+'.txt'); //gameQuestionList.LoadFromFile('C:/'+IntToStr(QuestionList)+'.txt');
formTappyTuxGame.Answer.ReadOnly := false; UpdateLevel(gameLevel);
formTappyTuxGame.GameOver.Visible := false; UpdateScore(gameScore);
formTappyTuxGame.Yes.Visible := false; UpdateLives(gameLives);
formTappyTuxGame.No.Visible := false;
formTappyTuxGame.Level.Text := IntToStr(gameLevel);
formTappyTuxGame.Score.Text := IntToStr(gameScore);
formTappyTuxGame.Lives.Text := IntToStr(gameLives);
// Animations Creation // Animations Creation
lTuxAnimation := TTappySpriteAnimation.Create; lTuxAnimation := TTappySpriteAnimation.Create;
@ -203,13 +150,12 @@ begin
//startupSound := TSoundDocument.Create; //startupSound := TSoundDocument.Create;
//startupSound.LoadFromFile(vTappyTuxConfig.GetResourcesDir() + 'images' + PathDelim + 'sounds' + PathDelim + 'startup.wav'); //startupSound.LoadFromFile(vTappyTuxConfig.GetResourcesDir() + 'images' + PathDelim + 'sounds' + PathDelim + 'startup.wav');
for i:= 1 to 5 do for i:= 1 to 3 do
begin begin
CreateQuestion; CreateQuestion;
end; end;
startupSound.Play; startupSound.Play;
end; end;
procedure TTappyWords.CreateQuestion(); procedure TTappyWords.CreateQuestion();
@ -222,7 +168,6 @@ var
existenceAux: array [0..4] of boolean; existenceAux: array [0..4] of boolean;
snowmanAnimation: TFallingText; snowmanAnimation: TFallingText;
begin begin
for i:= 0 to 4 do for i:= 0 to 4 do
begin begin
existenceAux[i]:= False; existenceAux[i]:= False;
@ -279,40 +224,55 @@ begin
end; end;
snowmanAnimation.StartPoint := Point(xAux, 5); snowmanAnimation.StartPoint := Point(xAux, 5);
snowmanAnimation.EndPoint := Point(xAux, 100); snowmanAnimation.EndPoint := Point(xAux, 270);
snowmanAnimation.IsInfinite:= false; snowmanAnimation.IsInfinite := false;
snowmanAnimation.StepCount := GetFallingDurationFromLevel();
snowmanAnimation.LoadImageFromPng(vTappyTuxConfig.GetResourcesDir() + 'images' + PathDelim + 'sprites' + PathDelim + 'snowman.png'); snowmanAnimation.LoadImageFromPng(vTappyTuxConfig.GetResourcesDir() + 'images' + PathDelim + 'sprites' + PathDelim + 'snowman.png');
snowmanAnimation.caption:= gameQuestionList[random(gameQuestionList.Count - 1)]; snowmanAnimation.caption:= gameQuestionList[random(gameQuestionList.Count - 1)];
vTappyTuxDrawer.AddAnimation(snowmanAnimation); vTappyTuxDrawer.AddAnimation(snowmanAnimation);
end; end;
procedure TTappyWords.Answered; function TTappyWords.GetFallingDurationFromLevel: Integer;
begin
case gameLevel of
1: Result := 25000;
2: Result := 20000;
3: Result := 15000;
4: Result := 10000;
else
Result := 7000;
end;
end;
procedure TTappyWords.Answered(AText: string);
var var
i: Integer; i: Integer;
j: Integer; j: Integer;
snowmanRight: TFallingText; snowmanRight: TFallingText;
lAnimation: TTappyTuxAnimation;
begin begin
i:= 0; i:= 0;
j:= vTappyTuxDrawer.GetAnimationCount - 1; j:= vTappyTuxDrawer.GetAnimationCount - 1;
while (i<= j) do while (i<= j) do
begin begin
if vTappyTuxDrawer.GetAnimation(i).InheritsFrom(TFallingText) then lAnimation := vTappyTuxDrawer.GetAnimation(i);
if lAnimation is TFallingText then
begin begin
if (vTappyTuxDrawer.GetAnimation(i).caption = formTappyTuxGame.Answer.Text) then if TFallingText(lAnimation).Caption = AText then
begin begin
gameScore := gameScore +1; gameScore := gameScore +1;
gameLevel := (gameScore div 20) + gameSLevel; gameLevel := (gameScore div 20) + gameSLevel;
formTappyTuxGame.Score.Text := IntToStr(gameScore); UpdateScore(gameScore);
formTappyTuxGame.Level.Text := IntToStr(gameLevel); UpdateLevel(gameLevel);
snowmanRight := TFallingText.Create; snowmanRight := TFallingText.Create;
snowmanRight.IsInfinite := False; snowmanRight.IsInfinite := False;
snowmanRight.StartPoint := vTappyTuxDrawer.GetAnimation(i).Position; snowmanRight.StartPoint := vTappyTuxDrawer.GetAnimation(i).Position;
snowmanRight.EndPoint := vTappyTuxDrawer.GetAnimation(i).Position; snowmanRight.EndPoint := vTappyTuxDrawer.GetAnimation(i).Position;
snowmanRight.Position := vTappyTuxDrawer.GetAnimation(i).Position; snowmanRight.Position := vTappyTuxDrawer.GetAnimation(i).Position;
snowmanRight.StepCount := 2000;
snowmanRight.LoadImageFromPng(vTappyTuxConfig.GetResourcesDir() + 'images' + PathDelim + 'sprites' + PathDelim + 'snowmanright.png'); snowmanRight.LoadImageFromPng(vTappyTuxConfig.GetResourcesDir() + 'images' + PathDelim + 'sprites' + PathDelim + 'snowmanright.png');
snowmanRight.caption:= 'OK!'; snowmanRight.caption:= 'OK!';
snowmanRight.value:= '0'; snowmanRight.ProcessOnEnd := False;
vTappyTuxDrawer.AddAnimation(snowmanRight); vTappyTuxDrawer.AddAnimation(snowmanRight);
vTappyTuxDrawer.RemoveAnimation(i); vTappyTuxDrawer.RemoveAnimation(i);
i := i - 1; i := i - 1;
@ -321,8 +281,6 @@ begin
i := i + 1; i := i + 1;
j := vTappyTuxDrawer.GetAnimationCount - 1; j := vTappyTuxDrawer.GetAnimationCount - 1;
end; end;
CreateQuestion;
end; end;
procedure TTappyWords.EndGame; procedure TTappyWords.EndGame;
@ -334,17 +292,8 @@ var
exitBtn: TButton; exitBtn: TButton;
begin begin
timerWords.Enabled := False; timerWords.Enabled := False;
formTappyTuxGame.Answer.ReadOnly := true;
//gameOverScreen := TTappySpriteAnimation.Create;
//gameOverScreen.IsInfinite := True;
//gameOverScreen.StartPoint := Point(90, 150);
//gameOverScreen.EndPoint := gameOverScreen.StartPoint;
//SetLength(gameOverScreen.Bitmaps, 1);
//gameOverScreen.Bitmaps[0] := TPortableNetworkGraphic.Create;
//gameOverScreen.Bitmaps[0].LoadFromFile(vTappyTuxConfig.GetResourcesDir() + 'images' + PathDelim + 'sprites' + PathDelim + 'gameover.png');
//vTappyTuxDrawer.AddAnimation(gameOverScreen);
// Delete all animations
i:= 0; i:= 0;
j:= vTappyTuxDrawer.GetAnimationCount - 1; j:= vTappyTuxDrawer.GetAnimationCount - 1;
while (i<= j) do while (i<= j) do
@ -353,9 +302,40 @@ begin
j := vTappyTuxDrawer.GetAnimationCount - 1; j := vTappyTuxDrawer.GetAnimationCount - 1;
end; end;
formTappyTuxGame.GameOver.Visible := true; GoToConfigForm();
formTappyTuxGame.Yes.Visible := true; end;
formTappyTuxGame.No.Visible := true;
procedure TTappyWords.GameWon;
var
lRes: Integer;
begin
timerWords.Enabled := False;
// Now check what the user desires to do
lRes := Application.MessageBox(
'Congratulations, you have won the game =D Would you like to play again?', '', MB_YESNO);
if lRes = ID_YES then RestartGame()
else EndGame();
end;
procedure TTappyWords.GameLost;
var
lRes: Integer;
begin
timerWords.Enabled := False;
// Now check what the user desires to do
lRes := Application.MessageBox(
'Unfortunately you have lost =P Would you like to play again?', '', MB_YESNO);
if lRes = ID_YES then RestartGame()
else EndGame();
end;
procedure TTappyWords.ProcessFallingTextEnd;
begin
gameLives := gameLives - 1;
UpdateLives(gameLives);
if gameLives <= 0 then GameLost();
end; end;
initialization initialization

View File

@ -18,10 +18,8 @@ type
StartPoint, EndPoint: TPoint; StartPoint, EndPoint: TPoint;
Position: TPoint; Position: TPoint;
CurrentStep: Integer; CurrentStep: Integer;
StepCount: Integer; StepCount: Integer; // In miliseconds
IsInfinite: Boolean; // if True the animation will never end IsInfinite: Boolean; // if True the animation will never end
caption: String;
value: String;
constructor Create; virtual; constructor Create; virtual;
procedure DrawToIntfImg(AIntfImage: TLazIntfImage); virtual; procedure DrawToIntfImg(AIntfImage: TLazIntfImage); virtual;
procedure DrawToCanvas(ACanvas: TCanvas); virtual; procedure DrawToCanvas(ACanvas: TCanvas); virtual;
@ -34,6 +32,8 @@ type
TTappySpriteAnimation = class(TTappyTuxAnimation) TTappySpriteAnimation = class(TTappyTuxAnimation)
public public
Images: array of TLazIntfImage; Images: array of TLazIntfImage;
SpriteChangeInterval: Integer;
constructor Create; override;
destructor Destroy; override; destructor Destroy; override;
procedure DrawToIntfImg(AIntfImage: TLazIntfImage); override; procedure DrawToIntfImg(AIntfImage: TLazIntfImage); override;
procedure ExecuteFinal; override; procedure ExecuteFinal; override;
@ -43,7 +43,11 @@ type
{ TFallingText } { TFallingText }
TFallingText = class(TTappyTuxAnimation) TFallingText = class(TTappyTuxAnimation)
public public
Caption: String;
Value: Integer;
ProcessOnEnd: Boolean;
Image: TLazIntfImage; Image: TLazIntfImage;
constructor Create; override;
destructor Destroy; override; destructor Destroy; override;
procedure DrawToIntfImg(AIntfImage: TLazIntfImage); override; procedure DrawToIntfImg(AIntfImage: TLazIntfImage); override;
procedure DrawToCanvas(ACanvas: TCanvas); override; procedure DrawToCanvas(ACanvas: TCanvas); override;
@ -78,7 +82,7 @@ type
function GetAnimation(AIndex: Integer): TTappyTuxAnimation; function GetAnimation(AIndex: Integer): TTappyTuxAnimation;
function GetAnimationCount: Integer; function GetAnimationCount: Integer;
procedure RemoveAnimation(AIndex: Integer); procedure RemoveAnimation(AIndex: Integer);
procedure HandleAnimationOnTimer(); procedure HandleAnimationOnTimer(AInterval: Integer);
end; end;
var var
@ -88,6 +92,12 @@ implementation
{ TTappySpriteAnimation } { TTappySpriteAnimation }
constructor TTappySpriteAnimation.Create;
begin
inherited Create;
SpriteChangeInterval := 1000;
end;
destructor TTappySpriteAnimation.Destroy; destructor TTappySpriteAnimation.Destroy;
var var
i: Integer; i: Integer;
@ -104,7 +114,7 @@ begin
lNumBitmaps := Length(Images); lNumBitmaps := Length(Images);
if lNumBitmaps = 0 then Exit; if lNumBitmaps = 0 then Exit;
lCurBmpIndex := CurrentStep mod lNumBitmaps; lCurBmpIndex := (CurrentStep div SpriteChangeInterval) mod lNumBitmaps;
TTappyTuxDrawer.DrawImageWithTransparentColor(AIntfImage, TTappyTuxDrawer.DrawImageWithTransparentColor(AIntfImage,
Position.X, Position.Y, colFuchsia, Images[lCurBmpIndex]); Position.X, Position.Y, colFuchsia, Images[lCurBmpIndex]);
@ -112,7 +122,7 @@ end;
procedure TTappySpriteAnimation.ExecuteFinal; procedure TTappySpriteAnimation.ExecuteFinal;
begin begin
inherited ExecuteFinal;
end; end;
procedure TTappySpriteAnimation.LoadImageFromPng(AIndex: Integer; APath: string); procedure TTappySpriteAnimation.LoadImageFromPng(AIndex: Integer; APath: string);
@ -131,6 +141,12 @@ end;
{TFallingText} {TFallingText}
constructor TFallingText.Create;
begin
inherited Create;
ProcessOnEnd := True;
end;
destructor TFallingText.Destroy; destructor TFallingText.Destroy;
begin begin
if Assigned(Image) then Image.Free; if Assigned(Image) then Image.Free;
@ -145,13 +161,35 @@ end;
procedure TFallingText.DrawToCanvas(ACanvas: TCanvas); procedure TFallingText.DrawToCanvas(ACanvas: TCanvas);
begin begin
//ACanvas.Pixels[CurrentStep, CurrentStep] := clRed; ACanvas.Brush.Style := bsSolid;
ACanvas.Brush.Color := clWhite;
ACanvas.Pen.Style := psSolid;
ACanvas.Pen.Color := clBlack;
ACanvas.Rectangle(Position.X + 25, Position.Y + 45,
Position.X + 30 + ACanvas.TextWidth(Caption)+5,
Position.Y + 50 + ACanvas.TextHeight(Caption)+5);
ACanvas.TextOut(Position.X + 30, Position.Y + 50, caption); ACanvas.TextOut(Position.X + 30, Position.Y + 50, caption);
end; end;
procedure TFallingText.ExecuteFinal; procedure TFallingText.ExecuteFinal;
var
snowmanWrong: TFallingText;
begin begin
inherited ExecuteFinal; if ProcessOnEnd then
begin
snowmanWrong := TFallingText.Create;
snowmanWrong.IsInfinite := False;
snowmanWrong.StartPoint := Position;
snowmanWrong.EndPoint := Position;
snowmanWrong.Position := Position;
snowmanWrong.caption:= 'Oh-oh!';
snowmanWrong.ProcessOnEnd := False;
snowmanWrong.StepCount := 2000;
snowmanWrong.LoadImageFromPng(vTappyTuxConfig.GetResourcesDir() + 'images' + PathDelim + 'sprites' + PathDelim + 'snowmanwrong.png');
vTappyTuxDrawer.AddAnimation(snowmanWrong);
GetCurrentModule().ProcessFallingTextEnd();
end;
end; end;
procedure TFallingText.LoadImageFromPng(APath: string); procedure TFallingText.LoadImageFromPng(APath: string);
@ -176,7 +214,7 @@ begin
inherited Create; inherited Create;
CurrentStep := 0; CurrentStep := 0;
StepCount := 20; StepCount := 20000;
end; end;
procedure TTappyTuxAnimation.DrawToIntfImg(AIntfImage: TLazIntfImage); procedure TTappyTuxAnimation.DrawToIntfImg(AIntfImage: TLazIntfImage);
@ -400,16 +438,24 @@ begin
FAnimationList.Delete(AIndex); FAnimationList.Delete(AIndex);
end; end;
procedure TTappyTuxDrawer.HandleAnimationOnTimer; procedure TTappyTuxDrawer.HandleAnimationOnTimer(AInterval: Integer);
var var
i: Integer; i: Integer;
lAnimation: TTappyTuxAnimation; lAnimation: TTappyTuxAnimation;
begin begin
i := 0;
for i := 0 to FAnimationList.Count - 1 do while i < FAnimationList.Count do
begin begin
lAnimation := TTappyTuxAnimation(FAnimationList.Items[i]); lAnimation := GetAnimation(i);
Inc(lAnimation.CurrentStep); Inc(lAnimation.CurrentStep, AInterval);
if (not lAnimation.IsInfinite) and (lAnimation.CurrentStep >= lAnimation.StepCount) then
begin
lAnimation.ExecuteFinal();
RemoveAnimation(i);
Continue;
end;
Inc(i);
end; end;
Self.Invalidate; Self.Invalidate;

View File

@ -22,14 +22,22 @@ type
destructor Destroy; override; destructor Destroy; override;
procedure LoadImages; virtual; procedure LoadImages; virtual;
function GetBackgroundImage(ALevel: Integer): TJPEGImage; function GetBackgroundImage(ALevel: Integer): TJPEGImage;
procedure GoToConfigForm;
procedure RestartGame;
procedure UpdateLevel(ALevel: Integer);
procedure UpdateScore(AScore: Integer);
procedure UpdateLives(ALives: Integer);
procedure TranslateTexts(ALanguage: Integer); procedure TranslateTexts(ALanguage: Integer);
procedure TranslateTextsToEnglish; virtual; procedure TranslateTextsToEnglish; virtual;
procedure TranslateTextsToPortuguese; virtual; procedure TranslateTextsToPortuguese; virtual;
procedure InitModule(); virtual; procedure InitModule(); virtual;
procedure StartNewGame(SndFX: Integer; Music: Integer; Level: Integer; QuestionList: Integer); virtual; abstract; procedure StartNewGame(SndFX: Integer; Music: Integer; Level: Integer; QuestionList: Integer); virtual; abstract;
procedure CreateQuestion(); virtual; abstract; procedure CreateQuestion(); virtual; abstract;
procedure Answered(); virtual; abstract; procedure Answered(AText: string); virtual; abstract;
procedure EndGame(); virtual; abstract; procedure EndGame(); virtual; abstract;
procedure GameWon(); virtual; abstract;
procedure GameLost(); virtual; abstract;
procedure ProcessFallingTextEnd(); virtual; abstract;
end; end;
procedure AddModule(AModule: TTappyModule); procedure AddModule(AModule: TTappyModule);
@ -40,12 +48,16 @@ procedure SetCurrentModule(AIndex: Integer);
implementation implementation
uses
gameplayform, gameconfigform;
var var
gTappyModules: TFPList; gTappyModules: TFPList;
gCurrentTappyModule: Integer = 0; //=-1 gCurrentTappyModule: Integer = 0; //=-1
procedure AddModule(AModule: TTappyModule); procedure AddModule(AModule: TTappyModule);
begin begin
if gTappyModules = nil then gTappyModules := TFPList.Create;
gTappyModules.Add(Pointer(AModule)); gTappyModules.Add(Pointer(AModule));
end; end;
@ -104,6 +116,35 @@ begin
Result := imgLevel3; Result := imgLevel3;
end; end;
procedure TTappyModule.GoToConfigForm;
begin
formConfig.Show;
formTappyTuxGame.Hide;
end;
procedure TTappyModule.RestartGame;
begin
StartNewGame(formConfig.comboSound.ItemIndex,
formConfig.comboMusic.ItemIndex,
formConfig.comboLevel.ItemIndex,
formConfig.ltbWordlist.ItemIndex);
end;
procedure TTappyModule.UpdateLevel(ALevel: Integer);
begin
formTappyTuxGame.Level.Text := IntToStr(ALevel);
end;
procedure TTappyModule.UpdateScore(AScore: Integer);
begin
formTappyTuxGame.Score.Text := IntToStr(AScore);
end;
procedure TTappyModule.UpdateLives(ALives: Integer);
begin
formTappyTuxGame.Lives.Text := IntToStr(ALives);
end;
procedure TTappyModule.TranslateTexts(ALanguage: Integer); procedure TTappyModule.TranslateTexts(ALanguage: Integer);
begin begin
case ALanguage of case ALanguage of
@ -128,6 +169,7 @@ begin
end; end;
initialization initialization
if gTappyModules = nil then
gTappyModules := TFPList.Create; gTappyModules := TFPList.Create;
finalization finalization
gTappyModules.Free; gTappyModules.Free;