seperate observer logic

i split apart the code that tells the dialogue when to update into a seperate file so that i can use it in other places! seemed like a faster solution to have observable-esque behaviour without using very new features, setting up compilers, and including huge libraries!

(not 100% sure its totally working, but i havn't caught it failing yet!)
This commit is contained in:
spaciecat 2019-09-12 17:21:12 +10:00
parent c1a136f590
commit 45e3f27c79
4 changed files with 72 additions and 45 deletions

View File

@ -216,6 +216,7 @@
</html>
<!-- SCRIPTS -->
<script src="scripts/lib/tickable_observer.js"></script>
<script src="scripts/lib/helpers.js"></script>
<script src="scripts/lib/rsvp.min.js"></script>
<script src="scripts/lib/minpubsub.min.js"></script>

View File

@ -310,59 +310,49 @@ Game.immediatePromise = function(){
Game.FORCE_TEXT_Y = -1;
Game.WORDS_HEIGHT_BOTTOM = -1;
(function(){
const offset = 80
let lastCount = 0
let lastBottom = -1
Game.updateText = function(instant) {
var wordsObserver = new TickableObserver(function(){
var offset = 80
if(Game.WORDS_HEIGHT_BOTTOM < 0) Game.WORDS_HEIGHT_BOTTOM = 250;
let advanceTextPosition = 0
if(Game.WORDS_HEIGHT_BOTTOM < 0) Game.WORDS_HEIGHT_BOTTOM = 250;
let updated = false
function updateTransform(){
if(updated) return
updated = true
let advanceTextPosition = 0
if(Game.FORCE_TEXT_Y != -1){
Game.wordsDOM.style.transform = `translateY(${Game.FORCE_TEXT_Y}px)`;
advanceTextPosition = Game.wordsDOM.clientHeight + Game.FORCE_TEXT_Y + 5
} else {
const wordsHeight = Game.wordsDOM.clientHeight;
let diff = wordsHeight - (Game.WORDS_HEIGHT_BOTTOM - offset)
if(diff < 0) diff = 0
Game.wordsDOM.style.transform = `translateY(${offset - diff}px)`;
advanceTextPosition = offset - diff + wordsHeight + 5
}
// Either force the text somewhere...
if(Game.FORCE_TEXT_Y != -1){
Game.wordsDOM.style.transform = `translateY(${Game.FORCE_TEXT_Y}px)`;
advanceTextPosition = Game.wordsDOM.clientHeight + Game.FORCE_TEXT_Y + 5
}
// Or calculate its position based on a window...
else {
const wordsHeight = Game.wordsDOM.clientHeight;
let diff = wordsHeight - (Game.WORDS_HEIGHT_BOTTOM - offset)
if(diff < 0) diff = 0
Game.wordsDOM.style.transform = `translateY(${offset - diff}px)`;
advanceTextPosition = offset - diff + wordsHeight + 5
}
// Also, move click_to_advance DOM
$('#click_to_advance').style.transform = `translateY(${Math.round(advanceTextPosition)}px)`;
}
// "Instant mode" was only used for clearing... so lets just do it when it's clear?
if(Game.wordsDOM.children.length == 0){
Game.wordsDOM.classList.add("clear_transition");
Game.wordsDOM.clientHeight;
Game.wordsDOM.classList.remove("clear_transition");
}
if(Game.wordsDOM.children.length != lastCount){
updateTransform()
lastCount = Game.wordsDOM.children.length;
}
if(Game.WORDS_HEIGHT_BOTTOM != lastBottom){
updateTransform()
lastBottom = Game.WORDS_HEIGHT_BOTTOM;
}
if(instant || Game.FORCE_TEXT_Y != -1){
updateTransform()
Game.wordsDOM.classList.add("clear_transition");
Game.wordsDOM.clientHeight;
Game.wordsDOM.classList.remove("clear_transition");
}
};
// Also, move the click_to_advance DOM
$('#click_to_advance').style.transform = `translateY(${Math.round(advanceTextPosition)}px)`;
});
// The words UI depends on these things:
wordsObserver.watch(function(){ return Game.FORCE_TEXT_Y });
wordsObserver.watch(function(){ return Game.WORDS_HEIGHT_BOTTOM });
wordsObserver.watch(function(){ return Game.wordsDOM.children.length });
Game.updateText = function() { wordsObserver.tick() };
})()
// CLEAR TEXT
Game.clearText = function(){
Game.wordsDOM.innerHTML = "";
Game.updateText(true);
Game.updateText();
};
Game.clearAll = function(){
Game.clearText();
Game.resetScene();

View File

@ -0,0 +1,36 @@
/*
Lots of things in this game were written to happen every frame, but they often don't need to!
Here's something I call a `Tickable Obersver`, it lets you (every frame) check if some values
have changed, and only then run the expensive code!
It's kinda like an observable, but it's tiny and runs on a frame-by-frame basis!
- Spacie
*/
class TickableObserver {
constructor(event){
this.depCount = 0;
this.previousValues = [];
this.watchers = [];
this.event = event;
}
tick(){
for(let i = 0; i < this.depCount; i++){
if(this.watchers[i]() != this.previousValues[i]){
this.previousValues[i] = this.watchers[i]();
if(this.event != null) return this.event();
}
}
}
watch(watcher){
this.depCount++;
this.watchers.push(watcher);
this.previousValues.push(null);
}
}

View File

@ -70,7 +70,7 @@ MAIN GAME
width: 100%;
position: absolute;
overflow: hidden;
transition: transform 0.3s;
transition: transform 0.5s;
}
#game_words.clear_transition {
transition: none !important;