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 hidden or 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