tower selection and info box

This commit is contained in:
Evert Prants 2017-08-22 11:57:48 +03:00
parent b1d9f469bc
commit 9d1aac4a73
Signed by: evert
GPG Key ID: 1688DA83D222D0B5

134
index.js
View File

@ -35,6 +35,7 @@ window.onload = function () {
wave: 0, wave: 0,
waveTimer: 0, waveTimer: 0,
tower: 'simple', tower: 'simple',
towerSel: null,
sellRatio: .8 sellRatio: .8
} }
@ -155,6 +156,7 @@ window.onload = function () {
class Component { class Component {
constructor (x, y) { constructor (x, y) {
this.visible = true
this.x = x this.x = x
this.y = y this.y = y
} }
@ -179,6 +181,7 @@ window.onload = function () {
} }
draw () { draw () {
if (!this.visible) return
if (this.font) ctx.font = this.font if (this.font) ctx.font = this.font
ctx.fillStyle = this.color ctx.fillStyle = this.color
ctx.fillRect(this.x, this.y, this.w, this.h) ctx.fillRect(this.x, this.y, this.w, this.h)
@ -226,6 +229,7 @@ window.onload = function () {
} }
draw () { draw () {
if (!this.visible) return
if (this.active) { if (this.active) {
ctx.fillStyle = '#afa' ctx.fillStyle = '#afa'
ctx.fillRect(this.x - 2, this.y - 2, this.w + 4, this.h + 4) ctx.fillRect(this.x - 2, this.y - 2, this.w + 4, this.h + 4)
@ -263,14 +267,17 @@ window.onload = function () {
} }
function clickBtn () { function clickBtn () {
let click = false
for (let i in Components) { for (let i in Components) {
let btn = Components[i] let btn = Components[i]
if (!(btn instanceof ButtonComponent)) continue if (!(btn instanceof ButtonComponent)) continue
if (btn.disabled) continue if (btn.disabled || !btn.visible) continue
if (mXr > btn.x && mYr > btn.y && mXr < btn.x + btn.w && mYr < btn.y + btn.h) { if (mXr > btn.x && mYr > btn.y && mXr < btn.x + btn.w && mYr < btn.y + btn.h) {
btn.fn() btn.fn()
click = true
} }
} }
return click
} }
// Use this function to spawn enemies depending on round // Use this function to spawn enemies depending on round
@ -394,12 +401,14 @@ window.onload = function () {
Game.particles.push({ Game.particles.push({
x: tower.x, x: tower.x,
y: tower.y, y: tower.y,
tower: {x: tower.x, y: tower.y},
velX: (target.x - tower.x) / target.dist * 1.24, velX: (target.x - tower.x) / target.dist * 1.24,
velY: (target.y - tower.y) / target.dist * 1.24, velY: (target.y - tower.y) / target.dist * 1.24,
dmg: tower.damage, dmg: tower.damage,
speed: tower.speed, speed: tower.speed,
life: 100 life: 100
}) })
tower.fires++
} }
function tickTowers () { function tickTowers () {
@ -440,6 +449,11 @@ window.onload = function () {
if (enemy.dmg <= 0) { if (enemy.dmg <= 0) {
Game.enemies.splice(j, 1) Game.enemies.splice(j, 1)
Game.money += 10 Game.money += 10
let tower = getTowerAt(parti.tower.x, parti.tower.y)
if (tower) {
tower.killcount++
}
} }
// remove particle // remove particle
@ -449,6 +463,8 @@ window.onload = function () {
} }
} }
// Render text telling the amount of money received when selling a tower
// Disappears after 30 game ticks
function tickSellText () { function tickSellText () {
for (let i in Game.selltext) { for (let i in Game.selltext) {
let txt = Game.selltext[i] let txt = Game.selltext[i]
@ -456,12 +472,18 @@ window.onload = function () {
txt.tick %= 30 txt.tick %= 30
if (txt.tick === 0) { if (txt.tick === 0) {
Game.selltext.splice(i, 1) Game.selltext.splice(i, 1)
continue
} }
txt.y -= 0.05 txt.y -= 0.05
} }
} }
function selectTower (x, y) {
let tower = getTowerAt(x, y)
Game.towerSel = tower
}
// Total enemy spawn count is used to determine that the round is over // 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 // Local (in-function) determines how many there are left to spawn as ordered by the function call
function addEnemies (cnt, type) { function addEnemies (cnt, type) {
@ -544,12 +566,14 @@ window.onload = function () {
x: x, x: x,
y: y, y: y,
tick: tower.rate, tick: tower.rate,
setting: 1 setting: 1,
fires: 0,
killcount: 0
}, tower)) }, tower))
} }
function sellTower (x, y) { function sellTower (x, y) {
var tower = getTowerAt(x, y) let tower = getTowerAt(x, y)
if(tower) { if(tower) {
let amount = tower.cost * Game.sellRatio let amount = tower.cost * Game.sellRatio
Game.money += amount Game.money += amount
@ -559,6 +583,11 @@ window.onload = function () {
amount: amount, amount: amount,
tick: 0 tick: 0
}) })
if (Game.towerSel && Game.towerSel.x === x && Game.towerSel.y === y) {
Game.towerSel = null
}
return Game.towers.splice(Game.towers.indexOf(tower), 1) return Game.towers.splice(Game.towers.indexOf(tower), 1)
}else{ }else{
return null return null
@ -597,6 +626,8 @@ window.onload = function () {
if (Game.state === 1) { if (Game.state === 1) {
Game.waveTimer++ Game.waveTimer++
} }
Components.sell.visible = Game.towerSel !== null
} }
function render () { function render () {
@ -609,7 +640,7 @@ window.onload = function () {
let index = parseInt(i) let index = parseInt(i)
let y = Math.floor(index / Maps.width) let y = Math.floor(index / Maps.width)
let x = Math.floor(index % Maps.height) let x = Math.floor(index % Maps.height)
var draw_tile = true let draw_tile = true
if (tile === 1) { if (tile === 1) {
ctx.fillStyle = '#fdd' ctx.fillStyle = '#fdd'
@ -666,20 +697,31 @@ window.onload = function () {
ctx.fillRect(tower.x * mt + mt / 16, tower.y * mt + mt / 16, 8, 8) ctx.fillRect(tower.x * mt + mt / 16, tower.y * mt + mt / 16, 8, 8)
} }
// tower placement // tower range visualization
if (Game.state === 2 && Game.tower && mX < Maps.width && mY < Maps.height) { let towerData = Towers[Game.tower]
// tower range visualization let vX = null
let towerData = Towers[Game.tower] let vY = null
if (towerData.cost <= Game.money && canPlaceTowerAt (mX, mY)) {
let towerData = Towers[Game.tower] // Render the currently selected tower's range if present
ctx.strokeStyle = '#ddd' if (Game.towerSel) {
ctx.fillStyle = 'rgba(200, 200, 200, 0.25)' towerData = Game.towerSel
ctx.beginPath() vX = towerData.x
ctx.arc(mX * mt + mt / 2, mY * mt + mt / 2, towerData.range * mt, 0, 2 * Math.PI) vY = towerData.y
ctx.stroke() } else if (towerData != null && towerData.cost <= Game.money && canPlaceTowerAt (mX, mY) &&
ctx.fill() mX < Maps.width && mY < Maps.height && Game.state === 2) {
ctx.closePath() vX = mX
} vY = mY
}
// Render range
if (vX != null && vY != null && towerData) {
ctx.strokeStyle = '#ddd'
ctx.fillStyle = 'rgba(200, 200, 200, 0.25)'
ctx.beginPath()
ctx.arc(vX * mt + mt / 2, vY * mt + mt / 2, towerData.range * mt, 0, 2 * Math.PI)
ctx.stroke()
ctx.fill()
ctx.closePath()
} }
for (let i in Game.selltext) { for (let i in Game.selltext) {
@ -699,11 +741,6 @@ window.onload = function () {
ctx.fillText('Health: ' + Game.health, 645, 45) ctx.fillText('Health: ' + Game.health, 645, 45)
ctx.fillText('Money: ' + Game.money, 645, 65) ctx.fillText('Money: ' + Game.money, 645, 65)
for (let i in Components) {
let btn = Components[i]
btn.draw()
}
if (Game.state === -1) { if (Game.state === -1) {
ctx.font = '80px Helvetica' ctx.font = '80px Helvetica'
ctx.fillStyle = '#f00' ctx.fillStyle = '#f00'
@ -714,6 +751,34 @@ window.onload = function () {
ctx.fillStyle = 'rgba(255, 0, 0, 0.24)' ctx.fillStyle = 'rgba(255, 0, 0, 0.24)'
ctx.fillRect(mX * mt, mY * mt, mt, mt) ctx.fillRect(mX * mt, mY * mt, mt, mt)
} }
// Render a selection information box
// TODO: component
if (Game.towerSel) {
let by = (Maps.height - 5) * Maps.tile
let ts = Game.towerSel
ctx.fillStyle = 'rgba(0, 0, 0, 0.45)'
ctx.fillRect(0, by, Maps.width * Maps.tile, 5 * Maps.tile)
ctx.fillStyle = '#fff'
ctx.font = '25px Helvetica'
ctx.fillText(ts.name + ' Tower', 5, by + 25)
ctx.font = '15px Helvetica'
ctx.fillText(ts.description, 5, by + 42)
ctx.fillText('Range: ' + ts.range + ' tiles', 5, by + 70)
ctx.fillText('Damage: ' + ts.damage + ' HP', 5, by + 85)
ctx.fillText('Fire Rate: ' + ts.rate, 5, by + 100)
ctx.fillText('Kills: ' + ts.killcount, 5, by + 115)
ctx.fillText('Fired ' + ts.fires + ' times', 5, by + 130)
}
for (let i in Components) {
let btn = Components[i]
btn.draw()
}
} }
let lastTime = Date.now() let lastTime = Date.now()
@ -736,10 +801,18 @@ window.onload = function () {
function initialize () { function initialize () {
Game.map = Maps.first Game.map = Maps.first
// Next wave button
Components.wave = new ButtonComponent('Next Wave', '#fff', '#11f', 650, 570, 200, 60, () => { Components.wave = new ButtonComponent('Next Wave', '#fff', '#11f', 650, 570, 200, 60, () => {
updateGameState(1) updateGameState(1)
}) })
// Tower sell button
Components.sell = new ButtonComponent('Sell Tower', '#fff', '#f11', 490, 590, 140, 40, () => {
if (Game.towerSel) {
sellTower(Game.towerSel.x, Game.towerSel.y)
}
})
let index = 0 let index = 0
for (let i in Towers) { for (let i in Towers) {
Components[i] = new TowerButton(i, index) Components[i] = new TowerButton(i, index)
@ -750,11 +823,20 @@ window.onload = function () {
} }
canvas.addEventListener('click', (e) => { canvas.addEventListener('click', (e) => {
if (Game.state === 2 && mX < Maps.width && mY < Maps.height && Game.tower) { if (clickBtn()) return
if (mX < Maps.width && mY < Maps.height) {
// Select a tower if present
if (getTowerAt(mX, mY)) {
return selectTower(mX, mY)
} else if (Game.towerSel) {
Game.towerSel = null
return
}
// Place a tower
if (!Game.tower || Game.state !== 2) return
placeTower(Towers[Game.tower], mX, mY) placeTower(Towers[Game.tower], mX, mY)
} }
clickBtn()
}) })
canvas.addEventListener('contextmenu', (e) => { canvas.addEventListener('contextmenu', (e) => {