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.
`Make a type for objects
type OBJECT_INFO
obj as dword
base as dword
lifespan as dword
spawntime as dword
linear_vel_x as float
linear_vel_y as float
linear_vel_z as float
angular_vel_x as float
angular_vel_y as float
angular_vel_z as float
endtype
`Declare our
dim objects(0) as OBJECT_INFO `this is where we put objects in play
dim objectbase(0) as OBJECT_INFO `original objects for cloning go here
dim sounds(0) as dword `playing sounds here
dim soundbase(0) as dword `original sounds here
`empty the arrays so they have no data since we haven't filled yet
empty array objects()
empty array objectbase()
empty array sounds()
empty array soundbase()
init()
main()
function init()
`set display mode 1680, 1050, 32
sync on
backdrop on
autocam off
move camera -30
`make base objects
array insert at bottom objectbase()
objectbase(0).obj = GetFreeObjectFast()
make object sphere objectbase(0).obj, 1
exclude object on objectbase(0).obj
array insert at bottom objectbase()
objectbase(1).obj = GetFreeObjectFast()
make object cube objectbase(1).obj, 1
exclude object on objectbase(1).obj
array insert at bottom objectbase()
objectbase(2).obj = GetFreeObjectFast()
make object plain objectbase(2).obj, 1, 1
exclude object on objectbase(2).obj
remstart
`this code is for loading sounds into the base sound
`since I haven't included media, this is commented out
`but it's left in for demonstration purposes
soundbase(0) = GetFreeSoundFast()
load sound "sound0.wav", soundbase(0)
load sound "sound1.wav", soundbase(1)
load sound "sound2.wav", soundbase(2)
remend
endfunction
function main()
lasttime = 0 `set up our timer based movement
lastthrow = 0
do
time = timer() `what time is it?
speed# = 1 + (time - lasttime) `how long has it been since the last loop?, and set a minimum of 1ms
lasttime = time `reset our lasttime
set cursor 0,0
print "FPS: " + str$(screen fps())
if time - lastthrow > 50 `throw a new object every 50 miliseconds
throw_new_random_base_object(time)
lastthrow = time
endif
garb_collect_objects(time)
update_objects(speed#)
sync
loop
endfunction
function throw_new_random_base_object(time)
randomize time
num_base = array count(objectbase())
array insert at bottom objects()
num_objects = array count(objects())
newobj = GetFreeObjectFast()
randbase = int(rnd(num_base + 1) - .001)
instance object newobj, objectbase(randbase).obj
objects(num_objects).obj = newobj
objects(num_objects).base = randbase
objects(num_objects).lifespan = 1000 + rnd(15000)
objects(num_objects).spawntime = time
objects(num_objectS).linear_vel_x = rnd(10) - 5
objects(num_objectS).linear_vel_y = rnd(10) - 5
objects(num_objectS).linear_vel_z = rnd(10) - 5
objects(num_objectS).angular_vel_x = rnd(72) - 36
objects(num_objectS).angular_vel_y = rnd(72) - 36
objects(num_objectS).angular_vel_z = rnd(72) - 36
endfunction
function garb_collect_objects(time)
count = array count(objects(0))
if count > -1
while count > -1
age = time - objects(count).spawntime
if age >= objects(count).lifespan
delete object objects(count).obj
array delete element objects(), count
endif
count = count - 1
endwhile
endif
endfunction
function garb_collect_sounds()
count = array count(sounds(0))
if count > -1
while count > -1
if sound playing(sounds(count)) = 0
delete sound sounds(count)
array delete element sounds(0), count
endif
count = count - 1
endwhile
endif
endfunction
function kill_object(index)
delete object objects(index).obj
array delete element objects(), index
endfunction
function update_objects(speed)
num_objects = array count(objects())
speed# = speed : speed# = speed# * .001`can't have everything moving TOO fast can we?
if count > -1
for i = 0 to num_objects
`set up the new positions ang angles using timer based movement
newPosX# = object position x(objects(i).obj) + (objects(i).linear_vel_x * speed#)
newPosY# = object position y(objects(i).obj) + (objects(i).linear_vel_y * speed#)
newPosZ# = object position z(objects(i).obj) + (objects(i).linear_vel_z * speed#)
newAngX# = object angle x(objects(i).obj) + (objects(i).angular_vel_x * speed#)
newAngY# = object angle y(objects(i).obj) + (objects(i).angular_vel_y * speed#)
newAngZ# = object angle z(objects(i).obj) + (objects(i).angular_vel_z * speed#)
`actually go and update the positions and angles
position object objects(i).obj, newPosX#, newPosY#, newPosZ#
rotate object objects(i).obj, newAngX#, newAngY#, newAngZ#
next i
endif
endfunction
`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) + 1 `the + 1 is to ensure it never hits 0
endwhile
endfunction ret
function GetFreeSoundFast()
ret as dword : ret = rnd(2000)
while object exist(ret)
ret = rnd(2000) + 1 `the + 1 is to ensure it never hits 0
endwhile
endfunction ret
function play_sound(base_index)
newsound = GetFreeSoundFast()
array insert at bottom sounds()
sounds(array count(sounds())) = newsound
clone sound newsound, soundbase(base_index)
play sound newsound
endfunction
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.