Skip to content

Instantly share code, notes, and snippets.

@dolpen
Created May 17, 2016 10:07
Show Gist options
  • Select an option

  • Save dolpen/75192ae5f20fcf2ac696190ce4469df8 to your computer and use it in GitHub Desktop.

Select an option

Save dolpen/75192ae5f20fcf2ac696190ce4469df8 to your computer and use it in GitHub Desktop.
クッキークリッカーっぽいゲームエンジン
#app {
width : 600px;
}
#click {
min-height:200px;
}
#lists {
overflow: hidden;
}
#equip {
float: left;
min-height:200px;
width: 300px;
}
#items {
float: right;
min-height:200px;
width: 300px;
}
#equip > div,#items > div{
background: #fff;
border: 1px #000 solid;
}
#equip > div.active,#items > div.active{
background: #ccc;
}
#equip div.amount {
float: right;
}
#equip div.desc, #items div.desc {
font-size: small;
color: #888;
}
#equip div.cost, #items div.cost {
font-size: small;
color: #0a0;
}
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title></title>
<link href="game.css" rel="stylesheet">
</head>
<body>
<div id="app">
<div id="click"></div>
<div id="lists">
<div id="items"></div>
<div id="equip"></div>
</div>
</div>
<script src="game.js"></script>
</body>
</html>
(function (d, w) {
var consts = {
tps: 20,
waitms: 1000 / 20
};
var utils = {
formatInt: function (num) {
return String(Math.floor(num)).replace(/(\d)(?=(\d\d\d)+(?!\d))/g, '$1,');
}
};
var Equip = function (name, initialCost, initialProfit, inflationRate) {
this.name = name;
this.baseCost = initialCost;
this.costInflationRate = inflationRate;
this.baseProfit = initialProfit;
this.profitMultiplier = 1;
this.computedCost = initialCost;
this.computedProfit = 0;
this.amount = 0;
this.money = null;
this._ui = {
all: null,
cost: null,
desc: null
};
this.initElement();
};
Equip.prototype = {
initElement: function () {
var self = this;
var _el = document.createElement("div");
var _desc = document.createElement("div");
var _name = document.createElement("div");
var _cost = document.createElement("div");
_cost.classList.add("cost");
_desc.classList.add("desc");
_name.textContent = self.name;
_el.appendChild(_name);
_el.appendChild(_desc);
_el.appendChild(_cost);
this._ui.all = _el;
this._ui.cost = _cost;
this._ui.desc = _desc;
_el.addEventListener("click", function () {
self.buy();
self.updateElement();
});
self.updateElement();
},
updateElement: function () {
if (this.amount > 0)this._ui.all.classList.add("active");
this._ui.cost.textContent = utils.formatInt(this.cost());
this._ui.desc.textContent = this._description();
},
getElement: function () {
return this._ui.all;
},
_description: function () {
return "Lv." + this.amount + ", " + utils.formatInt(this.computedProfit * consts.tps) + "pps";
},
setMoney: function (money) {
this.money = money;
},
tick: function () {
this.money.add(this.computedProfit);
},
_updateCost: function () {
this.computedCost = Math.floor(
this.baseCost
* Math.pow(this.costInflationRate, this.amount)
);
},
_updateProfit: function () {
this.computedProfit
= this.baseProfit
* this.profitMultiplier
* this.amount;
},
cost: function () {
return this.computedCost;
},
buy: function () {
if (!this.money.sub(this.cost())) {
return false;
}
this.amount++;
this._updateCost();
this._updateProfit();
this.updateElement();
return true;
},
multiple: function (x) {
this.profitMultiplier *= x;
this._updateProfit();
this.updateElement();
}
};
var ItemType = {
CURSOR_MUL: 0,
EQUIP_MUL: 1
};
var Item = function (name, type, target, value, cost) {
this.name = name;
this.type = type;
this.target = target;
this.value = value;
this.cost = cost;
this.active = false;
this._ui = {
all: null
};
this.initElement();
};
Item.prototype = {
initElement: function () {
var self = this;
var _el = document.createElement("div");
var _name = document.createElement("div");
var _desc = document.createElement("div");
var _cost = document.createElement("div");
_cost.classList.add("cost");
_desc.classList.add("desc");
_name.textContent = self.name;
_cost.textContent = utils.formatInt(self.cost);
_desc.textContent = self.description();
_el.appendChild(_name);
_el.appendChild(_desc);
_el.appendChild(_cost);
_el.addEventListener("click", function () {
self.activate();
self.updateElement();
});
this._ui.all = _el;
},
updateElement: function () {
if (this.active) this._ui.all.classList.add("active");
},
getElement: function () {
return this._ui.all;
},
setMoney: function (money) {
this.money = money;
},
activate: function () {
if (this.active || !this.money.sub(this.cost)) {
return false;
}
this.active = true;
switch (this.type) {
case ItemType.CURSOR_MUL:
this.target.multiple(this.value);
break;
case ItemType.EQUIP_MUL:
this.target.multiple(this.value);
break;
}
return true;
},
label: function () {
return "" + this.name + ":" + this.cost + "(" + this.description() + ")" + (this.active ? "[active]" : "");
},
description: function () {
switch (this.type) {
case ItemType.CURSOR_MUL:
return "ppc を " + this.value + "倍にする";
case ItemType.EQUIP_MUL:
return this.target.name + "の pps を " + this.value + "倍にする";
}
return "何もしない";
}
};
var Cursor = function (initialProfit) {
this.baseProfit = initialProfit;
this.profitMultiplier = 1;
this.computedProfit = initialProfit;
this.money = null;
this.el = null;
this.initElement();
};
Cursor.prototype = {
initElement: function () {
var self = this;
var _el = document.createElement("div");
_el.addEventListener("click", function () {
self.money.add(self.click());
self.updateElement();
});
_el.textContent = "0";
this.el = _el;
},
updateElement: function () {
this.el.textContent = this.money.label();
},
getElement: function () {
return this.el;
},
setMoney: function (money) {
this.money = money;
},
click: function () {
return this.computedProfit;
},
_updateProfit: function () {
this.computedProfit
= this.baseProfit
* this.profitMultiplier;
},
multiple: function (x) {
this.profitMultiplier *= x;
this._updateProfit();
},
label: function () {
return "click : +" + this.computedProfit;
}
};
var Money = function () {
this.amount = 0;
};
Money.prototype = {
has: function (x) { // boolean
return this.amount >= x;
},
add: function (x) { // void
this.amount += x;
},
sub: function (x) { // boolean
if (!this.has(x))return false;
this.amount -= x;
return true;
},
label: function () {
return utils.formatInt(this.amount);
}
};
var Game = function () {
this.cursor = new Cursor(1, this);
this.money = new Money();
this.cursorSelector = document.querySelector("#click");
this.equipSelector = document.querySelector("#equip");
this.itemsSelector = document.querySelector("#items");
this.equipments = [
new Equip("機械式クリックマシン", 15, 0.1, 1.05),
new Equip("電気式クリックマシン", 110, 1, 1.05),
new Equip("エンジン式クリックマシン", 2000, 150, 1.05)
];
this.items = [
new Item("指の強化", ItemType.CURSOR_MUL, this.cursor, 3, 100),
new Item("ギア強化", ItemType.EQUIP_MUL, this.equipments[0], 3, 200),
new Item("電子回路", ItemType.EQUIP_MUL, this.equipments[1], 5, 2000),
new Item("鋼の指", ItemType.CURSOR_MUL, this.cursor, 4, 5000),
new Item("直噴技術", ItemType.EQUIP_MUL, this.equipments[2], 10, 25000),
new Item("黄金の指", ItemType.CURSOR_MUL, this.cursor, 20, 50000)
];
};
Game.prototype = {
init: function () {
this.cursor.setMoney(this.money);
this.cursorSelector.appendChild(this.cursor.getElement());
for (var i = 0; i < this.equipments.length; i++) {
this.equipments[i].setMoney(this.money);
this.equipSelector.appendChild(this.equipments[i].getElement());
}
for (var i = 0; i < this.items.length; i++) {
this.items[i].setMoney(this.money);
this.itemsSelector.appendChild(this.items[i].getElement());
}
},
tick: function () {
for (var i = 0; i < this.equipments.length; i++) {
this.equipments[i].tick();
}
this.cursor.updateElement();
}
};
var bootstrap = function () {
var game = new Game();
game.init();
var tick = function () {
game.tick();
setTimeout(tick, consts.waitms);
};
w.game = game;
tick();
};
if (d.readyState !== "loading") {
bootstrap();
} else {
d.addEventListener("DOMContentLoaded", bootstrap);
}
})(document, window);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment