Sorry your browser is not supported!

You are using an outdated browser that does not support modern web technologies, in order to use this site please update to a new browser.

Browsers supported include Chrome, FireFox, Safari, Opera, Internet Explorer 10+ or Microsoft Edge.

Code Snippets / [DBP] Easy and fast management of objects and sounds

Author
Message
Lucy
17
Years of Service
User Offline
Joined: 19th Apr 2007
Location: Roanoke, VA USA
Posted: 10th Apr 2009 20:16 Edited at: 13th Apr 2009 21:23
You're free to use this code for any purpose, even world domination. Just please mention me somewhere in the credits and let me know what you've used it in, huh?

This snippet shows how to efficiently juggle potentially thousands of objects and dozens of sounds with minimal slowdown without having to touch any plugins. It also frees your hands of having to EVER keep track of object and sound numbers EVER AGAIN! Instead, all you need to do is remember which base index is which.

What it does is it keeps two array for objects and two arrays for sounds. One array is a base which stores the object and sound numbers to the original objects and sounds.

The other stores the cloned objects which are what actually gets displayed to the screen or output to the speakers.

For instance, "play_sound(1)" doesn't play sound 1, it makes a copy of the base sound whose index in the array is 1. It then plays the sound. When the sound finishes being played, it is automatically removed from the game, leaving the original base sound in tact for future use. In this fashion, you can have many sounds going at once without having to worry about managing them all.

Also, as a bonus, the code shows how to do timer based movement to ensure that objects move at the same rate no matter the frame rate.



