An elegant way of doing this simple thing?

Blitz3D Forums/Blitz3D Beginners Area/An elegant way of doing this simple thing?

VP(Posted 2005) [#1]
Right, I've just begun project #1 which I'm aiming to be similar Spheres of Chaos (see http://www.spheresofchaos.com/ and download the demo and then buy the full game!).

Rather than just trying to get the thing done and finished I'm using it as an excercise in re-learning good programming practice (I haven't 'done code' since the Amiga's hey-day).

Anyhoo, I'm looking for comments on the following code, of which [EDIT 3rd Oct: removed dead link, see later post in the thread] has a runnable version (i.e, has keyboard.bb and the wav files).

All it does at the moment is load in 4 wavs and plays them when you bash the numbers 1-4 on the keyboard.

Not exactly impressive, I know. What took me the time (half of the day) was figuring the best way of doing things. I'm especially interested in peoples views on how the wavs get loaded.

Main program:


included sfx.bb



Ross C(Posted 2005) [#2]
To use a sound again and again, simply load it and use PlaySound(). I think you overcomplicating this in your description.


Ross C(Posted 2005) [#3]
I would do something like...


Graphics 800,600
SetBuffer BackBuffer()

Const No_Sounds = 4

Dim Sounds(No_Sounds)

For loop = 1 to No_Sounds
   Sounds(loop) = LoadSound("sound"+loop+".wav")
Next

While Not KeyHit(1)
 
  Cls

  If KeyHit(2) then PlaySound(Sounds(1))
  If KeyHit(3) then PlaySound(Sounds(2))
  If KeyHit(4) then PlaySound(Sounds(3))
  If KeyHit(5) then PlaySound(Sounds(4))

  Flip
Wend
End



What you can do is do...


chn = PlaySound( sound)



And assign the playing sound to a channel. Then you can alter the playing sounds volume and panning. Your code at present is using a type collection to store these values, but there isn't much point unless you assign your playing sound to a channel. You might be better off, if this is the approach your taking, adding in a channel field, you can assign the sound whilst it's playing.

Your code whilst being propery written, isn't very simple to follow. Unless you need that kind of control over your code, you might be better off taking a simplier approach. Although, your loading method is good and will track down errors easily. Just my opinion of course :o)


VP(Posted 2005) [#4]
Some really good comments, thanks Ross C :)

I didn't know channels existed. Something for me to investigate!

My code IS a long-winded way of acheiving what it acheives when you consider that the program as it stands is incredibly simplistic and can be acheived with a LOT less code (as you mention).

Following points to consider though: -

1) As much of the 'initialise and load stuff' code is abstracted away from the main source file as is reasonably possible.
2) If I want to load my samples in a different way (unencrypting/unpacking from a .pak file for instance) then I only change sfx.bb and every project that depends on it continues to work without alteration.
3) The sfx_acquire() function will be very easy to base future resource loader functions on (like one for graphics, which is actually the plan).
4) Having an sfx type means that all the information relating to a sound effect is stored exactly where it needs to be.
5) The code pretty much comments itself as to what it is doing (my comments just add the 'why'). This is how it should be in any language but seems hard to do in B3D (compared to C or ASM).

I did consider alternative ways of doing things (just using a load of globals, using a global typeless multidimensional array) but they had such severe drawbacks that I binned them. Using a lod of Globals is just asking for trouble (this was even before I read the thread regarding using Global types instead of bare Globals). Using a multidimensional array (to store panning, volume, 3d positional) results in poorly documented code and a slew of changes throughout the source file if you add a new data element.

If I need to add a 3D positional element to any audio sample (or channel, now I have the idea!) I only need add a new Field to the sfx type and add a little initilisation code to the Read'ing loop.

The project right now is hardly off the ground but what I'm doing is solving scalability problems before they become an issue and start to impact on development of the /proper/ code, the game loop! If everything is modular (as OOP as possible) then seemingly radical design changes later on will not cause a big drama.

One last, possibly irrelevant at this stage, benefit is that the code looks to be quite nicely portable to C++ if ever I decide to go down that road :)

** edit **

The bit where I actually load the wavs in... it looks a bit rough (and I might change it yet) but the idea was to keep the mnemonic references to the sounds (e.g. SFX_BIGEXP) throughout the project. It also enables me to do the extra little sanity check to help ensure the right sound gets allocated to the right constant name (or vice-versa :) ).

I've seen a lot of B3D code that has zero error-checking where resources are loaded. Just because the program continues doesn't mean that it's OK to ignore the error!


jfk EO-11110(Posted 2005) [#5]
AFAIR there won't be a MAV when you try to play a nonexistant sound. Blitz simply ignores the call in that case.

Basicly I agree, there should be more error checking and tolerant code, so it will run even under extremly mean condition. Like a Browser that should display a HTML page that contains lots of nonos.


VP(Posted 2005) [#6]
If you move to a different language (C++, C#) and you carry on the habit of not explicitly checking for errors every step of the way then you are going to have the hardest time adapting to the 'correct' way of doing things.

In C and ASM you have to load in or hook up to many external resources and you have to be able to exit gracefully if even one of them fails to load. Even back in the Amiga days you had to constantly 'watch your back' for things like low-memory conditions, missing libraries and OS version differences (in ROM and in software). Even different CPU's or the (non) presence of an FPU.

** EDIT 2nd Oct 2005: This project now continuing at http://www.blitzbasic.com/Community/posts.php?topic=51593 with full source released under GPL at http://www.planetpgr.com/spheres/