new round system, debug mode

This commit is contained in:
Evert Prants 2017-08-22 19:19:00 +03:00
parent 2284ddd28a
commit fc91932513
Signed by: evert
GPG Key ID: 1688DA83D222D0B5

266
index.js
View File

@ -27,14 +27,13 @@ window.onload = function () {
let Game = { let Game = {
state: 2, state: 2,
enemies: [], enemies: [],
enemySpawnList: [],
towers: [], towers: [],
particles: [], particles: [],
selltext: [], selltext: [],
map: null, map: null,
health: 100, health: 100,
money: 100, money: 100,
enemySpawn: 0,
pace: 1,
wave: 0, wave: 0,
waveTimer: 0, waveTimer: 0,
tower: 'simple', tower: 'simple',
@ -57,7 +56,7 @@ window.onload = function () {
node: 1, node: 1,
health: 50, health: 50,
reward: 10, reward: 10,
frequency: 1000, frequency: 40,
icon: '#f00' icon: '#f00'
}, },
speedy: { speedy: {
@ -65,15 +64,15 @@ window.onload = function () {
node: 1, node: 1,
health: 60, health: 60,
reward: 15, reward: 15,
frequency: 500, frequency: 35,
icon: '#f11' icon: '#f11'
}, },
tough: { tough: {
speed: 5, speed: 5,
node: 1, node: 1,
health: 150, health: 80,
reward: 20, reward: 20,
frequency: 1000, frequency: 40,
icon: '#f40' icon: '#f40'
} }
} }
@ -166,6 +165,72 @@ window.onload = function () {
{x: 5, y: 12, end: false}, {x: 5, y: 12, end: false},
{x: 1, y: 12, end: false}, {x: 1, y: 12, end: false},
{x: 1, y: 17, end: true}, {x: 1, y: 17, end: true},
],
waves: [
{
type: 'recurring',
waveLow: 0,
waveHigh: 10,
enemies: [{
type: 'basic',
count: 5,
inclCount: true,
inclHealth: true
}]
},
{
type: 'recurring',
waveLow: 10,
waveHigh: 15,
enemies: [{
type: 'basic',
count: 5,
inclCount: true,
inclHealth: true
},
{
type: 'speedy',
count: 10,
inclCount: true,
inclHealth: true
}]
},
{
type: 'recurring',
waveLow: 15,
enemies: [{
type: 'basic',
count: 5,
inclCount: true,
inclHealth: true,
inclSpeed: true
},
{
type: 'speedy',
count: 10,
inclCount: true,
inclHealth: true,
inclSpeed: true
}]
},
{
type: 'once-every',
every: 5,
enemies: [{
type: 'tough',
count: 5,
inclCount: true,
inclHealth: true
}]
},
{
type: 'once',
wave: 5,
enemies: [{
type: 'tough',
count: 2
}]
}
] ]
} }
} }
@ -364,7 +429,7 @@ window.onload = function () {
update () { update () {
super.update() super.update()
this.disabled = this.towerObj.cost > Game.money this.disabled = this.towerObj.cost > Game.money && !Game.debug
this.active = Game.tower === this.tower this.active = Game.tower === this.tower
this.elUpdate() this.elUpdate()
} }
@ -508,39 +573,92 @@ window.onload = function () {
} }
} }
// Use this function to spawn enemies depending on round // Total enemy spawn count is used to determine that the round is over
function nextWave () { // Local (in-function) determines how many there are left to spawn as ordered by the function call
Game.wave++ function addEnemies (enemies, type, specs) {
let path = Game.map.pathgen[0]
if (Game.wave < 5) { let enemy = Enemies[type]
addEnemies(10 + Game.wave, Enemies.basic) // Copy the enemy and add x and y coordinates
} else { let enemyCopy = Object.assign({
addEnemies(10 + Game.wave, Enemies.speedy) x: path.x,
y: path.y
}, enemy)
// Modify the enemy according to wave settings
if (specs.healthIncrease) {
enemyCopy.health += specs.healthIncrease
} }
if (Game.wave > 10) { if (specs.speedIncrease) {
addEnemies(Game.wave - 5, Enemies.tough) enemyCopy.speed += specs.speedIncrease
} }
if (Game.wave % 5 === 0) { enemyCopy.dmg = enemyCopy.health
addEnemies(Game.wave / 5, Enemies.tough)
// Insert them into the spawn queue
for (let i = 0; i < enemies; i++) {
if (Game.debug) {
console.log('added %s to spawn at %d', type, enemyCopy.frequency * i)
}
Game.enemySpawnList.push(Object.assign({
time: enemyCopy.frequency * i
}, enemyCopy))
} }
} }
// Use this function to modify the enemies spawned each round function nextWave () {
function waveEnemyModifer (enemy, round) { Game.wave++
// Reduce the time between enemy spawns
let fr = enemy.frequency - 5 * round for (let i in Game.map.waves) {
if (fr < 100) { let wv = Game.map.waves[i]
fr = 100 let eSpawn = false
if (wv.type === 'once-every' && Game.wave % wv.every === 0) {
eSpawn = true
} else if (wv.type === 'once' && Game.wave === wv.wave) {
eSpawn = true
} else if (wv.type === 'recurring' && Game.wave >= wv.waveLow && (wv.waveHigh ? Game.wave < wv.waveHigh : true)) {
eSpawn = true
}
if (!eSpawn) continue
for (let i in wv.enemies) {
let e = wv.enemies[i]
let eCount = e.count || 5
let eHealthIncl = 0
let eSpeedIncl = 0
if (e.inclCount === true) {
eCount += Game.wave
}
if (e.baseHealth) {
eHealthIncl = e.baseHealth
}
if (e.baseSpeed) {
eSpeedIncl = e.baseSpeed
}
if (e.inclHealth === true) {
eHealthIncl = Game.wave * 5
if (eHealthIncl > 500) {
eHealthIncl = 500
}
}
if (e.inclSpeed === true) {
eSpeedIncl = Game.wave / 5
if (eSpeedIncl > 5) {
eSpeedIncl = 5
}
}
addEnemies(eCount, e.type, {
healthIncrease: eHealthIncl,
speedIncrease: eSpeedIncl
})
}
} }
enemy.frequency = fr
// Increase enemy health
enemy.health += round * 5
return enemy
} }
function getTileIn (map, x, y) { function getTileIn (map, x, y) {
@ -584,8 +702,8 @@ window.onload = function () {
} }
if (enemy.velocity.dist > 0.1) { if (enemy.velocity.dist > 0.1) {
enemy.x += (enemy.velocity.x * 0.01) * enemy.speed * Game.pace enemy.x += (enemy.velocity.x * 0.01) * enemy.speed
enemy.y += (enemy.velocity.y * 0.01) * enemy.speed * Game.pace enemy.y += (enemy.velocity.y * 0.01) * enemy.speed
} else { } else {
if (Game.map.pathgen[enemy.node + 1]) { if (Game.map.pathgen[enemy.node + 1]) {
enemy.node += 1 enemy.node += 1
@ -599,7 +717,7 @@ window.onload = function () {
} }
} }
if (Game.state === 1 && Game.enemies.length === 0 && Game.enemySpawn === 0) { if (Game.state === 1 && Game.enemies.length === 0 && Game.enemySpawnList.length === 0) {
updateGameState(2) updateGameState(2)
} }
} }
@ -722,31 +840,16 @@ window.onload = function () {
Game.towerSel = tower Game.towerSel = tower
} }
// Total enemy spawn count is used to determine that the round is over function spawnQueue () {
// Local (in-function) determines how many there are left to spawn as ordered by the function call if (Game.enemySpawnList.length) {
function addEnemies (cnt, type) { for (let i in Game.enemySpawnList) {
Game.enemySpawn += cnt // Total amount of enemies to spawn let ef = Game.enemySpawnList[i]
let enemies = cnt // Local amount of enemies to spawn if (ef.time < Game.waveTimer) {
Game.enemies.push(ef)
let path = Game.map.pathgen[0] Game.enemySpawnList.splice(i, 1)
// Copy the enemy and add x and y coordinates }
let enemyCopy = Object.assign({ }
x: path.x, }
y: path.y
}, type)
// Modify the enemy according to wave settings
enemyCopy = waveEnemyModifer(enemyCopy, Game.wave)
enemyCopy.dmg = enemyCopy.health
// Copy the enemy at an interval and spawn it
let ect = setInterval(() => {
if (enemies === 0) return clearInterval(ect)
Game.enemySpawn-- // Reduce total spawn count
enemies-- // Reduce local spawn count
Game.enemies.push(Object.assign({}, enemyCopy))
}, enemyCopy.frequency)
} }
function getTowerAt (x, y) { function getTowerAt (x, y) {
@ -767,9 +870,9 @@ window.onload = function () {
// Prevent towers from being placed right next to each-other // Prevent towers from being placed right next to each-other
let can = true let can = true
for (let i in Game.towers) { for (let j in Game.towers) {
if (can === false) break if (can === false) break
let tower = Game.towers[i] let tower = Game.towers[j]
// tower placement restriction visualization // tower placement restriction visualization
for (let i = 0; i < 4; i++) { for (let i = 0; i < 4; i++) {
@ -795,11 +898,14 @@ window.onload = function () {
} }
function placeTower (tower, x, y) { function placeTower (tower, x, y) {
if (tower.cost > Game.money) return // no money if (tower.cost > Game.money && !Game.debug) return // no money
if (!canPlaceTowerAt(x, y)) return if (!canPlaceTowerAt(x, y)) return
Game.money -= tower.cost if (!Game.debug) {
Game.money -= tower.cost
}
Game.towers.push(Object.assign({ Game.towers.push(Object.assign({
x: x, x: x,
y: y, y: y,
@ -864,8 +970,11 @@ window.onload = function () {
if (Game.state === 1) { if (Game.state === 1) {
Game.waveTimer++ Game.waveTimer++
} }
spawnQueue()
} }
let lastRenderTime = Date.now()
function render () { function render () {
let mt = Maps.tile let mt = Maps.tile
ctx.fillStyle = '#0fa' ctx.fillStyle = '#0fa'
@ -894,8 +1003,8 @@ window.onload = function () {
} }
// Draw obstructed tiles // Draw obstructed tiles
if (Game.state == 2 && tile == 0 && !getTowerAt(x, y) && !canPlaceTowerAt(x, y)) { if (Game.state === 2 && tile === 0 && !canPlaceTowerAt(x, y)) {
ctx.fillStyle = 'rgba(255, 0, 0, 0.45)' ctx.fillStyle = '#738c5d'
ctx.fillRect(x * mt, y * mt, mt, mt) ctx.fillRect(x * mt, y * mt, mt, mt)
} }
} }
@ -914,6 +1023,12 @@ window.onload = function () {
let tower = Game.towers[i] let tower = Game.towers[i]
ctx.fillStyle = tower.icon ctx.fillStyle = tower.icon
ctx.fillRect(tower.x * mt + 2, tower.y * mt + 2, 28, 28) ctx.fillRect(tower.x * mt + 2, tower.y * mt + 2, 28, 28)
if (Game.debug) {
ctx.fillStyle = '#f11'
ctx.font = '10px Helvetica'
ctx.fillText(tower.tick, tower.x * mt + 10, tower.y * mt + 25)
}
} }
// Draw enemies // Draw enemies
@ -932,6 +1047,12 @@ window.onload = function () {
ctx.fillStyle = '#0f0' ctx.fillStyle = '#0f0'
ctx.fillRect(hx, hy, (16 + 12) * enemy.dmg / enemy.health, 5) ctx.fillRect(hx, hy, (16 + 12) * enemy.dmg / enemy.health, 5)
if (Game.debug) {
ctx.fillStyle = '#511'
ctx.font = '10px Helvetica'
ctx.fillText(enemy.dmg, hx + 10, hy + 25)
}
} }
// Draw bullets // Draw bullets
@ -951,7 +1072,7 @@ window.onload = function () {
towerData = Game.towerSel towerData = Game.towerSel
vX = towerData.x vX = towerData.x
vY = towerData.y vY = towerData.y
} else if (towerData != null && towerData.cost <= Game.money && canPlaceTowerAt (mX, mY) && } else if (towerData != null && towerData.cost <= Game.money && canPlaceTowerAt(mX, mY) &&
mX < Maps.width && mY < Maps.height && Game.state === 2) { mX < Maps.width && mY < Maps.height && Game.state === 2) {
vX = mX vX = mX
vY = mY vY = mY
@ -1007,6 +1128,17 @@ window.onload = function () {
if (!(cmp) instanceof Component) continue if (!(cmp) instanceof Component) continue
cmp.draw() cmp.draw()
} }
if (Game.debug) {
ctx.fillStyle = '#f11'
ctx.font = '10px Helvetica'
ctx.fillText('enemy queue length ' + Game.enemySpawnList.length, 5, 580)
ctx.fillText('enemy count ' + Game.enemies.length, 5, 590)
ctx.fillText('tower count ' + Game.towers.length, 5, 600)
ctx.fillText('particle count ' + Game.particles.length, 5, 610)
ctx.fillText('render tick ms ' + (Date.now() - lastRenderTime), 5, 620)
lastRenderTime = Date.now()
}
} }
let lastTime = Date.now() let lastTime = Date.now()