Remember all that time in school that you complained that math is useless and you'll never need to know trig or calc? Guess what. If you're reading this, you need them.
Latch
17
Years of Service
User Offline
Joined: 23rd Jul 2006
Location:
Posted: 10th Apr 2009 22:04 Edited at: 10th Apr 2009 22:12
Quote: "`I used to check in a linear sequence, finding the lowest
`numbered free object/sound/etc
`but then it occured to me that if I checked a random range
`it should in theory have much less impact for spawning.
`since it's more likely to find a free object on the
`first go, and far more likely from there on as well
function GetFreeObjectFast()
ret as dword : ret = rnd(200000)
while object exist(ret)
ret = rnd(100000)
endwhile
endfunction ret"


Because there is the potential of never returning a free object with a random selection I would suggest sorting your arrays. In DBC, the highest returnable value from RND() is 32767. That may not be the case with DBPro. However, it might make sense to use quicksort on your object/sound arrays and always grab the top most index which in theory should always be free. And if the arrays are already sorted, each resort will be extremely fast with quicksort.

Might take a little restructuring in that your arrays would have to have an indicator of in use or not in use - which would be the sorting criteria - then you'd pull the available object number from the top of the array.

Enjoy your day.
Sixty Squares
17
Years of Service
User Offline
Joined: 7th Jun 2006
Location: Somewhere in the world
Posted: 10th Apr 2009 23:41 Edited at: 10th Apr 2009 23:42
Clever . I'm doing something like this for some objects in my game but I never thought of using it on sounds (I didn't even know there was a clone sound command)! Thanks for posting this.

<---Spell casting battle game!
Lucy
17
Years of Service
User Offline
Joined: 19th Apr 2007
Location: Roanoke, VA USA
Posted: 12th Apr 2009 18:14
Quote: "Because there is the potential of never returning a free object with a random selection I would suggest sorting your arrays. In DBC, the highest returnable value from RND() is 32767. That may not be the case with DBPro. However, it might make sense to use quicksort on your object/sound arrays and always grab the top most index which in theory should always be free. And if the arrays are already sorted, each resort will be extremely fast with quicksort."


Well, this isn't for DBC, it's for DBPro. In DBPro, rnd() returns a 32bit float, not a 16bit integer.

Also, if you'd read the code, GetFreeObjectFast() is actually going into a loop. I took it into consideration that it may find a duplicate, so it keeps picking random places until it finds one that's free. It's just the fact that it's doing random instead of sequential means that it's statistically impossible for it to go through more iterations of the loop to find a free place than it would if I were checking sequentially. Those comments in the code were merely saying why I was using ret = rnd() instead of ret = ret + 1 on iteration.

Everything I needed to know about trigonometry, I learned by becoming a game programmer.
Latch
17
Years of Service
User Offline
Joined: 23rd Jul 2006
Location:
Posted: 13th Apr 2009 01:23
Quote: "Also, if you'd read the code, GetFreeObjectFast() is actually going into a loop"

I thought I did. Even in a loop, the same random number could be generated over and over (not likely though). That's why I suggested an implementation of quick sort. On already sorted arrays the actual looping (sorting) would be very short, and there could even be an exit of the sort as soon as an available object sorts to the top. The sort could even be called in blocks - the top 10 or 100 or whatever available clone numbers could be on the top of the stack, and only after they are all pulled off is the sort run again instead of sorting or randomly picking each iteration. But, I didn't test any of this - it's just off the top of my head. It might not work at all

Enjoy your day.
Benjamin
21
Years of Service
User Offline
Joined: 24th Nov 2002
Location: France
Posted: 13th Apr 2009 15:22
I'm pretty sure a more efficient way of handling media number allocation is to use an array containing media numbers. When you need a free media number, you simply take it from the array at the counter position, blank the slot, and increment the counter. When you're done with the media number, you decrement the counter and store the media number in the array at the counter position. It's pretty fast and the operation occurs in constant time.

Lucy
17
Years of Service
User Offline
Joined: 19th Apr 2007
Location: Roanoke, VA USA
Posted: 13th Apr 2009 21:15 Edited at: 13th Apr 2009 21:25
Quote: "I'm pretty sure a more efficient way of handling media number allocation is to use an array containing media numbers. When you need a free media number, you simply take it from the array at the counter position, blank the slot, and increment the counter. When you're done with the media number, you decrement the counter and store the media number in the array at the counter position. It's pretty fast and the operation occurs in constant time."


That is another way of handling it, yes. However, you're assuming that objects are being created and deleted at the same rate. Your idea (as I understand how you've worded it) has the potential for creating memory leaks if more than one object is deleted before another is created. Also, I'm seeing the potential for media number collisions.

Maybe I'm misinterpreting what you're saying, so if you could be so kind as to adapt my snippet to show you what you mean?

As to Latch. A quicksort is fast, yes, but it's not as fast as not even needing to sort. If you have 500 objects and you're quicksorting them every time you delete an object, you're still going through the quicksort loop a lot more than you'd go through my random loop on object creation. Even if it finds the same number twice (highly unlikely) it becomes exponentially more unlikely each iteration. Statistically speaking, there are fewer instructions run per creation with my random search than per deletion with your sorting.

If you can show me an instance where a random number generator with that high of a range produces the same number enough times in a row to make quicksort worth it, then I'll use a quicksort.

Granted, with a large enough number of objects, the quicksort likely would result in finding a free media number faster. But I'm operating under the assumption that a game that has enough objects loadedin to cause that circumstance to occur is going to be unplayably bogged down by the sheer enormity of the object splatting.

Remember all that time in school that you complained that math is useless and you'll never need to know trig or calc? Guess what. If you're reading this, you need them.
Benjamin
21
Years of Service
User Offline
Joined: 24th Nov 2002
Location: France
Posted: 14th Apr 2009 07:02 Edited at: 14th Apr 2009 07:06
Quote: "Your idea (as I understand how you've worded it) has the potential for creating memory leaks if more than one object is deleted before another is created."

It doesn't. The only consequence of doing creation/deletion at an uneven rate is that the object numbers become shuffled about in the array, which isn't an issue at all. A couple of things to note:

1. A separate array must be used per type of media.
2. Array indices do not correspond to media numbers.



Of course, when you run out of media numbers you need to enlarge the array, but this is just a case of re-dim-ing and looping through the added array elements storing new media numbers.

I used to use a linked list for this style of allocation until someone explained how this can be done with arrays.

Login to post a reply

Server time is: 2024-05-18 14:44:10
Your offset time is: 2024-05-18 14:44:10