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

264
index.js
View File

@ -27,14 +27,13 @@ window.onload = function () {
let Game = {
state: 2,
enemies: [],
enemySpawnList: [],
towers: [],
particles: [],
selltext: [],
map: null,
health: 100,
money: 100,
enemySpawn: 0,
pace: 1,
wave: 0,
waveTimer: 0,
tower: 'simple',
@ -57,7 +56,7 @@ window.onload = function () {
node: 1,
health: 50,
reward: 10,
frequency: 1000,
frequency: 40,
icon: '#f00'
},
speedy: {
@ -65,15 +64,15 @@ window.onload = function () {
node: 1,
health: 60,
reward: 15,
frequency: 500,
frequency: 35,
icon: '#f11'
},
tough: {
speed: 5,
node: 1,
health: 150,
health: 80,
reward: 20,
frequency: 1000,
frequency: 40,
icon: '#f40'
}
}
@ -166,6 +165,72 @@ window.onload = function () {
{x: 5, y: 12, end: false},
{x: 1, y: 12, end: false},
{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 () {
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.elUpdate()
}
@ -508,39 +573,92 @@ window.onload = function () {
}
}
// Use this function to spawn enemies depending on round
function nextWave () {
Game.wave++
// Total enemy spawn count is used to determine that the round is over
// Local (in-function) determines how many there are left to spawn as ordered by the function call
function addEnemies (enemies, type, specs) {
let path = Game.map.pathgen[0]
let enemy = Enemies[type]
// Copy the enemy and add x and y coordinates
let enemyCopy = Object.assign({
x: path.x,
y: path.y
}, enemy)
if (Game.wave < 5) {
addEnemies(10 + Game.wave, Enemies.basic)
} else {
addEnemies(10 + Game.wave, Enemies.speedy)
// Modify the enemy according to wave settings
if (specs.healthIncrease) {
enemyCopy.health += specs.healthIncrease
}
if (Game.wave > 10) {
addEnemies(Game.wave - 5, Enemies.tough)
if (specs.speedIncrease) {
enemyCopy.speed += specs.speedIncrease
}
if (Game.wave % 5 === 0) {
addEnemies(Game.wave / 5, Enemies.tough)
enemyCopy.dmg = enemyCopy.health
// 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 waveEnemyModifer (enemy, round) {
// Reduce the time between enemy spawns
let fr = enemy.frequency - 5 * round
if (fr < 100) {
fr = 100
function nextWave () {
Game.wave++
for (let i in Game.map.waves) {
let wv = Game.map.waves[i]
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) {
@ -584,8 +702,8 @@ window.onload = function () {
}
if (enemy.velocity.dist > 0.1) {
enemy.x += (enemy.velocity.x * 0.01) * enemy.speed * Game.pace
enemy.y += (enemy.velocity.y * 0.01) * enemy.speed * Game.pace
enemy.x += (enemy.velocity.x * 0.01) * enemy.speed
enemy.y += (enemy.velocity.y * 0.01) * enemy.speed
} else {
if (Game.map.pathgen[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)
}
}
@ -722,31 +840,16 @@ window.onload = function () {
Game.towerSel = tower
}
// Total enemy spawn count is used to determine that the round is over
// Local (in-function) determines how many there are left to spawn as ordered by the function call
function addEnemies (cnt, type) {
Game.enemySpawn += cnt // Total amount of enemies to spawn
let enemies = cnt // Local amount of enemies to spawn
let path = Game.map.pathgen[0]
// 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 spawnQueue () {
if (Game.enemySpawnList.length) {
for (let i in Game.enemySpawnList) {
let ef = Game.enemySpawnList[i]
if (ef.time < Game.waveTimer) {
Game.enemies.push(ef)
Game.enemySpawnList.splice(i, 1)
}
}
}
}
function getTowerAt (x, y) {
@ -767,9 +870,9 @@ window.onload = function () {
// Prevent towers from being placed right next to each-other
let can = true
for (let i in Game.towers) {
for (let j in Game.towers) {
if (can === false) break
let tower = Game.towers[i]
let tower = Game.towers[j]
// tower placement restriction visualization
for (let i = 0; i < 4; i++) {
@ -795,11 +898,14 @@ window.onload = function () {
}
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
Game.money -= tower.cost
if (!Game.debug) {
Game.money -= tower.cost
}
Game.towers.push(Object.assign({
x: x,
y: y,
@ -864,8 +970,11 @@ window.onload = function () {
if (Game.state === 1) {
Game.waveTimer++
}
spawnQueue()
}
let lastRenderTime = Date.now()
function render () {
let mt = Maps.tile
ctx.fillStyle = '#0fa'
@ -894,8 +1003,8 @@ window.onload = function () {
}
// Draw obstructed tiles
if (Game.state == 2 && tile == 0 && !getTowerAt(x, y) && !canPlaceTowerAt(x, y)) {
ctx.fillStyle = 'rgba(255, 0, 0, 0.45)'
if (Game.state === 2 && tile === 0 && !canPlaceTowerAt(x, y)) {
ctx.fillStyle = '#738c5d'
ctx.fillRect(x * mt, y * mt, mt, mt)
}
}
@ -914,6 +1023,12 @@ window.onload = function () {
let tower = Game.towers[i]
ctx.fillStyle = tower.icon
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
@ -932,6 +1047,12 @@ window.onload = function () {
ctx.fillStyle = '#0f0'
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
@ -951,7 +1072,7 @@ window.onload = function () {
towerData = Game.towerSel
vX = towerData.x
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) {
vX = mX
vY = mY
@ -1007,6 +1128,17 @@ window.onload = function () {
if (!(cmp) instanceof Component) continue
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()