var playerGold = 30;
var playerScore = 0;
var enemySpawnDelay = 120;
var upgradeLevel = 0;
var upgradeCost = 100;
var towerDamage = [1, 1.5, 2, 2.5, 3, 3.5, 4, 5, 8];
var towerShotDelay = [50, 45, 45, 40, 35, 30, 25, 20, 15];
var lerp = function (start, end, t) {
return start * (1 - t) + end * t;
};
var createQuadraticBezierArcPoints = function (p0x, p0y, p1x, p1y, p2x, p2y, numberOfSteps) {
var points_along_axis = new Array(numberOfSteps).fill(null).map(() => [0, 0]);
var stepping_constant = 1 / numberOfSteps;
for (var i = 0; i < numberOfSteps; i++) {
var i_p0_p1x = lerp(p0x, p1x, i * stepping_constant);
var i_p0_p1y = lerp(p0y, p1y, i * stepping_constant);
var i_p1_p2x = lerp(p1x, p2x, i * stepping_constant);
var i_p1_p2y = lerp(p1y, p2y, i * stepping_constant);
if (false) points_along_axis.push(lerp(i_p0_p1x, i_p1_p2x, i * stepping_constant), lerp(i_p0_p1y, i_p1_p2y, i * stepping_constant));
points_along_axis[i][0] = lerp(i_p0_p1x, i_p1_p2x, i * stepping_constant);
points_along_axis[i][1] = lerp(i_p0_p1y, i_p1_p2y, i * stepping_constant);
}
if (false) {
console.log('path: ' + points_along_axis);
console.log('path[2]: ' + points_along_axis[2]);
}
return points_along_axis.reverse();
};
var temp = createQuadraticBezierArcPoints(0, 0, 50, 50, 0, 50, 10);
var TreasureChest = Container.expand(function () {
var self = Container.call(this);
var chestGraphics = self.createAsset('treasureChestSprite', 'Treasure Chest Sprite', 0.5, 0.5);
self.addChild(chestGraphics);
});
var UpgradeButton = Container.expand(function () {
var self = Container.call(this);
var upgradeButtonGraphics = self.createAsset('buttonSprite', 'Button Sprite', 0.5, 0.5);
self.addChild(upgradeButtonGraphics);
});
var GoldCoin = Container.expand(function (startX, startY, endX, endY, delay) {
var self = Container.call(this);
GoldCoin.delayIncrement = 0;
self.game = this;
var coinGraphics = self.createAsset('goldCoinSprite', 'Gold Coin Sprite', 0.5, 0.5);
self.addChild(coinGraphics);
self.x = startX;
self.y = startY;
var distance = Math.sqrt(Math.pow(endX - startX, 2) + Math.pow(endY - startY, 2));
self.delayCounter = delay * 2;
var duration = 60 + delay;
var vx = (endX - startX) / duration;
var vy = (endY - startY) / duration;
self.alpha = 0;
self.path = createQuadraticBezierArcPoints(startX, startY, endX, startY - 100, endX, endY, 60);
self.move = function () {
if (self.delayCounter > 0) {
self.delayCounter--;
} else {
self.alpha = 1;
if (self.path[duration]) {
self.x = self.path[duration - self.delayCounter][0];
self.y = self.path[duration - self.delayCounter][1];
}
}
if (--duration <= 0) {
self.destroy();
}
};
});
var CityWall = Container.expand(function () {
var self = Container.call(this);
var wallGraphics = self.createAsset('cityWallSprite', 'City Wall Sprite', 0.5, 0.5);
self.addChild(wallGraphics);
});
var TrollEnemy = Container.expand(function () {
var self = Container.call(this);
var trollGraphics = self.createAsset('trollSprite', 'Troll Enemy Sprite', .5, .5);
trollGraphics.scale.set(2.5);
self.hitpoints = 30;
self.move = function (towers) {
var minDist = Infinity;
var closestTower = null;
for (var i = 0; i < self.game.towers.length; i++) {
var dx = self.game.towers[i].x - self.x;
var dy = self.game.towers[i].y - self.y;
var dist = Math.sqrt(dx * dx + dy * dy);
if (dist < minDist) {
minDist = dist;
closestTower = self.game.towers[i];
}
}
if (closestTower && minDist < closestTower.width / 2 + this.width / 2) {
closestTower.health -= 0.5;
if (closestTower.health <= 0) {
var towerIndex = self.game.towers.indexOf(closestTower);
if (towerIndex > -1) {
self.game.towers.splice(towerIndex, 1);
}
closestTower.destroy();
}
} else if (closestTower && minDist < 100) {
var avoidanceForce = 8;
var ax = this.x - closestTower.x;
var ay = this.y - closestTower.y;
var len = Math.sqrt(ax * ax + ay * ay);
ax = ax / len * avoidanceForce;
ay = ay / len * avoidanceForce;
this.x += ax;
this.y += ay;
} else {
this.zigzagCounter = this.zigzagCounter || 0;
this.zigzagDirection = this.zigzagDirection || 1;
if (this.zigzagCounter++ % self.zigzagTension === 0) this.zigzagDirection *= -1;
this.x += 4 * this.zigzagDirection;
this.y += 2;
if (Math.random() < 0.01) {
this.zigzagTension = Math.floor(Math.random() * 40) + 10;
}
if (this.x > 2048) {
this.zigzagDirection = -1;
}
if (this.x < 0) {
this.zigzagDirection = 1;
}
var scaleIncrement = (1 - 0.1) / 200;
this.scale.x += scaleIncrement;
this.scale.y += scaleIncrement;
this.scale.x = Math.min(this.scale.x, 1);
this.scale.y = Math.min(this.scale.y, 1);
if (this.zigzagCounter % 5 == 0) {
this.rotation = (0.5 - Math.random()) * (Math.PI * 2 / 100);
}
}
};
self.die = function () {
playerGold += 20;
playerScore += 300;
this.game.updateScoreLabel();
this.game.updateGoldLabel();
for (var i = 0; i < 20; i++) {
var t = new GoldCoin(this.x, this.y, 720, 2450, i * 2);
this.game.addChild(t);
this.game.goldCoins.push(t);
}
var index = this.game.enemies.indexOf(this);
if (index > -1) {
this.game.enemies.splice(index, 1);
}
this.destroy();
};
});
var DeathKnightEnemy = Container.expand(function () {
var self = Container.call(this);
var dKnightGraphics = self.createAsset('deathKnightSprite', 'DeathKnight Enemy Sprite', .5, .5);
dKnightGraphics.scale.set(2.5);
self.hitpoints = 100;
self.move = function (towers) {
var minDist = Infinity;
var closestTower = null;
for (var i = 0; i < self.game.towers.length; i++) {
var dx = self.game.towers[i].x - self.x;
var dy = self.game.towers[i].y - self.y;
var dist = Math.sqrt(dx * dx + dy * dy);
if (dist < minDist) {
minDist = dist;
closestTower = self.game.towers[i];
}
}
if (closestTower && minDist < closestTower.width / 2 + this.width / 2) {
closestTower.health -= 1;
if (closestTower.health <= 0) {
var towerIndex = self.game.towers.indexOf(closestTower);
if (towerIndex > -1) {
self.game.towers.splice(towerIndex, 1);
}
closestTower.destroy();
}
} else if (closestTower && minDist < 100) {
var avoidanceForce = 8;
var ax = this.x - closestTower.x;
var ay = this.y - closestTower.y;
var len = Math.sqrt(ax * ax + ay * ay);
ax = ax / len * avoidanceForce;
ay = ay / len * avoidanceForce;
this.x += ax;
this.y += ay;
} else {
this.zigzagCounter = this.zigzagCounter || 0;
this.zigzagDirection = this.zigzagDirection || 1;
if (this.zigzagCounter++ % self.zigzagTension === 0) this.zigzagDirection *= -1;
this.x += 4 * this.zigzagDirection;
this.y += 2;
if (Math.random() < 0.01) {
this.zigzagTension = Math.floor(Math.random() * 40) + 10;
}
if (this.x > 2048) {
this.zigzagDirection = -1;
}
if (this.x < 0) {
this.zigzagDirection = 1;
}
var scaleIncrement = (1 - 0.1) / 200;
this.scale.x += scaleIncrement;
this.scale.y += scaleIncrement;
this.scale.x = Math.min(this.scale.x, 1);
this.scale.y = Math.min(this.scale.y, 1);
if (this.zigzagCounter % 10 == 0) {
this.rotation = (0.5 - Math.random()) * (Math.PI * 2 / 100);
}
}
};
self.die = function () {
playerGold += 50;
playerScore += 2222;
this.game.updateScoreLabel();
this.game.updateGoldLabel();
for (var i = 0; i < 40; i++) {
var t = new GoldCoin(this.x, this.y, 720, 2450, i * 2);
this.game.addChild(t);
this.game.goldCoins.push(t);
}
var index = this.game.enemies.indexOf(this);
if (index > -1) {
this.game.enemies.splice(index, 1);
}
this.destroy();
};
});
var BalrogEnemy = Container.expand(function () {
var self = Container.call(this);
var balrogGraphics = self.createAsset('balrogSprite', 'Balrog Enemy Sprite', .5, .5);
balrogGraphics.scale.set(2.5);
self.hitpoints = 500;
self.move = function (towers) {
var minDist = Infinity;
var closestTower = null;
for (var i = 0; i < self.game.towers.length; i++) {
var dx = self.game.towers[i].x - self.x;
var dy = self.game.towers[i].y - self.y;
var dist = Math.sqrt(dx * dx + dy * dy);
if (dist < minDist) {
minDist = dist;
closestTower = self.game.towers[i];
}
}
if (closestTower && minDist < closestTower.width / 2 + this.width / 2) {
closestTower.health -= 4;
if (closestTower.health <= 0) {
var towerIndex = self.game.towers.indexOf(closestTower);
if (towerIndex > -1) {
self.game.towers.splice(towerIndex, 1);
}
closestTower.destroy();
}
} else if (closestTower && minDist < 100) {
var avoidanceForce = 8;
var ax = this.x - closestTower.x;
var ay = this.y - closestTower.y;
var len = Math.sqrt(ax * ax + ay * ay);
ax = ax / len * avoidanceForce;
ay = ay / len * avoidanceForce;
this.x += ax;
this.y += ay;
} else {
this.zigzagCounter = this.zigzagCounter || 0;
this.zigzagDirection = this.zigzagDirection || 1;
if (this.zigzagCounter++ % self.zigzagTension === 0) this.zigzagDirection *= -1;
this.x += 4 * this.zigzagDirection;
this.y += 2;
if (Math.random() < 0.01) {
this.zigzagTension = Math.floor(Math.random() * 40) + 10;
}
if (this.x > 2048) {
this.zigzagDirection = -1;
}
if (this.x < 0) {
this.zigzagDirection = 1;
}
var scaleIncrement = (1 - 0.1) / 200;
this.scale.x += scaleIncrement;
this.scale.y += scaleIncrement;
this.scale.x = Math.min(this.scale.x, 1);
this.scale.y = Math.min(this.scale.y, 1);
if (this.zigzagCounter % 10 == 0) {
this.rotation = (0.5 - Math.random()) * (Math.PI * 2 / 100);
}
}
};
self.die = function () {
playerGold += 500;
playerScore += 10000;
this.game.updateScoreLabel();
this.game.updateGoldLabel();
for (var i = 0; i < 100; i++) {
var t = new GoldCoin(this.x, this.y, 720, 2450, i * 2);
this.game.addChild(t);
this.game.goldCoins.push(t);
}
var index = this.game.enemies.indexOf(this);
if (index > -1) {
this.game.enemies.splice(index, 1);
}
this.destroy();
};
});
var Tower = Container.expand(function (gameInstance) {
var self = Container.call(this);
self.game = gameInstance;
self.upgradeLevel = upgradeLevel;
var towerGraphics = self.createAsset('towerSprite', 'Tower Sprite', .5, .5);
var towerGraphics1 = self.createAsset('towerSprite1', 'Tower Sprite1', .5, .5);
var towerGraphics2 = self.createAsset('towerSprite2', 'Tower Sprite2', .5, .5);
var towerGraphics3 = self.createAsset('towerSprite3', 'Tower Sprite3', .5, .5);
var towerGraphics4 = self.createAsset('towerSprite4', 'Tower Sprite4', .5, .5);
var towerGraphics5 = self.createAsset('towerSprite5', 'Tower Sprite5', .5, .5);
var towerGraphics6 = self.createAsset('towerSprite6', 'Tower Sprite6', .5, .5);
var towerGraphics7 = self.createAsset('towerSprite7', 'Tower Sprite7', .5, .5);
var towerGraphics8 = self.createAsset('towerSprite8', 'Tower Sprite8', .5, .5);
towerGraphics.scale.set(2);
towerGraphics1.scale.set(2);
towerGraphics2.scale.set(2);
towerGraphics3.scale.set(2);
towerGraphics4.scale.set(2);
towerGraphics5.scale.set(2);
towerGraphics6.scale.set(2);
towerGraphics7.scale.set(2);
towerGraphics8.scale.set(2);
towerGraphics1.alpha = 0;
towerGraphics2.alpha = 0;
towerGraphics3.alpha = 0;
towerGraphics4.alpha = 0;
towerGraphics5.alpha = 0;
towerGraphics6.alpha = 0;
towerGraphics7.alpha = 0;
towerGraphics8.alpha = 0;
var a = [towerGraphics1, towerGraphics2, towerGraphics3, towerGraphics4, towerGraphics5, towerGraphics6, towerGraphics7, towerGraphics8];
if (upgradeLevel > 0) {
towerGraphics.alpha = 0;
for (var i = 0; i < 8; i++) {
if (i + 1 == upgradeLevel) {
a[i].alpha = 1;
} else {
a[i].alpha = 0;
}
}
}
self.shoot = function (enemies) {
if (self.shootCounter++ % towerShotDelay[self.upgradeLevel] === 0) {
for (var i = 0; i < enemies.length; i++) {
var enemy = enemies[i];
var dx = enemy.x - self.x;
var dy = enemy.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance <= 300) {
console.log('shot');
var bullet = new Bullet(self.upgradeLevel);
bullet.x = self.x;
bullet.y = self.y;
bullet.target = enemy;
var tx = bullet.target.x - bullet.x;
var ty = bullet.target.y - bullet.y;
var rad = Math.atan2(ty, tx);
bullet.rotation = rad + Math.PI / 2;
bullet.vx = Math.cos(rad);
bullet.vy = Math.sin(rad);
self.game.addBullet(bullet);
break;
}
}
}
};
self.upgrade = function () {};
self.shootCounter = 0;
self.health = 200;
});
var Enemy = Container.expand(function () {
var self = Container.call(this);
var enemyGraphics = self.createAsset('enemySprite', 'Enemy Sprite', .5, .5);
enemyGraphics.scale.set(0.8);
self.hitpoints = 3;
self.zigzagTension = Math.floor(Math.random() * 40) + 10;
self.move = function (towers) {
var minDist = Infinity;
var closestTower = null;
for (var i = 0; i < self.game.towers.length; i++) {
var dx = self.game.towers[i].x - self.x;
var dy = self.game.towers[i].y - self.y;
var dist = Math.sqrt(dx * dx + dy * dy);
if (dist < minDist) {
minDist = dist;
closestTower = self.game.towers[i];
}
}
if (closestTower && minDist < closestTower.width / 2 + this.width / 2) {
closestTower.health -= 0.5;
if (closestTower.health <= 0) {
var towerIndex = self.game.towers.indexOf(closestTower);
if (towerIndex > -1) {
self.game.towers.splice(towerIndex, 1);
}
closestTower.destroy();
}
} else if (closestTower && minDist < 100) {
var avoidanceForce = 8;
var ax = this.x - closestTower.x;
var ay = this.y - closestTower.y;
var len = Math.sqrt(ax * ax + ay * ay);
ax = ax / len * avoidanceForce;
ay = ay / len * avoidanceForce;
this.x += ax;
this.y += ay;
} else {
this.zigzagCounter = this.zigzagCounter || 0;
this.zigzagDirection = this.zigzagDirection || 1;
if (this.zigzagCounter++ % self.zigzagTension === 0) this.zigzagDirection *= -1;
this.x += 4 * this.zigzagDirection;
this.y += 2;
if (Math.random() < 0.01) {
this.zigzagTension = Math.floor(Math.random() * 40) + 10;
}
if (this.x > 2048) {
this.zigzagDirection = -1;
}
if (this.x < 0) {
this.zigzagDirection = 1;
}
var scaleIncrement = (1 - 0.1) / 200;
this.scale.x += scaleIncrement;
this.scale.y += scaleIncrement;
this.scale.x = Math.min(this.scale.x, 1);
this.scale.y = Math.min(this.scale.y, 1);
this.rotation = (0.5 - Math.random()) * (Math.PI * 2 / 50);
}
};
self.die = function () {
playerGold += 5;
playerScore += 100;
this.game.updateScoreLabel();
this.game.updateGoldLabel();
for (var i = 0; i < 5; i++) {
var t = new GoldCoin(this.x, this.y, 720, 2450, i * 2);
this.game.addChild(t);
this.game.goldCoins.push(t);
}
var index = this.game.enemies.indexOf(this);
if (index > -1) {
this.game.enemies.splice(index, 1);
}
this.destroy();
};
});
var OrcEnemy = Container.expand(function () {
var self = Container.call(this);
var enemyGraphics = self.createAsset('orcEnemySprite', 'Orc Enemy Sprite', .5, .5);
enemyGraphics.scale.set(0.8);
self.hitpoints = 6;
self.zigzagTension = Math.floor(Math.random() * 20) + 10;
self.move = function (towers) {
var minDist = Infinity;
var closestTower = null;
for (var i = 0; i < self.game.towers.length; i++) {
var dx = self.game.towers[i].x - self.x;
var dy = self.game.towers[i].y - self.y;
var dist = Math.sqrt(dx * dx + dy * dy);
if (dist < minDist) {
minDist = dist;
closestTower = self.game.towers[i];
}
}
if (closestTower && minDist < closestTower.width / 2 + this.width / 2) {
closestTower.health -= 0.8;
if (closestTower.health <= 0) {
var towerIndex = self.game.towers.indexOf(closestTower);
if (towerIndex > -1) {
self.game.towers.splice(towerIndex, 1);
}
closestTower.destroy();
}
} else if (closestTower && minDist < 100) {
var avoidanceForce = 8;
var ax = this.x - closestTower.x;
var ay = this.y - closestTower.y;
var len = Math.sqrt(ax * ax + ay * ay);
ax = ax / len * avoidanceForce;
ay = ay / len * avoidanceForce;
this.x += ax;
this.y += ay;
} else {
this.zigzagCounter = this.zigzagCounter || 0;
this.zigzagDirection = this.zigzagDirection || 1;
if (this.zigzagCounter++ % self.zigzagTension === 0) this.zigzagDirection *= -1;
this.x += 4 * this.zigzagDirection;
this.y += 2;
if (Math.random() < 0.01) {
this.zigzagTension = Math.floor(Math.random() * 40) + 10;
}
if (this.x > 2048) {
this.zigzagDirection = -1;
}
if (this.x < 0) {
this.zigzagDirection = 1;
}
var scaleIncrement = (1 - 0.1) / 200;
this.scale.x += scaleIncrement;
this.scale.y += scaleIncrement;
this.scale.x = Math.min(this.scale.x, 1);
this.scale.y = Math.min(this.scale.y, 1);
if (this.zigzagCounter % 5 == 0) {
this.rotation = (0.5 - Math.random()) * (Math.PI * 2 / 100);
}
}
};
self.die = function () {
playerGold += 10;
playerScore += 150;
this.game.updateScoreLabel();
this.game.updateGoldLabel();
for (var i = 0; i < 8; i++) {
var t = new GoldCoin(this.x, this.y, 720, 2450, i * 2);
this.game.addChild(t);
this.game.goldCoins.push(t);
}
var index = this.game.enemies.indexOf(this);
if (index > -1) {
this.game.enemies.splice(index, 1);
}
this.destroy();
};
});
var Bullet = Container.expand(function (upgradeLevel) {
var self = Container.call(this);
self.game = null;
self.upgradeLevel = upgradeLevel;
self.damage = towerDamage[self.upgradeLevel];
var bulletGraphics = self.createAsset('bullet', 'Bullet Graphics', .5, .5);
bulletGraphics.scale.set(0.2);
var bulletGraphics1 = self.createAsset('bulletSprite1', 'Bullet Sprite1', .5, .5);
var bulletGraphics2 = self.createAsset('bulletSprite2', 'Bullet Sprite2', .5, .5);
var bulletGraphics3 = self.createAsset('bulletSprite3', 'Bullet Sprite3', .5, .5);
var bulletGraphics4 = self.createAsset('bulletSprite4', 'Bullet Sprite4', .5, .5);
var bulletGraphics5 = self.createAsset('bulletSprite5', 'Bullet Sprite5', .5, .5);
var bulletGraphics6 = self.createAsset('bulletSprite6', 'Bullet Sprite6', .5, .5);
var bulletGraphics7 = self.createAsset('bulletSprite7', 'Bullet Sprite7', .5, .5);
var bulletGraphics8 = self.createAsset('bulletSprite8', 'Bullet Sprite8', .5, .5);
bulletGraphics1.scale.set(.2);
bulletGraphics2.scale.set(.2);
bulletGraphics3.scale.set(.2);
bulletGraphics4.scale.set(.2);
bulletGraphics5.scale.set(.2);
bulletGraphics6.scale.set(.2);
bulletGraphics7.scale.set(.2);
bulletGraphics8.scale.set(.2);
bulletGraphics1.alpha = 0;
bulletGraphics2.alpha = 0;
bulletGraphics3.alpha = 0;
bulletGraphics4.alpha = 0;
bulletGraphics5.alpha = 0;
bulletGraphics6.alpha = 0;
bulletGraphics7.alpha = 0;
bulletGraphics8.alpha = 0;
var a = [bulletGraphics1, bulletGraphics2, bulletGraphics3, bulletGraphics4, bulletGraphics5, bulletGraphics6, bulletGraphics7, bulletGraphics8];
if (self.upgradeLevel > 0) {
bulletGraphics.alpha = 0;
for (var i = 0; i < 8; i++) {
if (i + 1 == self.upgradeLevel) {
a[i].alpha = 1;
} else {
a[i].setAlpha = 0;
}
}
}
self.vx = 0;
self.vy = 0;
self.move = function () {
if (this.target) {
var tx = this.target.x - this.x;
var ty = this.target.y - this.y;
var dist = Math.sqrt(tx * tx + ty * ty);
if (dist > 0) {
this.x += this.vx * 10;
this.y += this.vy * 10;
}
if (dist < this.width / 2 + this.target.width / 2) {
this.hit();
} else if (this.x < 0 || this.x > 2048 || this.y < 0 || this.y > 2732) {
this.destroy();
}
}
};
self.hit = function () {
this.target.hitpoints -= this.damage;
if (this.target.hitpoints <= 0 && !this.target.dead) {
this.target.dead = true;
this.target.die();
}
this.destroy();
};
});
var Game = Container.expand(function () {
var self = Container.call(this);
self.updateGoldLabel = function () {
goldLabel.setText('Gold: ' + playerGold);
};
self.updateScoreLabel = function () {
scoreLabel.setText('Score: ' + playerScore);
};
self.updateCostLabel = function () {
costLabel.setText('Cost: ' + upgradeCost);
};
self.playerGold = 0;
self.addBullet = function (bullet) {
bullets.push(bullet);
self.addChild(bullet);
};
self.sufficientDistanceToOtherTowers = function (position) {
for (var i = 0; i < self.towers.length; i++) {
var tower = self.towers[i];
var dx = tower.x - position.x;
var dy = tower.y - position.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < 120) {
return false;
}
}
return true;
};
var background = self.createAsset('background', 'Background Image', 0, 0);
background.width = 2048;
background.height = 2732;
background.y = 0;
self.addChildAt(background, 0);
self.towers = [];
self.enemies = [];
var bullets = [];
self.goldCoins = [];
var selectedTowerType = null;
var initialEnemy = new Enemy();
initialEnemy.game = self;
initialEnemy.x = 300 + Math.random() * (1848 - 300);
initialEnemy.y = 200;
initialEnemy.scale.set(0.1);
self.enemies.push(initialEnemy);
self.addChild(initialEnemy);
LK.on('tick', function () {
self.enemySpawnCounter = self.enemySpawnCounter || 0;
self.totalEnemiesSpawned = self.totalEnemiesSpawned || 0;
if (++self.enemySpawnCounter >= enemySpawnDelay) {
var newEnemy;
if (self.totalEnemiesSpawned > 200 && self.totalEnemiesSpawned % 199 == 0) {
newEnemy = new BalrogEnemy();
} else if (self.totalEnemiesSpawned > 3 && self.totalEnemiesSpawned % 50 == 0) {
newEnemy = new DeathKnightEnemy();
} else if (self.totalEnemiesSpawned > 3 && self.totalEnemiesSpawned % 10 == 0) {
newEnemy = new TrollEnemy();
} else {
if (Math.random() < 0.2 + upgradeLevel * 0.06) {
newEnemy = new OrcEnemy();
} else {
newEnemy = new Enemy();
}
}
if (newEnemy) {
newEnemy.game = self;
newEnemy.x = 300 + Math.random() * (1848 - 300);
newEnemy.y = 200;
newEnemy.scale.set(0.1);
self.enemies.push(newEnemy);
self.addChild(newEnemy);
}
self.totalEnemiesSpawned++;
if (self.totalEnemiesSpawned > 0 && self.totalEnemiesSpawned % 20 == 0) {
enemySpawnDelay -= 4;
if (enemySpawnDelay < 20) {
enemySpawnDelay = 20;
}
}
self.enemySpawnCounter = 0;
}
for (var i = 0; i < self.enemies.length; i++) {
self.enemies[i].move();
if (self.enemies[i].y >= 2332 - self.enemies[i].height / 2) {
LK.showGameOver();
}
}
for (var j = 0; j < self.towers.length; j++) {
self.towers[j].shoot(self.enemies);
}
for (var k = bullets.length - 1; k >= 0; k--) {
bullets[k].move();
if (!bullets[k].parent) {
bullets.splice(k, 1);
}
}
for (var l = self.goldCoins.length - 1; l >= 0; l--) {
self.goldCoins[l].move();
if (!self.goldCoins[l].parent) {
self.goldCoins.splice(l, 1);
}
}
});
stage.on('down', function (obj) {
var position = obj.event.getLocalPosition(self);
if (position.y >= 600 && position.y <= 2112) {
if (playerGold >= 10) {
if (self.sufficientDistanceToOtherTowers(position)) {
playerGold -= 10;
var newTower = self.addChild(new Tower(self));
newTower.x = position.x;
newTower.y = position.y;
self.towers.push(newTower);
self.towers.sort(function (a, b) {
return a.y - b.y;
});
self.towers.forEach(function (tower, index) {
self.addChildAt(tower, 6 + index);
console.log('y and zIndex:' + tower.y + ', ' + tower.parent.getChildIndex(tower));
});
self.updateGoldLabel();
}
}
}
});
stage.on('move', function (obj) {});
stage.on('up', function (obj) {});
var cityWall = self.addChild(new CityWall());
cityWall.y = 2632;
cityWall.x = 332;
cityWall.scale.y = 0.5;
cityWall.scale.x = 0.5;
var cityWall2 = self.addChild(new CityWall());
cityWall2.y = 2632;
cityWall2.x = 1012;
cityWall2.scale.y = 0.5;
cityWall2.scale.x = 0.5;
var cityWall3 = self.addChild(new CityWall());
cityWall3.y = 2632;
cityWall3.x = 1691;
cityWall3.scale.y = 0.5;
cityWall3.scale.x = 0.5;
var bottomBlackBox = self.createAsset('blackBox', 'Black Box at bottom', 0, 1);
bottomBlackBox.width = 2048;
bottomBlackBox.height = 400;
bottomBlackBox.y = 2732;
self.addChild(bottomBlackBox);
var goldLabel = new Text2('Gold: 30', {
size: 100,
fill: '#ffd700',
align: 'left',
dropShadow: true
});
goldLabel.x = 120;
goldLabel.y = 2632 - bottomBlackBox.height + (bottomBlackBox.height - goldLabel.height) / 2;
self.addChild(goldLabel);
var scoreLabel = new Text2('Score: 0', {
size: 100,
fill: '#ccbbff',
align: 'left',
dropShadow: true
});
scoreLabel.x = 120;
scoreLabel.y = 2772 - bottomBlackBox.height + (bottomBlackBox.height - scoreLabel.height) / 2;
self.addChild(scoreLabel);
var instructionLabel = new Text2("Tap to build towers (cost 10 gold)\nDon't let enemies reach the City Wall!", {
size: 58,
fill: '#eeeeee',
align: 'left',
dropShadow: true
});
instructionLabel.x = 920;
instructionLabel.y = 2632 - bottomBlackBox.height + (bottomBlackBox.height - instructionLabel.height) / 2;
self.addChild(instructionLabel);
var treasureChest = self.addChild(new TreasureChest());
treasureChest.scale.x = 1.3;
treasureChest.scale.y = 1.3;
treasureChest.x = 720;
treasureChest.y = goldLabel.y + 65;
var upgradeButton = self.addChild(new UpgradeButton());
upgradeButton.x = 1500;
upgradeButton.y = 2590;
self.upgradeLabel = new Text2("Upgrade Towers:", {
size: 58,
fill: '#dddddd',
align: 'left',
dropShadow: true
});
self.upgradeLabel.x = 920;
self.upgradeLabel.y = 2552;
self.addChild(self.upgradeLabel);
var costLabel = new Text2("Cost: 100", {
size: 58,
fill: '#dddd00',
align: 'left',
dropShadow: true
});
costLabel.x = 1600;
costLabel.y = 2552;
self.addChild(costLabel);
self.upgradeTowers = function () {
if (playerGold >= upgradeCost) {
playerGold -= upgradeCost;
upgradeLevel += 1;
upgradeCost *= 2;
self.updateGoldLabel();
self.updateCostLabel();
if (upgradeLevel == 8) {
self.upgradeLabel.setText('All upgraded - Go for the High Score!');
if (upgradeButton) {
upgradeButton.destroy();
upgradeButton = null;
}
if (costLabel) {
costLabel.destroy();
costLabel = null;
}
}
}
};
upgradeButton.on('down', self.upgradeTowers);
});
===================================================================
--- original.js
+++ change.js
@@ -1,41 +1,819 @@
-var Tower = Container.expand(function () {
+var playerGold = 30;
+var playerScore = 0;
+var enemySpawnDelay = 120;
+var upgradeLevel = 0;
+var upgradeCost = 100;
+var towerDamage = [1, 1.5, 2, 2.5, 3, 3.5, 4, 5, 8];
+var towerShotDelay = [50, 45, 45, 40, 35, 30, 25, 20, 15];
+var lerp = function (start, end, t) {
+ return start * (1 - t) + end * t;
+};
+var createQuadraticBezierArcPoints = function (p0x, p0y, p1x, p1y, p2x, p2y, numberOfSteps) {
+ var points_along_axis = new Array(numberOfSteps).fill(null).map(() => [0, 0]);
+ var stepping_constant = 1 / numberOfSteps;
+ for (var i = 0; i < numberOfSteps; i++) {
+ var i_p0_p1x = lerp(p0x, p1x, i * stepping_constant);
+ var i_p0_p1y = lerp(p0y, p1y, i * stepping_constant);
+ var i_p1_p2x = lerp(p1x, p2x, i * stepping_constant);
+ var i_p1_p2y = lerp(p1y, p2y, i * stepping_constant);
+ if (false) points_along_axis.push(lerp(i_p0_p1x, i_p1_p2x, i * stepping_constant), lerp(i_p0_p1y, i_p1_p2y, i * stepping_constant));
+ points_along_axis[i][0] = lerp(i_p0_p1x, i_p1_p2x, i * stepping_constant);
+ points_along_axis[i][1] = lerp(i_p0_p1y, i_p1_p2y, i * stepping_constant);
+ }
+ if (false) {
+ console.log('path: ' + points_along_axis);
+ console.log('path[2]: ' + points_along_axis[2]);
+ }
+ return points_along_axis.reverse();
+};
+var temp = createQuadraticBezierArcPoints(0, 0, 50, 50, 0, 50, 10);
+var TreasureChest = Container.expand(function () {
var self = Container.call(this);
- var towerGraphics = self.createAsset('tower', 'Tower Graphics', .5, .5);
- self.shoot = function () {};
+ var chestGraphics = self.createAsset('treasureChestSprite', 'Treasure Chest Sprite', 0.5, 0.5);
+ self.addChild(chestGraphics);
});
+var UpgradeButton = Container.expand(function () {
+ var self = Container.call(this);
+ var upgradeButtonGraphics = self.createAsset('buttonSprite', 'Button Sprite', 0.5, 0.5);
+ self.addChild(upgradeButtonGraphics);
+});
+var GoldCoin = Container.expand(function (startX, startY, endX, endY, delay) {
+ var self = Container.call(this);
+ GoldCoin.delayIncrement = 0;
+ self.game = this;
+ var coinGraphics = self.createAsset('goldCoinSprite', 'Gold Coin Sprite', 0.5, 0.5);
+ self.addChild(coinGraphics);
+ self.x = startX;
+ self.y = startY;
+ var distance = Math.sqrt(Math.pow(endX - startX, 2) + Math.pow(endY - startY, 2));
+ self.delayCounter = delay * 2;
+ var duration = 60 + delay;
+ var vx = (endX - startX) / duration;
+ var vy = (endY - startY) / duration;
+ self.alpha = 0;
+ self.path = createQuadraticBezierArcPoints(startX, startY, endX, startY - 100, endX, endY, 60);
+ self.move = function () {
+ if (self.delayCounter > 0) {
+ self.delayCounter--;
+ } else {
+ self.alpha = 1;
+ if (self.path[duration]) {
+ self.x = self.path[duration - self.delayCounter][0];
+ self.y = self.path[duration - self.delayCounter][1];
+ }
+ }
+ if (--duration <= 0) {
+ self.destroy();
+ }
+ };
+});
+var CityWall = Container.expand(function () {
+ var self = Container.call(this);
+ var wallGraphics = self.createAsset('cityWallSprite', 'City Wall Sprite', 0.5, 0.5);
+ self.addChild(wallGraphics);
+});
+var TrollEnemy = Container.expand(function () {
+ var self = Container.call(this);
+ var trollGraphics = self.createAsset('trollSprite', 'Troll Enemy Sprite', .5, .5);
+ trollGraphics.scale.set(2.5);
+ self.hitpoints = 30;
+ self.move = function (towers) {
+ var minDist = Infinity;
+ var closestTower = null;
+ for (var i = 0; i < self.game.towers.length; i++) {
+ var dx = self.game.towers[i].x - self.x;
+ var dy = self.game.towers[i].y - self.y;
+ var dist = Math.sqrt(dx * dx + dy * dy);
+ if (dist < minDist) {
+ minDist = dist;
+ closestTower = self.game.towers[i];
+ }
+ }
+ if (closestTower && minDist < closestTower.width / 2 + this.width / 2) {
+ closestTower.health -= 0.5;
+ if (closestTower.health <= 0) {
+ var towerIndex = self.game.towers.indexOf(closestTower);
+ if (towerIndex > -1) {
+ self.game.towers.splice(towerIndex, 1);
+ }
+ closestTower.destroy();
+ }
+ } else if (closestTower && minDist < 100) {
+ var avoidanceForce = 8;
+ var ax = this.x - closestTower.x;
+ var ay = this.y - closestTower.y;
+ var len = Math.sqrt(ax * ax + ay * ay);
+ ax = ax / len * avoidanceForce;
+ ay = ay / len * avoidanceForce;
+ this.x += ax;
+ this.y += ay;
+ } else {
+ this.zigzagCounter = this.zigzagCounter || 0;
+ this.zigzagDirection = this.zigzagDirection || 1;
+ if (this.zigzagCounter++ % self.zigzagTension === 0) this.zigzagDirection *= -1;
+ this.x += 4 * this.zigzagDirection;
+ this.y += 2;
+ if (Math.random() < 0.01) {
+ this.zigzagTension = Math.floor(Math.random() * 40) + 10;
+ }
+ if (this.x > 2048) {
+ this.zigzagDirection = -1;
+ }
+ if (this.x < 0) {
+ this.zigzagDirection = 1;
+ }
+ var scaleIncrement = (1 - 0.1) / 200;
+ this.scale.x += scaleIncrement;
+ this.scale.y += scaleIncrement;
+ this.scale.x = Math.min(this.scale.x, 1);
+ this.scale.y = Math.min(this.scale.y, 1);
+ if (this.zigzagCounter % 5 == 0) {
+ this.rotation = (0.5 - Math.random()) * (Math.PI * 2 / 100);
+ }
+ }
+ };
+ self.die = function () {
+ playerGold += 20;
+ playerScore += 300;
+ this.game.updateScoreLabel();
+ this.game.updateGoldLabel();
+ for (var i = 0; i < 20; i++) {
+ var t = new GoldCoin(this.x, this.y, 720, 2450, i * 2);
+ this.game.addChild(t);
+ this.game.goldCoins.push(t);
+ }
+ var index = this.game.enemies.indexOf(this);
+ if (index > -1) {
+ this.game.enemies.splice(index, 1);
+ }
+ this.destroy();
+ };
+});
+var DeathKnightEnemy = Container.expand(function () {
+ var self = Container.call(this);
+ var dKnightGraphics = self.createAsset('deathKnightSprite', 'DeathKnight Enemy Sprite', .5, .5);
+ dKnightGraphics.scale.set(2.5);
+ self.hitpoints = 100;
+ self.move = function (towers) {
+ var minDist = Infinity;
+ var closestTower = null;
+ for (var i = 0; i < self.game.towers.length; i++) {
+ var dx = self.game.towers[i].x - self.x;
+ var dy = self.game.towers[i].y - self.y;
+ var dist = Math.sqrt(dx * dx + dy * dy);
+ if (dist < minDist) {
+ minDist = dist;
+ closestTower = self.game.towers[i];
+ }
+ }
+ if (closestTower && minDist < closestTower.width / 2 + this.width / 2) {
+ closestTower.health -= 1;
+ if (closestTower.health <= 0) {
+ var towerIndex = self.game.towers.indexOf(closestTower);
+ if (towerIndex > -1) {
+ self.game.towers.splice(towerIndex, 1);
+ }
+ closestTower.destroy();
+ }
+ } else if (closestTower && minDist < 100) {
+ var avoidanceForce = 8;
+ var ax = this.x - closestTower.x;
+ var ay = this.y - closestTower.y;
+ var len = Math.sqrt(ax * ax + ay * ay);
+ ax = ax / len * avoidanceForce;
+ ay = ay / len * avoidanceForce;
+ this.x += ax;
+ this.y += ay;
+ } else {
+ this.zigzagCounter = this.zigzagCounter || 0;
+ this.zigzagDirection = this.zigzagDirection || 1;
+ if (this.zigzagCounter++ % self.zigzagTension === 0) this.zigzagDirection *= -1;
+ this.x += 4 * this.zigzagDirection;
+ this.y += 2;
+ if (Math.random() < 0.01) {
+ this.zigzagTension = Math.floor(Math.random() * 40) + 10;
+ }
+ if (this.x > 2048) {
+ this.zigzagDirection = -1;
+ }
+ if (this.x < 0) {
+ this.zigzagDirection = 1;
+ }
+ var scaleIncrement = (1 - 0.1) / 200;
+ this.scale.x += scaleIncrement;
+ this.scale.y += scaleIncrement;
+ this.scale.x = Math.min(this.scale.x, 1);
+ this.scale.y = Math.min(this.scale.y, 1);
+ if (this.zigzagCounter % 10 == 0) {
+ this.rotation = (0.5 - Math.random()) * (Math.PI * 2 / 100);
+ }
+ }
+ };
+ self.die = function () {
+ playerGold += 50;
+ playerScore += 2222;
+ this.game.updateScoreLabel();
+ this.game.updateGoldLabel();
+ for (var i = 0; i < 40; i++) {
+ var t = new GoldCoin(this.x, this.y, 720, 2450, i * 2);
+ this.game.addChild(t);
+ this.game.goldCoins.push(t);
+ }
+ var index = this.game.enemies.indexOf(this);
+ if (index > -1) {
+ this.game.enemies.splice(index, 1);
+ }
+ this.destroy();
+ };
+});
+var BalrogEnemy = Container.expand(function () {
+ var self = Container.call(this);
+ var balrogGraphics = self.createAsset('balrogSprite', 'Balrog Enemy Sprite', .5, .5);
+ balrogGraphics.scale.set(2.5);
+ self.hitpoints = 500;
+ self.move = function (towers) {
+ var minDist = Infinity;
+ var closestTower = null;
+ for (var i = 0; i < self.game.towers.length; i++) {
+ var dx = self.game.towers[i].x - self.x;
+ var dy = self.game.towers[i].y - self.y;
+ var dist = Math.sqrt(dx * dx + dy * dy);
+ if (dist < minDist) {
+ minDist = dist;
+ closestTower = self.game.towers[i];
+ }
+ }
+ if (closestTower && minDist < closestTower.width / 2 + this.width / 2) {
+ closestTower.health -= 4;
+ if (closestTower.health <= 0) {
+ var towerIndex = self.game.towers.indexOf(closestTower);
+ if (towerIndex > -1) {
+ self.game.towers.splice(towerIndex, 1);
+ }
+ closestTower.destroy();
+ }
+ } else if (closestTower && minDist < 100) {
+ var avoidanceForce = 8;
+ var ax = this.x - closestTower.x;
+ var ay = this.y - closestTower.y;
+ var len = Math.sqrt(ax * ax + ay * ay);
+ ax = ax / len * avoidanceForce;
+ ay = ay / len * avoidanceForce;
+ this.x += ax;
+ this.y += ay;
+ } else {
+ this.zigzagCounter = this.zigzagCounter || 0;
+ this.zigzagDirection = this.zigzagDirection || 1;
+ if (this.zigzagCounter++ % self.zigzagTension === 0) this.zigzagDirection *= -1;
+ this.x += 4 * this.zigzagDirection;
+ this.y += 2;
+ if (Math.random() < 0.01) {
+ this.zigzagTension = Math.floor(Math.random() * 40) + 10;
+ }
+ if (this.x > 2048) {
+ this.zigzagDirection = -1;
+ }
+ if (this.x < 0) {
+ this.zigzagDirection = 1;
+ }
+ var scaleIncrement = (1 - 0.1) / 200;
+ this.scale.x += scaleIncrement;
+ this.scale.y += scaleIncrement;
+ this.scale.x = Math.min(this.scale.x, 1);
+ this.scale.y = Math.min(this.scale.y, 1);
+ if (this.zigzagCounter % 10 == 0) {
+ this.rotation = (0.5 - Math.random()) * (Math.PI * 2 / 100);
+ }
+ }
+ };
+ self.die = function () {
+ playerGold += 500;
+ playerScore += 10000;
+ this.game.updateScoreLabel();
+ this.game.updateGoldLabel();
+ for (var i = 0; i < 100; i++) {
+ var t = new GoldCoin(this.x, this.y, 720, 2450, i * 2);
+ this.game.addChild(t);
+ this.game.goldCoins.push(t);
+ }
+ var index = this.game.enemies.indexOf(this);
+ if (index > -1) {
+ this.game.enemies.splice(index, 1);
+ }
+ this.destroy();
+ };
+});
+var Tower = Container.expand(function (gameInstance) {
+ var self = Container.call(this);
+ self.game = gameInstance;
+ self.upgradeLevel = upgradeLevel;
+ var towerGraphics = self.createAsset('towerSprite', 'Tower Sprite', .5, .5);
+ var towerGraphics1 = self.createAsset('towerSprite1', 'Tower Sprite1', .5, .5);
+ var towerGraphics2 = self.createAsset('towerSprite2', 'Tower Sprite2', .5, .5);
+ var towerGraphics3 = self.createAsset('towerSprite3', 'Tower Sprite3', .5, .5);
+ var towerGraphics4 = self.createAsset('towerSprite4', 'Tower Sprite4', .5, .5);
+ var towerGraphics5 = self.createAsset('towerSprite5', 'Tower Sprite5', .5, .5);
+ var towerGraphics6 = self.createAsset('towerSprite6', 'Tower Sprite6', .5, .5);
+ var towerGraphics7 = self.createAsset('towerSprite7', 'Tower Sprite7', .5, .5);
+ var towerGraphics8 = self.createAsset('towerSprite8', 'Tower Sprite8', .5, .5);
+ towerGraphics.scale.set(2);
+ towerGraphics1.scale.set(2);
+ towerGraphics2.scale.set(2);
+ towerGraphics3.scale.set(2);
+ towerGraphics4.scale.set(2);
+ towerGraphics5.scale.set(2);
+ towerGraphics6.scale.set(2);
+ towerGraphics7.scale.set(2);
+ towerGraphics8.scale.set(2);
+ towerGraphics1.alpha = 0;
+ towerGraphics2.alpha = 0;
+ towerGraphics3.alpha = 0;
+ towerGraphics4.alpha = 0;
+ towerGraphics5.alpha = 0;
+ towerGraphics6.alpha = 0;
+ towerGraphics7.alpha = 0;
+ towerGraphics8.alpha = 0;
+ var a = [towerGraphics1, towerGraphics2, towerGraphics3, towerGraphics4, towerGraphics5, towerGraphics6, towerGraphics7, towerGraphics8];
+ if (upgradeLevel > 0) {
+ towerGraphics.alpha = 0;
+ for (var i = 0; i < 8; i++) {
+ if (i + 1 == upgradeLevel) {
+ a[i].alpha = 1;
+ } else {
+ a[i].alpha = 0;
+ }
+ }
+ }
+ self.shoot = function (enemies) {
+ if (self.shootCounter++ % towerShotDelay[self.upgradeLevel] === 0) {
+ for (var i = 0; i < enemies.length; i++) {
+ var enemy = enemies[i];
+ var dx = enemy.x - self.x;
+ var dy = enemy.y - self.y;
+ var distance = Math.sqrt(dx * dx + dy * dy);
+ if (distance <= 300) {
+ console.log('shot');
+ var bullet = new Bullet(self.upgradeLevel);
+ bullet.x = self.x;
+ bullet.y = self.y;
+ bullet.target = enemy;
+ var tx = bullet.target.x - bullet.x;
+ var ty = bullet.target.y - bullet.y;
+ var rad = Math.atan2(ty, tx);
+ bullet.rotation = rad + Math.PI / 2;
+ bullet.vx = Math.cos(rad);
+ bullet.vy = Math.sin(rad);
+ self.game.addBullet(bullet);
+ break;
+ }
+ }
+ }
+ };
+ self.upgrade = function () {};
+ self.shootCounter = 0;
+ self.health = 200;
+});
var Enemy = Container.expand(function () {
var self = Container.call(this);
- var enemyGraphics = self.createAsset('enemy', 'Enemy Graphics', .5, .5);
- self.move = function () {};
+ var enemyGraphics = self.createAsset('enemySprite', 'Enemy Sprite', .5, .5);
+ enemyGraphics.scale.set(0.8);
+ self.hitpoints = 3;
+ self.zigzagTension = Math.floor(Math.random() * 40) + 10;
+ self.move = function (towers) {
+ var minDist = Infinity;
+ var closestTower = null;
+ for (var i = 0; i < self.game.towers.length; i++) {
+ var dx = self.game.towers[i].x - self.x;
+ var dy = self.game.towers[i].y - self.y;
+ var dist = Math.sqrt(dx * dx + dy * dy);
+ if (dist < minDist) {
+ minDist = dist;
+ closestTower = self.game.towers[i];
+ }
+ }
+ if (closestTower && minDist < closestTower.width / 2 + this.width / 2) {
+ closestTower.health -= 0.5;
+ if (closestTower.health <= 0) {
+ var towerIndex = self.game.towers.indexOf(closestTower);
+ if (towerIndex > -1) {
+ self.game.towers.splice(towerIndex, 1);
+ }
+ closestTower.destroy();
+ }
+ } else if (closestTower && minDist < 100) {
+ var avoidanceForce = 8;
+ var ax = this.x - closestTower.x;
+ var ay = this.y - closestTower.y;
+ var len = Math.sqrt(ax * ax + ay * ay);
+ ax = ax / len * avoidanceForce;
+ ay = ay / len * avoidanceForce;
+ this.x += ax;
+ this.y += ay;
+ } else {
+ this.zigzagCounter = this.zigzagCounter || 0;
+ this.zigzagDirection = this.zigzagDirection || 1;
+ if (this.zigzagCounter++ % self.zigzagTension === 0) this.zigzagDirection *= -1;
+ this.x += 4 * this.zigzagDirection;
+ this.y += 2;
+ if (Math.random() < 0.01) {
+ this.zigzagTension = Math.floor(Math.random() * 40) + 10;
+ }
+ if (this.x > 2048) {
+ this.zigzagDirection = -1;
+ }
+ if (this.x < 0) {
+ this.zigzagDirection = 1;
+ }
+ var scaleIncrement = (1 - 0.1) / 200;
+ this.scale.x += scaleIncrement;
+ this.scale.y += scaleIncrement;
+ this.scale.x = Math.min(this.scale.x, 1);
+ this.scale.y = Math.min(this.scale.y, 1);
+ this.rotation = (0.5 - Math.random()) * (Math.PI * 2 / 50);
+ }
+ };
+ self.die = function () {
+ playerGold += 5;
+ playerScore += 100;
+ this.game.updateScoreLabel();
+ this.game.updateGoldLabel();
+ for (var i = 0; i < 5; i++) {
+ var t = new GoldCoin(this.x, this.y, 720, 2450, i * 2);
+ this.game.addChild(t);
+ this.game.goldCoins.push(t);
+ }
+ var index = this.game.enemies.indexOf(this);
+ if (index > -1) {
+ this.game.enemies.splice(index, 1);
+ }
+ this.destroy();
+ };
});
-var Bullet = Container.expand(function () {
+var OrcEnemy = Container.expand(function () {
var self = Container.call(this);
+ var enemyGraphics = self.createAsset('orcEnemySprite', 'Orc Enemy Sprite', .5, .5);
+ enemyGraphics.scale.set(0.8);
+ self.hitpoints = 6;
+ self.zigzagTension = Math.floor(Math.random() * 20) + 10;
+ self.move = function (towers) {
+ var minDist = Infinity;
+ var closestTower = null;
+ for (var i = 0; i < self.game.towers.length; i++) {
+ var dx = self.game.towers[i].x - self.x;
+ var dy = self.game.towers[i].y - self.y;
+ var dist = Math.sqrt(dx * dx + dy * dy);
+ if (dist < minDist) {
+ minDist = dist;
+ closestTower = self.game.towers[i];
+ }
+ }
+ if (closestTower && minDist < closestTower.width / 2 + this.width / 2) {
+ closestTower.health -= 0.8;
+ if (closestTower.health <= 0) {
+ var towerIndex = self.game.towers.indexOf(closestTower);
+ if (towerIndex > -1) {
+ self.game.towers.splice(towerIndex, 1);
+ }
+ closestTower.destroy();
+ }
+ } else if (closestTower && minDist < 100) {
+ var avoidanceForce = 8;
+ var ax = this.x - closestTower.x;
+ var ay = this.y - closestTower.y;
+ var len = Math.sqrt(ax * ax + ay * ay);
+ ax = ax / len * avoidanceForce;
+ ay = ay / len * avoidanceForce;
+ this.x += ax;
+ this.y += ay;
+ } else {
+ this.zigzagCounter = this.zigzagCounter || 0;
+ this.zigzagDirection = this.zigzagDirection || 1;
+ if (this.zigzagCounter++ % self.zigzagTension === 0) this.zigzagDirection *= -1;
+ this.x += 4 * this.zigzagDirection;
+ this.y += 2;
+ if (Math.random() < 0.01) {
+ this.zigzagTension = Math.floor(Math.random() * 40) + 10;
+ }
+ if (this.x > 2048) {
+ this.zigzagDirection = -1;
+ }
+ if (this.x < 0) {
+ this.zigzagDirection = 1;
+ }
+ var scaleIncrement = (1 - 0.1) / 200;
+ this.scale.x += scaleIncrement;
+ this.scale.y += scaleIncrement;
+ this.scale.x = Math.min(this.scale.x, 1);
+ this.scale.y = Math.min(this.scale.y, 1);
+ if (this.zigzagCounter % 5 == 0) {
+ this.rotation = (0.5 - Math.random()) * (Math.PI * 2 / 100);
+ }
+ }
+ };
+ self.die = function () {
+ playerGold += 10;
+ playerScore += 150;
+ this.game.updateScoreLabel();
+ this.game.updateGoldLabel();
+ for (var i = 0; i < 8; i++) {
+ var t = new GoldCoin(this.x, this.y, 720, 2450, i * 2);
+ this.game.addChild(t);
+ this.game.goldCoins.push(t);
+ }
+ var index = this.game.enemies.indexOf(this);
+ if (index > -1) {
+ this.game.enemies.splice(index, 1);
+ }
+ this.destroy();
+ };
+});
+var Bullet = Container.expand(function (upgradeLevel) {
+ var self = Container.call(this);
+ self.game = null;
+ self.upgradeLevel = upgradeLevel;
+ self.damage = towerDamage[self.upgradeLevel];
var bulletGraphics = self.createAsset('bullet', 'Bullet Graphics', .5, .5);
- self.move = function () {};
+ bulletGraphics.scale.set(0.2);
+ var bulletGraphics1 = self.createAsset('bulletSprite1', 'Bullet Sprite1', .5, .5);
+ var bulletGraphics2 = self.createAsset('bulletSprite2', 'Bullet Sprite2', .5, .5);
+ var bulletGraphics3 = self.createAsset('bulletSprite3', 'Bullet Sprite3', .5, .5);
+ var bulletGraphics4 = self.createAsset('bulletSprite4', 'Bullet Sprite4', .5, .5);
+ var bulletGraphics5 = self.createAsset('bulletSprite5', 'Bullet Sprite5', .5, .5);
+ var bulletGraphics6 = self.createAsset('bulletSprite6', 'Bullet Sprite6', .5, .5);
+ var bulletGraphics7 = self.createAsset('bulletSprite7', 'Bullet Sprite7', .5, .5);
+ var bulletGraphics8 = self.createAsset('bulletSprite8', 'Bullet Sprite8', .5, .5);
+ bulletGraphics1.scale.set(.2);
+ bulletGraphics2.scale.set(.2);
+ bulletGraphics3.scale.set(.2);
+ bulletGraphics4.scale.set(.2);
+ bulletGraphics5.scale.set(.2);
+ bulletGraphics6.scale.set(.2);
+ bulletGraphics7.scale.set(.2);
+ bulletGraphics8.scale.set(.2);
+ bulletGraphics1.alpha = 0;
+ bulletGraphics2.alpha = 0;
+ bulletGraphics3.alpha = 0;
+ bulletGraphics4.alpha = 0;
+ bulletGraphics5.alpha = 0;
+ bulletGraphics6.alpha = 0;
+ bulletGraphics7.alpha = 0;
+ bulletGraphics8.alpha = 0;
+ var a = [bulletGraphics1, bulletGraphics2, bulletGraphics3, bulletGraphics4, bulletGraphics5, bulletGraphics6, bulletGraphics7, bulletGraphics8];
+ if (self.upgradeLevel > 0) {
+ bulletGraphics.alpha = 0;
+ for (var i = 0; i < 8; i++) {
+ if (i + 1 == self.upgradeLevel) {
+ a[i].alpha = 1;
+ } else {
+ a[i].setAlpha = 0;
+ }
+ }
+ }
+ self.vx = 0;
+ self.vy = 0;
+ self.move = function () {
+ if (this.target) {
+ var tx = this.target.x - this.x;
+ var ty = this.target.y - this.y;
+ var dist = Math.sqrt(tx * tx + ty * ty);
+ if (dist > 0) {
+ this.x += this.vx * 10;
+ this.y += this.vy * 10;
+ }
+ if (dist < this.width / 2 + this.target.width / 2) {
+ this.hit();
+ } else if (this.x < 0 || this.x > 2048 || this.y < 0 || this.y > 2732) {
+ this.destroy();
+ }
+ }
+ };
+ self.hit = function () {
+ this.target.hitpoints -= this.damage;
+ if (this.target.hitpoints <= 0 && !this.target.dead) {
+ this.target.dead = true;
+ this.target.die();
+ }
+ this.destroy();
+ };
});
var Game = Container.expand(function () {
var self = Container.call(this);
- var towers = [];
- var enemies = [];
+ self.updateGoldLabel = function () {
+ goldLabel.setText('Gold: ' + playerGold);
+ };
+ self.updateScoreLabel = function () {
+ scoreLabel.setText('Score: ' + playerScore);
+ };
+ self.updateCostLabel = function () {
+ costLabel.setText('Cost: ' + upgradeCost);
+ };
+ self.playerGold = 0;
+ self.addBullet = function (bullet) {
+ bullets.push(bullet);
+ self.addChild(bullet);
+ };
+ self.sufficientDistanceToOtherTowers = function (position) {
+ for (var i = 0; i < self.towers.length; i++) {
+ var tower = self.towers[i];
+ var dx = tower.x - position.x;
+ var dy = tower.y - position.y;
+ var distance = Math.sqrt(dx * dx + dy * dy);
+ if (distance < 120) {
+ return false;
+ }
+ }
+ return true;
+ };
+ var background = self.createAsset('background', 'Background Image', 0, 0);
+ background.width = 2048;
+ background.height = 2732;
+ background.y = 0;
+ self.addChildAt(background, 0);
+ self.towers = [];
+ self.enemies = [];
var bullets = [];
- LK.stageContainer.setBackgroundColor(0x008080);
- var tower = self.addChild(new Tower());
- tower.x = 1024;
- tower.y = 1366;
- towers.push(tower);
- var enemy = self.addChild(new Enemy());
- enemy.x = 0;
- enemy.y = 1366;
- enemies.push(enemy);
+ self.goldCoins = [];
+ var selectedTowerType = null;
+ var initialEnemy = new Enemy();
+ initialEnemy.game = self;
+ initialEnemy.x = 300 + Math.random() * (1848 - 300);
+ initialEnemy.y = 200;
+ initialEnemy.scale.set(0.1);
+ self.enemies.push(initialEnemy);
+ self.addChild(initialEnemy);
LK.on('tick', function () {
- for (var i = 0; i < towers.length; i++) {
- towers[i].shoot();
+ self.enemySpawnCounter = self.enemySpawnCounter || 0;
+ self.totalEnemiesSpawned = self.totalEnemiesSpawned || 0;
+ if (++self.enemySpawnCounter >= enemySpawnDelay) {
+ var newEnemy;
+ if (self.totalEnemiesSpawned > 200 && self.totalEnemiesSpawned % 199 == 0) {
+ newEnemy = new BalrogEnemy();
+ } else if (self.totalEnemiesSpawned > 3 && self.totalEnemiesSpawned % 50 == 0) {
+ newEnemy = new DeathKnightEnemy();
+ } else if (self.totalEnemiesSpawned > 3 && self.totalEnemiesSpawned % 10 == 0) {
+ newEnemy = new TrollEnemy();
+ } else {
+ if (Math.random() < 0.2 + upgradeLevel * 0.06) {
+ newEnemy = new OrcEnemy();
+ } else {
+ newEnemy = new Enemy();
+ }
+ }
+ if (newEnemy) {
+ newEnemy.game = self;
+ newEnemy.x = 300 + Math.random() * (1848 - 300);
+ newEnemy.y = 200;
+ newEnemy.scale.set(0.1);
+ self.enemies.push(newEnemy);
+ self.addChild(newEnemy);
+ }
+ self.totalEnemiesSpawned++;
+ if (self.totalEnemiesSpawned > 0 && self.totalEnemiesSpawned % 20 == 0) {
+ enemySpawnDelay -= 4;
+ if (enemySpawnDelay < 20) {
+ enemySpawnDelay = 20;
+ }
+ }
+ self.enemySpawnCounter = 0;
}
- for (var i = 0; i < enemies.length; i++) {
- enemies[i].move();
+ for (var i = 0; i < self.enemies.length; i++) {
+ self.enemies[i].move();
+ if (self.enemies[i].y >= 2332 - self.enemies[i].height / 2) {
+ LK.showGameOver();
+ }
}
- for (var i = 0; i < bullets.length; i++) {
- bullets[i].move();
+ for (var j = 0; j < self.towers.length; j++) {
+ self.towers[j].shoot(self.enemies);
}
+ for (var k = bullets.length - 1; k >= 0; k--) {
+ bullets[k].move();
+ if (!bullets[k].parent) {
+ bullets.splice(k, 1);
+ }
+ }
+ for (var l = self.goldCoins.length - 1; l >= 0; l--) {
+ self.goldCoins[l].move();
+ if (!self.goldCoins[l].parent) {
+ self.goldCoins.splice(l, 1);
+ }
+ }
});
+ stage.on('down', function (obj) {
+ var position = obj.event.getLocalPosition(self);
+ if (position.y >= 600 && position.y <= 2112) {
+ if (playerGold >= 10) {
+ if (self.sufficientDistanceToOtherTowers(position)) {
+ playerGold -= 10;
+ var newTower = self.addChild(new Tower(self));
+ newTower.x = position.x;
+ newTower.y = position.y;
+ self.towers.push(newTower);
+ self.towers.sort(function (a, b) {
+ return a.y - b.y;
+ });
+ self.towers.forEach(function (tower, index) {
+ self.addChildAt(tower, 6 + index);
+ console.log('y and zIndex:' + tower.y + ', ' + tower.parent.getChildIndex(tower));
+ });
+ self.updateGoldLabel();
+ }
+ }
+ }
+ });
+ stage.on('move', function (obj) {});
+ stage.on('up', function (obj) {});
+ var cityWall = self.addChild(new CityWall());
+ cityWall.y = 2632;
+ cityWall.x = 332;
+ cityWall.scale.y = 0.5;
+ cityWall.scale.x = 0.5;
+ var cityWall2 = self.addChild(new CityWall());
+ cityWall2.y = 2632;
+ cityWall2.x = 1012;
+ cityWall2.scale.y = 0.5;
+ cityWall2.scale.x = 0.5;
+ var cityWall3 = self.addChild(new CityWall());
+ cityWall3.y = 2632;
+ cityWall3.x = 1691;
+ cityWall3.scale.y = 0.5;
+ cityWall3.scale.x = 0.5;
+ var bottomBlackBox = self.createAsset('blackBox', 'Black Box at bottom', 0, 1);
+ bottomBlackBox.width = 2048;
+ bottomBlackBox.height = 400;
+ bottomBlackBox.y = 2732;
+ self.addChild(bottomBlackBox);
+ var goldLabel = new Text2('Gold: 30', {
+ size: 100,
+ fill: '#ffd700',
+ align: 'left',
+ dropShadow: true
+ });
+ goldLabel.x = 120;
+ goldLabel.y = 2632 - bottomBlackBox.height + (bottomBlackBox.height - goldLabel.height) / 2;
+ self.addChild(goldLabel);
+ var scoreLabel = new Text2('Score: 0', {
+ size: 100,
+ fill: '#ccbbff',
+ align: 'left',
+ dropShadow: true
+ });
+ scoreLabel.x = 120;
+ scoreLabel.y = 2772 - bottomBlackBox.height + (bottomBlackBox.height - scoreLabel.height) / 2;
+ self.addChild(scoreLabel);
+ var instructionLabel = new Text2("Tap to build towers (cost 10 gold)\nDon't let enemies reach the City Wall!", {
+ size: 58,
+ fill: '#eeeeee',
+ align: 'left',
+ dropShadow: true
+ });
+ instructionLabel.x = 920;
+ instructionLabel.y = 2632 - bottomBlackBox.height + (bottomBlackBox.height - instructionLabel.height) / 2;
+ self.addChild(instructionLabel);
+ var treasureChest = self.addChild(new TreasureChest());
+ treasureChest.scale.x = 1.3;
+ treasureChest.scale.y = 1.3;
+ treasureChest.x = 720;
+ treasureChest.y = goldLabel.y + 65;
+ var upgradeButton = self.addChild(new UpgradeButton());
+ upgradeButton.x = 1500;
+ upgradeButton.y = 2590;
+ self.upgradeLabel = new Text2("Upgrade Towers:", {
+ size: 58,
+ fill: '#dddddd',
+ align: 'left',
+ dropShadow: true
+ });
+ self.upgradeLabel.x = 920;
+ self.upgradeLabel.y = 2552;
+ self.addChild(self.upgradeLabel);
+ var costLabel = new Text2("Cost: 100", {
+ size: 58,
+ fill: '#dddd00',
+ align: 'left',
+ dropShadow: true
+ });
+ costLabel.x = 1600;
+ costLabel.y = 2552;
+ self.addChild(costLabel);
+ self.upgradeTowers = function () {
+ if (playerGold >= upgradeCost) {
+ playerGold -= upgradeCost;
+ upgradeLevel += 1;
+ upgradeCost *= 2;
+ self.updateGoldLabel();
+ self.updateCostLabel();
+ if (upgradeLevel == 8) {
+ self.upgradeLabel.setText('All upgraded - Go for the High Score!');
+ if (upgradeButton) {
+ upgradeButton.destroy();
+ upgradeButton = null;
+ }
+ if (costLabel) {
+ costLabel.destroy();
+ costLabel = null;
+ }
+ }
+ }
+ };
+ upgradeButton.on('down', self.upgradeTowers);
});
A medieval wall built of ice blocks, with stars and christmas hearts as ornaments. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
A wooden plan with snow on top edge. In game gui element. Flat front view. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
A square metal button with the image of a tower. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
A turret tower built of iceblocks. Front view perspective. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
A snowball. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
A turret tower built of ice blocks. Front view perspective. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
A turret tower built of ice blocks. Front view perspective. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
A turret tower built of ice blocks. Front view perspective. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
A super awesome turret tower built of ice blocks. Front view perspective. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
A turret tower constructed out of square ice blocks. Front view perspective. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
A pine cone. Pixelart. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
A terrible frost giant enemy sprite. Pixelart. Front view. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
A frost orc enemy sprite. pixelart. front view. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
A winter goblin enemy character. Pixelart. front view. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
A winter horned ogre enemy character. pixelart. front view.. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
A straw goat christmas decoration. Pixelart. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
A christmas tree. Pixelart. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
A golden star. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
A gingerbread man. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
a heart christmas decoration. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
a white christmas present with red wrapper. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
A candy cane. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
A blue christmas present. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
An open sack. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
A snow covered plains stretching to horizon. Top down perspective view from afar. Rich winter colors. Illustration. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.