mirror of
https://github.com/wassname/cardsforscience.git
synced 2026-06-27 17:29:55 +08:00
Dragging back and forth between elements and test-tube workds
This commit is contained in:
@@ -326,6 +326,9 @@ h1 br {
|
||||
padding: 1px;
|
||||
z-index: 50;
|
||||
}
|
||||
.element.empty {
|
||||
opacity: 0.2;
|
||||
}
|
||||
#observationsContent {
|
||||
font-size: 24px;
|
||||
}
|
||||
|
||||
+38
-8
@@ -78,18 +78,24 @@
|
||||
</h4>
|
||||
</div>
|
||||
|
||||
<div class="panel-body large" id="elementLarge">
|
||||
<div id="elementContent" ng-controller="ElementController as rc">
|
||||
<div class="panel-body large" id="elementLarge"
|
||||
data-drop="true"
|
||||
jqyoui-droppable="{onDrop: 'rc.onDrop'}"
|
||||
data-jqyoui-options="{{rc.dropOptions}}"
|
||||
ng-controller="ElementController as rc"
|
||||
>
|
||||
<div id="elementContent">
|
||||
<div class="row" ng-cloak>
|
||||
|
||||
<div class="col-md-3" ng-repeat="r in rc.elements" ng-show="rc.isVisible(r)">
|
||||
<div class="col-md-4" ng-repeat="r in rc.elements" ng-show="rc.isVisible(r)">
|
||||
<span
|
||||
id="{{r.key}}"
|
||||
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'}} {{r.state.amount>0 ? '': 'empty'}}"
|
||||
data-element="{{r.key}}"
|
||||
data-drag="true"
|
||||
data-drag="{{r.state.amount>0}}"
|
||||
jqyoui-draggable="{containment:'offset'}"
|
||||
data-jqyoui-options="{{rc.dragOptions}}"
|
||||
data-hashkey={{r.$$hashKey}}
|
||||
>
|
||||
{{r.key}}
|
||||
</span>
|
||||
@@ -108,9 +114,33 @@
|
||||
<div id="detector-holder">
|
||||
|
||||
<div id="detector" ng-controller="DetectorController as dc">
|
||||
<!-- <canvas id="detector-core" class="test-tube center-block " width="400"
|
||||
height="400" style=""></canvas> -->
|
||||
<canvas ng-click="dc.click()" id="detector-core" width="400" height="400" class="test-tube prevent-select center-block " data-drop="true"
|
||||
|
||||
|
||||
<div id="detector-element-container" ng-cloak>
|
||||
<div ng-repeat="r in dc.elements">
|
||||
<span
|
||||
class="{{r.key}} element q{{r.state.color}}-12"
|
||||
data-element="{{r.key}}"
|
||||
data-drag="true"
|
||||
jqyoui-draggable="{containment:'offset'}"
|
||||
data-jqyoui-options="{{rc.dragOptions}}"
|
||||
aria-disabled="false"
|
||||
style="position: fixed; z-index: 9999; left: {{r.state.left}}px; top: {{r.state.top}}px;"
|
||||
data-hashkey={{r.$$hashKey}}
|
||||
>
|
||||
{{r.key}}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<canvas
|
||||
ng-click="dc.click()"
|
||||
id="detector-core"
|
||||
width="400"
|
||||
height="400"
|
||||
class="test-tube prevent-select center-block "
|
||||
data-drop="true"
|
||||
jqyoui-droppable="{onDrop: 'dc.onDrop'}"
|
||||
data-jqyoui-options="{{dc.dropOptions}}"
|
||||
>
|
||||
|
||||
@@ -21,46 +21,9 @@ var app = (function () {
|
||||
|
||||
// directives
|
||||
|
||||
/** Change scope values on window resize **/
|
||||
app.directive('resize', function ($window) {
|
||||
return function (scope, element, attr) {
|
||||
// make window into an angular element
|
||||
var w = angular.element($window);
|
||||
// watch window h&w, onchange scope
|
||||
scope.$watch(
|
||||
function () {
|
||||
return {
|
||||
'h': w.height(),
|
||||
'w': w.width()
|
||||
};
|
||||
},
|
||||
function (newValue, oldValue) {
|
||||
// update scope values
|
||||
scope.windowHeight = newValue.h;
|
||||
scope.windowWidth = newValue.w;
|
||||
|
||||
// new function
|
||||
scope.resizeWithOffset = function (offsetH) {
|
||||
scope.$eval(attr.notifier);
|
||||
return {
|
||||
'height': (newValue.h - offsetH) + 'px'
|
||||
//,'width': (newValue.w - 100) + 'px'
|
||||
};
|
||||
};
|
||||
|
||||
},
|
||||
true
|
||||
);
|
||||
|
||||
// update scope on resize event
|
||||
w.bind('resize', function () {
|
||||
scope.$apply();
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
// factories to provide game objects
|
||||
// factories to provide services. They serve shared game objects
|
||||
app.factory('elements', function () {
|
||||
var elements = Helpers.loadFile('json/elements.json');
|
||||
elements = elements.map(
|
||||
@@ -103,37 +66,74 @@ var app = (function () {
|
||||
};
|
||||
}]);
|
||||
|
||||
|
||||
|
||||
// controllers
|
||||
app.controller('DetectorController', ['$scope','game','detector', function ($scope,game,detector) {
|
||||
// this.detector.init(400);
|
||||
this.dropOptions = {
|
||||
app.controller('ElementController', ['$scope', '$compile', 'game', 'detector', function ($scope, $compile, game, detector) {
|
||||
var vs = this;
|
||||
vs.dragOptions = {
|
||||
revert: true, //"invalid",
|
||||
zIndex: 100,
|
||||
// helper: "clone", // drags a clone
|
||||
// opacity: 0.75,
|
||||
// start: vs.onRuneDrop.bind(vs),
|
||||
// stop: vs.onRuneDrop.bind(vs),
|
||||
cancel: false,
|
||||
// containment:false
|
||||
};
|
||||
vs.elements = game.elements;
|
||||
vs.isVisible = function (item) {
|
||||
return item.isVisible(game.lab);
|
||||
};
|
||||
vs.isAvailable = function (item) {
|
||||
return item.isAvailable(game.lab);
|
||||
};
|
||||
vs.onDrop = function (event, ui) {
|
||||
// store the dropped element
|
||||
var draggable = angular.element(ui.draggable);
|
||||
var key = draggable.data('element');
|
||||
if (!draggable.hasClass('element-icon')) {
|
||||
var elementStore = vs.elements.filter(function (e) {
|
||||
return e.key === key;
|
||||
})[0];
|
||||
var hashKey=draggable.data('hashkey');
|
||||
var found=false;
|
||||
for (var i = 0; i < detector.elements.length; i++) {
|
||||
if (detector.elements[i].$$hashKey===hashKey){
|
||||
// delete detector.elements[i];
|
||||
detector.elements.splice(i,1);
|
||||
var found=true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) console.warn('Could not find dragged element in detector.elements',draggable);
|
||||
else elementStore.state.amount+=1;
|
||||
}
|
||||
}
|
||||
vs.doElement = function (item) {
|
||||
var cost = item.element(game.lab);
|
||||
if (cost > 0) {
|
||||
UI.showUpdateValue("#update-data", -cost);
|
||||
UI.showUpdateValue("#update-reputation", item.state.reputation);
|
||||
}
|
||||
};
|
||||
vs.showInfo = function (r) {
|
||||
UI.showModal(r.name, r.getInfo());
|
||||
UI.showLevels(r.state.level);
|
||||
};
|
||||
}]);
|
||||
|
||||
app.controller('DetectorController', ['$scope', 'game', 'detector', function ($scope, game, detector) {
|
||||
var vm = this;
|
||||
vm.elements = detector.elements;
|
||||
vm.dropOptions = {
|
||||
// accept: ".rune",
|
||||
addClasses: true,
|
||||
// greedy: true,
|
||||
// tolerance: "pointer",
|
||||
activeClass: "ui-state-hover",
|
||||
hoverClass: "ui-state-active",
|
||||
}
|
||||
this.onDrop = function (event, ui) {
|
||||
detector.onDrop(event, ui, game);
|
||||
}
|
||||
this.click = function () {
|
||||
game.lab.clickDetector();
|
||||
detector.addEvent();
|
||||
UI.showUpdateValue("#update-data", game.lab.state.detector);
|
||||
return false;
|
||||
};
|
||||
this.toggleFlameFuel = function () {
|
||||
console.log('toggleFlameFuel');
|
||||
detector.flame.toggleFuel();
|
||||
}
|
||||
}]);
|
||||
|
||||
app.controller('ElementController', ['$scope', '$compile','game','detector', function ($scope, $compile,game,detector) {
|
||||
this.dragOptions = {
|
||||
revert: true, //"invalid",
|
||||
vm.dragOptions = {
|
||||
revert: "invalid",
|
||||
zIndex: 100,
|
||||
// helper: "clone", // drags a clone
|
||||
// opacity: 0.75,
|
||||
@@ -142,27 +142,22 @@ var app = (function () {
|
||||
cancel: false,
|
||||
// containment:false
|
||||
};
|
||||
this.elements = game.elements;
|
||||
this.isVisible = function (item) {
|
||||
return item.isVisible(game.lab);
|
||||
vm.onDrop = function (event, ui) {
|
||||
detector.onDrop(event, ui, game);
|
||||
};
|
||||
this.isAvailable = function (item) {
|
||||
return item.isAvailable(game.lab);
|
||||
vm.click = function () {
|
||||
game.lab.clickDetector();
|
||||
detector.addEvent();
|
||||
UI.showUpdateValue("#update-data", game.lab.state.detector);
|
||||
return false;
|
||||
};
|
||||
this.doElement = function (item) {
|
||||
var cost = item.element(game.lab);
|
||||
if (cost > 0) {
|
||||
UI.showUpdateValue("#update-data", -cost);
|
||||
UI.showUpdateValue("#update-reputation", item.state.reputation);
|
||||
}
|
||||
};
|
||||
this.showInfo = function (r) {
|
||||
UI.showModal(r.name, r.getInfo());
|
||||
UI.showLevels(r.state.level);
|
||||
vm.toggleFlameFuel = function () {
|
||||
console.log('toggleFlameFuel');
|
||||
detector.flamer.toggleFuel();
|
||||
};
|
||||
}]);
|
||||
|
||||
app.controller('LabController', ['$interval','game','detector', function ($interval,game,detector) {
|
||||
app.controller('LabController', ['$interval', 'game', 'detector', function ($interval, game, detector) {
|
||||
this.lab = game.lab;
|
||||
this.showDetectorInfo = function () {
|
||||
if (!this._detectorInfo) {
|
||||
@@ -189,7 +184,7 @@ var app = (function () {
|
||||
}, 1000);
|
||||
}]);
|
||||
|
||||
app.controller('HRController', ['$scope','game', function ($scope,game) {
|
||||
app.controller('HRController', ['$scope', 'game', function ($scope, game) {
|
||||
this.workers = game.workers;
|
||||
this.isVisible = function (worker) {
|
||||
return worker.isVisible(game.lab);
|
||||
@@ -205,7 +200,7 @@ var app = (function () {
|
||||
};
|
||||
}]);
|
||||
|
||||
app.controller('UpgradesController', ['$scope','game', function ($scope,game) {
|
||||
app.controller('UpgradesController', ['$scope', 'game', function ($scope, game) {
|
||||
this.upgrades = game.upgrades;
|
||||
this.isVisible = function (upgrade) {
|
||||
return upgrade.isVisible(game.lab, game.allObjects);
|
||||
@@ -220,7 +215,7 @@ var app = (function () {
|
||||
}
|
||||
}]);
|
||||
|
||||
app.controller('AchievementsController', function ($scope,game) {
|
||||
app.controller('AchievementsController', function ($scope, game) {
|
||||
$scope.achievements = game.achievements;
|
||||
$scope.progress = function () {
|
||||
return game.achievements.filter(function (a) {
|
||||
@@ -229,7 +224,7 @@ var app = (function () {
|
||||
};
|
||||
});
|
||||
|
||||
app.controller('SaveController', ['$scope', '$interval','game', function ($scope, $interval,game) {
|
||||
app.controller('SaveController', ['$scope', '$interval', 'game', function ($scope, $interval, game) {
|
||||
game.lastSaved = new Date().getTime();
|
||||
$scope.lastSaved = game.lastSaved;
|
||||
$scope.saveNow = function () {
|
||||
@@ -250,7 +245,7 @@ var app = (function () {
|
||||
$interval($scope.saveNow, 10000);
|
||||
}]);
|
||||
|
||||
app.controller('StatsController', ['$scope','game',function ($scope, game) {
|
||||
app.controller('StatsController', ['$scope', 'game', function ($scope, game) {
|
||||
$scope.lab = game.lab;
|
||||
}]);
|
||||
|
||||
|
||||
+91
-56
@@ -23,6 +23,8 @@ var Detector = function(){
|
||||
ctx: null
|
||||
},
|
||||
|
||||
elements: [],
|
||||
|
||||
visible: true,
|
||||
|
||||
width: 400,
|
||||
@@ -80,34 +82,34 @@ var Detector = function(){
|
||||
$(window).on('resize',this.onResize.bind(this));
|
||||
},
|
||||
|
||||
onResize: function(){
|
||||
// TODO, do one, schedule a check and then prevent firing until then
|
||||
if ($(window).width() >= 1200) {
|
||||
if (this.width != 500) {
|
||||
$('#detector').width(500).height(500);
|
||||
this.init(500);
|
||||
}
|
||||
} else if ($(window).width() < 768 && $(window).height() - 90 < 300) {
|
||||
var newWidth = $(window).width() - Math.max($(window).width() - ($(window).height() - 90 + 10), 300) - 10;
|
||||
if (this.width != newWidth) {
|
||||
$('#detector').width(newWidth).height(newWidth);
|
||||
this.init(newWidth);
|
||||
}
|
||||
} else if ($(window).width() < 992) {
|
||||
if (this.width != 300) {
|
||||
$('#detector').width(300).height(300);
|
||||
this.init(300);
|
||||
}
|
||||
} else {
|
||||
if (this.width != 400) {
|
||||
$('#detector').width(400).height(400);
|
||||
this.init(400);
|
||||
}
|
||||
}
|
||||
|
||||
this.bubblr.onResize();
|
||||
this.flamer.onResize();
|
||||
},
|
||||
// onResize: function(){
|
||||
// // TODO, do one, schedule a check and then prevent firing until then
|
||||
// if ($(window).width() >= 1200) {
|
||||
// if (this.width != 500) {
|
||||
// $('#detector').width(500).height(500);
|
||||
// this.init(500);
|
||||
// }
|
||||
// } else if ($(window).width() < 768 && $(window).height() - 90 < 300) {
|
||||
// var newWidth = $(window).width() - Math.max($(window).width() - ($(window).height() - 90 + 10), 300) - 10;
|
||||
// if (this.width != newWidth) {
|
||||
// $('#detector').width(newWidth).height(newWidth);
|
||||
// this.init(newWidth);
|
||||
// }
|
||||
// } else if ($(window).width() < 992) {
|
||||
// if (this.width != 300) {
|
||||
// $('#detector').width(300).height(300);
|
||||
// this.init(300);
|
||||
// }
|
||||
// } else {
|
||||
// if (this.width != 400) {
|
||||
// $('#detector').width(400).height(400);
|
||||
// this.init(400);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// this.bubblr.onResize();
|
||||
// this.flamer.onResize();
|
||||
// },
|
||||
|
||||
/** When a user clicks the detector **/
|
||||
addEvent: function()
|
||||
@@ -128,59 +130,92 @@ var Detector = function(){
|
||||
},
|
||||
|
||||
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);
|
||||
var $draggable = angular.element(ui.draggable),
|
||||
$droppable = angular.element(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())
|
||||
if ($draggable.hasClass('element-icon')){
|
||||
|
||||
var elementStore = game.elements.filter(function(e){return e.key==$draggable.data('element');})[0];
|
||||
elementStore.state.amount-=1;
|
||||
var newElement = angular.copy(elementStore);
|
||||
newElement.state.top=$draggable.offset().top;
|
||||
newElement.state.left=$draggable.offset().left;
|
||||
this.elements.push(newElement);
|
||||
}
|
||||
|
||||
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;
|
||||
var draggableLeft = $draggable.offset().left;
|
||||
var draggableWidth = $draggable.height();
|
||||
var draggableRight = draggableLeft + draggableWidth;
|
||||
var $droppables = $(".ui-droppable");
|
||||
var $droppablesCoveredByDraggable = $droppables.filter( function() {
|
||||
var $droppable = $(this);
|
||||
var top = $droppable.offset().top;
|
||||
var height = $droppable.height();
|
||||
var $draggables = angular.element('#detector').find('.element').not('.element-icon'); // replace with detector.elements
|
||||
var inputs = $draggables.filter( function() {
|
||||
var $elem = angular.element(this);
|
||||
var top = $elem.offset().top;
|
||||
var height = $elem.height();
|
||||
var bottom = top + height;
|
||||
|
||||
var left = $droppable.offset().left;
|
||||
var width = $droppable.width();
|
||||
var left = $elem.offset().left;
|
||||
var width = $elem.width();
|
||||
var right = left + width;
|
||||
|
||||
var isCoveredByDraggable = top <= draggableBottom && bottom >= draggableTop
|
||||
&& left <= draggableRight && right >= draggableLeft;
|
||||
return isCoveredByDraggable;
|
||||
});
|
||||
// TODO also get draggable covered by droppable
|
||||
for (var i = 0; i < $droppablesCoveredByDraggable.length; i++) {
|
||||
|
||||
var reaction = this.experiment({inputs:inputs},game);
|
||||
console.log('droppables', inputs.length);
|
||||
|
||||
|
||||
},
|
||||
|
||||
/** Run an experiment depending on ingredients and conditions **/
|
||||
experiment: function(options,game) {
|
||||
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 = game.rules[inputKeys]
|
||||
if (result) {
|
||||
return this.reaction(result.ingredients,result.rune,game)
|
||||
}
|
||||
// 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);
|
||||
return result;
|
||||
},
|
||||
|
||||
/** Remove ingredients and make results with animations **/
|
||||
reaction: function(ingredients,results,game){
|
||||
|
||||
// remove ingredients from detector
|
||||
for (var i = 0; i < ingredients.length; i++) {
|
||||
var ingredient = ingredients[i];
|
||||
}
|
||||
|
||||
// TODO use angular effects to remove in puff of fade
|
||||
|
||||
// add results and discover them
|
||||
for (var i = 0; i < results.length; i++) {
|
||||
var resultKey = results[i];
|
||||
|
||||
// make sure it's discovered
|
||||
var elementStore = this.elements.filter(function(e){return e.key===resultKey;});
|
||||
elementStore.state.discovered=true;
|
||||
|
||||
// add new element to beaker
|
||||
detector.elements.push();
|
||||
// var newElement = $('#elementContent').find('.'+resultKey).clone();
|
||||
// $('#detector').append(newElement);
|
||||
newElement.offset($draggable.offset());
|
||||
}
|
||||
|
||||
// effects
|
||||
this.bubblr.start(1500);
|
||||
|
||||
},
|
||||
}
|
||||
|
||||
@@ -182,10 +182,10 @@
|
||||
/** 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;
|
||||
this.state.on=!this.state.on;
|
||||
else
|
||||
detector.flame.state.on=state;
|
||||
return detector.flame.state.on;
|
||||
this.state.on=state;
|
||||
return this.state.on;
|
||||
}
|
||||
|
||||
Flame.prototype.animate = function(){
|
||||
|
||||
-44
@@ -98,50 +98,6 @@ 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 angular effects to remove in puff of fade
|
||||
$(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) {
|
||||
|
||||
+262
-258
@@ -2,279 +2,283 @@
|
||||
* Game objects such as workers, research, upgrades, and achievements.
|
||||
*/
|
||||
|
||||
var GameObjects = (function() {
|
||||
'use strict';
|
||||
var GLOBAL_VISIBILITY_THRESHOLD = 0.5;
|
||||
var GameObjects = (function () {
|
||||
'use strict';
|
||||
var GLOBAL_VISIBILITY_THRESHOLD = 0.5;
|
||||
|
||||
/** @class GameObject
|
||||
* Base class for all objects in the game. This works together with the
|
||||
* saving mechanism.
|
||||
*/
|
||||
var GameObject = function(obj) {
|
||||
this.state = {};
|
||||
$.extend(this, obj);
|
||||
if (!this.key) {
|
||||
throw 'Error: GameObject has to have a key!';
|
||||
}
|
||||
};
|
||||
GameObject.prototype.loadState =
|
||||
function(state) { $.extend(this.state, state); };
|
||||
/** @class GameObject
|
||||
* Base class for all objects in the game. This works together with the
|
||||
* saving mechanism.
|
||||
*/
|
||||
var GameObject = function (obj) {
|
||||
this.state = {};
|
||||
$.extend(this, obj);
|
||||
if (!this.key) {
|
||||
throw 'Error: GameObject has to have a key!';
|
||||
}
|
||||
};
|
||||
GameObject.prototype.loadState =
|
||||
function (state) {
|
||||
$.extend(this.state, state);
|
||||
};
|
||||
|
||||
/** @class Lab
|
||||
*/
|
||||
var Lab = function() {
|
||||
GameObject.apply(this, [{
|
||||
key : 'lab',
|
||||
state : {
|
||||
name : 'Click here to give your lab an awesome name!',
|
||||
detector : 1,
|
||||
factor : 5,
|
||||
data : 0,
|
||||
money : 0,
|
||||
reputation : 0,
|
||||
clicks : 0,
|
||||
moneyCollected : 0,
|
||||
moneySpent : 0,
|
||||
dataCollected : 0,
|
||||
dataSpent : 0,
|
||||
time: 0
|
||||
}
|
||||
}]);
|
||||
/** @class Lab
|
||||
*/
|
||||
var Lab = function () {
|
||||
GameObject.apply(this, [{
|
||||
key: 'lab',
|
||||
state: {
|
||||
name: 'Click here to give your lab an awesome name!',
|
||||
detector: 1,
|
||||
factor: 5,
|
||||
data: 0,
|
||||
money: 0,
|
||||
reputation: 0,
|
||||
clicks: 0,
|
||||
moneyCollected: 0,
|
||||
moneySpent: 0,
|
||||
dataCollected: 0,
|
||||
dataSpent: 0,
|
||||
time: 0
|
||||
}
|
||||
}]);
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
Lab.prototype = Object.create(GameObject.prototype);
|
||||
Lab.prototype = Object.create(GameObject.prototype);
|
||||
|
||||
Lab.prototype.constructor = Lab;
|
||||
Lab.prototype.constructor = Lab;
|
||||
|
||||
Lab.prototype.getGrant = function() {
|
||||
var addition = this.state.reputation * this.state.factor;
|
||||
this.state.money += addition;
|
||||
this.state.moneyCollected += addition;
|
||||
return addition;
|
||||
};
|
||||
Lab.prototype.getGrant = function () {
|
||||
var addition = this.state.reputation * this.state.factor;
|
||||
this.state.money += addition;
|
||||
this.state.moneyCollected += addition;
|
||||
return addition;
|
||||
};
|
||||
|
||||
Lab.prototype.acquireData = function(amount) {
|
||||
this.state.data += amount;
|
||||
this.state.dataCollected += amount;
|
||||
};
|
||||
Lab.prototype.acquireData = function (amount) {
|
||||
this.state.data += amount;
|
||||
this.state.dataCollected += amount;
|
||||
};
|
||||
|
||||
Lab.prototype.clickDetector = function() {
|
||||
this.state.clicks += 1;
|
||||
this.acquireData(this.state.detector);
|
||||
};
|
||||
Lab.prototype.clickDetector = function () {
|
||||
this.state.clicks += 1;
|
||||
this.acquireData(this.state.detector);
|
||||
};
|
||||
|
||||
Lab.prototype.research = function(cost, reputation) {
|
||||
if (this.state.data >= cost) {
|
||||
this.state.data -= cost;
|
||||
this.state.dataSpent += cost;
|
||||
this.state.reputation += reputation;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
|
||||
Lab.prototype.buy = function(cost) {
|
||||
if (this.state.money >= cost) {
|
||||
this.state.money -= cost;
|
||||
this.state.moneySpent += cost;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
/** @class Element
|
||||
*/
|
||||
var Element = function(obj) {
|
||||
GameObject.apply(this, [obj]);
|
||||
this.state.amount = Math.round(Math.random()*2);
|
||||
this.state.discovered = Math.random()<0.1;
|
||||
this.state.interesting = Math.random()<0.1;
|
||||
this.state.color = Math.round(Math.random()*12);
|
||||
};
|
||||
|
||||
Element.prototype = Object.create(GameObject.prototype);
|
||||
|
||||
Element.prototype.constructor = Element;
|
||||
|
||||
Element.prototype.isVisible = function(lab) {
|
||||
if (!lab) {
|
||||
return false;
|
||||
}
|
||||
return this.state.discovered;
|
||||
};
|
||||
|
||||
Element.prototype.isAvailable = function(lab) {
|
||||
if (!lab) {
|
||||
return false;
|
||||
}
|
||||
return this.state.amount>0;
|
||||
};
|
||||
|
||||
Element.prototype.research = function(lab) {
|
||||
if (lab && lab.research(this.state.cost, this.state.reputation)) {
|
||||
this.state.level++;
|
||||
if (this.state.info_levels.length > 0 &&
|
||||
this.state.level === this.state.info_levels[0]) {
|
||||
this.state.interesting = true;
|
||||
this.state.info_levels.splice(0, 1);
|
||||
}
|
||||
var old_cost = this.state.cost;
|
||||
this.state.cost = Math.floor(this.state.cost * this.cost_increase);
|
||||
return old_cost;
|
||||
}
|
||||
return -1;
|
||||
};
|
||||
|
||||
Element.prototype.getInfo = function() {
|
||||
if (!this._info) {
|
||||
this._info = Helpers.loadFile(this.info);
|
||||
}
|
||||
this.state.interesting = false;
|
||||
return this._info;
|
||||
};
|
||||
|
||||
/** @class Worker
|
||||
* Implement an auto-clicker in the game.
|
||||
*/
|
||||
var Worker = function(obj) {
|
||||
GameObject.apply(this, [obj]);
|
||||
this.state.hired = 0;
|
||||
};
|
||||
|
||||
Worker.prototype = Object.create(GameObject.prototype);
|
||||
|
||||
Worker.prototype.constructor = Worker;
|
||||
|
||||
Worker.prototype.isVisible = function(lab) {
|
||||
if (!lab) {
|
||||
return false;
|
||||
}
|
||||
return this.state.hired > 0 ||
|
||||
lab.state.money >= this.state.cost * GLOBAL_VISIBILITY_THRESHOLD;
|
||||
};
|
||||
|
||||
Worker.prototype.isAvailable = function(lab) {
|
||||
if (!lab) {
|
||||
return false;
|
||||
}
|
||||
return lab.state.money >= this.state.cost;
|
||||
};
|
||||
|
||||
Worker.prototype.hire = function(lab) {
|
||||
if (lab && lab.buy(this.state.cost)) {
|
||||
this.state.hired++;
|
||||
var cost = this.state.cost;
|
||||
this.state.cost = Math.floor(cost * this.cost_increase);
|
||||
return cost;
|
||||
}
|
||||
return -1; // not enough money
|
||||
};
|
||||
|
||||
Worker.prototype.getTotal =
|
||||
function() { return this.state.hired * this.state.rate; };
|
||||
|
||||
/** @class Upgrade
|
||||
*/
|
||||
var Upgrade = function(obj) {
|
||||
GameObject.apply(this, [obj]);
|
||||
this.state.visible = false;
|
||||
this.state.used = false;
|
||||
};
|
||||
|
||||
Upgrade.prototype = Object.create(GameObject.prototype);
|
||||
|
||||
Upgrade.prototype.constructor = Upgrade;
|
||||
|
||||
Upgrade.prototype.meetsRequirements = function(allObjects) {
|
||||
if (!allObjects) {
|
||||
return false;
|
||||
}
|
||||
for (var i = 0; i < this.requirements.length; i++) {
|
||||
var req = this.requirements[i];
|
||||
if (allObjects[req.key].state[req.property] < req.threshold) {
|
||||
Lab.prototype.research = function (cost, reputation) {
|
||||
if (this.state.data >= cost) {
|
||||
this.state.data -= cost;
|
||||
this.state.dataSpent += cost;
|
||||
this.state.reputation += reputation;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
Upgrade.prototype.isAvailable = function(lab, allObjects) {
|
||||
if (!lab || !allObjects) {
|
||||
return false;
|
||||
}
|
||||
return !this.state.used && lab.state.money >= this.cost &&
|
||||
this.meetsRequirements(allObjects);
|
||||
};
|
||||
|
||||
Upgrade.prototype.isVisible = function(lab, allObjects) {
|
||||
if (!lab || !allObjects) {
|
||||
return false;
|
||||
}
|
||||
if (!this.state.used &&
|
||||
(this.state.visible ||
|
||||
lab.state.money >= this.cost * GLOBAL_VISIBILITY_THRESHOLD &&
|
||||
this.meetsRequirements(allObjects))) {
|
||||
this._visible = true;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
Upgrade.prototype.buy = function(lab, allObjects) {
|
||||
if (lab && allObjects && !this.state.used && lab.buy(this.cost)) {
|
||||
for (var i = 0; i < this.targets.length; i++) {
|
||||
var t = this.targets[i];
|
||||
allObjects[t.key].state[t.property] *= this.factor || 1;
|
||||
allObjects[t.key].state[t.property] += this.constant || 0;
|
||||
}
|
||||
this.state.used = true; // How about actually REMOVING used upgrades?
|
||||
this.state.visible = false;
|
||||
return this.cost;
|
||||
}
|
||||
return -1;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
/** @class Achievement
|
||||
*/
|
||||
var Achievement = function(obj) {
|
||||
GameObject.apply(this, [obj]);
|
||||
this.state.timeAchieved = null;
|
||||
};
|
||||
Lab.prototype.buy = function (cost) {
|
||||
if (this.state.money >= cost) {
|
||||
this.state.money -= cost;
|
||||
this.state.moneySpent += cost;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
Achievement.prototype = Object.create(GameObject.prototype);
|
||||
/** @class Element
|
||||
*/
|
||||
var Element = function (obj) {
|
||||
GameObject.apply(this, [obj]);
|
||||
this.state.amount = Math.round(Math.random() * 2);
|
||||
this.state.discovered = Math.random() < 0.1;
|
||||
this.state.interesting = Math.random() < 0.1;
|
||||
this.state.color = Math.round(Math.random() * 11);
|
||||
};
|
||||
|
||||
Achievement.prototype.validate = function(lab, allObjects, saveTime) {
|
||||
if (this.state.timeAchieved) {
|
||||
return true;
|
||||
}
|
||||
if (allObjects.hasOwnProperty(this.targetKey) &&
|
||||
allObjects[this.targetKey].state.hasOwnProperty(this.targetProperty) &&
|
||||
allObjects[this.targetKey].state[this.targetProperty] >= this.threshold) {
|
||||
this.state.timeAchieved = lab.state.time + new Date().getTime() - saveTime;
|
||||
UI.showAchievement(this);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
Element.prototype = Object.create(GameObject.prototype);
|
||||
|
||||
Achievement.prototype.isAchieved = function() {
|
||||
if (this.state.timeAchieved) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
Element.prototype.constructor = Element;
|
||||
|
||||
Element.prototype.isVisible = function (lab) {
|
||||
if (!lab) {
|
||||
return false;
|
||||
}
|
||||
return this.state.discovered;
|
||||
};
|
||||
|
||||
Element.prototype.isAvailable = function (lab) {
|
||||
if (!lab) {
|
||||
return false;
|
||||
}
|
||||
return this.state.amount > 0;
|
||||
};
|
||||
|
||||
Element.prototype.research = function (lab) {
|
||||
if (lab && lab.research(this.state.cost, this.state.reputation)) {
|
||||
this.state.level++;
|
||||
if (this.state.info_levels.length > 0 &&
|
||||
this.state.level === this.state.info_levels[0]) {
|
||||
this.state.interesting = true;
|
||||
this.state.info_levels.splice(0, 1);
|
||||
}
|
||||
var old_cost = this.state.cost;
|
||||
this.state.cost = Math.floor(this.state.cost * this.cost_increase);
|
||||
return old_cost;
|
||||
}
|
||||
return -1;
|
||||
};
|
||||
|
||||
Element.prototype.getInfo = function () {
|
||||
if (!this._info) {
|
||||
this._info = Helpers.loadFile(this.info);
|
||||
}
|
||||
this.state.interesting = false;
|
||||
return this._info;
|
||||
};
|
||||
|
||||
/** @class Worker
|
||||
* Implement an auto-clicker in the game.
|
||||
*/
|
||||
var Worker = function (obj) {
|
||||
GameObject.apply(this, [obj]);
|
||||
this.state.hired = 0;
|
||||
};
|
||||
|
||||
Worker.prototype = Object.create(GameObject.prototype);
|
||||
|
||||
Worker.prototype.constructor = Worker;
|
||||
|
||||
Worker.prototype.isVisible = function (lab) {
|
||||
if (!lab) {
|
||||
return false;
|
||||
}
|
||||
return this.state.hired > 0 ||
|
||||
lab.state.money >= this.state.cost * GLOBAL_VISIBILITY_THRESHOLD;
|
||||
};
|
||||
|
||||
Worker.prototype.isAvailable = function (lab) {
|
||||
if (!lab) {
|
||||
return false;
|
||||
}
|
||||
return lab.state.money >= this.state.cost;
|
||||
};
|
||||
|
||||
Worker.prototype.hire = function (lab) {
|
||||
if (lab && lab.buy(this.state.cost)) {
|
||||
this.state.hired++;
|
||||
var cost = this.state.cost;
|
||||
this.state.cost = Math.floor(cost * this.cost_increase);
|
||||
return cost;
|
||||
}
|
||||
return -1; // not enough money
|
||||
};
|
||||
|
||||
Worker.prototype.getTotal =
|
||||
function () {
|
||||
return this.state.hired * this.state.rate;
|
||||
};
|
||||
|
||||
/** @class Upgrade
|
||||
*/
|
||||
var Upgrade = function (obj) {
|
||||
GameObject.apply(this, [obj]);
|
||||
this.state.visible = false;
|
||||
this.state.used = false;
|
||||
};
|
||||
|
||||
Upgrade.prototype = Object.create(GameObject.prototype);
|
||||
|
||||
Upgrade.prototype.constructor = Upgrade;
|
||||
|
||||
Upgrade.prototype.meetsRequirements = function (allObjects) {
|
||||
if (!allObjects) {
|
||||
return false;
|
||||
}
|
||||
for (var i = 0; i < this.requirements.length; i++) {
|
||||
var req = this.requirements[i];
|
||||
if (allObjects[req.key].state[req.property] < req.threshold) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
Upgrade.prototype.isAvailable = function (lab, allObjects) {
|
||||
if (!lab || !allObjects) {
|
||||
return false;
|
||||
}
|
||||
return !this.state.used && lab.state.money >= this.cost &&
|
||||
this.meetsRequirements(allObjects);
|
||||
};
|
||||
|
||||
Upgrade.prototype.isVisible = function (lab, allObjects) {
|
||||
if (!lab || !allObjects) {
|
||||
return false;
|
||||
}
|
||||
if (!this.state.used &&
|
||||
(this.state.visible ||
|
||||
lab.state.money >= this.cost * GLOBAL_VISIBILITY_THRESHOLD &&
|
||||
this.meetsRequirements(allObjects))) {
|
||||
this._visible = true;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
Upgrade.prototype.buy = function (lab, allObjects) {
|
||||
if (lab && allObjects && !this.state.used && lab.buy(this.cost)) {
|
||||
for (var i = 0; i < this.targets.length; i++) {
|
||||
var t = this.targets[i];
|
||||
allObjects[t.key].state[t.property] *= this.factor || 1;
|
||||
allObjects[t.key].state[t.property] += this.constant || 0;
|
||||
}
|
||||
this.state.used = true; // How about actually REMOVING used upgrades?
|
||||
this.state.visible = false;
|
||||
return this.cost;
|
||||
}
|
||||
return -1;
|
||||
};
|
||||
|
||||
|
||||
// Expose classes in module.
|
||||
return {
|
||||
Lab: Lab,
|
||||
Element: Element,
|
||||
Worker: Worker,
|
||||
Upgrade: Upgrade,
|
||||
Achievement: Achievement
|
||||
};
|
||||
/** @class Achievement
|
||||
*/
|
||||
var Achievement = function (obj) {
|
||||
GameObject.apply(this, [obj]);
|
||||
this.state.timeAchieved = null;
|
||||
};
|
||||
|
||||
Achievement.prototype = Object.create(GameObject.prototype);
|
||||
|
||||
Achievement.prototype.validate = function (lab, allObjects, saveTime) {
|
||||
if (this.state.timeAchieved) {
|
||||
return true;
|
||||
}
|
||||
if (allObjects.hasOwnProperty(this.targetKey) &&
|
||||
allObjects[this.targetKey].state.hasOwnProperty(this.targetProperty) &&
|
||||
allObjects[this.targetKey].state[this.targetProperty] >= this.threshold) {
|
||||
this.state.timeAchieved = lab.state.time + new Date().getTime() - saveTime;
|
||||
UI.showAchievement(this);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
Achievement.prototype.isAchieved = function () {
|
||||
if (this.state.timeAchieved) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// Expose classes in module.
|
||||
return {
|
||||
Lab: Lab,
|
||||
Element: Element,
|
||||
Worker: Worker,
|
||||
Upgrade: Upgrade,
|
||||
Achievement: Achievement
|
||||
};
|
||||
}());
|
||||
|
||||
Reference in New Issue
Block a user