diff --git a/bower.json b/bower.json index 42328e3..dc5258a 100644 --- a/bower.json +++ b/bower.json @@ -1,19 +1,26 @@ { - "name": "sciencealchemy", - "description": "Science Alchemy", - "main": "js/app.js", - "moduleType": [], - "license": "MIT", - "homepage": "", - "private": true, - "ignore": [ - "**/.*", - "node_modules", - "bower_components", - "test", - "tests" - ], - "dependencies": { - "angular-dragdrop": "~1.0.13" - } + "name": "sciencealchemy", + "description": "Science Alchemy", + "main": "js/app.js", + "moduleType": [], + "license": "MIT", + "homepage": "", + "private": true, + "ignore": [ + "**/.*", + "node_modules", + "bower_components", + "test", + "tests" + ], + "dependencies": { + "angular": "1.4.x", + "angular-mocks": "1.4.x", + "jquery": "~2.1.1", + "bootstrap": "~3.1.1", + "angular-route": "1.4.x", + "angular-resource": "1.4.x", + "angular-animate": "1.4.x", + "angular-dragdrop": "~1.0.13" + } } diff --git a/css/style.css b/css/style.css index 3516c7d..28a1d30 100644 --- a/css/style.css +++ b/css/style.css @@ -30,7 +30,7 @@ h1 br { position: relative; } -#detector canvas { +#detector .test-tube, #detector .detector-events{ position: absolute; left: 0; top: 0; diff --git a/index.html b/index.html index bfcccf0..56b7fd4 100644 --- a/index.html +++ b/index.html @@ -1,5 +1,5 @@ - + Science Alchemy @@ -88,7 +88,7 @@ class="{{r.key}} element element-icon {{ r.state.interesting ? 'blink' : '' }} {{'q'+r.state.color+'-12'}}" data-element="{{r.key}}" data-drag="true" - jqyoui-draggable + jqyoui-draggable="{containment:'offset'}" data-jqyoui-options="{{rc.dragOptions}}" > {{r.key}} @@ -116,7 +116,7 @@ > Your detector. Click on it to generate events. - + Your bunsen burner. Click it to turn on and off. diff --git a/js/app.js b/js/app.js index f318bcc..d03a3a5 100644 --- a/js/app.js +++ b/js/app.js @@ -17,7 +17,7 @@ var allObjects = game.allObjects; var lastSaved; - var app = angular.module('particleClicker', ['ngDragDrop']); + var app = angular.module('scienceAlchemy', ['ngDragDrop']); // add helpers as filters app.filter('niceNumber', ['$filter', function($filter) { @@ -56,7 +56,7 @@ hoverClass: "ui-state-active", } this.onDrop = function(event,ui){ - detector.onDrop(event,ui,lab); + detector.onDrop(event,ui,game); } this.click = function() { lab.clickDetector(); @@ -64,6 +64,10 @@ UI.showUpdateValue("#update-data", lab.state.detector); return false; }; + this.toggleFlameFuel = function(){ + console.log('toggleFlameFuel'); + detector.flame.toggleFuel(); + } }); app.controller('ElementController', ['$compile', function($compile) { diff --git a/js/detector/bubblr.js b/js/detector/bubblr.js index e7a06a1..8772082 100644 --- a/js/detector/bubblr.js +++ b/js/detector/bubblr.js @@ -5,16 +5,16 @@ This plugin available for use in all personal or commercial projects under both MIT and GPL licenses. */ -;(function ( $, window, document, undefined ) { +(function ( $, window, document, undefined ) { var pluginName = "bubblr"; + /** default options **/ var defaults = { - numberOfBubbles: 10, backgroundColor: "transparent", bubbleColor: "White", - bubbleOpacity: .7, + bubbleOpacity: 0.7, bubbleMinSize: 1, bubbleMaxSize: 2, bubbleMaxSpeed: 2, @@ -22,11 +22,23 @@ animationSpeed: 10 }; + /** + * Create the bubblr + * @param {dom element} element - dom canvas element + * @param {object} options - options see Bubblr._defaults for options + */ function Bubblr( element, options ) { this.element = element; this.options = $.extend( {}, defaults, options) ; this._defaults = defaults; + this.state = { + bubbles: [], + started: false, + globalTick: 0, + genBubbles: false, + } this.init(); + this.start(); } Bubblr.prototype.init = function () { @@ -38,95 +50,113 @@ return; } - if (this.timerId) this.remove(); - $canvas = $(this.element); this.width = $canvas.width(); this.height = $canvas.height(); + // this.state.globalTick=0; + // this.state.continuous=false; // new bubbles + // this.state.started = false // if there is an animation loop + $canvas.css("background-color", this.options.backgroundColor) - this.bubbles = new Array(); + // this.state.bubbles = new Array(); + // initial bubbles for(i = 0; i < this.options.numberOfBubbles; i++) { - this.bubbles[i] = this.generateBubble(); + this.state.bubbles[i] = this.generateBubble(); } - - var self = this; - this.on=false; - - for(i in this.bubbles) { - this.drawBubble(this.bubbles[i]); + for(i in this.state.bubbles) { + this.drawBubble(this.state.bubbles[i]); } - this.timerId = setInterval(function() { - self.animationLoop(); - }, this.options.animationSpeed); - }; + /** + * Recenter on resize, + * bind this to $(window).on('resize',bubblr.onResize.bind(bubblr);) if needed + **/ Bubblr.prototype.onResize= function(){ this.clear(); - this.width = Math.max($canvas.width(),this.element.width); - this.height = Math.max($canvas.height(),this.element.height); + this.width = $(this.element).outerWidth(); + this.height = $(this.element).outerWidth(); }; - Bubblr.prototype.start = function(timespan) { - var self = this; - if (!this.on){ - // this.timerId = setInterval(function() { - // self.animationLoop(); - // }, this.options.animationSpeed); - if (timespan) this.nextOffID = setTimeout(self.stop.bind(self),timespan); - this.on=true; - } else { - clearInterval(this.nextOffID); - this.nextOffID = setTimeout(self.stop.bind(self),timespan); + /** Start animation loop if not started **/ + Bubblr.prototype.start = function() { + if (!this.state.started){ + this.state.started=true; + this.animationLoop(); } }; + /** Stop animation loop **/ Bubblr.prototype.stop = function() { - this.on=false; - this.nextOffID=null; - }; - - /** remove animation loop **/ - Bubblr.prototype.remove = function (arguments) { - clearInterval(this.timerId); - this.timerId=null; - detector.bubblr.clear() - } - - Bubblr.prototype.animationLoop = function() { - + this.state.started=false; this.clear(); - - for(i in this.bubbles) { - this.update(i, this.bubbles[i]); - this.draw(i, this.bubbles[i]); - } - }; + /** Animation loop run Bubblr.stop and start control this **/ + Bubblr.prototype.animationLoop = function() { + window.requestAnimFrame(this.animationLoop.bind(this)); + this.state.globalTick++; + if (this.state.started) this.animate(); + }; + + Bubblr.prototype.animate = function (arguments) { + this.clear(); + for(i in this.state.bubbles) { + this.update(i, this.state.bubbles[i]); + this.draw(i, this.state.bubbles[i]); + } + } + Bubblr.prototype.clear = function () { this.ctx.globalAlpha = 1; this.ctx.fillStyle = this.options.backgroundColor; this.ctx.clearRect(0,0,this.width, this.height); }; + Bubblr.prototype.draw = function (index, bubble) { this.ctx.globalAlpha = this.options.bubbleOpacity; this.drawBubble(bubble); }; + /** Update bubble position **/ Bubblr.prototype.update = function (index, bubble) { bubble.y = bubble.y - bubble.speed - if(bubble.y < 0 && this.on) - this.bubbles[index] = this.generateBubble(true); + if(bubble.y < 0 && this.state.continuous) + // reset to bottom if continuous running is on + this.state.bubbles[index] = this.generateBubble(true); }; + /** + * Generate a single bubble + * @param {object} options - options for the bubble + * @param {Number} options.x - Starting x position. Defaults to a random + * location. + * @param {Number} options.y - starting y level. Default to the bottom or + * null for random position, a number sets a + * specific level. Note the top is 0, while the + * bottom is `-$(element).height()` + */ + Bubblr.prototype.bubble = function (options){ + this.state.bubbles.push(this.generateBubble(options)); + } + + /** + * Helper to generate multiple bubble + * @param {[type]} amount - amount of bubbles to create + * @param {[type]} options - see Bubblr.bubble for description + */ + Bubblr.prototype.genBubbles = function (amount,options) { + for (var i = 0; i < amount; i++) { + this.state.bubbles.push(this.generateBubble(options)); + } + } Bubblr.prototype.drawBubble = function(bubble) { this.ctx.fillStyle = this.options.bubbleColor; @@ -136,20 +166,33 @@ this.ctx.fill(); }; - Bubblr.prototype.generateBubble = function(start_y_at_zero) { + Bubblr.prototype.generateBubble = function(options) { + options = options || {}; var bubble = new Object(); - bubble.x = this.randomize(1,this.width); - if(start_y_at_zero) { + + if(options.x===undefined || options.x===null) + bubble.x = this.randomize(1,this.width); + else + bubble.x = options.x + + if(options.y===undefined) bubble.y = this.height; - } - else { + else if (options.y===null) bubble.y = this.randomize(1,this.height); - } + else + bubble.y = options.y + if (options.radius) + bubble.radius = options.radius + else + bubble.radius = this.randomize(this.options.bubbleMinSize, this.options.bubbleMaxSize); + + if (options.speed) + bubble.speed = options.speed; + else + bubble.speed = this.randomize(this.options.bubbleMinSpeed, this.options.bubbleMaxSpeed); - bubble.radius = this.randomize(this.options.bubbleMinSize, this.options.bubbleMaxSize); - bubble.speed = this.randomize(this.options.bubbleMinSpeed, this.options.bubbleMaxSpeed); return bubble; }; @@ -157,7 +200,7 @@ return Math.floor((Math.random()*max)+min); }; - + // $.flame will create or return the bubblr element $.fn[pluginName] = function ( options ) { return this.each(function () { if (!$.data(this, 'plugin_' + pluginName)) { @@ -168,3 +211,15 @@ } })( jQuery, window, document ); + +// shim for requestAnimFrame +window.requestAnimFrame = (function(){ + return window.requestAnimationFrame || + window.webkitRequestAnimationFrame || + window.mozRequestAnimationFrame || + window.oRequestAnimationFrame || + window.msRequestAnimationFrame || + function(/* function */ callback, /* DOMElement */ element){ + window.setTimeout(callback, 1000 / 60); + }; +})(); diff --git a/js/detector/detector.js b/js/detector/detector.js index bc06b56..f8cb9be 100644 --- a/js/detector/detector.js +++ b/js/detector/detector.js @@ -15,6 +15,12 @@ var detector = list: [], }, + flame: + { + canvas: null, + ctx: null + }, + visible: true, width: 400, @@ -36,6 +42,9 @@ var detector = detector.events.canvas = document.getElementById('detector-events'); detector.events.ctx = detector.events.canvas.getContext('2d'); + detector.flame.canvas = document.getElementById('detector-flame'); + detector.flame.ctx = detector.events.canvas.getContext('2d'); + // set size // TODO resize "#detector-flame" too var devicePixelRatio = window.devicePixelRatio || 1; @@ -58,6 +67,9 @@ var detector = detector.events.canvas.width = baseSize; detector.events.canvas.height = baseSize; + detector.flame.canvas.width = baseSize; + detector.flame.canvas.height = baseSize; + if (devicePixelRatio !== backingStoreRatio) { var oldWidth = detector.core.canvas.width; var oldHeight = detector.core.canvas.height; @@ -81,6 +93,7 @@ var detector = detector.initBubbles(); + detector.initFlame(); // TODO refactor flame animation and put it here // this.flame = $('#detector-flame').flame(); @@ -106,6 +119,16 @@ var detector = detector.bubblr = bubblrElem.data('plugin_bubblr'); }, + initFlame: function(){ + var flameElem = $('#detector-flame').flame(); + this.flame = flameElem.data('plugin_flame') + }, + + onResize: function(){ + this.bubblr.onResize(); + this.flame.onResize(); + }, + animate: function(time) { // var duration = typeof time !== 'undefined' ? time - detector.lastRender : 16; @@ -118,28 +141,42 @@ var detector = /** When a user clicks the detector **/ addEvent: function() { - detector.bubblr.start(500); // bubble for 500ms, TODO make one bubble + detector.bubblr.bubble(); // bubble for 500ms, TODO make one bubble }, /** When a worker clicks the detector **/ addEventExternal: function(numWorkers) { - // detector.bubblr.start(500*numWorkers); + // detector.bubblr.bubble(numWorkers); }, /** Draw current events **/ draw: function(duration) { - detector.bubblr.start(duration); + detector.bubblr.bubble(); }, - onDrop: function(event, ui, lab){ + onDrop: function(event, ui, game){ // TODO tidy this, attach new runes to something better // FIXME at the moment it duplicates runes, but we need a better system var self=this; console.debug('onDrop',arguments); var $draggable = $(ui.draggable), $droppable = $(event.target); + + // if the dragger came from the elements panels, clone it to here + var newElement = $draggable.clone(); + var $detector = $droppable.parent() + $detector.append(newElement); + // also set position to that of droppable + newElement.offset($draggable.offset()) + + + var elementStore = game.elements.filter(function(e){return e.key==$draggable.data('element')}); + elementStore[0].state.amount-=1; + + // get everything intersecting the drop + var draggableTop = $draggable.offset().top; var draggableHeight = $draggable.height(); var draggableBottom = draggableTop + draggableHeight; @@ -161,17 +198,19 @@ var detector = && left <= draggableRight && right >= draggableLeft; return isCoveredByDraggable; }); + // TODO also get draggable covered by droppable for (var i = 0; i < $droppablesCoveredByDraggable.length; i++) { - this.experiment($draggable,$droppablesCoveredByDraggable[i]); + } + // just get one thes with a data-element attribute + var inputs = $droppablesCoveredByDraggable.filter(function(e){ + return $(e).data('element'); + }) + inputs.push($draggable); + var reaction = game.experiment({inputs:inputs}); console.log('droppables', $droppablesCoveredByDraggable.length); - // duplicate - var newRune = this.runeElem(ui.draggable.data('id'),$draggable.parent().parent()); - newRune.position({my:'center', at:'center',of: $draggable}) - // var newRune = ui.draggable.clone(true,true); - // $draggable.parent().append(newRune); }, }; diff --git a/js/detector/flame.js b/js/detector/flame.js index c8d434b..985e8c3 100644 --- a/js/detector/flame.js +++ b/js/detector/flame.js @@ -1,109 +1,220 @@ -/* http://codepen.io/jackrugile/pen/Jbnpv */ -// TODO refactor this to be a object with inputs and outputs, and to center on -// window resize -var c = document.getElementById('detector-flame'), - ctx = c.getContext('2d'), - cw = c.width = 400, - ch = c.height = 300, - parts = [], - partCount = 200, - partsFull = false, - hueRange = 50, - globalTick = 0, - rand = function(min, max){ - return Math.floor( (Math.random() * (max - min + 1) ) + min); + +/** + * @name Flame + * @description jquery plugin to generate flame on a canvas element.. + * Based on http://codepen.io/jackrugile/pen/Jbnpv + * @copyright (c) 2015 wassname + * @license: MIT + */ +// TODO recenter on canvas/window resize +;(function ( $, window, document, undefined ) { + var pluginName = "flame"; + + var defaults = { + hueRange: 50, + }; + + var defaultState = { + parts: [], + partCount: 200, + partsFull: false, + on: true, + rendering: false, + globalTick: 0, + width: null, + height: null, + } + + var Part = function(flame){ + this.flame=flame; + this.ctx=this.flame.ctx; + this.reset(); }; -var Part = function(){ - this.reset(); -}; -Part.prototype.reset = function(){ - this.startRadius = rand(1, 25); - this.radius = this.startRadius; - this.x = cw/2 + (rand(0, 6) - 3); - this.y = 250; - this.vx = 0; - this.vy = 0; - this.hue = rand(globalTick - hueRange, globalTick + hueRange); - this.saturation = rand(50, 100); - this.lightness = rand(20, 70); - this.startAlpha = rand(1, 10) / 100; - this.alpha = this.startAlpha; - this.decayRate = .1; - this.startLife = 7; - this.life = this.startLife; - this.lineWidth = rand(1, 3); -} - -Part.prototype.update = function(){ - this.vx += (rand(0, 200) - 100) / 1500; - this.vy -= this.life/50; - this.x += this.vx; - this.y += this.vy; - this.alpha = this.startAlpha * (this.life / this.startLife); - this.radius = this.startRadius * (this.life / this.startLife); - this.life -= this.decayRate; - if( - this.x > cw + this.radius || - this.x < -this.radius || - this.y > ch + this.radius || - this.y < -this.radius || - this.life <= this.decayRate - ){ - this.reset(); - } -}; - -Part.prototype.render = function(){ - ctx.beginPath(); - ctx.arc(this.x, this.y, this.radius, 0, Math.PI * 2, false); - ctx.fillStyle = ctx.strokeStyle = 'hsla('+this.hue+', '+this.saturation+'%, '+this.lightness+'%, '+this.alpha+')'; - ctx.lineWidth = this.lineWidth; - ctx.fill(); - ctx.stroke(); -}; - -var createParts = function(){ - if(!partsFull){ - if(parts.length > partCount){ - partsFull = true; - } else { - parts.push(new Part()); + Part.prototype.reset = function(){ + this.startRadius = this.rand(1, 25); + this.radius = this.startRadius; + this.width = this.flame.state.width; + this.height = this.flame.state.height; + this.x = this.width/2 + (this.rand(0, 6) - 3); + this.y = 250; + this.vx = 0; + this.vy = 0; + this.hue = this.rand(this.flame.state.globalTick - this.flame.options.hueRange, this.flame.state.globalTick + this.flame.options.hueRange); + this.saturation = this.rand(50, 100); + this.lightness = this.rand(20, 70); + this.startAlpha = this.rand(1, 10) / 100; + this.alpha = this.startAlpha; + this.decayRate = 0.1; + this.startLife = 7; + this.life = this.startLife; + this.lineWidth = this.rand(1, 3); } - } -}; -var updateParts = function(){ - var i = parts.length; - while(i--){ - parts[i].update(); - } -}; + Part.prototype.update = function(){ + this.vx += (this.rand(0, 200) - 100) / 1500; + this.vy -= this.life/50; + this.x += this.vx; + this.y += this.vy; + this.alpha = this.startAlpha * (this.life / this.startLife); + this.radius = this.startRadius * (this.life / this.startLife); + this.life -= this.decayRate; + if( + this.x > this.width + this.radius || + this.x < -this.radius || + this.y > this.height + this.radius || + this.y < -this.radius || + this.life <= this.decayRate + ){ + this.reset(); + } + }; -var renderParts = function(){ - var i = parts.length; - while(i--){ - parts[i].render(); - } -}; + Part.prototype.render = function(){ + this.ctx.beginPath(); + this.ctx.arc(this.x, this.y, this.radius, 0, Math.PI * 2, false); + this.ctx.fillStyle = this.ctx.strokeStyle = 'hsla('+this.hue+', '+this.saturation+'%, '+this.lightness+'%, '+this.alpha+')'; + this.ctx.lineWidth = this.lineWidth; + this.ctx.fill(); + this.ctx.stroke(); + }; -var clear = function(){ - ctx.globalCompositeOperation = 'destination-out'; - ctx.fillStyle = 'hsla(0, 0%, 0%, .3)'; - ctx.fillRect(0, 0, cw, ch); - ctx.globalCompositeOperation = 'lighter'; -}; + Part.prototype.rand = function(min, max){ + return Math.floor( (Math.random() * (max - min + 1) ) + min); + }; -var loop = function(){ - window.requestAnimFrame(loop, c); - clear(); - createParts(); - updateParts(); - renderParts(); - globalTick++; -}; + var Flame = function(element, options){ + this.element = element; + this.options = $.extend( {}, defaults, options) ; + this._defaults = defaults; + this.init(); + }; -window.requestAnimFrame=function(){return window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||window.oRequestAnimationFrame||window.msRequestAnimationFrame||function(a){window.setTimeout(a,1E3/60)}}(); + Flame.prototype.init = function (arguments) { + if(this.element.getContext) { + this.ctx = this.element.getContext("2d"); + } else { + return; + } + if (this.state) this.stop(); + this.state = $.extend( {parts: [],partsFull: false,globalTick: 0,}, defaultState, this.state); + // this.state = { + // parts: [], + // partCount: 200, + // partsFull: false, + // on: true, + // rendering: false, + // globalTick: 0, + // width: null, + // height: null, + // } + this.state.width = $(this.element).outerWidth(); + this.state.height = $(this.element).outerWidth(); + this.start(); + } -loop(); + /** If needed: $(window).on('resize',this.onResize.bind(this) **/ + Flame.prototype.onResize = function (arguments) { + this.init(); + } + + Flame.prototype.createParts = function(){ + if(this.state.parts.length > this.state.partCount){ + this.state.partsFull = true; + } else { + this.state.parts.push(new Part(this)); + } + }; + + Flame.prototype.updateParts = function(){ + var i = this.state.parts.length; + while(i--){ + this.state.parts[i].update(); + } + }; + + Flame.prototype.renderParts = function(){ + var i = this.state.parts.length; + while(i--){ + this.state.parts[i].render(); + } + }; + + Flame.prototype.clear = function (arguments) { + this.ctx.globalAlpha = 1; + this.ctx.fillStyle = 'hsla(0, 0%, 0%, .0)'; + this.ctx.clearRect(0,0,this.state.width, this.state.height); + } + + /** Fades the previous flames into opacity to product a blur **/ + Flame.prototype.fade = function(){ + this.ctx.globalCompositeOperation = 'destination-out'; + this.ctx.fillStyle = 'hsla(0, 0%, 0%, .3)'; + this.ctx.fillRect(0, 0, this.state.width, this.state.height); + this.ctx.globalCompositeOperation = 'lighter'; + }; + + Flame.prototype.draw = function (arguments) { + this.fade(); + if (this.state.on){ + this.createParts(); + } else if (this.state.parts.length>1){ + this.state.parts.pop(); + } + this.updateParts(); + this.renderParts(); + } + + Flame.prototype.start = function (arguments) { + if (!this.state.rendering){ + this.state.rendering=true + this.animate(); + return this + } else {return;} + } + + Flame.prototype.stop = function (arguments) { + this.state.rendering=false; + this.clear(); + return this; + } + + /** Toggle fuel and the flame will burn down or up again **/ + Flame.prototype.toggleFuel = function (state) { + if (state===undefined) + detector.flame.state.on=!detector.flame.state.on; + else + detector.flame.state.on=state; + return detector.flame.state.on; + } + + Flame.prototype.animate = function(){ + window.requestAnimFrame(this.animate.bind(this),this.element); + this.state.globalTick++; + if (this.state.rendering) this.draw(); + }; + + $.fn[pluginName] = function ( options ) { + return this.each(function () { + if (!$.data(this, 'plugin_' + pluginName)) { + $.data(this, 'plugin_' + pluginName, + new Flame( this, options )); + } + }); + } + + // shim for requestAnimFrame + window.requestAnimFrame = (function(){ + return window.requestAnimationFrame || + window.webkitRequestAnimationFrame || + window.mozRequestAnimationFrame || + window.oRequestAnimationFrame || + window.msRequestAnimationFrame || + function(/* function */ callback, /* DOMElement */ element){ + window.setTimeout(callback, 1000 / 60); + }; + })(); + + +})( jQuery, window, document ); diff --git a/js/external/jquery.ui.touch-punch.min.js b/js/external/jquery.ui.touch-punch.min.js new file mode 100644 index 0000000..31272ce --- /dev/null +++ b/js/external/jquery.ui.touch-punch.min.js @@ -0,0 +1,11 @@ +/*! + * jQuery UI Touch Punch 0.2.3 + * + * Copyright 2011–2014, Dave Furfero + * Dual licensed under the MIT or GPL Version 2 licenses. + * + * Depends: + * jquery.ui.widget.js + * jquery.ui.mouse.js + */ +!function(a){function f(a,b){if(!(a.originalEvent.touches.length>1)){a.preventDefault();var c=a.originalEvent.changedTouches[0],d=document.createEvent("MouseEvents");d.initMouseEvent(b,!0,!0,window,1,c.screenX,c.screenY,c.clientX,c.clientY,!1,!1,!1,!1,0,null),a.target.dispatchEvent(d)}}if(a.support.touch="ontouchend"in document,a.support.touch){var e,b=a.ui.mouse.prototype,c=b._mouseInit,d=b._mouseDestroy;b._touchStart=function(a){var b=this;!e&&b._mouseCapture(a.originalEvent.changedTouches[0])&&(e=!0,b._touchMoved=!1,f(a,"mouseover"),f(a,"mousemove"),f(a,"mousedown"))},b._touchMove=function(a){e&&(this._touchMoved=!0,f(a,"mousemove"))},b._touchEnd=function(a){e&&(f(a,"mouseup"),f(a,"mouseout"),this._touchMoved||f(a,"click"),e=!1)},b._mouseInit=function(){var b=this;b.element.bind({touchstart:a.proxy(b,"_touchStart"),touchmove:a.proxy(b,"_touchMove"),touchend:a.proxy(b,"_touchEnd")}),c.call(b)},b._mouseDestroy=function(){var b=this;b.element.unbind({touchstart:a.proxy(b,"_touchStart"),touchmove:a.proxy(b,"_touchMove"),touchend:a.proxy(b,"_touchEnd")}),d.call(b)}}}(jQuery); \ No newline at end of file diff --git a/js/game.js b/js/game.js index 882466f..bc55915 100644 --- a/js/game.js +++ b/js/game.js @@ -28,7 +28,6 @@ var Game = (function(Helpers,GameObjects,ObjectStorage) { this.workers = Helpers.loadFile('json/workers.json'); this.upgrades = Helpers.loadFile('json/upgrades.json'); this.achievements = Helpers.loadFile('json/achievements.json'); - this.runes = Helpers.loadFile('json/runes.json'); this.keywords = Helpers.loadFile('json/keywords.json'); // Turn JSON files into actual game objects and fill map of all objects @@ -98,6 +97,49 @@ var Game = (function(Helpers,GameObjects,ObjectStorage) { return rules; }, + /** Run an experiment depending on ingredients and conditions **/ + Game.prototype.experiment = function(options) { + var inputs = options.inputs || []; + var inputKeys = inputs.map(function(i,e){return $(e).data('element')}); + inputKeys.sort(); // this makes reaction be independant of order + + var result = this.rules[inputKeys] + if (result) { + return this.reaction(result.ingredients,result.rune) + } + return result; + }, + + /** Remove ingredients and make results with animations **/ + Game.prototype.reaction= function(ingredients,results){ + + // remove ingredients + for (var i = 0; i < ingredients.length; i++) { + var ingredient = ingredients[i]; + + } + + // TODO use jqueru ui transfer effect to remove or puff + $(aElem).remove(); + $(bElem).remove(); + + // if the dragger came from the elements panels, clone it to here + for (var i = 0; i < results.length; i++) { + // make sure it's discovered + var resultKey = results[i]; + var elementStore = this.elements.filter(function(e){return e.key===resultKey;}); + elementStore.state.discovered=true; + + // add new element to beaker + var newElement = $('#elementContent').find('.'+resultKey).clone(); + $('#detector').append(newElement); + newElement.offset($draggable.offset()) + } + + // effects + this.bubblr.start(1500); + + }, Game.prototype.save = function() { // Save every object's state to local storage for (var key in this.allObjects) { diff --git a/js/gameobjects.js b/js/gameobjects.js index 138c7b2..a66ba5f 100644 --- a/js/gameobjects.js +++ b/js/gameobjects.js @@ -74,29 +74,7 @@ var GameObjects = (function() { return false; }; - /** Run an experiment depending on ingredients and conditions **/ - Lab.prototype.experiment = function(options) { - var elements = options.elements || []; - var elementKeys = elements.map(function(e){return $(e).data('element')}); - elementKeys.sort(); // this makes reaction be independant of order - var result = this.rules[elementKeys] - if (result) { - this.reaction(result.ingredients,result.rune) - } - return result; - }; - - /** Remove ingredients and make results with animations **/ - Lab.prototype.reaction= function(ingredients,results){ - // TODO put new rune in old position, add animations - var rune = this.runeElem(r,$(aElem).parent().parent()); - $('#observationsContent').append('
'+this.runes[a]+'+'+this.runes[b]+'='+this.runes[r]+'
') - this.bubblr.start(1500); - // TODO use jqueru ui transfer effect to remove or puff - $(aElem).remove(); - $(bElem).remove(); - } Lab.prototype.buy = function(cost) { if (this.state.money >= cost) { this.state.money -= cost; diff --git a/js/ui.js b/js/ui.js index 541d88f..bd96c40 100644 --- a/js/ui.js +++ b/js/ui.js @@ -66,7 +66,7 @@ var UI = (function () { } } - detector.bubblr.onResize(); + detector.onResize(); } $(window).resize(resize);