diff --git a/audio/bonk.mp3 b/audio/bonk.mp3 new file mode 100644 index 0000000..2c048fd Binary files /dev/null and b/audio/bonk.mp3 differ diff --git a/audio/button0.mp3 b/audio/button0.mp3 new file mode 100644 index 0000000..1102d7f Binary files /dev/null and b/audio/button0.mp3 differ diff --git a/audio/button1.mp3 b/audio/button1.mp3 new file mode 100644 index 0000000..6d8339d Binary files /dev/null and b/audio/button1.mp3 differ diff --git a/audio/button2.mp3 b/audio/button2.mp3 new file mode 100644 index 0000000..f9f92a9 Binary files /dev/null and b/audio/button2.mp3 differ diff --git a/audio/chimes.mp3 b/audio/chimes.mp3 new file mode 100644 index 0000000..ed1c690 Binary files /dev/null and b/audio/chimes.mp3 differ diff --git a/audio/contagion0.mp3 b/audio/contagion0.mp3 new file mode 100644 index 0000000..85b04db Binary files /dev/null and b/audio/contagion0.mp3 differ diff --git a/audio/contagion1.mp3 b/audio/contagion1.mp3 new file mode 100644 index 0000000..5eb4d34 Binary files /dev/null and b/audio/contagion1.mp3 differ diff --git a/audio/contagion2.mp3 b/audio/contagion2.mp3 new file mode 100644 index 0000000..a374d28 Binary files /dev/null and b/audio/contagion2.mp3 differ diff --git a/audio/party.mp3 b/audio/party.mp3 new file mode 100644 index 0000000..adb94f9 Binary files /dev/null and b/audio/party.mp3 differ diff --git a/audio/party_short.mp3 b/audio/party_short.mp3 new file mode 100644 index 0000000..bf6aa98 Binary files /dev/null and b/audio/party_short.mp3 differ diff --git a/audio/pencil.mp3 b/audio/pencil.mp3 new file mode 100644 index 0000000..f55de17 Binary files /dev/null and b/audio/pencil.mp3 differ diff --git a/audio/pencil_short.mp3 b/audio/pencil_short.mp3 new file mode 100644 index 0000000..702082e Binary files /dev/null and b/audio/pencil_short.mp3 differ diff --git a/audio/pluck0.mp3 b/audio/pluck0.mp3 new file mode 100644 index 0000000..583a92c Binary files /dev/null and b/audio/pluck0.mp3 differ diff --git a/audio/pluck1.mp3 b/audio/pluck1.mp3 new file mode 100644 index 0000000..56e8873 Binary files /dev/null and b/audio/pluck1.mp3 differ diff --git a/audio/pluck2.mp3 b/audio/pluck2.mp3 new file mode 100644 index 0000000..aad756b Binary files /dev/null and b/audio/pluck2.mp3 differ diff --git a/audio/pluck3.mp3 b/audio/pluck3.mp3 new file mode 100644 index 0000000..de0e07e Binary files /dev/null and b/audio/pluck3.mp3 differ diff --git a/audio/scratch_in.mp3 b/audio/scratch_in.mp3 new file mode 100644 index 0000000..f8c9b42 Binary files /dev/null and b/audio/scratch_in.mp3 differ diff --git a/audio/scratch_out.mp3 b/audio/scratch_out.mp3 new file mode 100644 index 0000000..e55b17a Binary files /dev/null and b/audio/scratch_out.mp3 differ diff --git a/audio/snip0.mp3 b/audio/snip0.mp3 new file mode 100644 index 0000000..d542a18 Binary files /dev/null and b/audio/snip0.mp3 differ diff --git a/audio/snip1.mp3 b/audio/snip1.mp3 new file mode 100644 index 0000000..9bc3e15 Binary files /dev/null and b/audio/snip1.mp3 differ diff --git a/audio/snip2.mp3 b/audio/snip2.mp3 new file mode 100644 index 0000000..ad20554 Binary files /dev/null and b/audio/snip2.mp3 differ diff --git a/css/index.css b/css/index.css index 7b1e420..b0ad17f 100644 --- a/css/index.css +++ b/css/index.css @@ -110,6 +110,12 @@ b, strong{ line-height: 25px; color: #aaa; text-align: right; + + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + } #container > #skip:hover{ color: #ccc; diff --git a/index.html b/index.html index 7b3a25e..48f2908 100644 --- a/index.html +++ b/index.html @@ -371,6 +371,7 @@ MY "WHY" FOR MAKING THIS:
Draw a network & run the simulation, so that everyone gets infected with the "contagion". +
(new rule: you can't cut the thick connections) @@ -403,8 +404,11 @@ MY "WHY" FOR MAKING THIS: Now, let's simulate what happens if people do start drinking when 50%+ of their friends do! - Before you start the sim, ask yourself what you think should happen. - Now, run the sim, and see what actually happens! → + Before you start the sim, ask yourself what you think should happen. + +

+ + Now, run the sim, and see what actually happens! → diff --git a/js/chapters/A_Preloader.js b/js/chapters/A_Preloader.js index 81eb38c..05da565 100644 --- a/js/chapters/A_Preloader.js +++ b/js/chapters/A_Preloader.js @@ -46,6 +46,7 @@ SLIDES.push( // START, FOR REAL button.onclick = function(){ publish("START"); + publish("sound/button"); }; }, diff --git a/js/chapters/C_Networks.js b/js/chapters/C_Networks.js index ace7e9d..6437c30 100644 --- a/js/chapters/C_Networks.js +++ b/js/chapters/C_Networks.js @@ -32,19 +32,19 @@ SLIDES.push( { type:"box", id:"connect_words", - text:"networks_tutorial_connect", x:280, y:183, w:400, align:"center", color:"#ccc" + text:"networks_tutorial_connect", x:280, y:183-7, w:400, align:"center", color:"#bbb" }, { type:"box", id:"connect_pic", - img:"sprites/tutorial_connect.png", x:330, y:150, w:300, h:100 + img:"sprites/tutorial_connect.png", x:330, y:150-7, w:300, h:100 }, // "Disconnect" instruction (words & picture) { type:"box", id:"disconnect_words", - text:"networks_tutorial_disconnect", x:280, y:280, w:400, align:"center", color:"#ccc" + text:"networks_tutorial_disconnect", x:280, y:280, w:400, align:"center", color:"#bbb" }, { type:"box", diff --git a/js/chapters/D_Simple_Contagion.js b/js/chapters/D_Simple_Contagion.js index 97ff792..bc5eda2 100644 --- a/js/chapters/D_Simple_Contagion.js +++ b/js/chapters/D_Simple_Contagion.js @@ -171,7 +171,10 @@ SLIDES.push( var boxes = slideshow.boxes; boxes.showChildByID("end", true); state.ended = true; - sim.win(); + sim.win({ + small:true, + x:280, y:200, width:400, height:200 + }); } } diff --git a/js/chapters/E_Complex_Contagion.js b/js/chapters/E_Complex_Contagion.js index 45b2ff7..15b23ff 100644 --- a/js/chapters/E_Complex_Contagion.js +++ b/js/chapters/E_Complex_Contagion.js @@ -132,7 +132,9 @@ SLIDES.push( boxes.removeChildByID("complex_complex_3", true); boxes.showChildByID("end", true); state.ended = true; - sim.win(); + sim.win({ + small:true + }); } } @@ -326,7 +328,8 @@ SLIDES.push( //boxes.showChildByID("end", true); sim.win({ x:350, y:270-90, - width:260, height:260 + width:260, height:260, + small:true }); },350); setTimeout(function(){ diff --git a/js/chapters/F_Bonding_And_Bridging.js b/js/chapters/F_Bonding_And_Bridging.js index 97a05bc..340e431 100644 --- a/js/chapters/F_Bonding_And_Bridging.js +++ b/js/chapters/F_Bonding_And_Bridging.js @@ -24,7 +24,8 @@ SLIDES.push( options:{ infectedFrame: 3, scale: 1, - _wisdom: true + _wisdom: true, + NO_BONK: true } }, @@ -81,7 +82,8 @@ SLIDES.push( state.ended = true; sim.win({ x:330+5, y:160-120+5, - width:280, height:280 + width:280, height:280, + small:true }); } } diff --git a/js/chapters/H_Conclusion.js b/js/chapters/H_Conclusion.js index cb5041f..f362bf0 100644 --- a/js/chapters/H_Conclusion.js +++ b/js/chapters/H_Conclusion.js @@ -88,6 +88,10 @@ SLIDES.push( {type:"box", id:"conclusion_3"} ], onstart: function(slideshow, state){ + + // SOUND + SOUNDS.chimes.play(); + // splash animation, then auto-next to CREDITS. var splash = slideshow.simulations.sims[0]; splash.options.CONCLUSION = true; @@ -95,6 +99,7 @@ SLIDES.push( setTimeout(function(){ slideshow.next(); },7000); + }, onupdate: function(slideshow, state){ var splash = slideshow.simulations.sims[0]; diff --git a/js/main.js b/js/main.js index 7d3a97b..cdc4c67 100644 --- a/js/main.js +++ b/js/main.js @@ -46,6 +46,7 @@ subscribe("START", function(){ // Show Skip Button $("#skip").style.display = "block"; $("#skip").onclick = function(){ + publish("sound/button"); slideshow.next(); }; diff --git a/js/sim/Connection.js b/js/sim/Connection.js index ebc66ae..f656feb 100644 --- a/js/sim/Connection.js +++ b/js/sim/Connection.js @@ -39,10 +39,19 @@ function Connection(config){ var dy = self.to.y - self.from.y; var a = Math.atan2(dy,dx); var dist = Math.sqrt(dx*dx + dy*dy); + ctx.rotate(a); + + // SHAKE + if(self.shaking>=0 && self.shaking<1){ + self.shaking+=0.05; + var amplitude = (1-self.shaking)*3; + ctx.translate(0, Math.sin(self.shaking*Math.TAU*3)*amplitude); + } + self.sprite.scaleX = dist/300; self.sprite.scaleY = self.uncuttable ? 1 : 0.5; // thick=uncuttable //self.sprite.scaleY *= s; - self.sprite.rotation = a; + //self.sprite.rotation = a; self.sprite.draw(ctx); ctx.restore(); @@ -117,5 +126,9 @@ function Connection(config){ } }; + self.shaking = -1; + self.shake = function(){ + self.shaking = 0; + }; } \ No newline at end of file diff --git a/js/sim/ConnectorCutter.js b/js/sim/ConnectorCutter.js index 00aa4c5..546b6b5 100644 --- a/js/sim/ConnectorCutter.js +++ b/js/sim/ConnectorCutter.js @@ -10,6 +10,21 @@ function ConnectorCutter(config){ self.isCutting = false; self.cutTrail = []; + // SNIP & PLUCK SOUND + var _SNIP_SOUND = 0; + var _SNIP = function(){ + _SNIP_SOUND = (_SNIP_SOUND+1)%3; + SOUNDS["snip"+_SNIP_SOUND].play(); + }; + var _PLUCK_SOUND_INDEX = 0; + var _PLUCK_SOUND = [0,1,2,3,2,1]; + var _PLUCK = function(){ + var soundName = "pluck"+_PLUCK_SOUND[_PLUCK_SOUND_INDEX]; + SOUNDS[soundName].play(); + _PLUCK_SOUND_INDEX++; + if(_PLUCK_SOUND_INDEX >= _PLUCK_SOUND.length) _PLUCK_SOUND_INDEX=0; + }; + // Update! self.state = 0; // 0-nothing | 1-connecting | 2-cutting self.sandbox_state = 0; // 0-pencil | 1-add_peep | 2-add_infected | 3-move | 4-delete | 5-bomb @@ -44,8 +59,14 @@ function ConnectorCutter(config){ // Clicked on a peep? var peepClicked = self.sim.getHoveredPeep(20); if(peepClicked){ + self.state = 1; // START CONNECTING self.connectFrom = peepClicked; + + // SOUND! + SOUNDS.pencil_short.volume(0.37); + SOUNDS.pencil_short.play(); + }else{ self.state = 2; // START ERASING } @@ -59,7 +80,14 @@ function ConnectorCutter(config){ if(self.state==1){ var peepReleased = self.sim.getHoveredPeep(20); if(peepReleased){ - self.sim.addConnection(self.connectFrom, peepReleased); + var successfulConnection = self.sim.addConnection(self.connectFrom, peepReleased); + + // SOUND! + if(successfulConnection){ + SOUNDS.pencil.volume(0.37); + SOUNDS.pencil.play(); + } + } } @@ -100,7 +128,13 @@ function ConnectorCutter(config){ // Try cutting var line = [mouse.lastX, mouse.lastY, mouse.x, mouse.y]; - self.sim.tryCuttingConnections(line); + var wasLineCut = self.sim.tryCuttingConnections(line); + if(wasLineCut==1){ // snip! + _SNIP(); + } + if(wasLineCut==-1){ // uncuttable + _PLUCK(); + } // Add to trail self.cutTrail.unshift([mouse.x,mouse.y]); // add to start diff --git a/js/sim/Simulations.js b/js/sim/Simulations.js index 67002ca..81b7948 100644 --- a/js/sim/Simulations.js +++ b/js/sim/Simulations.js @@ -119,6 +119,13 @@ function Sim(config){ self.id = config.id; + // CONTAGION SOUND + var _CONTAGION_SOUND = 0; + var _PLAY_CONTAGION_SOUND = function(){ + _CONTAGION_SOUND = (_CONTAGION_SOUND+1)%3; + SOUNDS["contagion"+_CONTAGION_SOUND].play(); + }; + // Canvas if(config.fullscreen){ var container = $("#simulations_container"); @@ -343,10 +350,23 @@ function Sim(config){ if(self.wonBefore) return; self.wonBefore = true; + // SOUND! + if(bounds && bounds.small){ + SOUNDS.party_short.play(); + }else{ + SOUNDS.party.play(); + } + + // AMOUNT OF CONFETTI + var AMOUNT_OF_CONFETTI = 100; + if(bounds && bounds.small){ + AMOUNT_OF_CONFETTI = 50; + } + // Get center of peeps var fullscreenOffsetX = config.x + simOffset.x; var fullscreenOffsetY = config.y + simOffset.y; - bounds = bounds || getBoundsOfPoints(self.peeps); // OPTIONAL BOUNDS + if(!bounds || !bounds.x) bounds = getBoundsOfPoints(self.peeps); // OPTIONAL BOUNDS var cx = bounds.x + bounds.width/2; var cy = bounds.y + bounds.height/2; cx += fullscreenOffsetX; @@ -360,7 +380,7 @@ function Sim(config){ self.winWord.ticker = 0; // Place confetti - for(var i=0; i<100; i++){ + for(var i=0; i0){ + _PLAY_CONTAGION_SOUND(); + }else if(self._canPlayBonkSound && !isEveryoneInfected){ + self._canPlayBonkSound = false; + + if(!config.options.NO_BONK){ + SOUNDS.bonk.play(); + } + + } + // "Infect" the peeps who need to get infected setTimeout(function(){ self.STEP++; @@ -565,11 +608,20 @@ function Sim(config){ }); }; self.tryCuttingConnections = function(line){ + var wasLineCut = 0; for(var i=self.connections.length-1; i>=0; i--){ // going BACKWARDS coz killing connections var c = self.connections[i]; - if(c.uncuttable) continue; // don't touch the UNCUTTABLES - if(c.hitTest(line)) self.connections.splice(i,1); + if(c.hitTest(line)){ + if(c.uncuttable){ // can't cut uncuttables! + wasLineCut = -1; + c.shake(); + }else{ + wasLineCut = 1; + self.connections.splice(i,1); + } + } } + return wasLineCut; }; self.removeAllConnectedTo = function(peep){ for(var i=self.connections.length-1; i>=0; i--){ // backwards index coz we're deleting diff --git a/js/slideshow/Boxes.js b/js/slideshow/Boxes.js index 8ae34a7..00e3fb5 100644 --- a/js/slideshow/Boxes.js +++ b/js/slideshow/Boxes.js @@ -83,6 +83,7 @@ function Boxes(){ nextButton.className = "next_button"; nextButton.innerHTML = next.innerHTML; nextButton.onclick = function(){ + publish("sound/button"); slideshow.next(); }; @@ -104,6 +105,7 @@ function Boxes(){ ref.onclick = function(){ var id = ref.id; publish("reference/show",[id]); + publish("sound/button"); }; }); @@ -113,6 +115,7 @@ function Boxes(){ bon.innerHTML = "(?) "+title; bon.onclick = function(){ publish("bonus/show", [bon.id]); + publish("sound/button"); }; }); @@ -171,4 +174,4 @@ function Boxes(){ }; -} \ No newline at end of file +} diff --git a/js/slideshow/Modal.js b/js/slideshow/Modal.js index 2652aca..3ee45d3 100644 --- a/js/slideshow/Modal.js +++ b/js/slideshow/Modal.js @@ -24,6 +24,7 @@ window.Modal = { $("#modal").setAttribute("size", large ? "large" : "small"); }, hide: function(){ + publish("sound/button"); $("#modal_container").removeAttribute("show"); } }; diff --git a/js/slideshow/Navigation.js b/js/slideshow/Navigation.js index 8579c76..d55578a 100644 --- a/js/slideshow/Navigation.js +++ b/js/slideshow/Navigation.js @@ -27,6 +27,7 @@ function Navigation(){ if(chapter){ (function(nav, chapter){ nav.onclick = function(){ + publish("sound/button"); slideshow.gotoChapter(chapter); }; })(nav, chapter); diff --git a/js/slideshow/Preloader.js b/js/slideshow/Preloader.js index edb6bb1..f2da650 100644 --- a/js/slideshow/Preloader.js +++ b/js/slideshow/Preloader.js @@ -3,12 +3,19 @@ subscribe("prepreload", function(){ Preload([ - // For the Sim + // For the Splash {id:"button_large", image:"sprites/button_large.png"}, {id:"line", image:"sprites/line.png"}, {id:"peeps", image:"sprites/peeps.png"}, {id:"pencil", image:"sprites/pencil.png"}, + // Sound Effects + {id:"pencil", audio:"audio/pencil.mp3"}, + {id:"pencil_short", audio:"audio/pencil_short.mp3"}, + {id:"snip0", audio:"audio/snip0.mp3"}, + {id:"snip1", audio:"audio/snip1.mp3"}, + {id:"snip2", audio:"audio/snip2.mp3"}, + ],function(progress){ console.log("Pre-Preloader: "+progress); if(progress==1){ @@ -16,7 +23,7 @@ subscribe("prepreload", function(){ pre_preloader.parentNode.removeChild(pre_preloader); slideshow.gotoChapter("Preloader"); - //slideshow.gotoChapter("SmallWorld-Explanation"); + //slideshow.gotoChapter("Simple-Cascade"); publish("preload"); } @@ -33,9 +40,35 @@ subscribe("preload", function(){ // Music {id:"bg_music", audio:"audio/bg_music.mp3"}, + // Sound Effects + {id:"bonk", audio:"audio/bonk.mp3"}, + {id:"button0", audio:"audio/button0.mp3"}, + {id:"button1", audio:"audio/button1.mp3"}, + {id:"button2", audio:"audio/button2.mp3"}, + {id:"chimes", audio:"audio/chimes.mp3"}, + {id:"contagion0", audio:"audio/contagion0.mp3"}, + {id:"contagion1", audio:"audio/contagion1.mp3"}, + {id:"contagion2", audio:"audio/contagion2.mp3"}, + {id:"party", audio:"audio/party.mp3"}, + {id:"party_short", audio:"audio/party_short.mp3"}, + {id:"pluck0", audio:"audio/pluck0.mp3"}, + {id:"pluck1", audio:"audio/pluck1.mp3"}, + {id:"pluck2", audio:"audio/pluck2.mp3"}, + {id:"pluck3", audio:"audio/pluck3.mp3"}, + {id:"scratch_in", audio:"audio/scratch_in.mp3"}, + {id:"scratch_out", audio:"audio/scratch_out.mp3"}, + // For the slides + {id:"icons/blue", image:"sprites/icons/blue.png"}, + {id:"icons/gray", image:"sprites/icons/gray.png"}, + {id:"icons/red", image:"sprites/icons/red.png"}, + {id:"icons/yellow", image:"sprites/icons/yellow.png"}, + {id:"confetti", image:"sprites/confetti.png"}, + {id:"nasa", image:"sprites/nasa.png"}, + {id:"red_button", image:"sprites/red_button.png"}, {id:"sandbox_tools", image:"sprites/sandbox_tools.png"}, {id:"scratch", image:"sprites/scratch.png"}, + {id:"small_world", image:"sprites/small_world.png"}, {id:"tutorial_connect", image:"sprites/tutorial_connect.png"}, {id:"tutorial_disconnect", image:"sprites/tutorial_disconnect.png"}, diff --git a/js/slideshow/SandboxUI.js b/js/slideshow/SandboxUI.js index 8d4c354..3aef802 100644 --- a/js/slideshow/SandboxUI.js +++ b/js/slideshow/SandboxUI.js @@ -158,6 +158,7 @@ function ChooseOne(config){ // On Input buttonDOM.onclick = function(){ + publish("sound/button"); self.highlight(buttonDOM); // highlight config.oninput(value); // input }; diff --git a/js/slideshow/Scratch.js b/js/slideshow/Scratch.js index e7b7ae3..c25b29c 100644 --- a/js/slideshow/Scratch.js +++ b/js/slideshow/Scratch.js @@ -4,14 +4,26 @@ function Scratch(){ self.dom = $("#scratch"); self.scratchIn = function(){ + + // SOUND! + SOUNDS.scratch_in.play(); + + // anim self.startUpdateLoop(false, function(){ self.dom.style.display = "none"; }); + }; self.scratchOut = function(){ + + // SOUND! + SOUNDS.scratch_in.play(); + + // anim self.dom.style.display = "block"; self.startUpdateLoop(true); + }; self.startUpdateLoop = function(out, callback){ diff --git a/js/slideshow/SimUI.js b/js/slideshow/SimUI.js index 807639b..48a7979 100644 --- a/js/slideshow/SimUI.js +++ b/js/slideshow/SimUI.js @@ -15,6 +15,7 @@ function SimUI(container, color){ event.stopPropagation(); }; startButton.onclick = function(event){ + publish("sound/button"); if(!Simulations.IS_RUNNING){ Simulations.IS_RUNNING = true; publish("sim/start"); diff --git a/js/slideshow/Slideshow.js b/js/slideshow/Slideshow.js index 1983763..b5c4707 100644 --- a/js/slideshow/Slideshow.js +++ b/js/slideshow/Slideshow.js @@ -181,3 +181,13 @@ function Slideshow(){ } } + +//////////////////////////////// +// BUTTON SOUNDS COZ WHATEVER // +//////////////////////////////// + +var _BUTTON_SOUND = 0; +subscribe("sound/button",function(){ + _BUTTON_SOUND = (_BUTTON_SOUND+1)%3; + SOUNDS["button"+_BUTTON_SOUND].play(); +}); \ No newline at end of file diff --git a/sprites/tutorial_connect.png b/sprites/tutorial_connect.png index e32fda0..878f0c4 100644 Binary files a/sprites/tutorial_connect.png and b/sprites/tutorial_connect.png differ diff --git a/sprites/tutorial_disconnect.png b/sprites/tutorial_disconnect.png index e351303..294739e 100644 Binary files a/sprites/tutorial_disconnect.png and b/sprites/tutorial_disconnect.png differ