From fa12f3c14e53ec9dc2a327243231c83ce2fca6f7 Mon Sep 17 00:00:00 2001 From: Kevin Dungs Date: Mon, 4 Aug 2014 02:16:05 +0200 Subject: [PATCH] Well I only wanted to implement saving and got carried away. I cleaned the code up a bit. Everything auto-saves now (every 10s) except for achievements. Maybe we should look at them together. --- index.html | 12 ++- js/achievements.js | 2 +- js/game.js | 238 +++++++++------------------------------------ js/gameobjects.js | 187 +++++++++++++++++++++++++++++++++++ js/helpers.js | 42 ++++++++ js/storage.js | 8 +- js/ui.js | 88 +++++++++++------ 7 files changed, 347 insertions(+), 230 deletions(-) create mode 100644 js/gameobjects.js create mode 100644 js/helpers.js diff --git a/index.html b/index.html index 3b72a06..eea8a66 100644 --- a/index.html +++ b/index.html @@ -47,7 +47,7 @@

{{ r.level > 0 ? r.name : '?????' }} Level {{ r.level }}

{{ r.description }} Researching it will give you {{ r.reputation }} reputation.

- +
@@ -56,7 +56,8 @@
-

{{ lc.lab.name }} Click here to change the name

+

{{ lc.lab.name }} Click here to change the name

+
@@ -97,7 +98,7 @@

{{ w.name }} {{ w.hired | niceNumber }}

{{ w.description }} They produce {{ w.rate }} data per second.

- +
@@ -111,7 +112,7 @@

{{ u.name }}

{{ u.description }}

