CSSE 2 Final Week 20
Personal blog for CSSE 2 Final Week 20
Quick current breakdown of my stats:
- Around 90 PRs now!
Ok, now for the important stuff. After I finished saving level progress locally in Week 19, I decided I wanted to save time. Here’s the burndown list item:
Add time saves so time does not reset to 0 when loading from local storage progress (allows for very fast game times, counterproductive to a leaderboard).
Day 1:
Added locally stored time to game (yay!)
GameControl.js
updateTimer() {
const time = GameEnv.time
// Subroutine to update time in local storage
localStorage.setItem(this.lastLocalStorageTime, time)
console.log("last local storage time set to: " + localStorage.getItem(this.lastLocalStorageTime))
if (GameEnv.timerActive) {
const newTime = time + GameEnv.timerInterval
GameEnv.time = newTime
if (document.getElementById('timeScore')) {
document.getElementById('timeScore').textContent = (time/1000).toFixed(2)
}
return newTime
}
if (document.getElementById('timeScore')) {
document.getElementById('timeScore').textContent = (time/1000).toFixed(2)
}
},
GameSetup.js
// Load the GameControl.lastLocalStorageTime value
const savedTime = localStorage.getItem(GameControl.lastLocalStorageTime);
// Set game time to saved local time or 0 if not set
// Note: local storage key values are stored as strings, so have to convert to int
GameEnv.time = savedTime ? parseInt(savedTime, 10) : 0;
You might have noticed how I added a few comments in the last 3 lines. When I did my first implementation of this method, it seems to update the GameControl.lastLocalStorageTime
key value by appending the GameEnv.time
value to the end of the locally stored value, causing the time in game to quickly increase to Infinity. Apparently, I forgot that local storage values were stored as strings (which was written in the help system doc file that I WROTE). Anyhow, the fix is quick: just parse savedTime
as an integer, hence the parseInt(savedTime, 10)
, where 10
indicates base 10 (decimal). Also, I love ternary operators!
Day 2:
A rather catastrophic day has befell the CSSE 2 class. Our entire focus has shifted to another codebase because of poor performance with platformer4x
, but I see some opporunity to do some cooler stuff.
Day 3:
I made a few changes by removing a few levels and cleaning up the game a little bit. Ended up deleting quite a few levels in this commit.
Refactoring by deleting quite a few levels (2, 3, 4, 6, 8 and maybe 7). Opening PR to sort out merge conflicts.
Was running into a few weird errors on the production repo when testing the game, but I later deduced it was because the game was trying to access previous localStorage IDs that were deleted. Game runs fine and transitions were all connected and fixed.
Day 4:
Tried a few experiments with accurate timing in the game, viz. with a self-adjusting timer, which I implemented in GameControl.js
:
updateTimer() {
const startTime = Date.now();
const interval = GameEnv.timeInterval;
const tick = () => {
const currentTime = Date.now();
const elapsedTime = currentTime - startTime;
const expectedTime = Math.floor(elapsedTime / interval) * interval;
const drift = elapsedTime - expectedTime;
GameEnv.time += interval;
// Ensure GameEnv.time is a valid number before setting it in localStorage
if (!isNaN(GameEnv.time)) {
localStorage.setItem(this.lastLocalStorageTime, GameEnv.time);
console.log("last local storage time set to: " + localStorage.getItem(this.lastLocalStorageTime));
} else {
console.error("GameEnv.time is NaN, not setting to localStorage");
}
if (GameEnv.timerActive) {
if (document.getElementById('timeScore')) {
document.getElementById('timeScore').textContent = (GameEnv.time / 1000).toFixed(2);
}
setTimeout(tick, interval - drift);
} else {
if (document.getElementById('timeScore')) {
document.getElementById('timeScore').textContent = (GameEnv.time / 1000).toFixed(2);
}
}
};
tick();
}
Was encountering quite a few bugs with NaN (which I presume was also to do with localStorage), hence the error handling. I ended up scrapping this idea because it was causing the game to run excruciatingly slow. Frankly, I’m not even sure it would have worked because the timer is still handled via the game loop refresh rate.