Recent

Author Topic: Caste Game Engine  (Read 820 times)

Maksim_maksim

  • Newbie
  • Posts: 4
Caste Game Engine
« on: November 13, 2019, 08:06:21 am »
Hi all.

How to correct the code, added 3 pictures, how to properly shift pictures separately?

Code: Pascal  [Select]
  1. unit Unit1;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.   Classes, SysUtils, Forms, Controls, Graphics, Dialogs, CastleControl, CastleGLImages, CastleFilesUtils, CastleKeysMouse;
  9.  
  10. type
  11.  
  12.   { TForm1 }
  13.  
  14.   TForm1 = class(TForm)
  15.     CastleControl1: TCastleControl;
  16.     procedure CastleControl1Press(Sender: TObject;
  17.       const Event: TInputPressRelease);
  18.     procedure CastleControl1Render(Sender: TObject);
  19.     procedure CastleControl1Update(Sender: TObject);
  20.     procedure FormCreate(Sender: TObject);
  21.     procedure FormDestroy(Sender: TObject);
  22.   private
  23.     Image, Image1, Image2: TGLImage;
  24.     X,x1, Y, y1: Single;
  25.   public
  26.  
  27.   end;
  28.  
  29. var
  30.   Form1: TForm1;
  31.  
  32. implementation
  33.  
  34. {$R *.lfm}
  35.  
  36. { TForm1 }
  37.  
  38. procedure TForm1.FormCreate(Sender: TObject);
  39. begin
  40.     Image := TGLImage.Create(ApplicationData('/IMG/player1.png'));
  41.     Image1 := TGLImage.Create(ApplicationData('/IMG/player2.png'));
  42.     Image2 := TGLImage.Create(ApplicationData('/IMG/objects/Box.png'));
  43. end;
  44.  
  45. procedure TForm1.CastleControl1Render(Sender: TObject);
  46. var i : integer;
  47. begin
  48.    Image.Draw(X, Y+16);
  49.    Image2.Draw(X, Y);
  50.    Image2.Draw(X+16, Y);
  51.    Image2.Draw(X+32, Y);
  52.    Image2.Draw(X+48, Y);
  53.    Image2.Draw(X+64, Y);
  54. end;
  55.  
  56. procedure TForm1.CastleControl1Press(Sender: TObject;
  57.   const Event: TInputPressRelease);
  58. begin
  59.     if Event.IsKey(K_Space) then  begin
  60.     Y := Y + 30.0;
  61.     X := X + 10.0;
  62.     end;
  63. end;
  64.  
  65. procedure TForm1.CastleControl1Update(Sender: TObject);
  66. var
  67.   SecondsPassed: Single;
  68. begin
  69.   if CastleControl1.Pressed[K_Left] then
  70.   begin
  71.      X := X - 2.0;
  72.   end;
  73.  
  74.   if CastleControl1.Pressed[K_Right] then
  75.     X := X + 2.0;
  76. end;
  77.  
  78. procedure TForm1.FormDestroy(Sender: TObject);
  79. begin
  80.    FreeAndNil(Image);
  81. end;
  82.  
  83. end.
  84.  




Maybe who has books on caste game engine?

Eugene Loza

  • Hero Member
  • *****
  • Posts: 563
    • My "almost daily" development blog
Re: Caste Game Engine
« Reply #1 on: November 13, 2019, 09:41:12 am »
I've tested your program and it works fine for me - all the images are moved "synchronously" when pressing K_Left, K_Right and K_Space. Note, that you have memory leaks here as you load Image, Image1 and Image2, but never free Image1 and Image2.
Quote
how to properly shift pictures separately?
You'll need to add separate X and Y coordinates for them. Currently TForm1.CastleControl1Render renders all the images relative to X, Y - which are changed by TForm1.CastleControl1Press and TForm1.CastleControl1Update. E.g. if you want the "player character" to walk around some other images (like walls or enemies) you'll need to make something like PlayerX, PlayerY.
Quote
Maybe who has books on caste game engine?
Unfortunately there are no specific books on Castle Game Engine at the moment. You can read an extensive documentation and a lot of tutorials here: https://castle-engine.io/documentation.php. Be sure to check examples folder too.
There is also a book on FreePascal by the Engine's author, Michalis: https://castle-engine.io/modern_pascal_introduction.html (Also translated into Russian: https://castle-engine.io/modern_pascal_introduction_russian.html) which sometimes refers to some functions Castle Game Engine.
Lazarus 1.9 + FPC 3.1.1 Debian Jessie 64 bit.

My Free and Open Source games in Lazarus/FreePascal/CastleGameEngine:
https://decoherence.itch.io/
(and some ancient games in Turbo Pascal too)
Sources are here: https://github.com/eugeneloza?tab=repositories

Maksim_maksim

  • Newbie
  • Posts: 4
Re: Caste Game Engine
« Reply #2 on: November 13, 2019, 10:00:39 am »
Thank's.   Thanks for the links, already reading. Can eat little example with used "PlayerX, PlayerY"?

