/* * global vars */ var lengthOfStep = 10; // distance between edges; in graphical mode -> 40 var numberOfEdges = 10; // will be set in start dialog var defTicksPerEdge = 33; // ticks for the drunken man to reach the next edge var numberOfTicksPerSec = 33; // sets tickrate (= framerate) var useTicksPerEdge = defTicksPerEdge; // for "even faster" var misc; // contains the Miscellaneous instance var graphics; // contains the Graphics instance var menu; // contains the Menu instance var path; // contains the path for the drunken man var edge; // contains the active edge var ticksPerEdge; // contains the number of ticks to reach the next edge var tickNum; // contains the global number of ticks var started; // true, if simulation is started var paused; // true, if simulation end is reached var checked; // contains the number of loaded includes var neededChecked; // contains the number of includes var dragEnabled; // true, if canvas element is clicked var dragInit; // true, if initial position is not defined yet var dragPosition; // contains the last mouse position var tickedDragPosition; // contains activ mouse position var tickId; // contains the interval id of the main ticker var fasterId; // contains the interval if of the "even faster" ticker var startpop; // contains the startup dialog var simTime; // contains the simulation time /* * setup routine */ function setup () { Debug.log("main", "setup routine started"); // some var init... misc = new Miscellaneous(); checked = 0; tickNum = 0; started = false; paused = false; edge = 0; ticksPerEdge = useTicksPerEdge; dragEnabled = false; dragInit = false; fasterId = 0; simTime = 0; // includes for all modules neededChecked = 7; misc.include("scripts/libs/Graphics.js", check); misc.include("scripts/libs/Position.js", check); misc.include("scripts/objects/Path.js", check); misc.include("scripts/objects/Menu.js", check); misc.include("scripts/objects/Drunken.js", check); misc.include("scripts/objects/Bar.js", check); misc.include("scripts/objects/Popup.js", check); } /* * check routine for includes */ function check() { Debug.log("main", "load checked: " + ++checked + "/" + neededChecked); // if all modules are loaded execute main routine if (checked == neededChecked) main(); } /* * main routine */ function main() { Debug.log("main", "main routine started"); // some other var init graphics = new Graphics(); menu = new Menu(); path = new Path(); dragPosition = new Position(); tickedDragPosition = new Position(); // module init graphics.init(); menu.init(); // pointless, because there isn't a default image to draw ; ) graphics.drawDefault(); // set all (most) events setEvents(); // generate startup dialog startpop = new Popup("Drunken Man Simulator"); startpop.text = ""; startpop.text += 'Options:
'; startpop.text += 'use graphical mode
'; startpop.text += 'Please select a time:
'; startpop.text += '
'; startpop.text += ''; startpop.display(); } /* * sets all (most) events */ function setEvents() { window.onmousewheel = scroll; window.onmousemove = drag; document.getElementById("canvas").onmousedown = enableDrag; window.onmouseup = disableDrag; tickId = window.setInterval(tick, 1000 / numberOfTicksPerSec); window.setInterval(infoUpdate, 100); window.onresize = updateAllStyles; } /* * tick function for "even faster" */ function fastTick() { // if not started, than do nothing... if (!started) return; // if end not reached if (edge != numberOfEdges) { // calculate new Position and decrement current ticksPerEdge graphics.drunken.position = graphics.drunken.getNextPosition(path.positions[edge], ticksPerEdge--); // calculate rotation for graphical mode graphics.drunken.rotation = graphics.drunken.getNextRotation(path.positions[edge]); // if next edge is reached: increment edge number and reset ticksPerEdge if (graphics.drunken.position.equals(path.positions[edge])) { edge++; ticksPerEdge = useTicksPerEdge; } // calculate steps for animation graphics.drunken.step = graphics.drunken.frames[parseInt((tickNum / (5)) % graphics.drunken.frames.length)]; } // if end reached stop simulation if (edge == numberOfEdges) stopSimulation(); // increment tick counter tickNum++; } /* * normal tick function */ function tick() { // the same as fastTick if (!started) return; // if fast tick is disabled if ((edge != numberOfEdges) && (!fasterId)) { graphics.drunken.position = graphics.drunken.getNextPosition(path.positions[edge], ticksPerEdge--); graphics.drunken.rotation = graphics.drunken.getNextRotation(path.positions[edge]); if (graphics.drunken.position.equals(path.positions[edge])) { edge++; ticksPerEdge = useTicksPerEdge; } graphics.drunken.step = graphics.drunken.frames[parseInt((tickNum / (5)) % graphics.drunken.frames.length)]; } // drag routine for canvas element if (!dragPosition.equals(tickedDragPosition)) { if (!(dragInit)) { var deltaX = dragPosition.x - tickedDragPosition.x; var deltaY = dragPosition.y - tickedDragPosition.y; // sets null position in graphics graphics.null.x += deltaX; graphics.null.y += deltaY; } else { dragInit = false; } tickedDragPosition.x = dragPosition.x; tickedDragPosition.y = dragPosition.y; } // update graphics graphics.tick(path); // if end is reached than stop simulation if (!paused && (edge == numberOfEdges)) stopSimulation(); if (!fasterId) tickNum++; } /* * scroll function */ function scroll(e) { e = e ? e : window.event; var wheelData = e.detail ? e.detail : e.wheelDelta; if (wheelData > 0) // on positiv scroll zoom in graphics.zoom *= 1.1; else // on negativ scroll zomm out graphics.zoom /= 1.1; } /* * updates debug box */ function infoUpdate() { var text = ""; text += "drunken: x=" + graphics.drunken.position.x + " y=" + graphics.drunken.position.y + " rot=" + graphics.drunken.rotation + "
"; text += "bar: x=" + graphics.bar.position.x + " y=" + graphics.bar.position.y + " rot=" + graphics.bar.rotation + "
"; text += "edges: " + edge + "/" + numberOfEdges + "
"; document.getElementById("debugInfo").innerHTML = text; } /* * enables drag for canvas element */ function enableDrag (e) { dragEnabled = true; dragInit = true; document.getElementById("canvas").style.cursor = "move"; } /* * disables drag for canvas element */ function disableDrag () { dragEnabled = false; document.getElementById("canvas").style.cursor = "pointer"; } /* * drag function */ function drag (e) { // check drag on all popups Popup.checkDrag(e); // check drag for canvas element if (!dragEnabled) return; dragPosition.x = e.clientX; dragPosition.y = e.clientY; } /* * select function for start popup */ function selectOption (select, other) { switch(other) { case 1: // numberOfEdges = select Debug.log("main", (numberOfEdges = select) + " edges selected"); break; case 0: var frames; // frames = select * numberOfTicksPerSec * 60; numberOfEdges = round(frames / defTicksPerEdge) // select in min Debug.log("main", select + " minutes selected -> " + (frames = select * numberOfTicksPerSec * 60) + " frames -> " + (numberOfEdges = Math.round(frames / defTicksPerEdge)) + " edges"); simTime = frames / numberOfTicksPerSec; break; // on other == undefined default: var frames; // if value == 0 -> display other block if (select.value == 0) { document.getElementById("other").style.display = "block"; return; } // same as case 1, but select is object // select.value in min Debug.log("main", select.value + " minutes selected -> " + (frames = select.value * numberOfTicksPerSec * 60) + " frames -> " + (numberOfEdges = Math.round(frames / defTicksPerEdge)) + " edges"); simTime = frames / numberOfTicksPerSec; } // if graphical mode, then displayBar, displayDrunken, lengthOfStep = 40 if (document.getElementById("graphical").checked) { lengthOfStep = 40; graphics.displayBar = true; graphics.displayDrunken = true; document.getElementById("displayBar").checked = true; document.getElementById("displayDrunken").checked = true; } // calculate new path path = new Path(); path.calculate(0, 0, numberOfEdges - 1); // close popup startpop.close(); // start simulation started = true; } /* * for the "start simulation" button */ function selectOther () { selectOption(parseInt(document.getElementById("val").value), parseInt(document.getElementById("siz").value)); } /* * on resize update all styles */ function updateAllStyles () { graphics.updateStyle(); menu.updateStyle(); } /* * is called when simulation end is reached */ function stopSimulation() { paused = true; // reset all ticks if (fasterId) { window.clearInterval(fasterId); fasterId = 0; } else { window.clearInterval(tickId); tickId = window.setInterval(tick, 1000 / numberOfTicksPerSec); } // yeah, what do you think? generateEndPopup(); } /* * generate the popup for the end */ function generateEndPopup () { var endPop = new Popup("simulation report"); endPop.text = ""; // if simulation time is set -> display time & frames if (simTime) { endPop.text += "simulation time: " + simTime + "s
"; endPop.text += "frames: " + simTime * numberOfTicksPerSec + " (@ " + numberOfTicksPerSec + " fps)
"; } endPop.text += "edges: " + numberOfEdges + "
"; endPop.text += "distance: " + Math.sqrt(graphics.drunken.position.x * graphics.drunken.position.x + graphics.drunken.position.y * graphics.drunken.position.y) + "
"; // calculated distance is the sqrt of time (einstein) endPop.text += "calculated distance: " + Math.sqrt(path.positions.length); endPop.display(); }