- +
@@ -191,6 +192,9 @@ + + + diff --git a/js/achievements.js b/js/achievements.js index 27ec3f0..8879c69 100644 --- a/js/achievements.js +++ b/js/achievements.js @@ -74,7 +74,7 @@ var achievements = achievements[type][subtype] >= achievements.list[i].threshold ) { - console.log(achievements.list[i].threshold, achievements[type][subtype]); + //console.log(achievements.list[i].threshold, achievements[type][subtype]); achievements.list[i].completed = true; achievements.displayAchievement(i); diff --git a/js/game.js b/js/game.js index f499add..d894d5c 100644 --- a/js/game.js +++ b/js/game.js @@ -1,203 +1,25 @@ 'use strict'; (function() { - var loadFile = function(filename) { - var res; - $.ajax({ - async: false, - url : filename, - success : function(data) { - res = data; - } - }); - return res; - } + var lab = GameObjects.lab; + var research = GameObjects.research; + var workers = GameObjects.workers; + var upgrades = GameObjects.upgrades; - var showModal = function(title, text) { - var $modal = $('#infoBox'); - $modal.find('#infoBoxLabel').html(title); - $modal.find('.modal-body').html(text); - $modal.modal({show: true}); - }; - - var lab = { - name: 'My Awesome Lab', - detector: { - rate: 1 - }, - factor: { - rate: 5 - }, - data: 0, - reputation: 0, - money: 0, - getGrant: function () { - var addition = this.reputation * this.factor.rate; // TODO: adjust factor - this.money += addition; - showUpdateValue("#update-funding", formatNiceNumber(addition)); - achievements.update('count', 'money', addition); - }, - acquire: function(amount) { - this.data += amount; - achievements.update('count', 'data', amount); - showUpdateValue("#update-data", formatNiceNumber(amount)); - }, - research: function(cost, reputation) { - if (this.data >= cost) { - this.data -= cost; - this.reputation += reputation; - achievements.update('count', 'reputation', reputation); - showUpdateValue("#update-data", formatNiceNumber(-cost)); - showUpdateValue("#update-reputation", formatNiceNumber(reputation)); - return true; - } - return false; - }, - buy: function(cost) { - if (this.money >= cost) { - this.money -= cost; - showUpdateValue("#update-funding", formatNiceNumber(-cost)); - return true; - } - return false; - }, - sell: function(cost) { - this.money += cost; - } - }; - - var research = loadFile('json/research.json'); achievements.addResearch(research); - research.map(function(item) { - item.level = 0; - item.is_visible = function() { - return this.level > 0 || lab.data >= this.cost * .7; - }; - item.is_available = function() { - return lab.data >= this.cost; - }; - item.research = function() { - if (lab.research(this.cost, this.reputation)) { - achievements.update('count', 'dataSpent', this.cost); - this.level++; - this.cost = Math.round(this.cost * this.cost_increase); - achievements.update('research', this.name, 1); - } - }; - item.getInfo = function() { - if (!this._info) { - this._info = loadFile(this.info); - } - return this._info; - }, - item.showInfo = function() { - showModal(this.name, this.getInfo()); - }; - }); - - var workers = loadFile('json/workers.json'); achievements.addWorkers(workers); - workers.map(function(worker) { - worker.hired = 0; - worker.is_visible = function() { - return this.hired > 0 || lab.money >= this.cost * .7; - }; - worker.is_available = function() { - return lab.money >= this.cost; - }; - worker.hire = function() { - if (lab.buy(this.cost)) { - achievements.update('count', 'moneyWorkers', this.cost); - this.hired++; - this.cost = Math.round(this.cost * this.cost_increase); - achievements.update('workers', this.name, 1); - achievements.update('count', 'workers', 1); - } - }; - }); - - var upgrades = loadFile('json/upgrades.json'); - upgrades.map(function(upgrade) { - upgrade.getReceiver = function() { - if (this.type === "detector") { - return lab.detector; - } else if (this.type === "reputation"){ - return lab.factor; - } - else { - var context; - if (this.type === "research") { context = research; } - else if (this.type === "hr") { context = workers; } - else { return null; } - for (var i = 0; i < context.length; i++) { - if (context[i].name === this.receiver) { - return context[i]; - } - } - return null; - } - }; - upgrade.hasReceiver = function() { - if (this.type === "detector") { - return true; - } - if (this.type === "reputation") { - return true; - } - var rec = this.getReceiver(); - if (this.type === "research") { - return rec.level > 0; - } else if (this.type === "hr") { - return rec.hired > 0; - } - return false; - }; - upgrade.is_visible = function() { - return !this.used && this.hasReceiver() && lab.money >= this.cost * .7; - }; - upgrade.is_available = function() { - return !this.used && this.hasReceiver() && lab.money >= this.cost; - }; - upgrade.buy = function() { - if (!this.used && lab.buy(this.cost)) { - achievements.update('count', 'moneyUpgrades', this.cost); - this.used = true; - var rec = this.getReceiver(); - if (rec) { - rec[this.property] = rec[this.property] * this.factor + this.constant; - } - } - }; - }); - + var app = angular.module('particleClicker', []); + app.filter('niceNumber', ['$filter', function($filter) { + return Helpers.formatNumberPostfix; + }]); + app.filter('currency', ['$filter', function($filter) { return function(input) { return 'JTN ' + $filter('niceNumber')(input); }; }]); - - function formatNiceNumber(number) { - var abs = Math.abs(number); - if (abs >= Math.pow(10, 12)) { - number = (number / Math.pow(10, 12)).toFixed(1) + "T"; - } else if (abs >= Math.pow(10, 9)) { - number = (number / Math.pow(10, 9)).toFixed(1) + "B"; - } else if (abs >= Math.pow(10, 6)) { - number = (number / Math.pow(10, 6)).toFixed(1) + "M"; - } else if (abs >= Math.pow(10, 3)) { - number = (number / Math.pow(10, 3)).toFixed(1) + "k"; - } else { - number = number.toFixed(0); - } - return number; - } - - app.filter('niceNumber', ['$filter', function($filter) { - return formatNiceNumber; - }]); - app.filter('reverse', ['$filter', function($filter) { return function(items) { return items.slice().reverse(); @@ -209,6 +31,8 @@ lab.acquire(lab.detector.rate); detector.addEvent(); achievements.update('count', 'clicks', 1); + achievements.update('count', 'data', lab.detector.rate); + UI.showUpdateValue("#update-data", lab.detector.rate); return false; }; }); @@ -217,12 +41,14 @@ this.lab = lab; this.showDetectorInfo = function() { if (!this._detectorInfo) { - this._detectorInfo = loadFile('html/detector.html'); + this._detectorInfo = Helpers.loadFile('html/detector.html'); } - showModal('Detector', this._detectorInfo); + UI.showModal('Detector', this._detectorInfo); }; $interval(function() { // one tick - lab.getGrant(); + var grant = lab.getGrant(); + achievements.update('count', 'money', grant); + UI.showUpdateValue("#update-funding", grant); var sum = 0; for (var i = 0; i < workers.length; i++) { sum += workers[i].hired * workers[i].rate; @@ -234,14 +60,38 @@ app.controller('ResearchController', function() { this.research = research; + this.doResearch = function(item) { + var cost = item.research(); + if (cost > 0) { + achievements.update('count', 'reputation', item.reputation); + achievements.update('count', 'dataSpent', cost); + achievements.update('research', item.name, 1); + UI.showUpdateValue("#update-data", -cost); + UI.showUpdateValue("#update-reputation", item.reputation); + } + }; }); app.controller('HRController', function() { this.workers = workers; + this.hire = function(worker) { + var cost = worker.hire(); + if (cost > 0) { + achievements.update('count', 'moneyWorkers', cost); + achievements.update('workers', worker.name, 1); + achievements.update('count', 'workers', 1); + UI.showUpdateValue("#update-funding", cost); + } + }; }); app.controller('UpgradesController', function() { this.upgrades = upgrades; + this.upgrade = function(upgrade) { + if (upgrade.buy()) { + achievements.update('count', 'moneyUpgrades', upgrade.cost); + } + } }); app.controller('AchievementsController', function() { @@ -249,5 +99,11 @@ this.achievementsAll = achievements.list; }); - achievements.setList(loadFile('json/achievements.json')); + achievements.setList(Helpers.loadFile('json/achievements.json')); + + // Activate auto-saving every 10 seconds + setInterval(function () { + GameObjects.saveAll(); + console.log('The game has been saved.'); + }, 10000); })(); diff --git a/js/gameobjects.js b/js/gameobjects.js new file mode 100644 index 0000000..c0c8556 --- /dev/null +++ b/js/gameobjects.js @@ -0,0 +1,187 @@ +'use strict'; + +/** Define all objects used in the game. + * They can be either loaded from localStorage or from JSON in case nothing is + * found in the localStorage. + */ +var GameObjects = (function() { + /** Lab + */ + var labPrototype = { + name: 'My Awesome Lab', + detector: { + rate: 1 + }, + factor: { + rate: 5 + }, + data: 0, + reputation: 0, + money: 0, + getGrant: function () { + var addition = this.reputation * this.factor.rate; + this.money += addition; + return addition; + }, + acquire: function(amount) { + this.data += amount; + }, + research: function(cost, reputation) { + if (this.data >= cost) { + this.data -= cost; + this.reputation += reputation; + return true; + } + return false; + }, + buy: function(cost) { + if (this.money >= cost) { + this.money -= cost; + return true; + } + return false; + }, + sell: function(cost) { + this.money += cost; + } + }; + var lab = $.extend({}, labPrototype, ObjectStorage.load('lab')); + + /** Research + */ + var researchPrototype = { + level: 0, + is_visible: function() { + return this.level > 0 || lab.data >= this.cost * .7; + }, + is_available: function() { + return lab.data >= this.cost; + }, + research: function() { + if (lab.research(this.cost, this.reputation)) { + this.level++; + var oldCost = this.cost; + this.cost = Math.round(this.cost * this.cost_increase); + return oldCost; + } + return -1; + }, + getInfo: function() { + if (!this._info) { + this._info = Helpers.loadFile(this.info); + } + return this._info; + }, + showInfo: function() { + Helpers.showModal(this.name, this.getInfo()); + } + }; + var research = $.extend([], Helpers.loadFile('json/research.json'), + ObjectStorage.load('research')); + research = research.map(function(item) { + return $.extend({}, researchPrototype, item); + }); + + + /** Workers + */ + var workersPrototype = { + hired: 0, + is_visible: function() { + return this.hired > 0 || lab.money >= this.cost * .7; + }, + is_available: function() { + return lab.money >= this.cost; + }, + hire: function() { + if (lab.buy(this.cost)) { + this.hired++; + var cost = this.cost; + this.cost = Math.round(this.cost * this.cost_increase); + return cost; + } + return -1; + } + }; + var workers = $.extend([], Helpers.loadFile('json/workers.json'), + ObjectStorage.load('workers')); + workers = workers.map(function(worker) { + return $.extend({}, workersPrototype, worker); + }); + + + /** Upgrades + */ + var upgradesPrototype = { + getReceiver: function() { + if (this.type === "detector") { + return lab.detector; + } else if (this.type === "reputation"){ + return lab.factor; + } else { + var context; + if (this.type === "research") { context = research; } + else if (this.type === "hr") { context = workers; } + else { return null; } + for (var i = 0; i < context.length; i++) { + if (context[i].name === this.receiver) { + return context[i]; + } + } + return null; + } + }, + hasReceiver: function() { + if (this.type === "detector" || this.type === "reputation") { + return true; + } + var rec = this.getReceiver(); + if (this.type === "research") { + return rec.level > 0; + } else if (this.type === "hr") { + return rec.hired > 0; + } + return false; + }, + is_visible: function() { + return !this.used && this.hasReceiver() && lab.money >= this.cost * .7; + }, + is_available: function() { + return !this.used && this.hasReceiver() && lab.money >= this.cost; + }, + buy: function() { + if (!this.used && lab.buy(this.cost)) { + this.used = true; + var rec = this.getReceiver(); + if (rec) { + rec[this.property] = rec[this.property] * this.factor + this.constant; + } + return true; + } + return false; + } + }; + var upgrades = $.extend([], Helpers.loadFile('json/upgrades.json'), + ObjectStorage.load('upgrades')); + upgrades = upgrades.map(function(upgrade) { + return $.extend({}, upgradesPrototype, upgrade); + }); + + + /** Save all the game objects at once. + */ + var saveAll = function() { + ObjectStorage.save('lab', lab); + ObjectStorage.save('research', research); + ObjectStorage.save('workers', workers); + ObjectStorage.save('upgrades', upgrades); + }; + + return { + lab: lab, + research: research, + workers: workers, + upgrades: upgrades, + saveAll: saveAll + } +})(); diff --git a/js/helpers.js b/js/helpers.js new file mode 100644 index 0000000..8aad0bc --- /dev/null +++ b/js/helpers.js @@ -0,0 +1,42 @@ +'use strict'; + +/** Define some useful helpers that are used throughout the game. + */ +var Helpers = (function() { + /** Load a file (usually JSON). + */ + var loadFile = function(filename) { + var res; + $.ajax({ + async: false, + url : filename, + success : function(data) { + res = data; + } + }); + return res; + }; + + /** Format a number with proper postfix. + */ + var formatNumberPostfix = function(number) { + var abs = Math.abs(number); + if (abs >= Math.pow(10, 12)) { + number = (number / Math.pow(10, 12)).toFixed(1) + "T"; + } else if (abs >= Math.pow(10, 9)) { + number = (number / Math.pow(10, 9)).toFixed(1) + "B"; + } else if (abs >= Math.pow(10, 6)) { + number = (number / Math.pow(10, 6)).toFixed(1) + "M"; + } else if (abs >= Math.pow(10, 3)) { + number = (number / Math.pow(10, 3)).toFixed(1) + "k"; + } else { + number = number.toFixed(0); + } + return number; + } + + return { + loadFile: loadFile, + formatNumberPostfix: formatNumberPostfix + }; +})(); diff --git a/js/storage.js b/js/storage.js index d086da9..8057188 100644 --- a/js/storage.js +++ b/js/storage.js @@ -12,6 +12,9 @@ var ObjectStorage = (function() { }, load: function(key) { return JSON.parse(_s.getItem(key)); + }, + clear: function() { + _s.clear(); } }; } catch (e) { @@ -19,7 +22,8 @@ var ObjectStorage = (function() { + ' If you refresh the page, all progress will be lost'); return { save: function(key, item) {}, - load: function(key) { return null; } + load: function(key) { return null; }, + clear: function() {} }; }; -}); +})(); diff --git a/js/ui.js b/js/ui.js index 3745b7d..56f85db 100644 --- a/js/ui.js +++ b/js/ui.js @@ -1,13 +1,64 @@ -$(function() { - var h = $(window).height(); - $('.scrollable').height(h - 50 + 'px'); +'use strict'; - $(window).resize(function() { +/** Define UI specific stuff. + */ +var UI = (function () { + /** Resize the scrollable containers and make sure they are resized whenever + * the window is resized. */ + $(function() { var h = $(window).height(); $('.scrollable').height(h - 50 + 'px'); + + $(window).resize(function() { + var h = $(window).height(); + $('.scrollable').height(h - 50 + 'px'); + }); }); -}); + /** Show a bootstrap modal with dynamic content. */ + var showModal = function(title, text) { + var $modal = $('#infoBox'); + $modal.find('#infoBoxLabel').html(title); + $modal.find('.modal-body').html(text); + $modal.modal({show: true}); + }; + + var showUpdateValue = function(ident, num) { + var formatted = Helpers.formatNumberPostfix(num); + if (num != 0) { + var insert; + if (num > 0) { + insert = $("
") + .attr("class", "update-plus") + .html("+" + num); + } else { + insert = $("
") + .attr("class", "update-minus") + .html(num); + } + showUpdate(ident, insert); + } + } + + var showUpdate = function(ident, insert) { + var elem = $(ident); + elem.append(insert); + insert.animate({ + "bottom":"+=30px", + "opacity": 0 + }, { duration: 500, complete: function() { + $(this).remove(); + }}); + } + + return { + showModal: showModal, + showUpdateValue: showUpdateValue + } +})(); + + +// I don't know what this is for, so I leave it here for the moment... (function() { var hidden = "hidden"; @@ -41,30 +92,3 @@ $(function() { detector.visible = !this[hidden]; } })(); - -function showUpdateValue(ident, num) { - if (num != 0) { - if (num > 0) { - insert = $("
") - .attr("class", "update-plus") - .html("+" + num); - } else { - insert = $("
") - .attr("class", "update-minus") - .html(num); - } - showUpdate(ident, insert); - } -} - -function showUpdate(ident, insert) { - elem = $(ident); - elem.append(insert); - insert.animate({ - "bottom":"+=30px", - "opacity": 0 - }, { duration: 500, complete: function() { - $(this).remove(); - }}); -} -