Eugene Loza

  • Hero Member
  • *****
  • Posts: 563
    • My "almost daily" development blog
Re: Caste Game Engine
« Reply #3 on: December 02, 2019, 07:42:19 pm »
Sorry for late reply...

Quote
Can eat little example with used "PlayerX, PlayerY"?

Check this way:

Code: Pascal  [Select]
  1. unit Unit1;
  2.  
  3. interface
  4.  
  5. uses
  6.   Classes, SysUtils, Forms, Controls, Graphics, Dialogs, CastleControl,
  7.   CastleGLImages, CastleKeysMouse, CastleTimeUtils;
  8.  
  9. type
  10.   TPlayer = class(TComponent)
  11.   public
  12.     Image: TGLImage;
  13.     X, Y: Single;
  14.     procedure Draw;
  15.     destructor Destroy; override;
  16.   end;
  17.  
  18.   TForm1 = class(TForm)
  19.     CastleControl1: TCastleControl;
  20.     procedure CastleControl1Press(Sender: TObject;
  21.       const Event: TInputPressRelease);
  22.     procedure CastleControl1Render(Sender: TObject);
  23.     procedure CastleControl1Update(Sender: TObject);
  24.     procedure FormCreate(Sender: TObject);
  25.     procedure FormDestroy(Sender: TObject);
  26.   private
  27.     GameTimer: TTimerResult;
  28.     Player1, Player2: TPlayer;
  29.     WallImage: TGLImage;
  30.   public
  31.  
  32.   end;
  33.  
  34. var
  35.   Form1: TForm1;
  36.  
  37. implementation
  38.  
  39. {$R *.lfm}
  40.  
  41. destructor TPlayer.Destroy;
  42. begin
  43.   FreeAndNil(Image);
  44.   inherited;
  45. end;
  46.  
  47. procedure TPlayer.Draw;
  48. begin
  49.   Image.Draw(X, Y);
  50. end;
  51.  
  52. procedure TForm1.FormCreate(Sender: TObject);
  53. begin
  54.   Player1 := TPlayer.Create(Self);
  55.   Player1.Image := TGLImage.Create('castle-data:/IMG/player1.png', true);
  56.   Player1.X := 32;
  57.   Player1.Y := 32;
  58.   Player2 := TPlayer.Create(Self);
  59.   Player2.Image := TGLImage.Create('castle-data:/IMG/player2.png', true);
  60.   Player2.X := 96;
  61.   Player2.Y := 96;
  62.   WallImage := TGLImage.Create('castle-data:/IMG/objects/Box.png', true);
  63.   GameTimer := Timer;
  64. end;
  65.  
  66. procedure TForm1.CastleControl1Render(Sender: TObject);
  67. var
  68.   I, J: integer;
  69. begin
  70.   Player1.Draw;
  71.   Player2.Draw;
  72.   for I := 0 to 10 do
  73.     for J := 0 to 10 do
  74.       if Odd(I + J) and Odd(I * 2 + J * 5) then
  75.         WallImage.Draw(I * 16, J * 16);
  76. end;
  77.  
  78. procedure TForm1.CastleControl1Press(Sender: TObject;
  79.   const Event: TInputPressRelease);
  80. begin
  81.   if Event.IsKey(keySpace) then
  82.   begin
  83.     Player2.Y := Player2.Y + 30.0;
  84.     Player2.X := Player2.X + 10.0;
  85.   end;
  86. end;
  87.  
  88. procedure TForm1.CastleControl1Update(Sender: TObject);
  89. var
  90.   SecondsPassed: TFloatTime;
  91. begin
  92.   SecondsPassed := TimerSeconds(Timer, GameTimer);
  93.   GameTimer := Timer;
  94.  
  95.   if CastleControl1.Pressed[keyLeft] then
  96.     Player1.X := Player1.X - 80.0 * SecondsPassed;
  97.   if CastleControl1.Pressed[keyRight] then
  98.     Player1.X := Player1.X + 80.0 * SecondsPassed;
  99. end;
  100.  
  101. procedure TForm1.FormDestroy(Sender: TObject);
  102. begin
  103.   FreeAndNil(WallImage);
  104. end;
  105.  
  106. end.

Overall, introduction of TPlayer wasn't absolutely necessary here, however, as you will develop more complex game, you may find very convenient to keep "everything related to some entity" in one class. E.g. this way we won't accidentally mix "player's 1 X and Y" with "player's 2 X1 and Y1". Also note Destructor which correctly frees the player's image.

Note: I was very surprised to see that there is no SecondsPassed in TCastleControl.OnUpdate event, so you might see I had to workaround it through CastleTimeUtils: Timer which is equivalent to SysUtils Now function, but is more accurate for counting frame time.
Lazarus 1.9 + FPC 3.1.1 Debian Jessie 64 bit.

My Free and Open Source games in Lazarus/FreePascal/CastleGameEngine:
https://decoherence.itch.io/
(and some ancient games in Turbo Pascal too)
Sources are here: https://github.com/eugeneloza?tab=repositories