258 lines
8.1 KiB
JavaScript
258 lines
8.1 KiB
JavaScript
import { levelList } from "./levelList.js"
|
|
import Player from "./player.js"
|
|
import { Bullet, Meteor, Turret } from "./gameObjects.js"
|
|
import { Renderer } from "./renderer.js"
|
|
import { setFastTurret, setHeavyTurret, setLaserTurret, setStandardTurret } from "./turretTypes.js"
|
|
import SoundEffect from "./soundEffect.js"
|
|
|
|
export default class Game {
|
|
|
|
constructor() {
|
|
this.canvas = document.getElementById("mainCanvas")
|
|
this.renderer = new Renderer(this.canvas)
|
|
this.player = new Player()
|
|
this.levelList = levelList
|
|
this.currentLevel;
|
|
this.nextTurretToFire = 0
|
|
this.turretFire = false
|
|
this.health = 10
|
|
this.healthDisplay = document.getElementById("health")
|
|
this.showTitle = false
|
|
this.lastSlowUpdate = 0
|
|
|
|
this.ammoCurrent = ""
|
|
this.ammo = {
|
|
laser: 100,
|
|
fast: 100,
|
|
standard: 100,
|
|
heavy: 100
|
|
}
|
|
|
|
SoundEffect.setEffectVolume(0.3)
|
|
|
|
document.addEventListener("keydown", (event) => {
|
|
switch(event.key) {
|
|
case "p": this.renderer.showStats = !this.renderer.showStats; break
|
|
case "o": this.renderer.showCollisionBox = !this.renderer.showCollisionBox; break
|
|
case "a": this.setTurretTypeAll("laser"); break
|
|
case "z": this.setTurretTypeAll("fast"); break
|
|
case "e": this.setTurretTypeAll("standard"); break
|
|
case "r": this.setTurretTypeAll("heavy"); break
|
|
}
|
|
})
|
|
}
|
|
|
|
setGameCanvas(gameCanvas = true) {
|
|
let backgroundColor
|
|
if (gameCanvas) {
|
|
this.canvas = document.getElementById("gameCanvas")
|
|
backgroundColor = "#a9cdd2"
|
|
} else {
|
|
this.canvas = document.getElementById("mainCanvas")
|
|
backgroundColor = "#153a3a"
|
|
}
|
|
this.renderer = new Renderer(this.canvas, backgroundColor)
|
|
this.setSize()
|
|
}
|
|
|
|
async loadMainMenu(level) {
|
|
await level.loadLevel()
|
|
this.player.setMusic(level.musicPath)
|
|
this.player.start()
|
|
this.currentLevel = level
|
|
}
|
|
|
|
async loadLevel(level) {
|
|
console.log('Set current level:', level.title)
|
|
|
|
this.player.stop()
|
|
|
|
await level.loadLevel()
|
|
await this.setupTurrets()
|
|
|
|
this.showTitle = true
|
|
const mainGameTitle = document.getElementById("main-game-title")
|
|
mainGameTitle.querySelector("h1").innerText = level.title
|
|
mainGameTitle.querySelector("h2").innerText = level.subtitle
|
|
this.setShowTitle(true)
|
|
setTimeout(() => this.setShowTitle(false), 10000)
|
|
|
|
this.player.setMusic(level.musicPath)
|
|
this.player.start()
|
|
|
|
this.canvas.addEventListener("mousemove", (event) => this.setTurretTarget(event))
|
|
this.canvas.addEventListener("mousedown", () => this.setTurretFire(true))
|
|
this.canvas.addEventListener("mouseup", () => this.setTurretFire(false))
|
|
this.canvas.addEventListener("dblclick", () => this.setTurretFire(!this.turretFire))
|
|
|
|
const volumeInput = document.getElementById("volume")
|
|
volumeInput.addEventListener("change", () => {
|
|
console.log('volume', volumeInput.value)
|
|
this.player.gain.gain.value = volumeInput.value / 10
|
|
})
|
|
|
|
this.setGameOver()
|
|
this.player.audio.addEventListener('ended', () => {
|
|
this.setGameOver(true)
|
|
this.health = 0
|
|
})
|
|
this.currentLevel = level
|
|
this.renderer.bossImg = this.currentLevel.bossImg
|
|
|
|
this.ammoCurrent = "standard"
|
|
this.ammo = {
|
|
laser: 100,
|
|
fast: 100,
|
|
standard: 100,
|
|
heavy: 100
|
|
}
|
|
|
|
this.setAmmoCounter()
|
|
}
|
|
|
|
setShowTitle(show = false) {
|
|
document.getElementById("main-game-title").style.display = show ? "flex" : "none"
|
|
}
|
|
|
|
setGameOver(win = false) {
|
|
const gameOverTitle = document.getElementById("game-over")
|
|
gameOverTitle.querySelector("h2").innerText = win ? "YOU HAVE OVERCOME THE ATTACK" : "YOU HAVE PERISHED"
|
|
gameOverTitle.querySelector("h3").innerText = win ? "Until next time" : "Not much to do left"
|
|
gameOverTitle.querySelector("button").innerText = win ? "yay" : "damn"
|
|
}
|
|
|
|
setSize(height, width) {
|
|
this.canvas.width = width ?? window.innerWidth
|
|
this.canvas.height = height ?? window.innerHeight
|
|
}
|
|
|
|
async setupTurrets() {
|
|
const turretY = this.canvas.height - 155
|
|
const firstTurretX = (this.canvas.width - 1500) / 2 + 95
|
|
|
|
this.renderer.turrets.push(new Turret(firstTurretX, turretY))
|
|
this.renderer.turrets.push(new Turret(firstTurretX + 380, turretY - 15))
|
|
this.renderer.turrets.push(new Turret(firstTurretX + 835, turretY - 10))
|
|
this.renderer.turrets.push(new Turret(firstTurretX + 1265, turretY + 5))
|
|
|
|
for (const turret of this.renderer.turrets) {
|
|
await setStandardTurret(turret)
|
|
}
|
|
|
|
this.ammoCurrent = "standard"
|
|
}
|
|
|
|
setTurretTypeAll(type) {
|
|
this.ammoCurrent = type
|
|
this.renderer.turrets.forEach((_, i) => this.setTurretType(i, type))
|
|
}
|
|
|
|
async setTurretType(i, type) {
|
|
const turret = this.renderer.turrets[i]
|
|
|
|
switch(type) {
|
|
case "standard": await setStandardTurret(turret); break
|
|
case "fast": await setFastTurret(turret); break
|
|
case "laser": await setLaserTurret(turret); break
|
|
case "heavy": await setHeavyTurret(turret); break
|
|
}
|
|
}
|
|
|
|
setTurretTarget(event) {
|
|
this.renderer.mouseX = event.offsetX
|
|
this.renderer.mouseY = event.offsetY
|
|
|
|
for (const turret of this.renderer.turrets) {
|
|
const dx = this.renderer.mouseX - turret.x
|
|
const dy = this.renderer.mouseY - turret.y
|
|
turret.angle = Math.atan2(dy, dx)
|
|
}
|
|
}
|
|
|
|
setTurretFire(fire) {
|
|
this.turretFire = fire
|
|
this.renderer.turrets.forEach((turret) => turret.animationRunning = fire)
|
|
|
|
// if (!fire) {
|
|
// SoundEffect.play(SoundEffect.turretRelease)
|
|
// }
|
|
}
|
|
|
|
setAmmoCounter() {
|
|
const ammoLaserCounter = document.getElementById("ammo-laser")
|
|
ammoLaserCounter.querySelector("h3").innerText = this.ammo.laser
|
|
|
|
const ammoFastCounter = document.getElementById("ammo-fast")
|
|
ammoFastCounter.querySelector("h3").innerText = this.ammo.fast
|
|
|
|
const ammoStandardCounter = document.getElementById("ammo-standard")
|
|
ammoStandardCounter.querySelector("h3").innerText = this.ammo.standard
|
|
|
|
const ammoHeavyCounter = document.getElementById("ammo-heavy")
|
|
ammoHeavyCounter.querySelector("h3").innerText = this.ammo.heavy
|
|
}
|
|
|
|
spawnBullet() {
|
|
if (this.ammo[this.ammoCurrent] <= 0) {
|
|
return
|
|
}
|
|
|
|
const turret = this.renderer.turrets[this.nextTurretToFire]
|
|
const deltaLastShot = performance.now() - turret.lastShot
|
|
if (deltaLastShot > turret.firingRate) {
|
|
const angle = turret.angle - ((Math.floor(Math.random() * turret.spread) / 1000) * (Math.random() < 0.5 ? -1 : 1))
|
|
this.renderer.bullets.push(new Bullet(turret.x , turret.y, angle, turret.bulletSprite, turret.damage))
|
|
turret.lastShot = performance.now()
|
|
// SoundEffect.play(turret.sound)
|
|
}
|
|
|
|
this.nextTurretToFire = this.nextTurretToFire < this.renderer.turrets.length - 1 ? this.nextTurretToFire + 1 : 0
|
|
}
|
|
|
|
spawnMeteor() {
|
|
// meteors[Math.floor(Math.random() * this.meteors.length)]
|
|
this.renderer.meteors.push(new Meteor(this.canvas.width, this.canvas.height, this.currentLevel.maxHealth, this.currentLevel.meteorImg, this.currentLevel.meteorImgList))
|
|
}
|
|
|
|
render() {
|
|
// Frames
|
|
const now = performance.now()
|
|
if ((now - this.renderer.lastFrame) > (1000 / 60)) {
|
|
if (this.turretFire) {
|
|
this.spawnBullet()
|
|
}
|
|
|
|
const damageTaken = this.renderer.render()
|
|
|
|
if (damageTaken > 0 && this.currentLevel.title !== "MainMenu") {
|
|
SoundEffect.play(SoundEffect.explosionBig)
|
|
this.health -= damageTaken
|
|
}
|
|
|
|
this.healthDisplay.innerText = `${this.health} HP`
|
|
}
|
|
|
|
// Slow updates
|
|
if ((now - this.lastSlowUpdate) > 1000) {
|
|
console.log('SLOW')
|
|
if (this.turretFire) {
|
|
console.log('SET AMMO', this.ammoCurrent, this.ammo)
|
|
this.ammo.laser += this.ammo.laser < 100 ? 5 : 0
|
|
this.ammo.fast += this.ammo.fast < 100 ? 5 : 0
|
|
this.ammo.standard += this.ammo.standard < 100 ? 5 : 0
|
|
this.ammo.heavy += this.ammo.heavy < 100 ? 5 : 0
|
|
|
|
this.ammo[this.ammoCurrent] -= 6
|
|
|
|
if (this.ammo[this.ammoCurrent] <= 0) {
|
|
this.ammo[this.ammoCurrent] = 0
|
|
}
|
|
|
|
this.setAmmoCounter()
|
|
}
|
|
|
|
this.lastSlowUpdate = now
|
|
}
|
|
}
|
|
|
|
} |