//store game variables in an associative array var storage = []; function isNumber(value) { return (!isNaN(value)); } function sleep(milliseconds) { const date = Date.now(); let currentDate = null; do { currentDate = Date.now(); } while (currentDate - date < milliseconds); } class Action { constructor() { this.arg = []; this.argCount = 0; this.weight = 0; this.idx = -1; this.bag = []; this.lastBagIdx = -1; } dump(pad) { console.log(pad + this.arg[0]); for(var i = 1; i < this.argCount; i++) { console.log(pad + " '" + this.arg[i] + "'"); } } } class Point2I { constructor() { this.x = 0; this.y = 0; } normalize(len) { var factor = len / Math.sqrt(this.x*this.x + this.y*this.y); this.x *= factor; this.y *= factor; } } class Overlay { constructor() { this.origin = new Point2I(); this.pos = new Point2I(); this.w = 0; this.h = 0; this.opacity = 100; this.action = []; this.actionCount = 0; this.actionIdx = 0; this.name = ""; this.parent = ""; // this.frameParent = ""; //overlay which we get our subframe prefix from this.subFrame = ""; //name of current subframe this.scene = ""; this.frameTime = 0; this.nextFrameTime = 1; this.clickAction = new Action(); //position tweening this.posA = new Point2I(); this.posB = new Point2I(); this.posStartTime = 0; this.posEndTime = 0; this.posEaseType = "inOutQuad"; this.posEaseDecay = 10.0; this.posEaseBounce = 5; //opacity tweening this.opacA = 0; this.opacB = 0; this.opacStartTime = 0; this.opacEndTime = 0; this.opacEaseType = "inOutQuad"; //blur tweening this.blurA = 0; this.blurB = 0; this.blurStartTime = 0; this.blurEndTime = 0; this.blurEaseType = "inOutQuad"; //stack this.stack = []; } addAction(word) { this.action[this.actionCount] = new Action(); for(var i = 0; i < word.length; i++) { this.action[this.actionCount].arg[i] = word[i]; this.action[this.actionCount].argCount++; } this.action[this.actionCount].idx = this.actionCount; this.actionCount++; } addRandAction(word) { this.action[this.actionCount] = new Action(); this.action[this.actionCount].weight = word[0]; for(var i = 1; i < word.length; i++) { this.action[this.actionCount].arg[i-1] = word[i]; this.action[this.actionCount].argCount++; } this.action[this.actionCount].idx = this.actionCount; this.actionCount++; } dump(pad) { console.log(pad + "OVERLAY " + this.pos.x + " " + this.pos.y + " " + this.w + " " + this.h + " " + this.name); console.log(pad + " frameTime " + this.frameTime); console.log(pad + " nextFrameTime " + this.nextFrameTime); if(this.clickAction.argCount > 0) { this.clickAction.dump(pad + " CLICK->"); } for(var i = 0; i < this.actionCount; i++) { if(this.actionIdx == i) this.action[i].dump(pad + " >"); else this.action[i].dump(pad + " "); } } create() { //reset to initial condition this.pos.x = this.origin.x; this.pos.y = this.origin.y; this.opacity = 1.0; this.posStartTime = 0; this.posEndTime = 0; this.opacStartTime = 0; this.opacEndTime = 0; this.blur = 0; this.blurA = 0; this.blurB = 0; this.blurStartTime = 0; this.blurEndTime = 0; this.blurEaseType = "inOutQuad"; //create an image object on the page var o = document.createElement("div"); o.id = "overlay-" + this.name; //console.log("Creating overlay ", o.id); o.style.height = this.h * gScale; o.style.width = this.w * gScale; o.style.left = "0px"; //this.pos.x * gScale; o.style.top = "0px"; //this.pos.y * gScale; o.style.transform = "translate(" + (this.pos.x * gScale) + "px," + this.pos.y * gScale + "px)"; o.style.position = "absolute"; o.style.backgroundSize = "100%"; o.onclick = clickHandler; o.onmousedown = selectionPreventer; if(this.parent) { var p = scene[currSceneIdx].getDivByName(this.parent); if(p) { p.appendChild(o); } else { console.log("ERROR: cannot find parent '" + this.parent + "'"); playArea.appendChild(o); } } else { playArea.appendChild(o); } this.div = o; this.actionIdx = -1; this.nextFrameTime = gTimeStamp; //this.doNextAction(); //where we're putting stuff (for relative positioning) this.cursor = new Point2I(); } preload() { //create a preloader object //TODO: maximum number of pre-loader objects, cycle out the old ones //create a preloader object for all frames for(var i = 0; i < this.actionCount; i++) { switch(this.action[i].arg[0]) { case "FRAME": addPreloader(this.action[i].arg[1]); break; case "OFRAME": addPreloader(this.action[i].arg[2]); break; case "SUBFRAME": //add variations of preloader for all of the parentFrame's frames if(!this.frameParent) console.log("ERROR: preload SUBFRAME without FRAME_PARENT"); this.scene.getOverlayByName(this.frameParent).preloadSubFrame(this.action[i].arg[1]); break; case "SOUND": preloadSound(this.action[i].arg[1]); setSoundLoop(this.action[i].arg[1], false); setSoundVolume(this.action[i].arg[1], 1.0); setSoundChannel(this.action[i].arg[1], -1); for(var j = 2; j < this.action[i].arg.length; j++) { var soundName = this.action[i].arg[1]; if(this.action[i].arg[j] == "LOOP") { setSoundLoop(soundName, true); continue; } if(this.action[i].arg[j] == "VOL") { j++; setSoundVolume(soundName, this.action[i].arg[j]); } if(this.action[i].arg[j] == "CH") { j++; setSoundChannel(soundName, this.action[i].arg[j]); } } break; } } } preloadSubFrame(subFrameSuffix) { for(var i = 0; i < this.actionCount; i++) { switch(this.action[i].arg[0]) { case "FRAME": var imgName = this.action[i].arg[1]; imgName = getBaseName(imgName); imgName += subFrameSuffix; console.log("Preloading subframe " + imgName); addPreloader(imgName); break; } } } onClick() { //console.log(gTimeStamp + " clicked on overlay " + this.name); if(this.clickAction.argCount > 0) { //can't click if we're in a transition var inTransition = false; if(this.actionIdx >= 0) { if(this.action[this.actionIdx].arg[0] == "WAIT" && this.nextFrameTime != 0) inTransition = true; } if(!inTransition) { this.doAction(this.clickAction); } } } jumpTo(labelName) { //varaible lookup if(labelName.charAt(0) == "$") labelName = storage[labelName]; if(labelName == "NEXT") { this.doNextAction(); return; } for(var i = 0; i < this.actionCount; i++) { if(this.action[i].arg[0] != "LABEL") continue; if(this.action[i].arg[1] != labelName) continue; this.actionIdx = i; this.doNextAction(); return; } console.log("ERROR: could not find jump label '" + labelName + "'"); } doNextAction() { if(this.actionCount <= 0) return; this.actionIdx++; this.actionIdx %= this.actionCount; this.doAction(this.action[this.actionIdx]); } updateSubFrame() { //get frame prefix from frameParent overlay var p = this.scene.getDivByName(this.frameParent); var prefix = p.className.substr("preload-".length, 999); //assemble subframe name this.div.className = "preload-" + prefix + getBaseName(this.subFrame); } doAction(action) { if(typeof action === 'undefined') return; if(action.argCount == 1) console.log(gTimeStamp + " " + this.name + " " + action.arg[0] ); else console.log(gTimeStamp + " " + this.name + " " + action.arg[0] + " " + action.arg[1]); switch(action.arg[0]) { case "FRAME": //images are loaded into preloader boxes, just set the class this.div.className = "preload-" + getBaseName(action.arg[1]); if(action.argCount == 2) { //blank = wait forever this.nextFrameTime = 0; } else if(action.argCount == 3) { if(action.arg[2] == "") { //blank = wait forever this.nextFrameTime = 0; } else if(action.arg[2] == 0) { //0 = advance immediately } else { //all others treated as a hold time //this.nextFrameTime = gTimeStamp + parseInt(action.arg[2]); //this.nextFrameTime += parseInt(action.arg[2]); //this will have more accurate timing, but has problems with OGOTO lines if(action.arg[2].charAt(0) == "$") this.nextFrameTime += parseInt(storage[action.arg[2]]); else this.nextFrameTime += parseInt(action.arg[2]); } } else { console.log("ERROR: FRAME command has unknown argument count"); } this.scene.updateSubFrames(this.name); break; case "OFRAME": //set the frame on a different overlay var o = document.getElementById("overlay-" + action.arg[1]); o.className = "preload-" + getBaseName(action.arg[2]); if(action.argCount == 3) { //blank = wait forever this.nextFrameTime = 0; } else if(action.argCount == 3) { if(action.arg[2] == "") { //blank = wait forever this.nextFrameTime = 0; } else if(action.arg[2] == 0) { //0 = advance immediately } else { //all others treated as a hold time //this.nextFrameTime = gTimeStamp + parseInt(action.arg[2]); //this.nextFrameTime += parseInt(action.arg[2]); //this will have more accurate timing, but has problems with OGOTO lines if(action.arg[2].charAt(0) == "$") this.nextFrameTime += parseInt(storage[action.arg[2]]); else this.nextFrameTime += parseInt(action.arg[2]); } } //this.doNextAction(); break; case "SUBFRAME": if(!this.frameParent) { console.log("ERROR: overlay '" + this.name + "' has SUBFRAME op without FRAME_PARENT"); break; } //save the subframe suffix name this.subFrame = action.arg[1]; this.updateSubFrame(); if(action.arg[2] == "") { //blank = wait forever this.nextFrameTime = 0; } else if(action.arg[2] == 0) { //zero = immediately continue (do multiple actions at once) //this.doNextAction(); } else { //all others treated as a hold time this.nextFrameTime += parseInt(action.arg[2]); //this will have more accurate timing, but has problems with OGOTO lines } break; case "NEXT": //console.log("doing next"); this.nextFrameTime = gTimeStamp; this.doNextAction(); break; case "SETSCENE": this.nextFrameTime = 0; setScene(action.arg[1]); break; case "WAIT": if(action.argCount == 1) { //no arguments, wait forever this.nextFrameTime = 0; } else if(action.argCount == 2) { //one argument, want that amount if(action.arg[1].charAt(0) == "$") this.nextFrameTime = gTimeStamp + parseInt(storage[action.arg[1]]); else this.nextFrameTime = gTimeStamp + parseInt(action.arg[1]); } else if(action.argCount == 3) { //two arguments, use as random range var low = action.arg[1]; var high = action.arg[2]; if(low.charAt(0) == "$") low = storage[low]; if(high.charAt(0) == "$") high = storage[high]; var time = rand(parseInt(low), parseInt(high)); this.nextFrameTime = gTimeStamp + parseInt(time); } else { console.log("ERROR: bad agument count (" + action.argCount + ") on WAIT"); } break; case "GOTO": if(action.argCount == 2) { //just a label, assume this overlay this.jumpTo(action.arg[1]); } else if(action.argCount == 3) { //overlay name and label provided this.scene.overlayJumpTo(action.arg[1], action.arg[2]); //this.doNextAction(); } else { console.log("ERROR: bad number of arguments on GOTO"); } break; case "CALL": //like goto except we set the stack pointer if(action.argCount == 2) { //just a label, use this overlay this.stack.push(this.actionIdx); this.jumpTo(action.arg[1]); } else if(action.argCount == 3) { //overlay name and label provided this.scene.overlayCall(action.arg[1], action.arg[2]); //this.doNextAction(); } else { console.log("ERROR: bad number of arguments on CALL"); } break; case "RETURN": //jump to the saved stack pointer this.actionIdx = this.stack.pop(); this.doNextAction(); break; case "LABEL": //this.doNextAction(); this.nextFrameTime = gTimeStamp; break; case "RANDOM": /* //randomly jump to one of the given labels //add up total odds var totalOdds = 0; for(var i = 1; i < action.argCount; i += 2) { //console.log("adding " + word[i]); totalOdds += Math.floor(action.arg[i]); //lol if you don't do math.floor it appends them as strings } //pick a random number between 1 and totalodds var pick = Math.floor(Math.random() * totalOdds) + 1; //console.log("picked " + pick + " / " + totalOdds); //walk along until we go past picked value // then chose label before that totalOdds = 0; for(var i = 1; i < action.argCount; i += 2) { totalOdds += Math.floor(action.arg[i]); if(pick <= totalOdds) { this.jumpTo(action.arg[i+1]); break; } } */ //actions between here and end_random should have weights var totalOdds = 0; var walkIdx = action.idx + 1; var endIdx = 0; while(1) { if(this.action[walkIdx].arg[0] == "END_RANDOM") { endIdx = walkIdx; break; } if(this.action[walkIdx].weight <= 0) { console.log("ERROR: RANDOM without END_RANDOM?"); break } totalOdds += Math.floor(this.action[walkIdx].weight); walkIdx++; } //pick a random number between 1 and totalodds var pick = Math.floor(Math.random() * totalOdds) + 1; //console.log("picked " + pick + " / " + totalOdds); //walk along until we go past picked value // then chose label before that totalOdds = 0; var walkIdx = action.idx + 1; while(1) { if(this.action[walkIdx].weight <= 0) { console.log("RAN OFF RANDOM LIST"); this.actionIdx = walkIdx-2; //this.doNextAction(); break; } totalOdds += Math.floor(this.action[walkIdx].weight); //console.log("WALK " + totalOdds + " " + pick); if(pick <= totalOdds) { this.actionIdx = endIdx; this.doAction(this.action[walkIdx]); //this.doNextAction(); return; } walkIdx++; } break; case "END_RANDOM": //this.doNextAction(); break; case "RANDOM_BAG": //like random, except no repeats //actions between here and end_random should have weights var totalOdds = 0; var walkIdx = action.idx + 1; var endIdx = 0; while(1) { if(this.action[walkIdx].arg[0] == "END_RANDOM") { endIdx = walkIdx; break; } if(this.action[walkIdx].weight <= 0) { console.log("ERROR: RANDOM_BAG without END_RANDOM?"); break; } //skip items already picked in this bag, and the last item picked in the previous bag if(action.bag[walkIdx] !== 1 && walkIdx !== action.lastBagIdx) totalOdds += Math.floor(this.action[walkIdx].weight); walkIdx++; } if(totalOdds == 0) { //bag full, start a new one action.bag = []; //gabage collected //add odds again totalOdds = 0; walkIdx = action.idx + 1; endIdx = 0; while(1) { if(this.action[walkIdx].arg[0] == "END_RANDOM") { endIdx = walkIdx; break; } if(this.action[walkIdx].weight <= 0) { console.log("ERROR: RANDOM_BAG without END_RANDOM?"); break; } //skip items already picked in this bag, and the last item picked in the previous bag if(action.bag[walkIdx] !== 1 && walkIdx !== action.lastBagIdx) totalOdds += Math.floor(this.action[walkIdx].weight); walkIdx++; } if(totalOdds == 0) { console.log("ERROR: Failed to add odds after random_bag reset"); break; } } //pick a random number between 1 and totalodds var pick = Math.floor(Math.random() * totalOdds) + 1; //walk along until we go past picked value // then chose label before that totalOdds = 0; var walkIdx = action.idx + 1; while(1) { if(this.action[walkIdx].weight <= 0) { console.log("RAN OFF RANDOM LIST"); this.actionIdx = walkIdx-2; //this.doNextAction(); break; } if(action.bag[walkIdx] !== 1 && walkIdx !== action.lastBagItem) totalOdds += Math.floor(this.action[walkIdx].weight); //console.log("WALK " + totalOdds + " " + pick); if(pick <= totalOdds) { this.actionIdx = endIdx; action.lastBagIdx = walkIdx; action.bag[walkIdx] = 1; //console.log("Bag item " + walkIdx); this.doAction(this.action[walkIdx]); //this.doNextAction(); return; } walkIdx++; } break; case "POS": //update position target if(action.argCount == 3) { //POS, x, y this.pos.x = parseInt(action.arg[1]); this.pos.y = parseInt(action.arg[2]); //cancel position animation this.posStartTime = 0; this.posEndTime = 0; this.resize(); } else if(action.argCount >= 4) { //POS, x, y, time, (easeType) this.posA.x = this.pos.x; this.posA.y = this.pos.y; this.posB.x = parseInt(action.arg[1]); this.posB.y = parseInt(action.arg[2]); this.posStartTime = gTimeStamp; this.posEndTime = gTimeStamp + parseInt(action.arg[3]); if(action.argCount == 7) { this.posEaseType = action.arg[4]; this.posEaseBounce = parseFloat(action.arg[5]); this.posEaseDecay = parseFloat(action.arg[6]); } else if(action.argCount == 5) { this.posEaseType = action.arg[4]; this.posEaseDecay = 10.0; this.posEaseBounce = 5; } else { this.posEaseType = "inOutQuad"; } } //this.doNextAction(); break; case "POS+": //update position target if(action.argCount == 3) { //POS+, x, y this.pos.x = parseInt(this.pos.x) + parseInt(action.arg[1]); this.pos.y = parseInt(this.pos.y) + parseInt(action.arg[2]); //cancel position animation this.posStartTime = 0; this.posEndTime = 0; this.resize(); } else if(action.argCount >= 4) { //POS+, x, y, time, (easeType) if(this.posEndTime > 0) { //currently an animation in progress, start at the end of it this.posA.x = this.posB.x; this.posA.y = this.posB.y; } else { this.posA.x = this.pos.x; this.posA.y = this.pos.y; } this.posB.x = parseInt(this.posA.x) + parseInt(action.arg[1]); this.posB.y = parseInt(this.posA.y) + parseInt(action.arg[2]); this.posStartTime = gTimeStamp; this.posEndTime = gTimeStamp + parseInt(action.arg[3]); if(action.argCount == 7) { //console.log("seven args"); this.posEaseType = action.arg[4]; this.posEaseBounce = parseFloat(action.arg[5]); this.posEaseDecay = parseFloat(action.arg[6]); } else if(action.argCount == 5) { this.posEaseType = action.arg[4]; this.posEaseDecay = 10.0; this.posEaseBounce = 5; } else { this.posEaseType = "inOutQuad"; } } //this.doNextAction(); break; case "OPAC": //update opacity target if(action.argCount == 2) { //no time given, apply immediately this.opacity = parseFloat(action.arg[1]); this.opacStartTime = 0; this.opacEndTime = 0; //console.log("setting opacity " + this.name, this.opacity); } else if(action.argCount == 3 || action.argCount == 4) { //time given, set target this.opacA = parseFloat(this.opacity); this.opacB = parseFloat(action.arg[1]); this.opacStartTime = gTimeStamp; this.opacEndTime = gTimeStamp + parseInt(action.arg[2]); if(action.argCount == 4) this.opacEaseType = action.arg[3]; else this.opacEaseType = "inOutQuad"; //console.log("setting opacity " + this.name, this.opacB); } this.div.style.opacity = parseFloat(this.opacity); //this.doNextAction(); break; case "FLIP": if(action.argCount == 2) { if(action.arg[1] == 1) this.div.style.scale = "1 -1"; else this.div.style.scale = "1 1"; } else { //scale is magic and if you set it to "1 1", it becomes "1" // this should just be two variables or a type with .x and .y // css/javascript is fucking retarded var xScale = 1; var yScale = 1; if(this.div.style.scale != "1" && this.div.style.scale != "") { xScale = this.div.style.scale.split(' ')[0]; yScale = this.div.style.scale.split(' ')[1]; } yScale *= -1; this.div.style.scale = xScale + " " + yScale; } break; case "SOUND": //set sound defaults //setSoundLoop(action.arg[1], false); //setSoundVolume(action.arg[1], 1.0); //setSoundChannel(action.arg[1], -1); for(var i = 2; i < action.arg.length; i++) { if(action.arg[i] == "LOOP") { setSoundLoop(action.arg[1], true); continue; } if(action.arg[i] == "VOL") { i++; setSoundVolume(action.arg[1], action.arg[i]); } if(action.arg[i] == "CH") { i++; setSoundChannel(action.arg[1], action.arg[i]); } } if(action.arg[3] == "LOOP") setSoundLoop(action.arg[1], true); else playSound(action.arg[1]); //this.doNextAction(); break; case "BLUR": if(action.argCount == 2) { //instant this.blur = action.arg[1]; this.div.style.filter = "blur(" + this.blur + "px)"; //this.doNextAction(); } else if(action.argCount == 3) { //time target this.blurA = this.blur; this.blurB = action.arg[1]; this.blurStartTime = gTimeStamp; this.blurEndTime = gTimeStamp + parseInt(action.arg[2]); this.blurEaseType = "inOutQuad"; } else if(action.argCount == 4) { //time target + ease type this.blurA = this.blur; this.blurB = action.arg[1]; this.blurStartTime = gTimeStamp; this.blurEndTime = gTimeStamp + parseInt(action.arg[2]); this.blurEaseType = action.arg[3]; } break; case "PRELOAD": this.resize(); if(isPreloadComplete()) { //this.doNextAction(); //this.div.innerHTML = "Loaded!"; //this.div.className = "loadingText"; //in case of instant preload this.div.innerHTML = getPreloadString() + "
Click to play"; this.div.className = "loadingText noSelect"; //this.nextFrameTime = 0; //this.actionIdx--; this.nextFrameTime = gTimeStamp + 30; resizePage(); } else { //preload overlay this.div.innerHTML = getPreloadString(); this.div.className = "loadingText"; //check again in a little bit this.actionIdx--; this.nextFrameTime = gTimeStamp + 30; resizePage(); } break; case "FILL": this.div.style.backgroundColor = action.arg[1]; break; case "TEXT": //create text object //console.log("TEXT " + action.arg[4]); var d = document.createElement("div"); d.innerHTML = action.arg[4]; d.className = action.arg[1].replaceAll(",", " ") + " " + "noSelect"; d.origin = new Point2I(); //position may be relative to previous text box (makes moving things easier) var relative = false; if(action.arg[2].charAt(0) == "+") relative = true; if(action.arg[3].charAt(0) == "+") relative = true; if(relative) { d.origin.x = this.cursor.x + parseInt(action.arg[2]); d.origin.y = this.cursor.y + parseInt(action.arg[3]); } else { d.origin.x = parseInt(action.arg[2]); d.origin.y = parseInt(action.arg[3]); } this.cursor.x = d.origin.x; this.cursor.y = d.origin.y; d.style.left = (parseFloat(d.origin.x) / parseFloat(imageWidth) * 100.0) + "%"; d.style.top = (parseFloat(d.origin.y) / parseFloat(imageHeight) * 100.0) + "%"; this.div.appendChild(d); //foo = d; d.addEventListener("mousedown", onMouseDownText); d.addEventListener("mousemove", onMouseMoveText); d.addEventListener("mouseup", onMouseUpText); d.addEventListener("click", onClickText); d.overlay = this; //this.doNextAction(); this.resize(); break; case "ONCLICKTEXT": //set a click event for the latest text object this.div.lastChild.clickAction = new Action(); if(action.arg[1].charAt(0) == "$") { //variable assignments start with $ this.div.lastChild.clickAction.arg[0] = "VAR-OP"; this.div.lastChild.clickAction.argCount++; for(var a = 1; a < action.argCount; a++) { this.div.lastChild.clickAction.arg[a] = action.arg[a]; this.div.lastChild.clickAction.argCount++; } } else { for(var a = 1; a < action.argCount; a++) { this.div.lastChild.clickAction.arg[a-1] = action.arg[a]; this.div.lastChild.clickAction.argCount++; } } break; case "CLEARTEXT": //clear all text objects while (this.div.firstChild) { this.div.removeChild(this.div.firstChild); } //this.doNextAction(); break; case "TAIL": var svg = document.createElementNS("http://www.w3.org/2000/svg", "svg"); var polygon = document.createElementNS("http://www.w3.org/2000/svg", "polygon"); svg.appendChild(polygon); makeTail(polygon, action.arg[1], action.arg[2], action.arg[3], action.arg[4]) svg.style.top = 0; svg.style.left = 0; svg.style.position = "absolute"; svg.style.width = "100%"; svg.style.height = "100%"; svg.setAttribute("viewBox", "0 0 " + imageWidth + " " + imageHeight); polygon.style.stroke = action.arg[5]; polygon.style.fill = action.arg[5]; //svg.onclick = clickHandler; svg.style.pointerEvents = "none"; this.div.appendChild(svg); currDebugTail = polygon; //this.doNextAction(); break; case "PARENT": //this.doNextAction(); break; case "FRAME_PARENT": //this.doNextAction(); break; case "TRANSITION": this.scene.transitionType = action.arg[1]; // fade/scrubLeft/etc this.scene.transitionDirection = action.arg[2]; // in/out this.scene.fader.style.backgroundColor = action.arg[3]; // hex color this.scene.transitionStartTime = gTimeStamp; var time = action.arg[4]; if(time.charAt(0) == "$") time = parseInt(storage[time]); else time = parseInt(time); this.scene.transitionEndTime = gTimeStamp + time; if(action.arg[5]) this.scene.transitionEaseType = action.arg[5]; else this.scene.transitionEaseType = "inOutQuad"; this.scene.fader.style.opacity = 0.0; this.scene.fader.style.left = "0px;"; this.scene.fader.style.right = ""; this.scene.fader.style.width = "100%"; this.scene.fader.style.height = "100%"; //this.doNextAction(); break; case "PLAYALLSOUND": //hack for iOS, which will only play a sound in response to user input playAllSound(); //this.doNextAction(); break; case "STOPALLSOUND": //hack for iOS, which will only play a sound in response to user input stopAllSound(action.arg[1]); //this.doNextAction(); break; case "CHVOLUME": //sound channel volume animation //CHVOLUME