First there was sound and music, now there is the ability to stop it from happening. Also a resolution to yesterday’s problem as well.
After giving things some thought, I have fixed the issue I was encountering yesterday, which was really more of a logical inconsistency than anything else. The solution is not 100% clean, but then in game development, I guess that’s the norm?
I ended up doing exactly what I was thinking of yesterday. The SceneManager class has a new property named nextScene which tells you what the next scene will be during the period where a scene change is pending but not yet complete. Scene switches happen at the top of the game loop in the Stage class to make sure that everything remains consistent.
The Stage class used to automatically force a scene change if you attempted to change scenes while the game loop is not running, but it no longer does. Instead, the currentScene property checks to see if the game loop is running. If it is, it works as before, but if not, it returns what the next scene would be if a scene change was done right now, or the current scene if there is no scene change scheduled.
This allows code that wants to query the current scene before things launch to still do it and get a sensible answer while at the same time making sure that scene switches can only happen after preloading of assets is finished, which means that there is no more ordering problem and the demo “game” can now start the music playing right in the activating() method without causing an error.
Once I had that working I immediately set to work on the ability to mute the music, because having it playing (plus the little boops in the background while the demo is running) was starting to get on my nerves a bit. I modified my Dot entity properties to have a mute property which defaults to false and controls whether the dot plays its sound when it collides. This property (and music playback) is toggled by a key press.
I went down a bit of a rabbit hole here because I was going to implement a static property on the Sound class so that all sounds would just mute if it was set. However, the Music class subclasses Sound, which means that it ends up with its own copy of the static. There appears to be no way to stop this from happening in TypeScript directly. It hurts my delicate sensibilities to know that the Music class would have a mute property that didn’t do anything.
For my last little bit of development today, I set out to create a SpriteSheet class, which I can then subclass as a Sprite class (a sprite will be just a SpriteSheet 1 tile across and 1 down), and then maybe even an Animation class or something. I have a little code for this, but it’s not checked in yet because it’s not in a workable state.
I ran into a little snag in that the sheet needs to know the dimensions of the image so that it can slice it appropriately, but the size is not available until the load completes. I spent some time trying to determine what happens if you attach a “load” event to an image that is already loaded but as yet I haven’t found a satisfactory answer. I assume the browser would be clever enough to fire the event right away if it was already loaded, but I don’t know for sure.
So, a little more research in that area and maybe I can get a little sprite action going in Rx before Devember expires. Lets hope!
Of course, I guess that would require me to actually draw real sprites. Hmmm.