Results 1 to 10 of 31

Thread: Dynamic in-game object creation and manipulation

Hybrid View

Previous Post Previous Post   Next Post Next Post
  1. #1
    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.
    Right!
    (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.)

  2. #2
    Quote Originally Posted by Tomi View Post
    Right!
    (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.

  3. #3
    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.

  4. #4
    You can use dynamic arrays. They are declared pretty much the same as fixed-size arrays - just don't specify the size. e.g.
    Code:
    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.

  5. #5
    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?

  6. #6
    Quote Originally Posted by Super Vegeta View Post
    or maybe do something like NewLength := OldLength * 1.5.
    I strongly recommend against using of this approach. Why? Because it leads to exponential growth of the array and could therefore become a great memory hog.
    Imagine next scenario. You have an arrays with 100k items. Each item is 10KB in size. Which means that your array would be roughly 1GB in size. So following your approach adding 1 additional item would increase its size from roughly 1GB to 1.5GB in size. Or in other hand you would be wasting about 500MB of memory just because you had to increase the size of the array to hold additional item.
    So I would rather suggest increasing the array in fixed increments instead.

    Quote Originally Posted by Tomi View Post
    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?
    While dynamic arrays do allow you to change their size at any time you don't have to do this. If you want you can set their size at the start based on your expected requirement and don't update their size later on.
    One instance of this would be using dynamic arrays to store game map. You know the map dimensions upon level loading so you set the size of dynamic array to be big enough to hold that data and you don't resize them until you decide to load different level.
    So unless you are concerned about your game to be using as little memory as possible the whole time you don't need to be to much concerned about resizing of dynamic arrays you would probably do it rarely.

  7. #7
    PGD Staff / News Reporter phibermon's Avatar
    Join Date
    Sep 2009
    Location
    England
    Posts
    524
    It's just an example - exponential array growth is a *good* solution - if you're using dynamic arrays in such a way then it means you have no idea on the maximum number of elements you need - ergo an exponential growth is a good default mode of operation.

    Take a parser that loaded lines of text - it might be asked to load 10 lines and then it might be asked to load 10 million lines - a fixed increment would have to be huge to make this close to efficient in terms of performance and it would then become inefficient in terms of storage for smaller numbers of lines.

    Exponential growth is the best trade-off you can make between performance and storage in a number of scenarios - the detriment remains roughly equal across both domains.

    In fact a better solution is to have an affordable but reasonably large initial size (say 4096 elements) and then grow exponentially from that - you lose a little bit of storage space for lots of small collections but you minimize the number of resizes as they're all bunched at the lower end with exponential growth.

    if you *know* you're storing 1GB of data in memory then you *never* want to be resizing an array of that size anyway - that's just silly - you'd pick a more efficient access pattern in the first place - one that doesn't rely on continuous blocks across the entire set.

    Memory is plentiful, you can afford to waste some for the sake of performance.
    Last edited by phibermon; 20-12-2015 at 12:01 AM.
    When the moon hits your eye like a big pizza pie - that's an extinction level impact event.

Bookmarks

Posting Permissions

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