mirror of
https://github.com/wassname/cardsforscience.git
synced 2026-06-27 17:47:51 +08:00
Refactored flame and bubbles
This commit is contained in:
+24
-17
@@ -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
@@ -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
@@ -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>
|
||||||
|
|||||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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);
|
||||||
+43
-1
@@ -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) {
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
Reference in New Issue
Block a user