I really did not think it would get done, but thanks to the delay in the exam, I did! Maxwell’s Demon now has a “map” in the background. I don’t know which version of TILEDMapClass.js I was originally working with, but it was a bug-filled disaster. I went back and got a new copy from the very end of the Atlases unit and it only had one bug I needed to change: “data.requestText” should be “this.requestText”. There was some strangeness with my original image because of unwanted margin and spacing, but that was easily rectified.
The only thing I never got around to fixing was the loading of all of the sounds before launching the game.
While waiting for the exam to come online (and waiting … and waiting …) I decided to put the time to good use and see what broken bits of Maxwell’s Demon could be fixed. The failure to load spritesheet.js was the most mysterious, so I pursued that first.
Turns out it was not much of a mystery. I simply mistyped ‘spritesheet.js’ as ‘spritesheet.hs’ (the ‘H’ key being right next to the ‘J’ key on my keyboard). Because ‘.hs’ was not a recognized file extension, the asset loader could not load it. I cannot tell you how many times I looked at that file name and did not notice that the file extension was not ‘.js’.
Unfortunately, because of the unknown file type and the way the asset loader was written, the asset loader was waiting for one more file than it was ever going to load — not the ideal behavior. A better behavior would be to notify the person trying to load the unknown file type in an alert and offer the option of aborting the program or ignoring the missing file and continuing on. Something else for when I have more time.
Now back to waiting ….
While reviewing and studying for my exam, I can’t help but reflect back on the subject of “sanity checks” in game code. These are the “if-then” statements that look for null pointers, variables with values outside of their domain, etc. — in other words: bad code. For a small game such as “Maxwell’s Demon”, such checks really don’t make much sense because each of those possibilities is essentially going to be an unrecoverable error that needs to get fixed anyway, and the sanity checks only serve to slow down the code.
When the sanity checks become important is when the code gets re-used or repurposed. “Engines” and “libraries”, especially those meant to be used by teams of programmers or released to the public for inclusion in multiple projects, absolutely need this stuff. You always want the programmer using your code to know the problem is his code and not yours. Toward that end, it makes sense that your library code throws meaningful and helpful error messages whenever possible. Because these error messages are usually not meaningful to the end user though, it is a good idea to let the programmer who is using your code to toggle whether error messages are displayed or not. In fact, you might even want to provide two versions of the code: one with sanity checks and error messages (for ease of programming) and one version stripped of all such checks and compressed such that it takes up a minimum of space and time.
I regret that my code lies on neither extreme at this point. It has not been optimized for re-use, nor has it been optimized for speed. As such, I really don’t recommend trying to use it at this time (even though I have made it available). Typically i write much better code, but the time constraints and the desire to use the existing code from the course have resulted in the less-than-ideal code on this project.
I tried adding the floor using Tiled and TexturePacker — I really did. Unfortunately, it does not appear to be working and I really don’t have time to fix it now. The code and files are all there, so it probably won’t be too hard to get it working once I do find time. I do have a question about it though. Why is there no callback to let us know when it has finished loading?
And speaking of the asset loader and atlases, I asked the following question on the Udacity forum and as far as I know at the time of this writing there has been no reply yet. Here is the question:
Maxwell’s Demon is ready to play, if not quite ready for prime time. I still need to lay down a floor using the tile atlas, and it would be nice to pre-load my audio. Of course, a background soundtrack would be good to have too. Alas, I have not time for all of that. I’ll start with the atlas and see if I can accomplish anything else, but I really need to study for the certification exam instead.
I have switched over to Maxwell’s Demon. It currently has a hot molecule (in red) and a cold molecule (in blue). You don’t have to watch very long to determine that molecules can change temperature when they collide. I will need to take that into account. It would be fun to show a distribution graph alongside the game. I will do that when I have time. I suppose “losing” would be when the molecules all reach some type of thermal equilibrium.
Note to those having trouble with items sticking to walls (as I was). Set
- Box2D.Common.b2Settings.b2_velocityThreshold = 0.0;
first thing to avoid this problem.
I finally got my paddles working properly. I wanted a key press to pop up a paddle for a tenth of a second and then have the paddle disappear. This worked well, except for the fact that my keyboard, like most keyboards, will automatically start sending repeat key presses when held down. So I had to add some logic to the InputEngine to essentially disable the onKeyDown method for a key immediately after its first invokation until a matching onKeyUp method call for that key re-enables it.
Oddly enough, now that all of the pieces of “Meltdown!” are present, I have decided to switch to a game based on Maxwell’s Demon because it will be quicker to program and more fun to play. “Meltdown!” will probably need a great deal of game play, testing, and redesign to get it right.
I am hard at work using the InputEngine to pop up paddles with which to whack the ball. In so doing, I discovered an apparent error in InputEngine.js. Whereas it has “event.keyID” for identifying which key is pressed or released in the “onKeyDown()” and “onKeyUp()” methods, the correct attribute is named “event.keyCode”.
No steps back! Things are finally starting to come together the way they are supposed to do so. I have added sound to the game. I still need to load the sounds before the game actually launches, but that is a minor issue.
I finally have my ball on the canvas. Unfortunately, it is not behaving well at all. Ideally right now it should just sit there because I have defined gravity as:
But for some reason, the y-value is changing. To add weirdness to it, the y-value changes differently for different starting y positions. I think it has something to do with my “ground” bounding box. Time to do a little exploring.
Update: It was a problem with my ground bounding box. My ball was inside the box. Turning the ground into a “wall” and placing the ball outside of it fixed the problem.
Update update: I now have a bouncing ball! This might actually work now!