Hi,
I'm trying to add a mechanic to my story where the background color of the sidebar changes to reflect the time of day in the story, which passes by in real time and can be sped up and slowed down. This system I've written works pretty well while a passage is being displayed, but creates visual artifacts during passage transitions.
Long story short, I use setInterval() to create a game tick, and during each tick I update the game's internal clock and update the styles on various elements.
During a passage transition, some time after PassageDone, the StoryCaption is redrawn and the custom styles are reverted to default. The styles are corrected during the next game tick, but this leaves a few milliseconds where everything is the noticeably the wrong color.
Is there a better way to dynamically recolor the UI bar? Failing that, is there some way to reliably hook into UI bar updates so I can reapply custom styles before those updates are rendered?
Relevant snippets of code below:
StoryInit Passage
<<set $game_clock to new Date(Date.UTC(0, 0, 1, 12, 0, 0))>>
<<set $time_factor to 1>>
<<run window.setInterval(window.gametick, 33)>>
Story Javascript
// ...
window.lastTick = new Date().getTime();
window.gametick = function() {
var now = new Date().getTime(),
interval = now - window.lastTick;
window.lastTick = now;
window.timeSystem.addTime(interval); // updates $game_clock
window.uiSystem.updateUI(); // modifies DOM
}
// ...
window.timeSystem = {
addTime: function (interval) {
var clock = variables().game_clock,
timeFactor = variables().time_factor;
clock.setTime(clock.getTime() + (interval * timeFactor));
},
// ...
}
// ...
window.uiSystem = {
// ...
updateUI: function () {
var time_system = window.timeSystem;
// calculate new background colours based on current game time
var bgColor = this.getTimeGradient(this.colors.bgPanelDay, this.colors.bgPanelDelta),
textPanelColor = this.getTimeGradient(this.colors.textPanelDay, this.colors.textPanelDelta),
dropShadowColor = this.getTimeGradient(this.colors.dropShadowDay, this.colors.dropShadowDelta);
// update any DOM elements displaying the current time and date
jQuery(".timespan").text(time_system.getTime());
jQuery(".dayspan").text(time_system.getDays());
// recolour the background, using the new colors
jQuery("#ui-bar, #ui-bar-2").css('background-color', bgColor);
jQuery("body, .story-box").css('background-color', textPanelColor);
jQuery("#ui-bar, #ui-bar-2, .story-box").css('box-shadow', '0px 0px 5px 0px ' + dropShadowColor);
}
// ...
};
Comments
This allows me to call updateUI() within the same task object, ensuring that the custom styles are applied before the user sees anything.
eg. if you have X CSS classes (period1, period2, period3, etc..) the related CSS selectors could look something like: ... and the Javascript to assign each time periods class to the html element:
I'm in the middle of rewriting my story engine before I port my existing content into it, but feel free to take a peek at the work in progress:
http://rokiyo.net/games/cetacea/Story%20Engine.html
If you click the time factor buttons, time will speed up and slow down accordingly. My intention is that the player will be able to perform activities that take a certain amount of time, such as sleeping for 6 hours. While the player is asleep, time will pass really quickly until 6 hours have passed, and then it slow back down to real time.
The end goal here is to go for something of an X-COM vibe, where the player feels like they are managing a situation that will continue to progress even as they take actions to try and stop it. I really want the player to feel the importance time passing, which is why I'm putting so much effort into creating something of a realtime experience.
If you want to do something to that effect, specify all of the classes you intend to use within the call to .removeClass(). For example: