Refactored flame and bubbles

This commit is contained in:
2016-02-23 11:33:34 +08:00
parent d9551548ec
commit a4bce5bc3c
11 changed files with 463 additions and 216 deletions
+24 -17
View File
@@ -1,19 +1,26 @@
{ {
"name": "sciencealchemy", "name": "sciencealchemy",
"description": "Science Alchemy", "description": "Science Alchemy",
"main": "js/app.js", "main": "js/app.js",
"moduleType": [], "moduleType": [],
"license": "MIT", "license": "MIT",
"homepage": "", "homepage": "",
"private": true, "private": true,
"ignore": [ "ignore": [
"**/.*", "**/.*",
"node_modules", "node_modules",
"bower_components", "bower_components",
"test", "test",
"tests" "tests"
], ],
"dependencies": { "dependencies": {
"angular-dragdrop": "~1.0.13" "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"
}
} }
+1 -1
View File
@@ -30,7 +30,7 @@ h1 br {
position: relative; position: relative;
} }
#detector canvas { #detector .test-tube, #detector .detector-events{
position: absolute; position: absolute;
left: 0; left: 0;
top: 0; top: 0;
+3 -3
View File
@@ -1,5 +1,5 @@
<!DOCTYPE html> <!DOCTYPE html>
<html lang="en" ng-app="particleClicker"> <html lang="en" ng-app="scienceAlchemy">
<head> <head>
<title>Science Alchemy</title> <title>Science Alchemy</title>
<meta charset="utf-8"> <meta charset="utf-8">
@@ -88,7 +88,7 @@
class="{{r.key}} element element-icon {{ r.state.interesting ? 'blink' : '' }} {{'q'+r.state.color+'-12'}}" class="{{r.key}} element element-icon {{ r.state.interesting ? 'blink' : '' }} {{'q'+r.state.color+'-12'}}"
data-element="{{r.key}}" data-element="{{r.key}}"
data-drag="true" data-drag="true"
jqyoui-draggable jqyoui-draggable="{containment:'offset'}"
data-jqyoui-options="{{rc.dragOptions}}" data-jqyoui-options="{{rc.dragOptions}}"
> >
{{r.key}} {{r.key}}
@@ -116,7 +116,7 @@
> >
Your detector. Click on it to generate events. Your detector. Click on it to generate events.
</canvas> </canvas>
<canvas id="detector-flame" width="400" height="400" class="prevent-select"> <canvas id="detector-flame" width="400" height="400" class="prevent-select" ng-click="dc.toggleFlameFuel()">
Your bunsen burner. Click it to turn on and off. Your bunsen burner. Click it to turn on and off.
</canvas> </canvas>
</div> </div>
+6 -2
View File
@@ -17,7 +17,7 @@
var allObjects = game.allObjects; var allObjects = game.allObjects;
var lastSaved; var lastSaved;
var app = angular.module('particleClicker', ['ngDragDrop']); var app = angular.module('scienceAlchemy', ['ngDragDrop']);
// add helpers as filters // add helpers as filters
app.filter('niceNumber', ['$filter', function($filter) { app.filter('niceNumber', ['$filter', function($filter) {
@@ -56,7 +56,7 @@
hoverClass: "ui-state-active", hoverClass: "ui-state-active",
} }
this.onDrop = function(event,ui){ this.onDrop = function(event,ui){
detector.onDrop(event,ui,lab); detector.onDrop(event,ui,game);
} }
this.click = function() { this.click = function() {
lab.clickDetector(); lab.clickDetector();
@@ -64,6 +64,10 @@
UI.showUpdateValue("#update-data", lab.state.detector); UI.showUpdateValue("#update-data", lab.state.detector);
return false; return false;
}; };
this.toggleFlameFuel = function(){
console.log('toggleFlameFuel');
detector.flame.toggleFuel();
}
}); });
app.controller('ElementController', ['$compile', function($compile) { app.controller('ElementController', ['$compile', function($compile) {
+115 -60
View File
@@ -5,16 +5,16 @@
This plugin available for use in all personal or commercial projects under both MIT and GPL licenses. 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"; var pluginName = "bubblr";
/** default options **/
var defaults = { var defaults = {
numberOfBubbles: 10, numberOfBubbles: 10,
backgroundColor: "transparent", backgroundColor: "transparent",
bubbleColor: "White", bubbleColor: "White",
bubbleOpacity: .7, bubbleOpacity: 0.7,
bubbleMinSize: 1, bubbleMinSize: 1,
bubbleMaxSize: 2, bubbleMaxSize: 2,
bubbleMaxSpeed: 2, bubbleMaxSpeed: 2,
@@ -22,11 +22,23 @@
animationSpeed: 10 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 ) { function Bubblr( element, options ) {
this.element = element; this.element = element;
this.options = $.extend( {}, defaults, options) ; this.options = $.extend( {}, defaults, options) ;
this._defaults = defaults; this._defaults = defaults;
this.state = {
bubbles: [],
started: false,
globalTick: 0,
genBubbles: false,
}
this.init(); this.init();
this.start();
} }
Bubblr.prototype.init = function () { Bubblr.prototype.init = function () {
@@ -38,95 +50,113 @@
return; return;
} }
if (this.timerId) this.remove();
$canvas = $(this.element); $canvas = $(this.element);
this.width = $canvas.width(); this.width = $canvas.width();
this.height = $canvas.height(); 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) $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++) { for(i = 0; i < this.options.numberOfBubbles; i++) {
this.bubbles[i] = this.generateBubble(); this.state.bubbles[i] = this.generateBubble();
} }
for(i in this.state.bubbles) {
var self = this; this.drawBubble(this.state.bubbles[i]);
this.on=false;
for(i in this.bubbles) {
this.drawBubble(this.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(){ Bubblr.prototype.onResize= function(){
this.clear(); this.clear();
this.width = Math.max($canvas.width(),this.element.width); this.width = $(this.element).outerWidth();
this.height = Math.max($canvas.height(),this.element.height); this.height = $(this.element).outerWidth();
}; };
Bubblr.prototype.start = function(timespan) { /** Start animation loop if not started **/
var self = this; Bubblr.prototype.start = function() {
if (!this.on){ if (!this.state.started){
// this.timerId = setInterval(function() { this.state.started=true;
// self.animationLoop(); this.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);
} }
}; };
/** Stop animation loop **/
Bubblr.prototype.stop = function() { Bubblr.prototype.stop = function() {
this.on=false; this.state.started=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.clear(); 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 () { Bubblr.prototype.clear = function () {
this.ctx.globalAlpha = 1; this.ctx.globalAlpha = 1;
this.ctx.fillStyle = this.options.backgroundColor; this.ctx.fillStyle = this.options.backgroundColor;
this.ctx.clearRect(0,0,this.width, this.height); this.ctx.clearRect(0,0,this.width, this.height);
}; };
Bubblr.prototype.draw = function (index, bubble) { Bubblr.prototype.draw = function (index, bubble) {
this.ctx.globalAlpha = this.options.bubbleOpacity; this.ctx.globalAlpha = this.options.bubbleOpacity;
this.drawBubble(bubble); this.drawBubble(bubble);
}; };
/** Update bubble position **/
Bubblr.prototype.update = function (index, bubble) { Bubblr.prototype.update = function (index, bubble) {
bubble.y = bubble.y - bubble.speed bubble.y = bubble.y - bubble.speed
if(bubble.y < 0 && this.on) if(bubble.y < 0 && this.state.continuous)
this.bubbles[index] = this.generateBubble(true); // 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) { Bubblr.prototype.drawBubble = function(bubble) {
this.ctx.fillStyle = this.options.bubbleColor; this.ctx.fillStyle = this.options.bubbleColor;
@@ -136,20 +166,33 @@
this.ctx.fill(); this.ctx.fill();
}; };
Bubblr.prototype.generateBubble = function(start_y_at_zero) { Bubblr.prototype.generateBubble = function(options) {
options = options || {};
var bubble = new Object(); 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; bubble.y = this.height;
} else if (options.y===null)
else {
bubble.y = this.randomize(1,this.height); 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; return bubble;
}; };
@@ -157,7 +200,7 @@
return Math.floor((Math.random()*max)+min); return Math.floor((Math.random()*max)+min);
}; };
// $.flame will create or return the bubblr element
$.fn[pluginName] = function ( options ) { $.fn[pluginName] = function ( options ) {
return this.each(function () { return this.each(function () {
if (!$.data(this, 'plugin_' + pluginName)) { if (!$.data(this, 'plugin_' + pluginName)) {
@@ -168,3 +211,15 @@
} }
})( jQuery, window, document ); })( 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);
};
})();
+49 -10
View File
@@ -15,6 +15,12 @@ var detector =
list: [], list: [],
}, },
flame:
{
canvas: null,
ctx: null
},
visible: true, visible: true,
width: 400, width: 400,
@@ -36,6 +42,9 @@ var detector =
detector.events.canvas = document.getElementById('detector-events'); detector.events.canvas = document.getElementById('detector-events');
detector.events.ctx = detector.events.canvas.getContext('2d'); 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 // set size
// TODO resize "#detector-flame" too // TODO resize "#detector-flame" too
var devicePixelRatio = window.devicePixelRatio || 1; var devicePixelRatio = window.devicePixelRatio || 1;
@@ -58,6 +67,9 @@ var detector =
detector.events.canvas.width = baseSize; detector.events.canvas.width = baseSize;
detector.events.canvas.height = baseSize; detector.events.canvas.height = baseSize;
detector.flame.canvas.width = baseSize;
detector.flame.canvas.height = baseSize;
if (devicePixelRatio !== backingStoreRatio) { if (devicePixelRatio !== backingStoreRatio) {
var oldWidth = detector.core.canvas.width; var oldWidth = detector.core.canvas.width;
var oldHeight = detector.core.canvas.height; var oldHeight = detector.core.canvas.height;
@@ -81,6 +93,7 @@ var detector =
detector.initBubbles(); detector.initBubbles();
detector.initFlame();
// TODO refactor flame animation and put it here // TODO refactor flame animation and put it here
// this.flame = $('#detector-flame').flame(); // this.flame = $('#detector-flame').flame();
@@ -106,6 +119,16 @@ var detector =
detector.bubblr = bubblrElem.data('plugin_bubblr'); 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) animate: function(time)
{ {
// var duration = typeof time !== 'undefined' ? time - detector.lastRender : 16; // var duration = typeof time !== 'undefined' ? time - detector.lastRender : 16;
@@ -118,28 +141,42 @@ var detector =
/** When a user clicks the detector **/ /** When a user clicks the detector **/
addEvent: function() 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 **/ /** When a worker clicks the detector **/
addEventExternal: function(numWorkers) addEventExternal: function(numWorkers)
{ {
// detector.bubblr.start(500*numWorkers); // detector.bubblr.bubble(numWorkers);
}, },
/** Draw current events **/ /** Draw current events **/
draw: function(duration) 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 // TODO tidy this, attach new runes to something better
// FIXME at the moment it duplicates runes, but we need a better system // FIXME at the moment it duplicates runes, but we need a better system
var self=this; var self=this;
console.debug('onDrop',arguments); console.debug('onDrop',arguments);
var $draggable = $(ui.draggable), var $draggable = $(ui.draggable),
$droppable = $(event.target); $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 draggableTop = $draggable.offset().top;
var draggableHeight = $draggable.height(); var draggableHeight = $draggable.height();
var draggableBottom = draggableTop + draggableHeight; var draggableBottom = draggableTop + draggableHeight;
@@ -161,17 +198,19 @@ var detector =
&& left <= draggableRight && right >= draggableLeft; && left <= draggableRight && right >= draggableLeft;
return isCoveredByDraggable; return isCoveredByDraggable;
}); });
// TODO also get draggable covered by droppable
for (var i = 0; i < $droppablesCoveredByDraggable.length; i++) { 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); 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);
}, },
}; };
+210 -99
View File
@@ -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 * @name Flame
var c = document.getElementById('detector-flame'), * @description jquery plugin to generate flame on a canvas element..
ctx = c.getContext('2d'), * Based on http://codepen.io/jackrugile/pen/Jbnpv
cw = c.width = 400, * @copyright (c) 2015 wassname
ch = c.height = 300, * @license: MIT
parts = [], */
partCount = 200, // TODO recenter on canvas/window resize
partsFull = false, ;(function ( $, window, document, undefined ) {
hueRange = 50, var pluginName = "flame";
globalTick = 0,
rand = function(min, max){ var defaults = {
return Math.floor( (Math.random() * (max - min + 1) ) + min); 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(){ Part.prototype.reset = function(){
this.startRadius = rand(1, 25); this.startRadius = this.rand(1, 25);
this.radius = this.startRadius; this.radius = this.startRadius;
this.x = cw/2 + (rand(0, 6) - 3); this.width = this.flame.state.width;
this.y = 250; this.height = this.flame.state.height;
this.vx = 0; this.x = this.width/2 + (this.rand(0, 6) - 3);
this.vy = 0; this.y = 250;
this.hue = rand(globalTick - hueRange, globalTick + hueRange); this.vx = 0;
this.saturation = rand(50, 100); this.vy = 0;
this.lightness = rand(20, 70); this.hue = this.rand(this.flame.state.globalTick - this.flame.options.hueRange, this.flame.state.globalTick + this.flame.options.hueRange);
this.startAlpha = rand(1, 10) / 100; this.saturation = this.rand(50, 100);
this.alpha = this.startAlpha; this.lightness = this.rand(20, 70);
this.decayRate = .1; this.startAlpha = this.rand(1, 10) / 100;
this.startLife = 7; this.alpha = this.startAlpha;
this.life = this.startLife; this.decayRate = 0.1;
this.lineWidth = rand(1, 3); this.startLife = 7;
} this.life = this.startLife;
this.lineWidth = this.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());
} }
}
};
var updateParts = function(){ Part.prototype.update = function(){
var i = parts.length; this.vx += (this.rand(0, 200) - 100) / 1500;
while(i--){ this.vy -= this.life/50;
parts[i].update(); 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(){ Part.prototype.render = function(){
var i = parts.length; this.ctx.beginPath();
while(i--){ this.ctx.arc(this.x, this.y, this.radius, 0, Math.PI * 2, false);
parts[i].render(); 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(){ Part.prototype.rand = function(min, max){
ctx.globalCompositeOperation = 'destination-out'; return Math.floor( (Math.random() * (max - min + 1) ) + min);
ctx.fillStyle = 'hsla(0, 0%, 0%, .3)'; };
ctx.fillRect(0, 0, cw, ch);
ctx.globalCompositeOperation = 'lighter';
};
var loop = function(){ var Flame = function(element, options){
window.requestAnimFrame(loop, c); this.element = element;
clear(); this.options = $.extend( {}, defaults, options) ;
createParts(); this._defaults = defaults;
updateParts(); this.init();
renderParts(); };
globalTick++;
};
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 );
+11
View File
@@ -0,0 +1,11 @@
/*!
* jQuery UI Touch Punch 0.2.3
*
* Copyright 20112014, 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);
+43 -1
View File
@@ -28,7 +28,6 @@ var Game = (function(Helpers,GameObjects,ObjectStorage) {
this.workers = Helpers.loadFile('json/workers.json'); this.workers = Helpers.loadFile('json/workers.json');
this.upgrades = Helpers.loadFile('json/upgrades.json'); this.upgrades = Helpers.loadFile('json/upgrades.json');
this.achievements = Helpers.loadFile('json/achievements.json'); this.achievements = Helpers.loadFile('json/achievements.json');
this.runes = Helpers.loadFile('json/runes.json');
this.keywords = Helpers.loadFile('json/keywords.json'); this.keywords = Helpers.loadFile('json/keywords.json');
// Turn JSON files into actual game objects and fill map of all objects // 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; 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() { Game.prototype.save = function() {
// Save every object's state to local storage // Save every object's state to local storage
for (var key in this.allObjects) { for (var key in this.allObjects) {
-22
View File
@@ -74,29 +74,7 @@ var GameObjects = (function() {
return false; 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('<div class="col-md-12">'+this.runes[a]+'+'+this.runes[b]+'='+this.runes[r]+'</div>')
this.bubblr.start(1500);
// TODO use jqueru ui transfer effect to remove or puff
$(aElem).remove();
$(bElem).remove();
}
Lab.prototype.buy = function(cost) { Lab.prototype.buy = function(cost) {
if (this.state.money >= cost) { if (this.state.money >= cost) {
this.state.money -= cost; this.state.money -= cost;
+1 -1
View File
@@ -66,7 +66,7 @@ var UI = (function () {
} }
} }
detector.bubblr.onResize(); detector.onResize();
} }
$(window).resize(resize); $(window).resize(resize);