Page 1 of 4 123 ... LastLast
Results 1 to 10 of 31

Thread: Dynamic in-game object creation and manipulation

  1. #1

    Dynamic in-game object creation and manipulation

    Hello everybody!
    I'm still new here and the Lazarus is a bit new for me. I would like make a small game with Lazarus, in which the player can put down balls in the window on the mouse coordinates - but my code doesn't work. Here is:

    unit Unit1;
    {$mode objfpc}{$H+}
      Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, mouse;
      { TMainWindow }
      TMainWindow = class(TForm)
        procedure FormClick(Sender: TObject);
        procedure FormCreate(Sender: TObject);
        { private declarations }
        { public declarations }
    type TBall=class(TObject)
        constructor makeit(xplace,yplace: integer; itspic: Tbitmap);
      MainWindow: TMainWindow;
      ballpic: TBitmap;
      aball: TBall;
    {$R *.lfm}
    constructor TBall.makeit(xplace,yplace: integer; itspic: Tbitmap);
    { TMainWindow }
    procedure TMainWindow.FormClick(Sender: TObject);
    procedure TMainWindow.FormCreate(Sender: TObject);
    And the error messages:
    Projekt fordítása, Cél: kepfutidoben.exe: Kilépési kód: 1, Hibák: 3, Tippek: 3
    unit1.pas(26,24) Hint: Value parameter "xplace" is assigned but never used
    unit1.pas(26,31) Hint: Value parameter "yplace" is assigned but never used
    unit1.pas(26,4 Hint: Value parameter "itspic" is assigned but never used
    unit1.pas(50,36) Error: identifier idents no member "xplace"
    unit1.pas(50,49) Error: identifier idents no member "yplace"
    unit1.pas(50,62) Error: identifier idents no member "itspic"

    Somebody can help me to solving this problem? I would like placing ball objects at runtime.
    Last edited by SilverWarior; 18-12-2015 at 04:45 PM. Reason: Adding code tags

  2. #2
    Your Ball does not have any fields inside. It does not store any information. What you do is make a constructor that takes three arguments, overwrites their value and discards them. What you want is to have your Ball store information about its position and picture. This is done via fields inside the class. Check out the FreePascal language guide:
    Also, you should use the [code]your pascal code here[/code] tags when pasting in code. Preferably make a new topic if you have more questions. (Or maybe a mod can move this post into a separate topic?)

  3. #3
    I didn't know these things, Super Vegeta, and I didn't want to burden the forum with a new thread; sorry... But I have corrected my code according to your advice, and now it works properly; thank you for your help!
    And now let's go programming!

  4. #4
    Quote Originally Posted by SilverWarior View Post
    if you want I can move your posts in a new thread inside a "My project" section of the forum which is not intended for specific topics.
    (Although my first Lazarus game project will be (hopefully) a small space shooter, not that ball game, in which I only asked for information about creating objects in runtime.)

  5. #5
    Quote Originally Posted by Tomi View Post
    (Although my first Lazarus game project will be (hopefully) a small space shooter, not that ball game, in which I only asked for information about creating objects in runtime.)
    You say you are interested in making a small space shooter. Do you need any guidance in specific areas like:
    - defining classes for ingame units (entities)
    - defining data structure for storing game level information
    - performing collision detection between different ingame entities
    If so I can provide you a few ideas for implementing these.

  6. #6
    Thank you for summary, SilverWarrior.
    And what is the best way of cleaning the object instances from the memory and it's picture from the screen?
    Now, I'm using arrays to store the instances and the FreeAndNil(); to delete the instances from the array, and after I use Canvas.Clear; to wipe the screen.
    for i:=1 to numofenemies-1 do FreeAndNil(enemies[i]);
    After all, it's works, but is this the only and best solution? Because in this case I have to give the maximum amount of enemies, shoots, etc. at the declaration of these arrays ( var enemies: array [1..100] of Tenemy; ), and I would like keep open the possibility to add new instances to the arrays, then redimensioning these arrays - if it's possible.

  7. #7
    You can use dynamic arrays. They are declared pretty much the same as fixed-size arrays - just don't specify the size. e.g.
    Var Enemies: Array of TEnemy;
    Then you can use the Length() function to check the current array size and SetLength() to change the size (on program start, the size is 0). Dynamic arrays are always indexed from 0 to Length(ArrayVar)-1.
    One thing that should be noted, though, is that resizing the array is quite a complicated task - the program has to find a new, contiguous memory region of required size, copy-paste all the values from the old place in memory to the new one, and then free the old memory region. As such, it's best to only change the array size when necessary (so don't call SetLength() every time you add/remove an enemy), and to do it in some larger steps - so instead of increasing the array by 1 slot when you need to add a new enemy, you increase it by, for example, 16 slots, or maybe do something like NewLength := OldLength * 1.5. This way, the next time you need to add an enemy, you don't have to resize the array again, but can use one of the empty slots you got left from the previous resize.

  8. #8
    Wow, thanks, Super Vegeta! I didn't know this technique about dynamic arrays. But using of it are not recommended because the resizing is complicated?

  9. #9
    Is the right place for drawing objects the FormPaint event? I have put the following piece of code there, but the bullets aren't visible. Only the background and the player's spaceship are visible. What is wrong?
    procedure TMain.FormPaint(Sender: TObject);
      var i: integer;
      Canvas.StretchDraw(Rect(0, 0, ClientWidth, ClientHeight), backg);
      if numofbullets>1 then
           for i:=1 to numofbullets-1 do
            if bullets[i]<>nil then

  10. #10
    PGD Staff / News Reporter phibermon's Avatar
    Join Date
    Sep 2009
    Firstly dynamic arrays start at 0 so you should do :

    for I := 0 to numofbullets-1 do
    Secondly your answer my lie in your checks - you've got an array of bullets and you're checking to see if a member is nil before you render - perhaps they are nil? please post your code for how you setup the array of bullets so we can check to see if that's a factor.

    Thirdly you have a 'picture' property for each bullet - if each bullet has a different image then this is fine but I'm guessing you only have a single bullet texture - it's best to load it once and draw it over and over for each bullet - only storing the unique properties per bullet IE :

    Canvas.Draw(bullets[i].xplace,bullets[i].yplace, FGlobalBulletPicture);
    and lastly because dynamic arrays start at 0 you don't need :

    if numofbullets>1 then
    (but that should read numofbullets > 0 or numofbullets >= 1) because :

    for I := 0 to numofbullets-1 do
    when numofbullets = 0 equates to :

    for 0 to -1 do
    Which will not enter the loop (use 'downto' instead of 'to' if you want to use descending for loops)
    Last edited by phibermon; 19-12-2015 at 06:52 PM.
    When the moon hits your eye like a big pizza pie - that's an extinction level impact event.

Page 1 of 4 123 ... LastLast


Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts