This past Saturday I worked on Oracle’s Eye for the first time in over a month. When I last worked on it in late December, I was trying to update the Frame Rate Independent Movement code I created. It was good enough when I implemented it, but I had a nagging suspicion that I didn’t do it right. I never did check in the changes I had made, and since it has been so long, I had to figure out what I was doing and then do it.
Originally, my code required that the Ball and the Player had movement functions that took an argument. This argument was the delta. For example, the Player could move 5 pixels each frame. 30 frames per second would mean that the Player should move 150 pixels per second. Of course, each frame might not be exactly 1/30th of a second, so I would have to calculate how far to move each frame so that the movement seems smooth. If, for example, a frame takes 1/30th of a second, then the delta multiplier should be 1. If it takes 1/10th of a second, then the multiplier should be 3. A frame that took 1/60th of a second would result in a multiplier of 0.5.
The sad thing is that it wasn’t all that clear how it should work when I originally implemented it. Also, I didn’t understand how to repeat the exact results in case I wanted to script it, nor did I know how it would work if I ever wanted to run a networked game on multiple platforms. After reading through a few more tutorials, I decided to fix it. I based my new code off of Sol’s Tutorials. Running the example game, I noticed that it isn’t terribly smooth itself. It periodically seems that the player’s ship takes small jumps. Perhaps it isn’t the best example to use? I’m open to better implementations if they exist.
This implementation works by setting game updates to specific time intervals. If the Player should move at 5 pixels per frame, then each update will result in a movement of 5 pixels. Multiple updates can take place during each rendered frame, but it is really easy to track the movement for each frame and use the data to accurately reenact it. For instance, I could eventually code replay functionality, which would be a great way to show solutions to the puzzles. I had to change a lot of the code to allow for this change, which shows how fundamental FRIM code is to a game engine. It wasn’t terribly difficult, and it didn’t take me too long.
The best part is that I’m familiar with the project again, which means that I won’t feel apprehension whenever I think to work on it. There were a number of days last month when I felt guilty for not working on the project. I just felt uneasy about the project, and while originally it was probably because I needed to focus on the direction to take it, it eventually was due to the fact that I hadn’t worked on it and had vague thoughts about not understanding it. Rationally, working on it would necessarily bring back familiarity, but it can be tough to pinpoint the fear sometimes.
I decided to focus on coding a configuration loader next. Basically, if I wanted to change the speed at which the Player, the Ball, or the game engine ran, I would have to recompile. Being able to load the configuration dynamically without recompiling or even rerunning the game would do wonders for productivity. I wrote some stub code on Saturday, and I will work on it this week.