Sound makes an amazing difference

Yesterday’s plan for today was to work on a SpriteSheet/Sprite/Animation class cluster, but a bit more research into that gave me a bit of pause so I went ahead on to the next item on my list in the interests of getting the Rx prototype more “complete” by the end of Devember, sound.

Primarily the reason for the switch was due to my being unsure as to the best way to proceed with the image code I was working on. It seems that the load event won’t fire if the image is already loaded when you add it, (as far as I can see, anyway) which is not great for code that wants to consume the image. You need to add the handler BEFORE you start the load. I could use the complete property to see if the image is loaded, and if not add an event handler, but that seems like it would create a race condition since events happen asynchronously.

In any case, I proceeded on to including music and sound into the prototype, because if there’s a thing that makes a game seem more “gamey”, it’s sounds and music. You know, if you discount good art, solid game play, controls and other things like that.

I got some songs from courtesy of Kevin McLeod and generated some sound effects from The repository contains the wav/ogg/mp3 versions of these, as well as (for the sound effects) files that can be loaded into bfxr to recreate and tweak the sounds I generated.

The bulk of the changes come with a new sound API added to the Stage class. I wanted to implement a way to mute/unmute/volume control all music and sound effects all at once. Since the tags are generated dynamically they’re not a part of the DOM at all, so something needs to keep track of them. The Stage seems like a good candidate for that.

So there is now some methods in Stage that allow you to register a Sound instance with the stage, and then apply volume and mute status changes to everything registered all at once. As a convenience, there are also new methods that will call the appropriate Preloader function for you and automatically register the return value of the preload.

As a part of this change I modified the sound preloader to not share tags when something preloads the same sound more than once, since doing so would cause changes to affect everyone loading the same sound, which seems like a Bad Thing ™.

I also pushed the Sound class to its own file and out of Preload.ts and removed the Music class in favor of a simple boolean flag that flags a Sound instance as either music or a regular sound effect. There didn’t seem to be much reason to have a separate class at this point. The API in Stage uses this boolean to operate over only sounds/music as appropriate.

I still want to do some sprite action, but I’m not sure that it’s entirely needed in this particular prototype since the vector graphics seem to work well enough, so now I’m not sure what I should do. I could perhaps finish the required code before Devember is over, but I don’t know that I could come up with proper graphics in time.

At this stage I might just tweak the engine a bit more to make it compile out as a separate JS file from the actual game code; having one extra script tag is not bad and it would make merges a heck of a lot easier. That would also allow me to work with TypeScript definition files, which I’ve skipped over up to now.