Created
November 7, 2010 06:56
-
-
Save zbanks/665991 to your computer and use it in GitHub Desktop.
http://pivotfinland.com/frozendefence/ Uncondensed source
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function randomChoice(arr) { | |
return arr[Math.floor(Math.random() * arr.length)]; | |
} | |
function randint(min, max) { | |
return Math.floor(Math.random() * (max - min + 1)) + min; | |
} | |
function drawCircleANotFilled(ctx, x, y, radius, width, color) { | |
ctx.beginPath(); | |
ctx.arc(x, y, radius, 0, Math.PI * 2, true); | |
ctx.closePath(); | |
ctx.strokeStyle = "rgba(" + color + ")"; | |
ctx.lineWidth = width; | |
ctx.stroke(); | |
} | |
function drawCircleA(ctx, x, y, radius, color) { | |
ctx.fillStyle = "rgba(" + color + ")"; | |
ctx.beginPath(); | |
ctx.arc(x, y, radius, 0, Math.PI * 2, true); | |
ctx.closePath(); | |
ctx.fill(); | |
} | |
function drawCircle(ctx, x, y, radius, color) { | |
ctx.fillStyle = "rgb(" + color + ")"; | |
ctx.beginPath(); | |
ctx.arc(x, y, radius, 0, Math.PI * 2, true); | |
ctx.closePath(); | |
ctx.fill(); | |
} | |
function drawLine(ctx, x1, y1, x2, y2, width, color) { | |
ctx.strokeStyle = "rgb(" + color + ")"; | |
ctx.lineWidth = width; | |
ctx.beginPath(); | |
ctx.moveTo(x1, y1); | |
ctx.lineTo(x2, y2); | |
ctx.stroke(); | |
ctx.closePath(); | |
if (width > 1) { | |
drawCircle(ctx, x1, y1, width / 2, color); | |
drawCircle(ctx, x2, y2, width / 2, color); | |
} | |
} | |
function arrayWithoutDead(arr, value) { | |
u = []; | |
$.each(arr, function (i, o) { | |
if (o.dead !== true) { | |
u.push(o); | |
} | |
}); | |
return u; | |
} | |
function arrayWithout(arr, value) { | |
u = []; | |
$.each(arr, function (i, o) { | |
if (o != value) { | |
u.push(o); | |
} | |
}); | |
return u; | |
} | |
function getAngle(pos1, pos2) { | |
return 90 - Math.atan2(pos2[1] - pos1[1], pos2[0] - pos1[0]) / (Math.PI / 180); | |
} | |
if (!window.console) { | |
window.console = {}; | |
window.console.log = function (a) { | |
return; | |
}; | |
} | |
document.getElementById('tdTextSpan').innerHTML = 'Loading jQuery'; | |
function getTime() { | |
return (new Date()).getTime(); | |
} | |
function directorHelper() { | |
director.checkIfLevelDone(); | |
setTimeout(directorHelper, 500); | |
} | |
var showNoteTimer; | |
function showNote(text, time) { | |
if (time === undefined) { | |
time = 3000; | |
} | |
$('#tdNote').text(text); | |
$('#tdNote').fadeIn('fast'); | |
if (time > 0) { | |
showNoteTimer = setTimeout("$('#tdNote').hide();", time); | |
} | |
} | |
function loadFromCookie() { | |
if ($.cookie('frozendefence') !== null) { | |
var a = jQuery.parseJSON($.cookie('frozendefence')); | |
console.log(a); | |
$('#tdPlayerName').attr('value', a['playerName']); | |
gameSettings = a['gameSettings']; | |
personalScores = a['personalScores']; | |
} else { | |
personalScores = {} | |
gameSettings = { | |
'playerName': 'Player', | |
'gameSettings': {} | |
} | |
} | |
if (!('autoQuality' in gameSettings)) { | |
gameSettings['autoQuality'] = true; | |
} | |
if (!('particles' in gameSettings)) { | |
gameSettings['particles'] = true; | |
} | |
if (!('dispersion' in gameSettings)) { | |
gameSettings['dispersion'] = true; | |
} | |
} | |
function saveToCookie() { | |
a = { | |
playerName: $('#tdPlayerName').attr('value'), | |
gameSettings: gameSettings, | |
personalScores: personalScores | |
}; | |
$.cookie('frozendefence', JSON.stringify(a), { | |
expires: 365 * 100 | |
}); | |
} | |
function Director() { | |
this.difficulty = 1; | |
this.level = 1; | |
this.levelData = {}; | |
this.creepTimer = 0; | |
this.levelData[1] = [1000, 0.25, 3, 30, 500]; | |
this.levelData[2] = [200, 1, 40, 45, 600]; | |
this.levelData[3] = [100, 1, 40, 56, 700]; | |
for (var mapId = 4; mapId <= 500; mapId++) { | |
var hp = Math.round(30 + (mapId - 1) * (20 * Math.pow(1.06, mapId - 4))); | |
if (mapId >= 100) { | |
hp = hp * Math.pow(1.05, mapId - 100); | |
} | |
if (mapId >= 200) { | |
hp = hp * Math.pow(1.1, mapId - 200); | |
} | |
if (mapId >= 300) { | |
hp = hp * Math.pow(1.2, mapId - 300); | |
} | |
if (mapId >= 400) { | |
hp = hp * Math.pow(1.5, mapId - 400); | |
} | |
var modAmount = 40; | |
var money = 700 + 100 * (mapId - 3); | |
var modMapId = (mapId - 4) % 10; | |
if (map_id == 'perfection') money = 0; | |
if (modMapId === 0) this.levelData[mapId] = [100, 1, modAmount, hp, money]; | |
if (modMapId === 1) this.levelData[mapId] = [70, 2, modAmount, hp / 2, money]; | |
if (modMapId === 2) this.levelData[mapId] = [200, 1, modAmount / 2, hp * 3, money]; | |
if (modMapId === 3) this.levelData[mapId] = [1000, 1, modAmount / 10, hp * 10, money]; | |
if (modMapId === 4) this.levelData[mapId] = [1000, 1, 3, hp * 10, money]; | |
if (modMapId === 5) this.levelData[mapId] = [50, 4, modAmount * 3, hp / 2, money]; | |
if (modMapId === 6) this.levelData[mapId] = [100, 1, modAmount, hp, money]; | |
if (modMapId === 7) this.levelData[mapId] = [1000, 1, 1, hp * 20, money]; | |
if (modMapId === 8) this.levelData[mapId] = [50, 7, modAmount * 3, hp / 3, money]; | |
if (modMapId === 9) this.levelData[mapId] = [100, 0.5, modAmount, hp * 2, money]; | |
} | |
if (map_id == 'perfection') { | |
this.levelData[1] = [1000, 0.25, 0, 30, 0]; | |
this.levelData[2] = [200, 1, 40, 45, 0]; | |
this.levelData[3] = [100, 1, 40, 56, 0]; | |
} | |
console.log(this.levelData) | |
this.lastSummon = tickTimerLast; | |
this.creepsSummoned = 0; | |
this.checkIfLevelDone = function () { | |
if (map_id == 'perfection' && this.level == 1) { | |
return; | |
} | |
var count = 0; | |
$.each(objects, function (i, o) { | |
if (o.objectType == 'creep') { | |
count += 1; | |
return; | |
} | |
}); | |
if (count === 0) { | |
if (this.creepsSummoned >= this.levelData[this.level][2]) { | |
this.creepTimer += 1; | |
if (this.creepTimer <= 2) return; | |
this.nextLevel(); | |
this.creepTimer = 0; | |
} | |
} | |
}; | |
this.nextLevel = function () { | |
this.level = this.level + 1; | |
this.lastSummon = tickTimerLast; | |
this.creepsSummoned = 0; | |
console.log("Next level!"); | |
updateGUI(); | |
}; | |
this.newcreep = function () { | |
for (var x = 0; x < 15; x++) { | |
for (var y = 0; y < 15; y++) { | |
if (gameMap[x][y] == 'c') { | |
var o = new Creep(); | |
o.x = x * 32 + 32 / 2; | |
o.y = y * 32 + 32 / 2; | |
o.speed = this.levelData[this.level][1] + randint(0, 10) / 10; | |
o.hp = Math.round(this.levelData[this.level][3] * this.difficulty); | |
objects.push(o); | |
particleCircles.push([o.x, o.y, 30, "230,0,0,0.1"]); | |
this.creepsSummoned += 1; | |
} | |
} | |
} | |
}; | |
this.update = function () { | |
if (this.level == 1) { | |
towers = false; | |
$.each(objects, function (i, o) { | |
if (o.objectType == 'tower') { | |
towers = true; | |
return; | |
} | |
}); | |
if (towers == false) return; | |
} | |
if (this.creepsSummoned < this.levelData[this.level][2] && getTime() > this.lastSummon + this.levelData[this.level][0]) { | |
this.lastSummon = getTime(); | |
this.newcreep(); | |
} | |
}; | |
this.creepHP = function () { | |
return Math.round(this.levelData[this.level][3]); | |
} | |
this.creepMoney = function () { | |
return Math.round(this.levelData[this.level][4] / this.levelData[this.level][2]); | |
}; | |
this.allCreepsSummoned = function () { | |
if (this.creepsSummoned >= this.levelData[this.level][2]) { | |
return true; | |
} else { | |
return false; | |
} | |
}; | |
} | |
function nearestCreep(x, y, maxDist) { | |
var minDist = 99999999999999999999999999; | |
var pos = false; | |
$.each(objects, function (i, o) { | |
if (o.objectType == 'creep') { | |
dist = Math.pow(o.x - x, 2) + Math.pow(o.y - y, 2); | |
if (dist < minDist) { | |
minDist = dist; | |
pos = o; | |
} | |
} | |
}); | |
if (minDist > Math.pow(maxDist, 2)) { | |
return false; | |
} | |
if (minDist == 99999999999999999999999999) { | |
return false; | |
} | |
else { | |
return pos; | |
} | |
} | |
function creepIn(x, y, maxDist) { | |
var position = false; | |
$.each(objects, function (i, o) { | |
if (o.objectType == 'creep') { | |
dist = Math.pow(o.x - x, 2) + Math.pow(o.y - y, 2); | |
if (dist < Math.pow(maxDist, 2)) { | |
position = o; | |
return; | |
} | |
} | |
}); | |
return position; | |
} | |
scoreAdvisor = function (s, m) { | |
return crc32(picture_of_a_cat + '?' + s + '|' + m); | |
}; | |
function Bullet() { | |
this.objectType = 'bullet'; | |
this.x = 32 * 7; | |
this.y = 32 * 5; | |
this.angle = 40; | |
this.speed = 5; | |
this.hpHurt = 100; | |
this.dead = false; | |
this.color = "72,127,183"; | |
this.draw = function (ctx) { | |
drawCircle(ctx, this.x, this.y, 5, this.color); | |
}; | |
this.update = function (ctx) { | |
this.x += Math.sin(this.angle * Math.PI / 180) * this.speed; | |
this.y += Math.cos(this.angle * Math.PI / 180) * this.speed; | |
if (this.x > 700 || this.y > 700 || this.x < 0 || this.y < 0) { | |
this.dead = true; | |
objects = arrayWithoutDead(objects); | |
return; | |
} | |
me = this; | |
$.each(objects, function (i, o) { | |
if (o.objectType == 'creep') { | |
dist = Math.sqrt(Math.pow(o.x - me.x, 2) + Math.pow(o.y - me.y, 2)); | |
if (dist <= 30) { | |
o.hp -= me.hpHurt; | |
me.dead = true; | |
objects = arrayWithoutDead(objects); | |
} | |
} | |
}); | |
}; | |
} | |
function WaterTower() { | |
this.objectName = 'watertower'; | |
this.objectType = 'tower'; | |
this.level = 1; | |
this.x = 32 * 7; | |
this.y = 32 * 7; | |
this.lastShoot = 0; | |
this.lock = false; | |
this.dead = false; | |
this.upgradePrice = function (lvl) { | |
if (lvl === undefined) lvl = this.level; | |
return Math.round(500 * Math.pow(1.55, lvl)); | |
}; | |
this.getShootDist = function (lvl) { | |
if (lvl === undefined) lvl = this.level; | |
return Math.min(140, 75 + 5 * lvl); | |
} | |
this.getShootTime = function (lvl) { | |
if (lvl === undefined) lvl = this.level; | |
return Math.max(300, 405 - 5 * lvl); | |
} | |
this.getDamage = function (lvl) { | |
if (lvl === undefined) lvl = this.level; | |
return 135 * (((1 - Math.pow(1.55, lvl))) / (1 - 1.55)) * Math.pow(1.1, lvl - 1); | |
} | |
this.getDPS = function (lvl) { | |
return this.getDamage(lvl) / (this.getShootTime(lvl) / 1000); | |
} | |
this.draw = function (ctx) { | |
p = [this.x, this.y]; | |
ctx.drawImage(document.getElementById('tdImageWater'), p[0], p[1]); | |
for (var i = 1; i <= Math.min(4, (this.level - 1)); i++) { | |
drawCircleA(ctx, p[0] + 7 + 5 * (i - 1), p[1] + 7, 2, "225,225,225,0.4"); | |
} | |
}; | |
this.drawBuild = function (ctx) { | |
drawCircleA(ctx, this.x + 15, this.y + 15, this.getShootDist(), "255,255,255,0.3"); | |
drawCircleANotFilled(ctx, this.x + 15, this.y + 15, this.getShootDist(), 1, "30,30,30,0.5"); | |
smallSin2 = this.getShootDist() * (((getTime() / 8) % 100) / 100) | |
drawCircleANotFilled(ctx, this.x + 15, this.y + 15, smallSin2, 1, "30,30,30,0.2"); | |
this.draw(ctx); | |
}; | |
this.drawSelect = function (ctx) { | |
this.drawBuild(ctx); | |
this.draw(ctx); | |
ctx.fillStyle = "rgb(30,30,30)"; | |
ctx.font = defaultFont; | |
ctx.fillText("Level " + this.level, this.x - 1, this.y + 45); | |
}; | |
this.update = function (ctx) { | |
shootTime = this.getShootTime(); | |
shootDist = this.getShootDist(); | |
if (tickTimerLast > this.lastShoot + shootTime) { | |
this.lastShoot = tickTimerLast; | |
if (this.lock === false || this.lock.dead === true || Math.sqrt(Math.pow(this.lock.x - this.x, 2) + Math.pow(this.lock.y - this.y, 2)) > shootDist) { | |
this.lock = nearestCreep(this.x + 16, this.y + 16, shootDist); | |
} | |
if (this.lock !== false) { | |
b = new Bullet(); | |
b.x = this.x + 16; | |
b.y = this.y + 16; | |
b.speed = 5; | |
b.hpHurt = this.getDamage(); | |
angle = getAngle([this.x + 16, this.y + 16], [this.lock.x, this.lock.y]); | |
b.angle = angle; | |
objects.push(b); | |
particleCircles.push([b.x, b.y, shootDist, "221,230,239,0.3"]); | |
} | |
} | |
} | |
} | |
function GatlingTower() { | |
this.objectName = 'gatlingtower'; | |
this.objectType = 'tower'; | |
this.level = 1; | |
this.x = 32 * 7; | |
this.y = 32 * 7; | |
this.lastShoot = 0; | |
this.lock = false; | |
this.dead = false; | |
this.upgradePrice = function (lvl) { | |
if (lvl === undefined) lvl = this.level; | |
return Math.round(600 * Math.pow(1.55, this.level)); | |
}; | |
this.getShootDist = function (lvl) { | |
if (lvl === undefined) lvl = this.level; | |
return Math.min(180, 100 + 7 * this.level); | |
} | |
this.getShootTime = function (lvl) { | |
if (lvl === undefined) lvl = this.level; | |
return Math.max(60, 0.25 * 405 - 3 * this.level); | |
} | |
this.getDamage = function (lvl) { | |
if (lvl === undefined) lvl = this.level; | |
return 37 * (((1 - Math.pow(1.55, lvl))) / (1 - 1.55)) * Math.pow(1.1, lvl - 1); | |
} | |
this.getDPS = function (lvl) { | |
return this.getDamage(lvl) / (this.getShootTime(lvl) / 1000); | |
} | |
this.draw = function (ctx) { | |
p = [this.x, this.y]; | |
ctx.drawImage(document.getElementById('tdImageGatlingTower'), p[0], p[1]); | |
for (var i = 1; i <= Math.min(4, (this.level - 1)); i++) { | |
drawCircleA(ctx, p[0] + 7 + 5 * (i - 1), p[1] + 7, 2, "225,225,225,0.4"); | |
} | |
}; | |
this.drawBuild = function (ctx) { | |
drawCircleA(ctx, this.x + 15, this.y + 15, this.getShootDist(), "255,255,255,0.3"); | |
drawCircleANotFilled(ctx, this.x + 15, this.y + 15, this.getShootDist(), 1, "30,30,30,0.5"); | |
smallSin2 = this.getShootDist() * (((getTime() / 8) % 100) / 100) | |
drawCircleANotFilled(ctx, this.x + 15, this.y + 15, smallSin2, 1, "30,30,30,0.2"); | |
this.draw(ctx); | |
}; | |
this.drawSelect = function (ctx) { | |
this.drawBuild(ctx); | |
this.draw(ctx); | |
ctx.fillStyle = "rgb(30,30,30)"; | |
ctx.font = defaultFont; | |
ctx.fillText("Level " + this.level, this.x - 1, this.y + 45); | |
}; | |
this.update = function (ctx) { | |
shootTime = this.getShootTime(); | |
shootDist = this.getShootDist(); | |
if (tickTimerLast > this.lastShoot + shootTime) { | |
this.lastShoot = tickTimerLast; | |
if (this.lock === false || this.lock.dead === true || Math.sqrt(Math.pow(this.lock.x - this.x, 2) + Math.pow(this.lock.y - this.y, 2)) > shootDist) { | |
this.lock = nearestCreep(this.x + 16, this.y + 16, shootDist); | |
} | |
if (this.lock !== false) { | |
b = new Bullet(); | |
b.x = this.x + 16; | |
b.y = this.y + 16; | |
b.speed = 2; | |
b.color = "21,189,45"; | |
b.hpHurt = this.getDamage(); | |
angle = getAngle([this.x + 16, this.y + 16], [this.lock.x, this.lock.y]); | |
b.angle = angle; | |
objects.push(b); | |
} | |
} | |
} | |
} | |
function LaserTower() { | |
this.objectName = 'lasertower'; | |
this.objectType = 'tower'; | |
this.level = 1; | |
this.x = 32 * 7; | |
this.y = 32 * 7; | |
this.lastShoot = 0; | |
this.lock = false; | |
this.dead = false; | |
this.upgradePrice = function (lvl) { | |
if (lvl === undefined) lvl = this.level; | |
return Math.round(1100 * Math.pow(1.55, lvl)); | |
}; | |
this.getShootDist = function (lvl) { | |
if (lvl === undefined) lvl = this.level; | |
return Math.min(250, 105 + 10 * lvl); | |
} | |
this.getDamage = function (lvl) { | |
if (lvl === undefined) lvl = this.level; | |
return 6 * (((1 - Math.pow(1.55, lvl))) / (1 - 1.55)) * Math.pow(1.1, lvl - 1); | |
} | |
this.getDPS = function (lvl) { | |
return this.getDamage(lvl) / 0.016 | |
} | |
this.draw = function (ctx) { | |
p = [this.x, this.y]; | |
ctx.drawImage(document.getElementById('tdImageGuidedLaser'), p[0], p[1]); | |
if (this.lock !== false) { | |
drawLine(ctx, p[0] + 15, p[1] + 15, this.lock.x, this.lock.y, (5 + Math.min(4, this.level)), "220,209,73"); | |
} | |
for (var i = 1; i <= Math.min(4, (this.level - 1)); i++) { | |
drawCircleA(ctx, p[0] + 7 + 5 * (i - 1), p[1] + 7, Math.round((5 + Math.min(4, this.level)) / 2), "225,225,225,0.4"); | |
} | |
}; | |
this.drawBuild = function (ctx) { | |
drawCircleA(ctx, this.x + 15, this.y + 15, this.getShootDist() - 5, "255,255,255,0.3"); | |
drawCircleANotFilled(ctx, this.x + 15, this.y + 15, this.getShootDist() - 5, 1, "30,30,30,0.5"); | |
smallSin2 = this.getShootDist() * (((getTime() / 8) % 100) / 100) | |
drawCircleANotFilled(ctx, this.x + 15, this.y + 15, smallSin2, 1, "30,30,30,0.2"); | |
this.draw(ctx); | |
}; | |
this.drawSelect = function (ctx) { | |
this.drawBuild(ctx); | |
this.draw(ctx); | |
ctx.fillStyle = "rgb(30,30,30)"; | |
ctx.font = defaultFont; | |
ctx.fillText("Level " + this.level, this.x - 1, this.y + 45); | |
}; | |
this.update = function (ctx) { | |
shootDist = this.getShootDist(); | |
if (this.lock === false || this.lock.dead === true || Math.sqrt(Math.pow(this.lock.x - this.x, 2) + Math.pow(this.lock.y - this.y, 2)) > shootDist) { | |
this.lock = nearestCreep(this.x, this.y, shootDist); | |
} | |
if (this.lock !== false) { | |
this.lock.hp -= this.getDamage(); | |
} | |
} | |
} | |
var lol; | |
function ShakeTower() { | |
this.objectName = 'shaketower'; | |
this.objectType = 'tower'; | |
this.level = 1; | |
this.x = 32 * 7; | |
this.y = 32 * 7; | |
this.lastShoot = 0; | |
this.dead = false; | |
this.upgradePrice = function (lvl) { | |
if (lvl === undefined) lvl = this.level; | |
return Math.round(3000 * Math.pow(1.55, lvl)); | |
}; | |
this.getShootDist = function (lvl) { | |
if (lvl === undefined) lvl = this.level; | |
return Math.min(140, 80 + 5 * lvl); | |
} | |
this.getShootTime = function (lvl) { | |
if (lvl === undefined) lvl = this.level; | |
return Math.max(1000, 3020 - 20 * lvl) * 0.75; | |
} | |
this.getDamage = function (lvl) { | |
if (lvl === undefined) lvl = this.level; | |
return (3 * 378) * (((1 - Math.pow(1.55, lvl))) / (1 - 1.55)) * Math.pow(1.1, lvl - 1); | |
} | |
this.getDPS = function (lvl) { | |
return this.getDamage(lvl) / (this.getShootTime(lvl) / 1000); | |
} | |
this.draw = function (ctx) { | |
p = [this.x, this.y]; | |
ctx.drawImage(document.getElementById('tdImageShakeTower'), p[0], p[1]); | |
for (var i = 1; i <= Math.min(4, (this.level - 1)); i++) { | |
drawCircleA(ctx, p[0] + 7 + 5 * (i - 1), p[1] + 7, 2, "225,225,225,0.4"); | |
} | |
}; | |
this.drawBuild = function (ctx) { | |
drawCircleA(ctx, this.x + 15, this.y + 15, this.getShootDist(), "255,255,255,0.3"); | |
drawCircleANotFilled(ctx, this.x + 15, this.y + 15, this.getShootDist(), 1, "30,30,30,0.5"); | |
smallSin2 = this.getShootDist() * (((getTime() / 8) % 100) / 100) | |
drawCircleANotFilled(ctx, this.x + 15, this.y + 15, smallSin2, 1, "30,30,30,0.2"); | |
this.draw(ctx); | |
}; | |
this.drawSelect = function (ctx) { | |
this.drawBuild(ctx); | |
this.draw(ctx); | |
ctx.fillStyle = "rgb(30,30,30)"; | |
ctx.font = defaultFont; | |
ctx.fillText("Level " + this.level, this.x - 1, this.y + 45); | |
}; | |
this.update = function (ctx) { | |
shootDist = this.getShootDist(); | |
shootTime = this.getShootTime(); | |
shootDistPow2 = Math.pow(shootDist, 2) | |
if (tickTimerLast > this.lastShoot + shootTime) { | |
if (creepIn(this.x, this.y, shootDist - 10) !== false) { | |
distortionFields.push([this.x / 32, this.y / 32, 0, 10000]); | |
this.lastShoot = tickTimerLast; | |
particleCircles.push([this.x + 15, this.y + 15, shootDist, "64,64,64,0.1"]); | |
me = this; | |
$.each(objects, function (i, o) { | |
distPow2 = Math.pow(o.x - me.x, 2) + Math.pow(o.y - me.y, 2) | |
if (distPow2 < shootDistPow2) { | |
particleCircles.push([o.x, o.y, 40, "64,64,64,0.2"]); | |
o.hp -= me.getDamage(); | |
} | |
}); | |
} | |
} | |
} | |
} | |
function Nuke(x, y) { | |
this.objectName = 'nuke'; | |
this.objectType = 'tower'; | |
this.level = 1; | |
this.x = x; | |
this.y = y; | |
this.dead = false; | |
this.upgradePrice = function (lvl) { | |
return 1; | |
}; | |
this.getShootDist = function (lvl) { | |
return 100; | |
} | |
this.getShootTime = function (lvl) { | |
return 1; | |
} | |
this.getDamage = function (lvl) { | |
return 10000; | |
} | |
this.getDPS = function (lvl) { | |
return this.getDamage(lvl); | |
} | |
this.draw = function (ctx) { | |
p = [this.x, this.y]; | |
ctx.drawImage(document.getElementById('tdImageNuke'), p[0], p[1]); | |
for (var i = 1; i <= Math.min(4, (this.level - 1)); i++) { | |
drawCircleA(ctx, p[0] + 7 + 5 * (i - 1), p[1] + 7, 2, "225,225,225,0.4"); | |
} | |
}; | |
this.drawSelect = function (ctx) { | |
if (this.dead == true) return; | |
shootDist = this.getShootDist(); | |
shootDistPow2 = Math.pow(this.getShootDist(), 2); | |
this.dead = true; | |
distortionFields.push([this.x / 32, this.y / 32, 0, 20000]); | |
particleCircles.push([this.x + 15, this.y + 15, shootDist, "188,47,47,0.6"]); | |
me = this; | |
$.each(objects, function (i, o) { | |
distPow2 = Math.pow(o.x - me.x, 2) + Math.pow(o.y - me.y, 2) | |
if (distPow2 < shootDistPow2) { | |
particleCircles.push([o.x, o.y, 40, "64,64,64,0.2"]); | |
o.hp -= me.getDamage(); | |
} | |
}); | |
objects = arrayWithoutDead(objects); | |
}; | |
this.update = function (ctx) {} | |
} | |
function Creep() { | |
this.objectType = 'creep'; | |
this.hp = 100; | |
this.maxHp = 0; | |
this.x = 50; | |
this.y = 10; | |
this.speed = 1; | |
this.direction = 1; | |
this.radius = 7; | |
this.dead = false; | |
this.lastpos = false; | |
this.draw = function (ctx) { | |
if (this.dead === true) { | |
return; | |
} | |
drawCircle(ctx, this.x, this.y, this.radius, "220,0,0"); | |
if (this.hp > 0) { | |
ctx.fillStyle = "rgba(102,88,88,1)"; | |
ctx.fillRect(this.x - 10, this.y - 16, 20, 6); | |
ctx.fillStyle = "rgba(215,69,69,1)"; | |
width = Math.floor(18 * (this.hp / this.maxHp)); | |
if (width > 0) { | |
try { | |
ctx.fillRect(this.x - 10 + 1, this.y - 16 + 1, width, 4); | |
} catch (err) {} | |
} | |
} | |
}; | |
this.update = function (ctx) { | |
this.maxHp = Math.max(this.maxHp, this.hp); | |
a = 15; | |
xord = [Math.floor((this.x + a) / 32), Math.floor((this.y + a) / 32)]; | |
bx = this.x; | |
by = this.y; | |
if (this.direction === 0) { | |
this.x += this.speed; | |
} | |
if (this.direction === 1) { | |
this.y += this.speed; | |
} | |
if (this.direction === 2) { | |
this.x -= this.speed; | |
a = -14; | |
} | |
if (this.direction === 3) { | |
this.y -= this.speed; | |
a = -14; | |
} | |
cord = [Math.floor((this.x + a) / 32), Math.floor((this.y + a) / 32)]; | |
if (this.hp <= 0) { | |
this.dead = true; | |
money += director.creepMoney(); | |
gameScore += director.creepMoney(); | |
if (map_id == 'perfection') gameScore += director.level; | |
if ((getTime() - lastGuiUpdate) >= 80) { | |
updateGUI(); | |
} | |
distortionFields.push([this.x / 32, this.y / 32, 0, 4000]); | |
if (gameSettings['particles'] == true) { | |
particleCircles.push([this.x, this.y, 30, "230,0,0,0.2"]); | |
} | |
objects = arrayWithout(objects, this); | |
return; | |
} | |
if (cord[0] > 15 || cord[1] > 15) { | |
particleCircles.push([this.x, this.y, 60, "230,0,0,0.6"]); | |
lifes -= 1; | |
me = this; | |
this.dead = true; | |
objects = arrayWithoutDead(objects); | |
$.each(objects, function (i, o) { | |
if (o.objectType == 'creep' && o != me) { | |
distancePow2 = Math.pow(o.x - me.x, 2) + Math.pow(o.y - me.y, 2); | |
if (distancePow2 <= Math.pow(100, 2)) { | |
o.hp = 0; | |
} | |
} | |
}); | |
updateGUI(); | |
return; | |
} | |
if (this.lastpos !== false && this.lastpos[0] == this.x && this.lastpos[1] == this.y) { | |
this.hp -= 10; | |
} | |
this.lastpos = [this.x, this.y]; | |
block = gameMap[cord[0]][cord[1]]; | |
if (block == 'r') { | |
if (gameMap[xord[0]][xord[1]] == 'rd') { | |
this.direction = 1; | |
return; | |
} | |
} | |
if (block != 'r' && block != 'rd' && block != 'c' && block != '@') { | |
this.x = bx; | |
this.y = by; | |
possibleDirections = []; | |
if (gameMap[xord[0] + 1][xord[1]] == 'r') { | |
possibleDirections.push(0); | |
} | |
if (gameMap[xord[0]][xord[1] + 1] == 'r') { | |
possibleDirections.push(1); | |
} | |
if (gameMap[xord[0] - 1][xord[1]] == 'r') { | |
possibleDirections.push(2); | |
} | |
if (gameMap[xord[0]][xord[1] - 1] == 'r') { | |
possibleDirections.push(3); | |
} | |
newPossibleDirections = arrayWithout(possibleDirections, ((this.direction + 2) % 4)); | |
this.direction = randomChoice(newPossibleDirections); | |
} | |
}; | |
} | |
var tickTimerLast = 0; | |
function updateObjects() { | |
if (distortionFields.length > 0) { | |
var n = []; | |
$.each(distortionFields, function (i, o) { | |
distortionFields[i][3] -= 100; | |
if (distortionFields[i][3] > 0) { | |
n.push(distortionFields[i]); | |
} | |
}); | |
distortionFields = n; | |
} | |
if (lifes > 5 || score > 0) { | |
if (!('cheater' in runOnce)) { | |
runOnce['cheater'] = true; | |
$.ajax({ | |
url: 'frozendefence_scores.php?map_id=xiit&score=1', | |
success: function (a) {} | |
}); | |
} | |
} | |
if (guiStatus == 'select') { | |
$('#tdTowerInfo').show(); | |
$('#tdTowerInfoDMS').text(Math.round(selectedTower.getDPS())); | |
$('#tdTowerInfoDMSUpgrade').text(Math.round(selectedTower.getDPS(selectedTower.level + 1))); | |
$('#tdTowerInfoDMSPP').text(Math.round(100 * (selectedTower.getDPS() / selectedTower.upgradePrice(selectedTower.level - 1))) / 100); | |
} else { | |
$('#tdTowerInfo').hide(); | |
} | |
if (lifes <= 0 || guiStatus == 'gameover') { | |
$('#tdNote').hide(); | |
if (guiStatus != 'gameover') updateGUI(); | |
guiStatus = 'gameover'; | |
if (ajaxScoresRequested === false) { | |
ajaxScoresRequested = true; | |
showScores(map_id); | |
} | |
timerUpdateObjects = setTimeout(updateObjects, 15); | |
return; | |
} | |
if (!('victory' in runOnce) && winningConditions !== undefined && winningConditions() === true) { | |
$('#endGameButton').animate({ | |
backgroundColor: '#09d926' | |
}, 1500); | |
if (runAfterWinning !== undefined) runAfterWinning(); | |
runOnce['victory'] = true; | |
} | |
if (hasBrokenPersonalScore === false && map_id in personalScores && gameScore > personalScores[map_id]) { | |
hasBrokenPersonalScore = true; | |
personalScores[map_id] = gameScore; | |
showNote('New personal high score! ' + gameScore); | |
saveToCookie(); | |
} | |
director.update(); | |
if ((getTime() - tickTimerLast) >= 16 * 30) { | |
tickTimerLast = getTime(); | |
} | |
while (tickTimerLast <= getTime()) { | |
$.each(objects, function (i, o) { | |
o.update(); | |
}); | |
tickTimerLast += 16; | |
} | |
timerUpdateObjects = setTimeout(updateObjects, 15); | |
} | |
function addDistortion(x, y) { | |
if (distortionFields.length > 0) { | |
var factor = Math.sin(getTime() / 100); | |
$.each(distortionFields, function (i, o) { | |
var distance = Math.sqrt(Math.pow(x - o[0], 2) + Math.pow(y - o[1], 2)); | |
var powerful = o[3] / 10000; | |
var force = (2 / Math.pow((distance) + 2, 1.5)) * factor * powerful; | |
if (force > 1 / 32 || force < -1 / 32) { | |
var angle = getAngle([o[0], o[1]], [x, y]); | |
x = o[0] + Math.sin(angle * Math.PI / 180) * (distance + force); | |
y = o[1] + Math.cos(angle * Math.PI / 180) * (distance + force); | |
} | |
}); | |
} | |
return [x, y]; | |
} | |
var tutorialBuildATowerHide = false; | |
function updateCanvas() { | |
fps += 1; | |
var c = document.getElementById("tdGame"); | |
var ctx = c.getContext("2d"); | |
ctx.fillStyle = "rgb(220,220,220)"; | |
ctx.fillRect(0, 0, 480, 480); | |
for (var x = 0; x < 15; x++) { | |
for (var y = 0; y < 15; y++) { | |
if (gameSettings['dispersion'] == true) { | |
p = addDistortion(x, y); | |
} else { | |
p = [x, y]; | |
distortionFields = []; | |
} | |
if (gameMap[x][y] === '' || gameMap[x][y] === null || gameMap[x][y] === undefined) { | |
ctx.fillStyle = "rgb(240,240,240)"; | |
ctx.fillRect((p[0]) * 32, (p[1]) * 32, 31, 31); | |
} | |
if (gameMap[x][y] === 'r' || gameMap[x][y] === 'c' || gameMap[x][y] == '@') { | |
ctx.fillStyle = "rgb(218," + Math.floor(229 + 5 * Math.sin(getTime() / 1000)) + ",216)"; | |
ctx.fillRect((p[0]) * 32, (p[1]) * 32, 31, 31); | |
} | |
if (gameMap[x][y] === '-') { | |
ctx.drawImage(document.getElementById('tdImageNotAllowed'), (p[0]) * 32, (p[1]) * 32); | |
} | |
} | |
} | |
n = []; | |
$.each(particleCircles, function (i, o) { | |
if (particleCircles[i][2] > 0) { | |
drawCircleA(ctx, o[0], o[1], o[2], o[3]); | |
particleCircles[i][2] -= 1; | |
n.push(o); | |
} | |
}); | |
particleCircles = n; | |
$.each(objects, function (i, o) { | |
o.draw(ctx); | |
}); | |
if (guiStatus == 'build') { | |
var x = Math.round((mouseX - 15) / 32) * 32; | |
var y = Math.round((mouseY - 15) / 32) * 32; | |
var distance = 0; | |
if (buildItem == 'WaterTower') { | |
distance = (new WaterTower()).getShootDist(); | |
ctx.drawImage(document.getElementById('tdImageWater'), x, y); | |
} else if (buildItem == 'LaserTower') { | |
distance = (new LaserTower()).getShootDist(); | |
ctx.drawImage(document.getElementById('tdImageGuidedLaser'), x, y); | |
} else if (buildItem == 'ShakeTower') { | |
distance = (new ShakeTower()).getShootDist(); | |
ctx.drawImage(document.getElementById('tdImageShakeTower'), x, y); | |
} else if (buildItem == 'GatlingTower') { | |
distance = (new GatlingTower()).getShootDist(); | |
ctx.drawImage(document.getElementById('tdImageGatlingTower'), x, y); | |
} | |
drawCircleA(ctx, x + 15, y + 15, distance, "255,255,255,0.3"); | |
drawCircleANotFilled(ctx, x + 15, y + 15, distance, 1, "30,30,30,0.5"); | |
smallSin2 = distance * (((getTime() / 8) % 100) / 100) | |
drawCircleANotFilled(ctx, x + 15, y + 15, smallSin2, 1, "30,30,30,0.2"); | |
ctx.fillStyle = "rgb(30,30,30)"; | |
ctx.font = defaultFont; | |
ctx.fillText("Click to place a tower", x - 30, y + 45); | |
} | |
if (guiStatus == 'select') { | |
selectedTower.drawSelect(ctx); | |
} | |
if (director.level == 1) { | |
$.each(objects, function (i, o) { | |
if (o.objectType == 'creep') { | |
ctx.fillStyle = "rgb(116,6,6)"; | |
ctx.font = defaultFont; | |
ctx.fillText("Shoot me", o.x - 22, o.y + 22); | |
} | |
}); | |
} | |
if ('victory' in runOnce) { | |
ctx.font = '15px Tahoma'; | |
ctx.fillStyle = "#076414"; | |
ctx.fillText("You have completed this level. Congratulations!", 20, 480 - 25); | |
} | |
if (guiStatus == 'gameover') { | |
ctx.font = '40px Tahoma'; | |
ctx.fillStyle = "rgb(30,30,30)"; | |
if (winningConditions !== undefined && winningConditions() == true) { | |
ctx.fillStyle = "rgb(60,30,30)"; | |
s = ctx.measureText("VICTORY!!!"); | |
ctx.fillText("VICTORY!!!", 480 / 2 - Math.round(s.width / 2), 480 / 2 - 20 / 2 + Math.sin(getTime() / 100) * 5); | |
} else { | |
s = ctx.measureText("Game Over!"); | |
ctx.fillStyle = "rgb(30,30,30)"; | |
ctx.fillText("Game Over!", 480 / 2 - Math.round(s.width / 2), 480 / 2 - 20 / 2 + Math.sin(getTime() / 100) * 5); | |
} | |
ctx.fillStyle = "rgb(30,30,30)"; | |
ctx.font = '30px Tahoma'; | |
s = ctx.measureText(gameScore); | |
ctx.fillText(gameScore, 480 / 2 - Math.round(s.width / 2), 480 / 2 + 45 - 15 / 2 + Math.sin(getTime() / 100) * 5); | |
$.each(objects, function (i, o) { | |
if (o.objectType == 'creep') { | |
radius = (o.x + o.y + 1234 * i + getTime() / 20) % 80 | |
drawCircleANotFilled(ctx, o.x, o.y, radius, 2, "140,140,140,0.2"); | |
} | |
}); | |
} else { | |
ctx.font = '10px Tahoma'; | |
ctx.fillStyle = "rgba(0,0,0,0.4)"; | |
s = ctx.measureText("VICTORY!!!"); | |
ctx.fillText("(C) 2010 Frozenball <[email protected]>", 15, 480 - 15); | |
s = ctx.measureText("Creep HP: " + director.creepHP()); | |
ctx.fillText("Creep HP: " + director.creepHP(), 480 - s.width - 15, 480 - 15); | |
} | |
if (gameSettings['autoQuality'] == true) { | |
if (!('autoQualityInc' in runOnce)) { | |
runOnce['autoQualityInc'] = 0; | |
} | |
if (last_fps <= 50) { | |
runOnce['autoQualityInc'] += 1; | |
if (runOnce['autoQualityInc'] >= 100 && gameSettings['dispersion'] == true) { | |
gameSettings['dispersion'] = false; | |
runOnce['autoQualityInc'] = 0; | |
} | |
if (runOnce['autoQualityInc'] >= 800 && gameSettings['particles'] == true) { | |
gameSettings['particles'] = false; | |
runOnce['autoQualityInc'] = 0; | |
} | |
} else { | |
runOnce['autoQualityInc'] = Math.max(0, runOnce['autoQualityInc'] - 0.25); | |
} | |
} | |
ctx.fillStyle = "rgb(30,30,30)"; | |
ctx.font = defaultFont; | |
ctx.fillText("FPS " + last_fps + " Objects: " + objects.length + " Particles: " + particleCircles.length, 10, 20); | |
timerUpdateCanvas = setTimeout(updateCanvas, 13); | |
} | |
var lastGuiUpdate; | |
var timerUpdateCanvas = false; | |
var timerUpdateObjects = false; | |
function updateGUI() { | |
lastGuiUpdate = getTime(); | |
if (maxLevel > 0) { | |
$('#tdLevel').html('Level ' + director.level + '/' + (maxLevel - 1)); | |
} else { | |
$('#tdLevel').html('Level ' + director.level); | |
} | |
$('#tdMoney').text(money + ' e'); | |
$('#tdScore').text(gameScore); | |
if (map_id == 'perfection' && director.level == 1) { | |
$('#nextWaveButton').css({ | |
opacity: 1 | |
}); | |
} else { | |
if (director.allCreepsSummoned() === true) { | |
$('#nextWaveButton').css({ | |
opacity: 1 | |
}); | |
} else { | |
$('#nextWaveButton').css({ | |
opacity: 0.1 | |
}); | |
} | |
} | |
if (guiStatus == 'build') { | |
$('#tdBuild').css({ | |
opacity: 0.5 | |
}); | |
} else { | |
$('#tdBuild').css({ | |
opacity: 1 | |
}); | |
} | |
$('#tdBuild tr').each(function (i, e) { | |
price = $(this).attr('data-price'); | |
if (price > money) { | |
$(this).css({ | |
opacity: 0.3 | |
}); | |
} else { | |
$(this).css({ | |
opacity: 1 | |
}); | |
} | |
}); | |
$('#tdLifes').html(''); | |
for (var i = 1; i <= lifes; i++) { | |
$('#tdLifes').append('<img src="' + $('#tdImageHeart').attr('src') + '" alt="" style="margin-right:1px;">'); | |
} | |
if (guiStatus == 'select') { | |
$('#sellButton').css({ | |
opacity: 1 | |
}); | |
if (money >= selectedTower.upgradePrice()) { | |
$('#upgradeButton').css({ | |
opacity: 1 | |
}); | |
} else { | |
$('#upgradeButton').css({ | |
opacity: 0.1 | |
}); | |
} | |
$('#upgradeButton').text('Upgrade for ' + selectedTower.upgradePrice() + 'e'); | |
$('#sellButton').text('Sell for ' + Math.round(selectedTower.upgradePrice() / 2) + 'e'); | |
} else { | |
$('#upgradeButton,#sellButton').css({ | |
opacity: 0.1 | |
}); | |
$('#upgradeButton').text('Upgrade'); | |
$('#sellButton').text('Sell'); | |
} | |
} | |
function nextWave() { | |
if (map_id == 'perfection' && director.level == 1) { | |
director.nextLevel(); | |
return; | |
} | |
if (director.allCreepsSummoned() === true) { | |
director.nextLevel(); | |
} | |
} | |
function upgrade() { | |
if (guiStatus == 'select') { | |
if (money < Math.round(selectedTower.upgradePrice())) { | |
return; | |
} | |
else { | |
money -= Math.round(selectedTower.upgradePrice()); | |
selectedTower.level += 1; | |
updateGUI(); | |
} | |
} | |
} | |
function sell() { | |
if (guiStatus == 'select') { | |
money += Math.round(selectedTower.upgradePrice() / 2); | |
guiStatus = ''; | |
objects = arrayWithout(objects, selectedTower) | |
updateGUI(); | |
} | |
} | |
function parseMap(lvlstring) { | |
lines = lvlstring.split("\n"); | |
$.each(lines, function (y, line) { | |
for (var x = 0; x < line.length; x++) { | |
chr = line[x]; | |
if (chr == 'c') { | |
gameMap[x][y] = 'c'; | |
} | |
else if (chr == '#') { | |
gameMap[x][y] = 'r'; | |
} | |
else if (chr == 'D') { | |
gameMap[x][y] = 'rd'; | |
} | |
else if (chr == '-') { | |
gameMap[x][y] = '-'; | |
} | |
else if (chr == '@') { | |
gameMap[x][y] = '@'; | |
} | |
else if (chr == 'N') { | |
gameMap[x][y] = undefined; | |
} | |
else if (chr == '.') { | |
gameMap[x][y] = undefined; | |
} | |
else { | |
console.log('Invalid chr ' + chr + ' at ' + x + 'x' + y + ' in line: ' + line); | |
} | |
} | |
}); | |
} | |
function showMenu() { | |
$('.tdBox').hide(); | |
$('#tdMenuSelect').show(); | |
$('.tdImageLink').css({ | |
opacity: 0.8 | |
}); | |
$('.tdImageLink').hover(function (e) { | |
$('.tdImageLink').css({ | |
opacity: 0.8 | |
}); | |
$(this).css({ | |
opacity: 1 | |
}); | |
}, function () { | |
$('.tdImageLink').css({ | |
opacity: 0.8 | |
}); | |
}); | |
} | |
function showSettings() { | |
$('.tdBox').hide(); | |
$('#tdMenuSettings').show(); | |
if (gameSettings['autoQuality'] === true) { | |
$('#tdSettingsAutoQuality').attr('checked', true); | |
} | |
if (gameSettings['particles'] === true) { | |
$('#tdSettingsParticles').attr('checked', true); | |
} | |
if (gameSettings['dispersion'] === true) { | |
$('#tdSettingsDispersion').attr('checked', true); | |
} | |
$('#tdSettingsAutoQuality,#tdSettingsParticles,#tdSettingsDispersion').click(function () { | |
gameSettings['autoQuality'] = $('#tdSettingsAutoQuality').attr('checked'); | |
gameSettings['particles'] = $('#tdSettingsParticles').attr('checked'); | |
gameSettings['dispersion'] = $('#tdSettingsDispersion').attr('checked'); | |
saveToCookie(); | |
}); | |
} | |
function showMenuCampaign() { | |
$('.tdBox').hide(); | |
$('#tdMenuCampaign').show(); | |
if (!('campaign' in gameSettings)) { | |
gameSettings['campaign'] = 0; | |
} | |
$('#tdMenuCampaign div a').addClass('notYetCompleted'); | |
$('#tdMenuCampaign div a').each(function (i, o) { | |
i = $(this).text(); | |
console.log(i); | |
if ((i - 1) <= gameSettings['campaign']) $(this).removeClass('notYetCompleted'); | |
}); | |
} | |
function playArcade() { | |
if (typeof _qag != 'undefined') _gaq.push(['_setCustomVar', 1, 'Arcade', 'Yes', 3]); | |
$('.tdBox').hide(); | |
$('#tdAll').show(); | |
gameMap = new Array(15); | |
for (var i = 0; i < 15; i++) { | |
gameMap[i] = new Array(15); | |
} | |
parseMap(mapData['arcade']); | |
map_id = 'arcade'; | |
initGame(); | |
retryFunction = playArcade; | |
winningConditions = undefined; | |
showNote('This is a tower defence game. Try building a Cannon Tower.', 6000); | |
setTimeout(function () { | |
$('#tdBuildWaterTower').effect('pulsate', { | |
times: 2 | |
}, 'slow') | |
}, 1000); | |
} | |
function playPerfection() { | |
if (typeof _qag != 'undefined') _gaq.push(['_setCustomVar', 1, 'Perfection', 'Yes', 3]); | |
$('.tdBox').hide(); | |
$('#tdAll').show(); | |
gameMap = new Array(15); | |
for (var i = 0; i < 15; i++) { | |
gameMap[i] = new Array(15); | |
} | |
parseMap(mapData['perfection']); | |
map_id = 'perfection'; | |
initGame(); | |
retryFunction = playPerfection; | |
winningConditions = undefined; | |
money = 3000 * 50; | |
director.difficulty = 3; | |
updateGUI(); | |
} | |
function playCampaign(campaign_id, reachLevel, startFunction, winningFunction) { | |
if (typeof _qag != 'undefined') _gaq.push(['_setCustomVar', 1, 'CampaignLevel', campaign_id, 3]); | |
if (gameSettings['campaign'] < (campaign_id - 1)) return; | |
$('.tdBox').hide(); | |
$('#tdAll').show(); | |
if (winningFunction === undefined) { | |
winningFunction = function () { | |
if (director.level >= reachLevel) { | |
return true; | |
} else { | |
return false; | |
} | |
}; | |
} | |
console.log('Playing campaign ' + campaign_id + ' map ' + mapData[campaign_id]); | |
gameMap = new Array(15); | |
for (var i = 0; i < 15; i++) { | |
gameMap[i] = new Array(15); | |
} | |
parseMap(mapData[campaign_id]); | |
map_id = crc32(gameMap); | |
initGame(); | |
lines = mapData[campaign_id].split("\n"); | |
$.each(lines, function (y, line) { | |
for (var x = 0; x < line.length; x++) { | |
chr = line[x]; | |
if (chr == 'N') { | |
console.log('creating a nuke at ' + (x * 32) + 'x' + (y * 32)); | |
objects.push(new Nuke(x * 32, y * 32)); | |
} | |
} | |
}); | |
retryFunction = function () { | |
playCampaign(campaign_id, reachLevel, startFunction, winningFunction); | |
}; | |
winningConditions = winningFunction; | |
runAfterWinning = function () { | |
gameSettings['campaign'] = Math.max(gameSettings['campaign'], campaign_id); | |
saveToCookie(); | |
$('#highscoreRetryButton').text('Challenges'); | |
retryFunction = function () { | |
showMenuCampaign(); | |
}; | |
}; | |
maxLevel = reachLevel; | |
if (startFunction !== undefined) startFunction(); | |
updateGUI(); | |
} | |
function initGame() { | |
fps = 0; | |
last_fps = 0; | |
objects = []; | |
director = new Director(); | |
lifes = 5; | |
score = 0; | |
particleCircles = []; | |
distortionFields = []; | |
money = 1000; | |
guiStatus = 'normal'; | |
selectedTower = false; | |
defaultFont = '10px Tahoma'; | |
difficulty = 1; | |
picture_of_a_cat = 'http://i.imgur.com/R2mf8.gif'; | |
ajaxScoresRequested = false; | |
gameScore = 0; | |
retryFunction = function () { | |
console.log('dummy'); | |
return false; | |
}; | |
winningConditions = undefined; | |
runAfterWinning = undefined; | |
maxLevel = 0; | |
hasBrokenPersonalScore = false; | |
runOnce = {}; | |
towerCosts = 0; | |
if (timerUpdateObjects !== false) { | |
clearTimeout(timerUpdateObjects); | |
} | |
if (timerUpdateCanvas !== false) { | |
clearTimeout(timerUpdateCanvas); | |
} | |
$('#tdHighscores,#tdNote').hide(); | |
$('#highscoreRetryButton').text('Retry'); | |
updateCanvas(); | |
updateObjects(); | |
directorHelper(); | |
updateGUI(); | |
$('#tdBuild tr').click(function () { | |
if (guiStatus == 'build' || guiStatus == 'gameover') return; | |
item = $(this).attr('data-build'); | |
price = $(this).attr('data-price'); | |
towerCosts = price; | |
if (price > money) { | |
showNote('You don\'t have enough money to build this tower.'); | |
return; | |
} | |
guiStatus = 'build'; | |
buildItem = item; | |
updateGUI(); | |
}); | |
mouseX = mouseY = 0; | |
$(document).mousemove(function (e) { | |
var canvasPos = $('#tdGameDiv').position(); | |
mouseX = e.pageX - canvasPos.left; | |
mouseY = e.pageY - canvasPos.top; | |
}); | |
$(function () { | |
$(this).bind("contextmenu", function (e) { | |
var canvasPos = $('#tdGameDiv').position(); | |
if (mouseX <= 640 && mouseY <= 480) { | |
guiStatus = ''; | |
e.preventDefault(); | |
} | |
}); | |
}); | |
$('#tdNote').click(function () { | |
$(this).hide(); | |
}); | |
$('#tdTowerInfo').click(function () { | |
$(this).hide(); | |
guiStatus = ''; | |
}); | |
$('#tdGame').click(function (e) { | |
var canvasPos = $('#tdGame').position(); | |
var x = Math.round((mouseX - 15) / 32) * 32; | |
var y = Math.round((mouseY - 15) / 32) * 32; | |
if (guiStatus == 'build') { | |
if (gameMap[x / 32][y / 32] !== undefined) { | |
return; | |
} | |
objectBlocks = false; | |
$.each(objects, function (i, o) { | |
if (o.objectType == 'tower') { | |
if (x == o.x && y == o.y) { | |
objectBlocks = true; | |
return; | |
} | |
} | |
}); | |
if (objectBlocks == true) return; | |
console.log('Building: ' + buildItem); | |
if (money < towerCosts) { | |
guiStatus = ''; | |
updateGUI(); | |
return; | |
} | |
money -= towerCosts; | |
if (buildItem == 'WaterTower') { | |
t = new WaterTower(); | |
} else if (buildItem == 'LaserTower') { | |
t = new LaserTower(); | |
} else if (buildItem == 'ShakeTower') { | |
t = new ShakeTower(); | |
} else if (buildItem == 'GatlingTower') { | |
t = new GatlingTower(); | |
} else { | |
alert("Invalid item: " + buildItem); | |
} | |
t.x = x; | |
t.y = y; | |
objects.push(t); | |
guiStatus = 'normal'; | |
distortionFields.push([x / 32, y / 32, 0, 10000]); | |
updateGUI(); | |
} else { | |
clickedOnATower = false; | |
$.each(objects, function (i, o) { | |
if (o.objectType == 'tower') { | |
if (x == o.x && y == o.y) { | |
console.log('Object ' + o + ' selected.'); | |
guiStatus = 'select'; | |
selectedTower = o; | |
clickedOnATower = true; | |
updateGUI(); | |
return; | |
} | |
} | |
}); | |
if (clickedOnATower == false) { | |
guiStatus = ''; | |
} | |
} | |
}); | |
$('#tdGame, #tdAll').show(); | |
} | |
function checkImagesLoaded() { | |
all_loaded = true; | |
$('#loadImages img').each(function (i, img) { | |
if (!(img.complete || img.readyState === 4)) { | |
all_loaded = false; | |
} | |
}); | |
if (all_loaded === true) { | |
$('#tdText').hide(); | |
showMenu(); | |
return; | |
} else { | |
setTimeout(checkImagesLoaded, 10); | |
} | |
} | |
function showScores(map_id) { | |
lifes = 0; | |
$.ajax({ | |
url: 'frozendefence_scores.php?map_id=' + escape(map_id) + '&show_scores=1', | |
success: function (a) { | |
$('#endGameButton').css({ | |
backgroundColor: '#3b3b3b' | |
}); | |
picture_of_a_cat = 'http://i.imgur.com/g2rve.gif'; | |
$('#tdHighscoresLoad').html(a); | |
$('#tdNote').hide(); | |
$('#tdShowYourScore').text(gameScore); | |
personalScores[map_id] = Math.max(personalScores[map_id], gameScore); | |
saveToCookie(); | |
$('#tdShowYourLevel').text(director.level); | |
$('#tdSubmitScoresButton,#tdPlayerName').css({ | |
opacity: 1 | |
}); | |
$('#tdHighscores').show(); | |
} | |
}); | |
} | |
submitScore = function () { | |
$('#tdPlayerName').attr('disabled', true); | |
$('#tdSubmitScoresButton').css({ | |
opacity: 0.4 | |
}); | |
towers = ''; | |
$.each(objects, function (i, o) { | |
if (o.objectType == 'tower') { | |
towers += o.objectName + '|' + o.x + '|' + o.y + '|' + o.level + "\n"; | |
} | |
}); | |
$.ajax({ | |
url: "frozendefence_scores.php?map_id=" + escape(map_id) + "&nick=" + escape($('#tdPlayerName').attr('value')) + "&score=" + escape(gameScore) + "&level=" + escape(director.level) + "&towers=" + escape(towers) + "&" + scoreAdvisor(gameScore, map_id), | |
success: function (a) { | |
console.log(a); | |
$('#tdSubmitScoresButton,#tdPlayerName').css({ | |
opacity: 0.1 | |
}); | |
$('#tdPlayerName').attr('disabled', false); | |
$.ajax({ | |
url: 'frozendefence_scores.php?map_id=' + escape(map_id) + '&show_scores=1', | |
success: function (a) { | |
$('#tdHighscoresLoad').html(a); | |
} | |
}); | |
} | |
}); | |
}; | |
$(document).ready(function () { | |
if ( !! document.createElement('canvas').getContext === false) { | |
$('#tdText').hide(); | |
$('#tdCanvasNotSupported').show(); | |
return; | |
} | |
fps = 0; | |
function updateFPS() { | |
last_fps = fps; | |
fps = 0; | |
setTimeout(updateFPS, 1000); | |
} | |
updateFPS(); | |
document.getElementById('tdTextSpan').innerHTML = 'Loading graphics...'; | |
loadFromCookie(); | |
checkImagesLoaded(); | |
$('#tdPlayerName').keyup(function () { | |
saveToCookie(); | |
}).change(function () { | |
saveToCookie(); | |
}); | |
return; | |
$('#tdTextSpan').text('Loading graphics'); | |
gameMap = new Array(15); | |
for (var i = 0; i < 15; i++) { | |
gameMap[i] = new Array(15); | |
} | |
gameMap[7][0] = 'c'; | |
gameMap[7][1] = 'r'; | |
for (var i = 3; i <= 11; i++) { | |
gameMap[i][2] = 'r'; | |
} | |
for (var i = 3; i <= 7; i++) { | |
gameMap[11][i] = 'r'; | |
gameMap[3][i] = 'r'; | |
} | |
for (var i = 3; i <= 11; i++) { | |
if (i != 7) { | |
gameMap[i][8] = 'r'; | |
} | |
} | |
for (var i = 9; i <= 15; i++) { | |
gameMap[8][i] = 'r'; | |
gameMap[6][i] = 'r'; | |
} | |
$('#tdTextSpan').text('Done'); | |
$('#tdText').hide(); | |
updateCanvas(); | |
updateObjects(); | |
directorHelper(); | |
updateGUI() | |
$('#tdGame, #tdAll').show(); | |
}); | |
everythingIsOk = 1; | |
mapData = []; | |
mapData[0] = undefined; | |
a = []; | |
a.push(".......c......."); | |
a.push(".......#......."); | |
a.push(".......#......."); | |
a.push(".......#......."); | |
a.push("....#######...."); | |
a.push("....#.....#...."); | |
a.push("....#.....#...."); | |
a.push("....#.....#...."); | |
a.push("....#.....#...."); | |
a.push("....#.....#...."); | |
a.push("....###.###...."); | |
a.push("......#.#......"); | |
a.push("......#.#......"); | |
a.push("......#.#......"); | |
a.push("......#.#......"); | |
a.push("......#.#......"); | |
mapData['arcade'] = a.join("\n"); | |
a = []; | |
a.push("--c---------c--"); | |
a.push("--#---------#--"); | |
a.push("--#####.#####--"); | |
a.push("......#.#......"); | |
a.push("......#.#......"); | |
a.push("......#.#......"); | |
a.push("..###########.."); | |
a.push("..#.........#.."); | |
a.push("..#.........#.."); | |
a.push("..#.........#.."); | |
a.push("..#####.#####.."); | |
a.push("......#.#......"); | |
a.push("......#.#......"); | |
a.push("......#.#......"); | |
a.push("......#.#......"); | |
a.push("......#.#......"); | |
mapData['perfection'] = a.join("\n"); | |
a = []; | |
a.push("-------c-------"); | |
a.push("-------#-------"); | |
a.push("-------#-------"); | |
a.push(".......#......."); | |
a.push(".......#......."); | |
a.push(".......#......."); | |
a.push(".......#......."); | |
a.push(".......#......."); | |
a.push(".......#......."); | |
a.push(".......#......."); | |
a.push(".......#......."); | |
a.push(".......#......."); | |
a.push(".......#......."); | |
a.push(".......#......."); | |
a.push(".......#......."); | |
a.push(".......#......."); | |
mapData[1] = a.join("\n"); | |
a = []; | |
a.push(".........--c--."); | |
a.push(".........--#--."); | |
a.push(".........--#--."); | |
a.push(".........--#--."); | |
a.push(".........--#--."); | |
a.push(".----------#--."); | |
a.push(".---------.#--."); | |
a.push(".--#########--."); | |
a.push(".--#.---------."); | |
a.push(".--#----------."); | |
a.push(".--#--........."); | |
a.push(".--#--........."); | |
a.push(".--#--........."); | |
a.push(".--#--........."); | |
a.push(".--#--........."); | |
a.push(".--#--........."); | |
mapData[2] = a.join("\n"); | |
a = []; | |
a.push("---c-----------"); | |
a.push("---#-----------"); | |
a.push("---#-----------"); | |
a.push("---#-----------"); | |
a.push("---#########---"); | |
a.push("---........#---"); | |
a.push("---........#---"); | |
a.push("---#####...#---"); | |
a.push("---#...#...#---"); | |
a.push("---#...#...#---"); | |
a.push("---#########---"); | |
a.push("-------#-------"); | |
a.push("-------#-------"); | |
a.push("-------#-------"); | |
a.push("-------#-------"); | |
a.push("-------#-------"); | |
mapData[3] = a.join("\n"); | |
a = []; | |
a.push("..c............"); | |
a.push("..#............"); | |
a.push("..#............"); | |
a.push("..#............"); | |
a.push("..#............"); | |
a.push("..###########.."); | |
a.push("............#.."); | |
a.push("..########..#.."); | |
a.push("..#NNNNNN#..#.."); | |
a.push("..#NNNNNN#..#.."); | |
a.push("..###########.."); | |
a.push(".........#....."); | |
a.push(".........#....."); | |
a.push(".........#....."); | |
a.push(".........#....."); | |
a.push(".........#....."); | |
mapData[4] = a.join("\n"); | |
a = []; | |
a.push("....c......c..."); | |
a.push("....#......#..."); | |
a.push("....#......#..."); | |
a.push("....#####..#..."); | |
a.push("........#..#..."); | |
a.push(".......#####..."); | |
a.push(".......##......"); | |
a.push(".......##......"); | |
a.push(".......##......"); | |
a.push(".......##......"); | |
a.push(".......##......"); | |
a.push(".......##......"); | |
a.push(".......##......"); | |
a.push(".......##......"); | |
a.push(".......##......"); | |
a.push(".......##......"); | |
mapData[5] = a.join("\n"); | |
a = []; | |
a.push("-c-------------"); | |
a.push("-###-----------"); | |
a.push("---#-----------"); | |
a.push("---#-------.---"); | |
a.push("---#########.--"); | |
a.push("----------.#---"); | |
a.push("-----------#---"); | |
a.push("-----------#---"); | |
a.push("---.------.#---"); | |
a.push("--.#########.--"); | |
a.push("---#.------.---"); | |
a.push("---#-----------"); | |
a.push("---#-----------"); | |
a.push("---#-----------"); | |
a.push("---#-----------"); | |
a.push("---#-----------"); | |
mapData[6] = a.join("\n"); | |
a = []; | |
a.push("..............."); | |
a.push("..............."); | |
a.push("...#########..."); | |
a.push("...#.......#..."); | |
a.push("...#.#####.#..."); | |
a.push("...#.#...#.#..."); | |
a.push("...#.#.c.#.#..."); | |
a.push("...#.#.#.#.#..."); | |
a.push("...#.###.#.#..."); | |
a.push("...#....N#.#..."); | |
a.push("...#######.#..."); | |
a.push("...........#..."); | |
a.push(".......#####..."); | |
a.push(".......#......."); | |
a.push(".......#......."); | |
a.push(".......#......."); | |
mapData[7] = a.join("\n"); | |
a = []; | |
a.push("------ccc------"); | |
a.push("------###------"); | |
a.push("......###......"); | |
a.push("......###......"); | |
a.push("......###......"); | |
a.push("......###......"); | |
a.push("......###......"); | |
a.push("......###......"); | |
a.push("......###......"); | |
a.push("......###......"); | |
a.push("......###......"); | |
a.push("......###......"); | |
a.push("......###......"); | |
a.push("......###......"); | |
a.push("......###......"); | |
a.push("......###......"); | |
mapData[8] = a.join("\n"); | |
a = []; | |
a.push("...........c..."); | |
a.push("...........#..."); | |
a.push("...........#..."); | |
a.push("..c........#..."); | |
a.push("..##########..."); | |
a.push("...........#..."); | |
a.push("...........#..."); | |
a.push("...........#..."); | |
a.push("...........#..."); | |
a.push("..c........#..."); | |
a.push("..##########..."); | |
a.push("...........#..."); | |
a.push("...........#..."); | |
a.push("...........#..."); | |
a.push("...........#..."); | |
a.push("...........#..."); | |
mapData[9] = a.join("\n"); | |
a = []; | |
a.push("...c..........."); | |
a.push("...#..........."); | |
a.push("...#..........."); | |
a.push("...#N.........."); | |
a.push("...###........."); | |
a.push(".....#........."); | |
a.push(".....###......."); | |
a.push("......N#......."); | |
a.push(".......###....."); | |
a.push("........N#....."); | |
a.push(".........#....."); | |
a.push(".........#....."); | |
a.push(".........#....."); | |
a.push(".........#....."); | |
a.push(".........#....."); | |
a.push(".........#....."); | |
mapData[10] = a.join("\n"); | |
a = []; | |
a.push("..............."); | |
a.push("..............."); | |
a.push("..............."); | |
a.push("..............."); | |
a.push("..............."); | |
a.push("..............."); | |
a.push("..............."); | |
a.push("..............."); | |
a.push("..............."); | |
a.push("..............."); | |
a.push("..............."); | |
a.push("..............."); | |
a.push("..............."); | |
a.push("..............."); | |
a.push("..............."); | |
a.push("..............."); | |
mapData[42424] = a.join("\n"); | |
a = []; | |
a.push(".c...........c."); | |
a.push(".#####...#####."); | |
a.push(".....#...#....."); | |
a.push(".....#...#....."); | |
a.push(".....#...#....."); | |
a.push(".#####...#####."); | |
a.push(".#...........#."); | |
a.push(".#...........#."); | |
a.push(".#...........#."); | |
a.push(".######D######."); | |
a.push(".......#......"); | |
a.push(".......#......."); | |
a.push(".......#......."); | |
a.push(".......#......."); | |
a.push(".......#......."); | |
a.push(".......#......."); | |
mapData[99999] = a.join("\n"); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment