var gameMod = (function(){
var GAME_MONEY_START = 0,
GAME_UPDATE_MAX_SECS = 0.8,
MONEY_PERLOSS_ON_DEATH = 0.1,
BLOCK_COUNT = 40,
BLOCK_POS_MAX_DIST = 1500,
BLOCK_SPAWN_DIST = 250,
BLOCK_SPAWN_COUNT_PER_DIST_MIN = 3,
BLOCK_POS_SLOT_DIST = 15,
BLOCK_HP_MIN = 10,
BLOCK_HP_MAX = 1000,
BLOCK_MONEY_BASE = 1,
BLOCK_MONEY_DIST = 999,
BLOCK_ARMOR_MINDAM_MIN = 0,
BLOCK_ARMOR_MINDAM_MAX = 45,
SHIP_AUTOFIRE = true,
SHIP_HP = 100,
SHIP_AUTOHEAL_ENABLED=true,
SHIP_AUTOHEAL_RATE = 3,
SHIP_AUTOHEAL_AMOUNT = 1,
SHIP_ROTATION_RATE_MIN = 45,
SHIP_ROTATION_RATE_MAX = 180,
SHIP_MAX_SPEED_START = 128,
SHIP_MAX_SPEED_MAX = 1024,
SHIP_ACC_START = 64,
SHIP_ACC_MAX = 256,
MAP_MAX_DIST = 2.5 * Math.pow(10,5),
ENERGY_MAX = 100,
ENERGY_AUTOHEAL_COST=3,
BASE_DIST = 100;
var WEAPONS = {
0: {
name: 'Pulse Gun',
firesPerSecond: {
min: 2,
max: 10,
levelOpt: {
levelCap: 10,
expCap: 1000,
perMethod: 'log1',
perArgs: [],
tableX: 160 - 12,
tableY: 120 - 12 - 30
}
},
shotDamage: {
min: 0.25,
max: Math.floor(BLOCK_HP_MAX * 0.05),
levelOpt: {
levelCap: 10,
expCap: 1500,
perMethod: 'log1',
perArgs: [],
tableX: 160 - 12,
tableY: 120 - 12
}
},
effects: ['burn', 'acid'],
shotRange: 128,
shotPPS: 96,
shotsPerFire: [2,2,1],
onFireStart: function(game, secs, state){
var weapon = game.weapons[game.ship.weaponIndex];
var shotIndex = 0;
var radianStart = state.game.map.radian;
var shotsPerFire = weapon.shotsPerFire[weapon.shotsPerFireIndex];
while(shotIndex < shotsPerFire){
var side = shotIndex % 2 === 0 ? -1 : 1;
var dist = 8;
if(shotsPerFire === 1){
dist = 0;
}
poolMod.spawn(game.shots, state, {
radian: radianStart,
x: Math.sin(Math.PI - radianStart) * dist * side,
y: Math.cos(Math.PI + radianStart) * dist * side
});
shotIndex += 1;
}
}
},
1: {
name: 'Cannon',
firesPerSecond: {
min: 4,
max: 10,
levelOpt: {
levelCap: 10,
expCap: 15000,
perMethod: 'log1',
perArgs: [],
tableX: 160 - 12,
tableY: 120 - 12 - 30
}
},
shotDamage: {
min: Math.floor(BLOCK_HP_MAX * 0.05),
max: Math.floor(BLOCK_HP_MAX * 0.10),
levelOpt: {
levelCap: 10,
expCap: 50000,
perMethod: 'log1',
perArgs: [],
tableX: 160 - 12,
tableY: 120 - 12
}
},
effects: ['burn', 'acid'],
shotRange: 256,
shotsPerFire: [3, 2],
onFireStart: function(game, secs, state){
var weapon = game.weapons[game.ship.weaponIndex];
var shotIndex = 0;
var radianStart = state.game.map.radian - Math.PI / 180 * 20;
while(shotIndex < weapon.shotsPerFire[weapon.shotsPerFireIndex]){
var shotPer = shotIndex / (weapon.shotsPerFire[weapon.shotsPerFireIndex] - 1);
var radianDelta = Math.PI / 180 * 40 * shotPer;
poolMod.spawn(game.shots, state, {
radian: radianStart + radianDelta
});
shotIndex += 1;
}
}
},
2: {
name: 'Atom',
firesPerSecond: {
min: 1,
max: 5,
levelOpt: {
levelCap: 10,
expCap: 25000,
perMethod: 'log1',
perArgs: [],
tableX: 160 - 12,
tableY: 120 - 12 - 30
}
},
shotDamage: {
min: Math.floor(BLOCK_HP_MAX * 0.10),
max: Math.floor(BLOCK_HP_MAX * 0.25),
levelOpt: {
levelCap: 10,
expCap: 30000,
perMethod: 'log1',
perArgs: [],
tableX: 160 - 12,
tableY: 120 - 12
}
},
effects: ['acid'],
shotRange: 64,
shotsPerFire: [1]
}
};
var create_DEFAULT_WEAPONS = function(){
return Object.keys(WEAPONS).map(function(weaponKey){
var weaponDATA = WEAPONS[weaponKey];
return {
name: weaponDATA.name,
firesPerSecond: weaponDATA.firesPerSecond.min,
shotDamage: weaponDATA.shotDamage.min,
shotRange: weaponDATA.shotRange || 64,
shotsPerFire: weaponDATA.shotsPerFire || [1],
onFireStart: weaponDATA.onFireStart || function(game, secs, state){
poolMod.spawn(game.shots, state, {
radian: state.game.map.radian
});
},
shotPPS: weaponDATA.shotPPS || 128,
shotsPerFireIndex : 0,
effects: weaponDATA.effects || []
};
});
};
var DEFAULT_WEAPONS = create_DEFAULT_WEAPONS();
var SPACE_BUTTONS = {
main: {
0: {
desc: 'Auto Fire',
x: 130,
y: 40,
r: 10,
onClick: function(game){
console.log('click auto fire');
game.autoFire = !game.autoFire;
}
}
}
};
var BASE_BUTTONS = {
main: {
0: {
desc: 'Weapons',
x: 64,
y: -32,
r: 16,
onClick: function(game){
game.buttons.currentPage = 'weapons';
}
},
1: {
desc: 'Ship',
x: 64,
y: 32,
r: 16,
onClick: function(game){
game.buttons.currentPage = 'ship';
}
},
2: {
desc: 'Effects',
x: 96 + 8,
y: -32,
r: 16,
onClick: function(game){
game.buttons.currentPage = 'effects';
}
}
},
weapons:{
0: {
desc: 'Back',
x: 64,
y: 0,
r: 16,
onClick: function(game){
game.buttons.currentPage = 'main';
}
},
1: {
desc: 'Change Weapon',
x: 64,
y: 32,
r: 16,
onClick: function(game){
game.ship.weaponIndex += 1;
game.ship.weaponIndex = utils.mod(game.ship.weaponIndex, Object.keys(game.weapons).length);
game.ship.weapon = game.weapons[game.ship.weaponIndex];
updateButtons(game);
}
},
2: {
desc: 'Fires Per Second',
x: -64,
y: -32,
r: 16,
cost:0,
type: 'weaponUpgrade',
weaponProp: 'firesPerSecond',
onClick: function(game, button){
var upgradeID = 'w-' + game.ship.weaponIndex + '-firesPerSecond',
upgrade = getUpgradeById(game, upgradeID);
buyUpgrade(game, upgrade);
button.cost = upgrade.levelObj.xpForNext;
}
},
3: {
desc: 'Damage',
x: -64,
y: 0,
r: 16,
cost:0,
type: 'weaponUpgrade',
weaponProp: 'shotDamage',
onClick: function(game, button){
var upgradeID = 'w-' + game.ship.weaponIndex + '-shotDamage',
upgrade = getUpgradeById(game, upgradeID);
buyUpgrade(game, upgrade);
button.cost = upgrade.levelObj.xpForNext;
}
}
},
ship:{
0: {
desc: 'Back',
x: 64,
y: 0,
r: 16,
onClick: function(game){
game.buttons.currentPage = 'main';
}
},
1: {
desc: 'Max Speed',
x: 64,
y: -32,
r: 16,
cost: 0,
upgradeID: 's1',
onClick: function(game, button){
var upgrade = button.upgrade;
buyUpgrade(game, upgrade);
button.cost = upgrade.levelObj.xpForNext;
}
},
2: {
desc: 'Max Acc',
x: 64,
y: 32,
r: 16,
cost: 0,
upgradeID: 's2',
onClick: function(game, button){
var upgrade = button.upgrade;
buyUpgrade(game, upgrade);
button.cost = upgrade.levelObj.xpForNext;
}
},
3: {
desc: 'Rotation',
x: 64,
y: 64,
r: 16,
cost: 0,
upgradeID: 's3',
onClick: function(game, button){
var upgrade = button.upgrade;
buyUpgrade(game, upgrade);
button.cost = upgrade.levelObj.xpForNext;
}
}
},
effects: {
0: {
desc: 'Back',
x: 64,
y: 0,
r: 16,
onClick: function(game){
game.buttons.currentPage = 'main';
}
},
1: {
desc: 'Burn',
type: 'effectUpgrade',
effectType: 'burn',
x: 64,
y: 32,
r: 16,
cost: 0,
onClick: function(game, button){
var upgrade = button.upgrade;
buyUpgrade(game, upgrade);
button.cost = upgrade.levelObj.xpForNext;
}
},
2: {
desc: 'ACID',
type: 'effectUpgrade',
effectType: 'acid',
x: 64,
y: -32,
r: 16,
cost: 0,
onClick: function(game, button){
var upgrade = button.upgrade;
buyUpgrade(game, upgrade);
button.cost = upgrade.levelObj.xpForNext;
}
}
}
};
var updateButtons = function(game){
['base'].forEach(function(mode){
Object.keys(game.buttons[mode]).forEach(function(pageKey){
Object.keys(game.buttons[mode][pageKey]).forEach(function(buttonKey){
var button = game.buttons[mode][pageKey][buttonKey];
if(button.upgradeID){
button.upgrade = getUpgradeById(game, button.upgradeID);
}
if(button.type){
if(button.type === 'weaponUpgrade'){
var upgradeID = 'w-' + game.ship.weaponIndex + '-' + button.weaponProp;
button.upgrade = getUpgradeById(game, upgradeID);
}
if(button.type === 'effectUpgrade'){
var upgradeID = 'e-' + button.effectType;
button.upgrade = getUpgradeById(game, upgradeID);
}
}
if(button.upgrade && button.cost != undefined){
button.cost = button.upgrade.levelObj.xpForNext;
}
});
});
});
};
var DEFAULT_UPGRADES = [
{
id: 's1',
desc: 'Max Speed',
applyToState: function(game, levelObj, upgrade){
var delta = SHIP_MAX_SPEED_MAX - SHIP_MAX_SPEED_START;
game.map.maxPPS = SHIP_MAX_SPEED_START + delta * levelObj.perToLevelCap;
},
levelOpt: {
levelCap: 10,
expCap: 10000,
perMethod: 'log1',
perArgs: [],
tableX: 260,
tableY: 120 - 12 - 32
}
},
{
id: 's2',
desc: 'Ship Acceleration',
applyToState: function(game, levelObj, upgrade){
var delta = SHIP_ACC_MAX - SHIP_ACC_START;
game.map.ppsDelta = SHIP_ACC_START + delta * levelObj.perToLevelCap;
},
levelOpt: {
levelCap: 10,
expCap: 7500,
perMethod: 'log1',
perArgs: [],
tableX: 260,
tableY: 120 - 12 + 32
}
},
{
id: 's3',
desc: 'Rotation',
applyToState: function(game, levelObj, upgrade){
var delta = SHIP_ROTATION_RATE_MAX - SHIP_ROTATION_RATE_MIN;
game.map.degreesPerSecond = SHIP_ROTATION_RATE_MIN + delta * levelObj.perToLevelCap;
},
levelOpt: {
levelCap: 10,
expCap: 5000,
perMethod: 'log1',
perArgs: [],
tableX: 260,
tableY: 120 - 12 + 64
}
}
];
var append_WEAPON_UPGRADES = function(){
Object.keys(WEAPONS).forEach(function(weaponKey){
var weapon = WEAPONS[weaponKey];
['firesPerSecond', 'shotDamage'].forEach(function(weaponProp){
levelOpt = utils.deepClone(weapon[weaponProp].levelOpt || {});
levelOpt.levelCap = levelOpt.levelCap || 30;
levelOpt.expCap = levelOpt.expCap || 10000;
levelOpt.perArgs = levelOpt.perArgs || [0];
var upgrade = {
id: 'w-' + weaponKey + '-' + weaponProp,
desc: weapon.name + ' ' + weaponProp,
applyToState: function(game, levelObj, upgrade){
var weaponIndex = Number(upgrade.id.split('-')[1]),
weapon = game.weapons[weaponIndex],
weaponDATA = WEAPONS[weaponIndex],
weaponProp = upgrade.id.split('-')[2];
var delta = weaponDATA[weaponProp].max - weaponDATA[weaponProp].min;
weapon[weaponProp] = weaponDATA[weaponProp].min + delta * levelObj.perToLevelCap;
},
levelOpt: levelOpt
};
DEFAULT_UPGRADES.push(upgrade);
});
});
};
var append_EFFECT_UPGRADES = function(){
Object.keys(poolMod.EFFECT_TYPES).forEach(function(key){
var effectDATA = poolMod.EFFECT_TYPES[key];
DEFAULT_UPGRADES.push({
id: 'e-' + key,
desc: key,
applyToState: function(game, levelObj, upgrade){
var effect = game.effects[upgrade.id.split('-')[1]];
Object.keys(effect.upStat).forEach(function(effectKey){
var upStat = effect.upStat[effectKey];
var delta = (upStat.max - upStat.min) * levelObj.perToLevelCap;
effect[effectKey] = upStat.min + delta;
if(upStat.round){
effect[effectKey] = Math[upStat.round](effect[effectKey]);
}
});
},
levelOpt: utils.deepClone({
levelCap: 10,
expCap: 50000,
perMethod: 'log1'
})
});
});
};
append_WEAPON_UPGRADES();
append_EFFECT_UPGRADES();
var getUpgradeById = function(game, id){
var i = game.upgrades.length;
while(i--){
var upgrade = game.upgrades[i];
if(id === upgrade.id){
return upgrade;
}
}
return false;
};
var buyUpgrade = function(game, upgrade){
var lvCurrent = upgrade.levelObj,
lvNext;
if(lvCurrent.level < upgrade.opt.levelCap){
lvNext = upgrade.levelObjArray[lvCurrent.level];
if(game.money >= lvNext.xp){
upgrade.levelIndex = lvNext.level -1;
upgrade.levelObj = lvNext;
game.money -= lvNext.xp;
upgrade.applyToState(game, upgrade.levelObj, upgrade);
}else{
}
}else{
}
};
var api = {};
var createHPObject = function(maxHP){
return {
current: maxHP || 100,
max: maxHP || 100,
per: 1,
autoHeal: {
enabled: false,
rate: 5,
amount: -1,
secs: 0
}
};
};
var autoHealObject = function(obj, secs){
if(obj.hp){
if(obj.hp.autoHeal.enabled){
obj.hp.autoHeal.secs += secs;
if(obj.hp.autoHeal.secs >= obj.hp.autoHeal.rate){
obj.hp.current += obj.hp.autoHeal.amount;
obj.hp.current = obj.hp.current > obj.hp.max ? obj.hp.max : obj.hp.current;
obj.hp.current = obj.hp.current < 0 ? 0 : obj.hp.current;
obj.hp.per = obj.hp.current / obj.hp.max;
obj.hp.autoHeal.secs = 0;
}
}else{
obj.hp.autoHeal.secs = 0;
}
}
};
var onShipDeath = function(game){
game.ship = createShip(game);
game.map.x = 0;
game.map.y = 0;
game.map.pps = 0;
poolMod.getAllActive(game.blocks).forEach(function(block){
block.active = false;
block.lifespan = 0;
});
game.money = game.money > 0 ? game.money * ( 1 - MONEY_PERLOSS_ON_DEATH) : 0;
};
var attackObject = function(game, target, attacker){
if(target.hp){
if(target.armor){
if(attacker.damage < target.armor.minDam){
attacker.damage = 0;
}
}
if(target.type === 'block'){
poolMod.applyOnAttackEffects(target, attacker.damage);
attacker.effects.forEach(function(effect){
poolMod.createEffect(target, effect);
target.effectStats=poolMod.getEffectStats(target);
});
}
target.hp.current -= attacker.damage;
target.hp.current = target.hp.current < 0 ? 0 : target.hp.current;
target.hp.per = target.hp.current / target.hp.max;
if(target.hp.current === 0 && target.type === 'ship'){
onShipDeath(game);
}
}
};
var createEnergyObject = function(){
return {
current: ENERGY_MAX * 0.5,
max: ENERGY_MAX,
per: 0,
rate: 1,
secs: 0
};
};
var clampEnergy = function(energy){
energy.current = energy.current > energy.max ? energy.max: energy.current;
energy.current = energy.current < 0 ? 0: energy.current;
};
var updateEnergy = function(game, secs){
var energy = game.ship.energy;
energy.per = energy.current / energy.max;
energy.current += energy.rate * secs;
clampEnergy(energy);
};
var shotStyleHelper = function(shot){
shot.fillStyle = 'rgba(255,255,255,0.2)';
shot.r = 2;
if(shot.effects.length > 0){
var r = 0, b = 0, g = 0;
shot.effects.forEach(function(effect){
if(effect.effectType === 'burn'){
r = 255;
}
if(effect.effectType === 'acid'){
b = 255;
}
});
shot.fillStyle = 'rgb(' + r + ',' + g + ', ' + b + ')';
shot.r = 3;
}
};
var createShotsPool = function(){
return poolMod.create({
type: 'shot',
count: 60,
fillStyle: 'white',
r: 2,
spawn: function(shot, pool, state, opt){
var weapon = state.game.ship.weapon,
range = weapon.shotRange || 32;
shot.x = opt.x === undefined ? 0 : opt.x;
shot.y = opt.y === undefined ? 0 : opt.y;
shot.radian = opt.radian;
shot.pps = weapon.shotPPS;
shot.lifespan = 1 / shot.pps * range;
shot.damage = weapon.shotDamage;
shot.effects = [];
weapon.effects.forEach(function(effectType){
var effect = poolMod.parseEffectObject(state.game.effects[effectType]);
var roll = Math.random();
if(roll < effect.chance){
shot.effects.push(effect);
}
});
shotStyleHelper(shot);
},
update: function(shot, pool, state, secs){
var objDeltaX = Math.cos(shot.radian) * shot.pps * secs;
var objDeltaY = Math.sin(shot.radian) * shot.pps * secs;
shot.x += objDeltaX;
shot.y += objDeltaY;
var blocks = poolMod.getAllActive(state.game.blocks, true);
var i = blocks.length;
while(i--){
var block = blocks[i];
var dist = utils.distance(shot.x, shot.y, block.x, block.y);
if(dist <= block.r + shot.r){
shot.lifespan = 0;
attackObject(state.game, block, shot);
if(block.hp.current <= 0 ){
state.game.money += block.money;
block.lifespan = 0;
block.active = false;
}
break;
}
}
}
});
};
var getFreePositions = function(game, blockPool){
var map = game.map,
activeBlocks = poolMod.getAllActive(blockPool || game.blocks, true),
xMapAjust = utils.mod(game.map.x, 32),
yMapAjust = utils.mod(game.map.y, 32),
spotX,
spotY,
blockIndex,
block,
free = [],
gridH = 10,
gridW = 10,
slotDist = BLOCK_POS_SLOT_DIST,
sx = Math.ceil(Math.cos(game.map.radian) * (gridH / 2 + slotDist) - gridW / 2),
sy = Math.ceil(Math.sin(game.map.radian) * (gridH / 2 + slotDist) - gridH / 2),
x = sx,
y = sy;
while(y < gridH + sy){
x = sx;
spotY = y * 32 - yMapAjust;
loopx:while(x < gridW + sx){
spotX = x * 32 - xMapAjust;
blockIndex = activeBlocks.length;
while(blockIndex--){
block = activeBlocks[blockIndex];
if(utils.distance(block.x, block.y, spotX, spotY) <= block.r){
x+=1;
continue loopx;
}
}
free.push({
x: spotX,
y: spotY
});
x += 1;
}
y += 1;
}
return free;
};
var positionBlock = function(state, obj){
var game = state.game;
var freeSlots = getFreePositions(game);
if(freeSlots.length === 0){
obj.active = false;
obj.lifespan = 0;
}else{
var slot = freeSlots.splice(Math.floor(freeSlots.length * Math.random()), 1)[0];
obj.x = slot.x;
obj.y = slot.y;
}
};
var getValueByMapDist = function(game, opt){
opt = opt || {};
opt.minVal = opt.minVal || 0;
opt.maxVal = opt.maxVal || 1;
opt.roundFunc = opt.roundFunc || Math.round;
opt.perFunc = opt.perFunc || utils.log1;
opt.perFuncArgs = opt.perFuncArgs || [];
var per = game.map.per,
delta = opt.maxVal - opt.minVal;
if(opt.perFunc){
per = opt.perFunc.apply(null, [per, 1, 'per'].concat(opt.perFuncArgs));
}
var result = opt.minVal + delta * per;
if(opt.roundFunc){
return opt.roundFunc(result);
}
return result;
};
var createBlocksPool = function(){
return poolMod.create({
type: 'block',
data: {},
fillStyle: '#1a1a1a',
count: BLOCK_COUNT,
spawn: function(obj, pool, state, opt){
var game = state.game,
map = game.map;
positionBlock(state, obj);
obj.radian = utils.wrapRadian(map.radian + Math.PI);
obj.pps = map.pps;
obj.lifespan = 1;
obj.hp = createHPObject( BLOCK_HP_MIN + Math.round( (BLOCK_HP_MAX - BLOCK_HP_MIN) ) * map.per );
obj.damage = getValueByMapDist(game, {
minVal: 1,
maxVal: 100,
perFunc: utils.log1,
roundFunc: Math.floor
});
obj.money = BLOCK_MONEY_BASE + Math.round(game.map.per * BLOCK_MONEY_DIST);
obj.armor.minDam = getValueByMapDist(game, {
minVal: BLOCK_ARMOR_MINDAM_MIN,
maxVal: BLOCK_ARMOR_MINDAM_MAX,
perFunc: utils.log1,
roundFunc: Math.floor
});
},
update: function(block, pool, state, secs){
var game = state.game;
var map = state.game.map;
block.lifespan = 1;
block.radian = utils.wrapRadian(state.game.map.radian + Math.PI);
block.pps = state.game.map.pps;
var objDeltaX = Math.cos(block.radian) * block.pps * secs;
var objDeltaY = Math.sin(block.radian) * block.pps * secs;
block.x += objDeltaX;
block.y += objDeltaY;
block.data.dist = utils.distance(block.x, block.y, state.game.ship.x, state.game.ship.y);
autoHealObject(block, secs);
if(block.data.dist <= game.ship.r + block.r){
attackObject(game, game.ship, block);
block.lifespan = 0;
}
if(block.data.dist >= BLOCK_POS_MAX_DIST){
block.lifespan = 0;
}
if(block.hp.current <= 0){
if(block.awardBlockMoney){
game.money += block.money;
}
block.lifespan = 0;
}
block.effectStats=poolMod.getEffectStats(block);
}
});
};
var createShip = function(game){
var ship = {
type: 'ship',
x: 0,
y: 0,
r: 8,
newShip: true,
hp: createHPObject(SHIP_HP),
energy: createEnergyObject(),
fillStyle: 'blue',
weaponSecs: 0,
weaponIndex:0,
weapon: game.weapons[0]
};
ship.hp.autoHeal.enabled = SHIP_AUTOHEAL_ENABLED;
ship.hp.autoHeal.rate = SHIP_AUTOHEAL_RATE;
ship.hp.autoHeal.amount = SHIP_AUTOHEAL_AMOUNT;
return ship;
};
api.create = function(opt){
opt = opt || {};
var game = {
money: opt.money === undefined ? GAME_MONEY_START : opt.money,
mode: 'space',
autoFire: SHIP_AUTOFIRE,
weapons: utils.deepClone(DEFAULT_WEAPONS),
effects: utils.deepClone(poolMod.EFFECT_TYPES),
upgrades: [],
ship: {},
shots: createShotsPool(),
blocks: createBlocksPool(),
blockSpawn: {
dist: 0,
lastPos: {x:0, y:0}
},
map: {
x: opt.mapX === undefined ? 0 : opt.mapX,
y: opt.mapY === undefined ? 0 : opt.mapY,
degree: 270,
degreesPerSecond: SHIP_ROTATION_RATE_MIN,
radian: 0,
aToOrigin: 0,
pps: 0,
ppsDelta: SHIP_ACC_START,
maxPPS: SHIP_MAX_SPEED_START,
dist: 0,
per: 0
},
buttons: {
currentPage: 'main',
base: utils.deepClone(BASE_BUTTONS),
space: utils.deepClone(SPACE_BUTTONS)
},
baseObj : {
fillStyle: '#282828',
x: 0,
y: 0,
r: BASE_DIST
}
};
game.ship = createShip(game);
var upgradeIndices = opt.upgradeIndices || {
s1: 1
};
game.upgrades = DEFAULT_UPGRADES.map(function(upDef){
var upgrade = utils.xp.createUpgrade(upDef.desc, 0, upDef.applyToState, upDef.levelOpt);
upgrade.id = upDef.id;
upgrade.levelIndex = upgradeIndices[upgrade.id] || 0;
upgrade.levelObj = upgrade.levelObjArray[upgrade.levelIndex];
if(upgrade.id == 's1'){
console.log(upgrade.levelIndex);
console.log(upgrade.levelObjArray[upgrade.levelIndex]);
}
upgrade.applyToState(game, upgrade.levelObj, upgrade);
return upgrade;
});
updateButtons(game);
var upgrade = getUpgradeById(game, 'e-burn');
buyUpgrade(game, upgrade);
buyUpgrade(game, upgrade);
buyUpgrade(game, upgrade);
var upgrade = getUpgradeById(game, 'e-acid');
buyUpgrade(game, upgrade);
buyUpgrade(game, upgrade);
buyUpgrade(game, upgrade);
*/
console.log(game.upgrades.map(function(upgrade){
return upgrade.levelObjArray.map(function(levelObj){
//var lvNext = utils.xp.byLevel(levelObj.l + 1, upgrade.opt);
//return lvNext.l;
return levelObj.xp;
});
}));
*/
return game;
};
api.setMapMovement = function(game, degree, pps){
game.map.radian = utils.wrapRadian(Math.PI / 180 * degree);
game.map.pps = pps;
game.map.pps = game.map.pps < 0 ? 0 : game.map.pps;
game.map.pps = game.map.pps > game.map.maxPPS ? game.map.maxPPS : game.map.pps;
};
var clampMapPos = function(map){
if(map.dist >= MAP_MAX_DIST){
var radian = utils.wrapRadian(map.radian + Math.PI);
map.x = Math.cos(radian) * MAP_MAX_DIST;
map.y = Math.sin(radian) * MAP_MAX_DIST;
}
};
var updateMap = function(game, secs){
var map = game.map;
map.x += Math.cos(map.radian) * map.pps * secs;
map.y += Math.sin(map.radian) * map.pps * secs;
map.dist = utils.distance(0, 0, map.x, map.y);
clampMapPos(map);
map.per = game.map.dist / MAP_MAX_DIST;
map.aToOrigin = utils.angleTo(0, 0, map.x, map.y);
};
var updateBlocks = function(game, secs, state){
var blockSpawn = game.blockSpawn,
spawnIndex;
if(game.mode === 'space'){
poolMod.update(game.blocks, secs, state);
blockSpawn.dist = utils.distance(game.map.x, game.map.y, blockSpawn.lastPos.x, blockSpawn.lastPos.y);
if(blockSpawn.dist >= BLOCK_SPAWN_DIST){
blockSpawn.lastPos.x = game.map.x;
blockSpawn.lastPos.y = game.map.y;
spawnIndex = BLOCK_SPAWN_COUNT_PER_DIST_MIN;
while(spawnIndex--){
poolMod.spawn(game.blocks, state, {});
}
}
}
if(game.mode === 'base'){
poolMod.setActiveStateForAll(game.blocks, false);
}
};
var updateShots = function(game, secs, state){
var ship = game.ship,
weapon = ship.weapon;
if(game.mode === 'space'){
ship.weaponSecs += secs;
if(game.autoFire || state.input.fire){
if(ship.weaponSecs >= 1 / weapon.firesPerSecond){
weapon.onFireStart(game, secs, state);
weapon.shotsPerFireIndex += 1;
weapon.shotsPerFireIndex %= weapon.shotsPerFire.length;
ship.weaponSecs = 0;
}
}
}
poolMod.update(game.shots, secs, state);;
};
api.update = function(game, secs, state){
secs = secs > GAME_UPDATE_MAX_SECS ? GAME_UPDATE_MAX_SECS : secs;
secs = secs < 0 ? 0 : secs;
game.baseObj.x = game.map.x * -1;
game.baseObj.y = game.map.y * -1;
updateMap(game, secs);
if(game.map.dist > BASE_DIST && game.mode === 'base'){
game.buttons.currentPage= 'main';
game.mode = 'space';
}
if(game.map.dist <= BASE_DIST && game.mode === 'space'){
poolMod.setActiveStateForAll(game.shots, false);
poolMod.setActiveStateForAll(game.shots, false);
game.buttons.currentPage = 'main';
game.mode = 'base';
}
if(game.mode === 'space'){
updateBlocks(game, secs, state);
updateShots(game, secs, state);
}
updateEnergy(game, secs);
if(game.ship.hp.current < game.ship.hp.max && game.ship.energy.current > ENERGY_AUTOHEAL_COST * secs){
game.ship.energy.current -= ENERGY_AUTOHEAL_COST * secs;
autoHealObject(game.ship, secs);
}
};
var buttonCheck = function(button, pos){
if(utils.distance(button.x, button.y, pos.x - 160, pos.y - 120) <= button.r){
return true;
}
return false;
};
api.checkButtons = function(game, pos, e){
var buttons_mode = game.buttons[game.mode],
i;
if(buttons_mode){
i = Object.keys(buttons_mode[game.buttons.currentPage]).length;
while(i--){
button = buttons_mode[game.buttons.currentPage][i];
if(buttonCheck(button, pos)){
button.onClick(game, button, e);
break;
}
}
}
};
api.updateButtons = updateButtons;
return api;
}());