import Logger from "../utils/Logger.js"; import Config from "./GameConfig.js"; import Time from "../utils/Time.js"; import GameRenderer from "./GameRenderer.js"; import Enemy from "./Enemy.js"; var gameLoop, gameArea, lastUpdate, lastEnemySpawn, options, enemies, gazePoints; function onTick() { let now = Date.now(), delta = now - lastUpdate, adjustment = (Time.ONE_SECOND_IN_MS / options.frameRate) / delta; updateEnemies(now, adjustment); updateGazePoints(now); GameRenderer.render(getCurrentState(now)); lastUpdate = Date.now(); } function getCurrentState(now) { return { delta: now - lastUpdate, frameRate: options.frameRate, enemies: enemies, gazePoints: gazePoints, debug: options.debug, }; } function updateEnemies(now, adjustment) { let currentGazePosition = gazePoints[gazePoints.length - 1]; if ((now - lastEnemySpawn) >= Config.ENEMEY_SPAWN_DELAY) { if (enemies.length < Config.MAX_NUMBER_OF_ENEMIES) { Logger.log("Add new enemy", "Game"); enemies.push(Enemy.createEnemy(gameArea)); lastEnemySpawn = now; } } for (let i = enemies.length - 1; i >= 0; i--) { // Update enemy's position enemies[i].update(gameArea.center, adjustment); // Check if enemy has hit target if (enemies[i].distanceTo(gameArea.center) < Config.TARGET_RADIUS) { onEnemyHitsTarget(enemies[i].damage); enemies.splice(i, 1); } // Skip other checks if no gaze data is available if (currentGazePosition === undefined) { continue; } // Check if enemy was hit if (enemies[i].isHitBy({ x: currentGazePosition.targetX, y: currentGazePosition.targetY, })) { // Update enemy's health enemies[i].health -= Config.DEFAULT_PLAYER_DAMAGE; // Remove enemy if destroyed if (enemies[i].health <= 0) { Logger.log(`Enemy destroyed by player`, "Game"); enemies.splice(i, 1); // TODO: Add exposion at last position } } } } function onEnemyHitsTarget(damage) { Logger.log(`Enemy hit target for ${damage} dmg`, "Game"); } function updateGazePoints(now) { let lastIndexForRemoval = -1; for (let i = 0; i < gazePoints.length; i++) { gazePoints[i].age = now - gazePoints[i].createdAt; gazePoints[i].inversedAge = 1 - (gazePoints[i].age / Config.MAX_GAZE_POINT_AGE); if (gazePoints[i].age > Config.MAX_GAZE_POINT_AGE) { lastIndexForRemoval = i; } } if (lastIndexForRemoval !== -1) { gazePoints.splice(0, lastIndexForRemoval + 1); } } class GameManager { constructor() { enemies = []; gazePoints = []; lastEnemySpawn = 0; } setOptions(gameOptions) { options = gameOptions; gameArea = { width: options.width, height: options.height, center: { x: options.width / 2, y: options.height / 2, }, }; } start() { GameRenderer.init(options.canvas, options.width, options.height, options.version); lastUpdate = Date.now(); gameLoop = setInterval(onTick, (Time.ONE_SECOND_IN_MS / options.frameRate)); } addGazePoint(point) { gazePoints.push(point); } } export default new GameManager();