diff --git a/assets/Scenes/scene.scene b/assets/Scenes/Game.scene similarity index 100% rename from assets/Scenes/scene.scene rename to assets/Scenes/Game.scene diff --git a/assets/Scenes/scene.scene.meta b/assets/Scenes/Game.scene.meta similarity index 100% rename from assets/Scenes/scene.scene.meta rename to assets/Scenes/Game.scene.meta diff --git a/assets/Scenes/scene-2d.scene b/assets/Scenes/Menu.scene similarity index 84% rename from assets/Scenes/scene-2d.scene rename to assets/Scenes/Menu.scene index 904bfaf..b3fe44b 100644 --- a/assets/Scenes/scene-2d.scene +++ b/assets/Scenes/Menu.scene @@ -10,12 +10,15 @@ }, { "__type__": "cc.Scene", - "_name": "scene-2d", + "_name": "Menu", "_objFlags": 0, "_parent": null, "_children": [ { "__id__": 2 + }, + { + "__id__": 10 } ], "_active": true, @@ -23,13 +26,13 @@ "_prefab": null, "autoReleaseAssets": false, "_globals": { - "__id__": 9 + "__id__": 12 }, "_id": "1a3bccb5-bbb7-4058-846c-ed41b52415b0" }, { "__type__": "cc.Node", - "_name": "Canvas", + "_name": "Menu", "_objFlags": 0, "_parent": { "__id__": 1 @@ -41,14 +44,14 @@ ], "_active": true, "_components": [ - { - "__id__": 6 - }, { "__id__": 7 }, { "__id__": 8 + }, + { + "__id__": 9 } ], "_prefab": null, @@ -95,6 +98,9 @@ }, { "__id__": 5 + }, + { + "__id__": 6 } ], "_prefab": null, @@ -185,6 +191,17 @@ "_atlas": null, "_id": "72StvrPGhHK4bp9R7RA2NO" }, + { + "__type__": "22c61zFd7hNRaAttffaS6ep", + "_name": "", + "_objFlags": 0, + "node": { + "__id__": 3 + }, + "_enabled": true, + "__prefab": null, + "_id": "0e1btqtltATbmaReZXZW4r" + }, { "__type__": "cc.UITransform", "_name": "", @@ -247,21 +264,75 @@ "_id": "2aCNE8+JdDk581XA25TXI9" }, { - "__type__": "cc.SceneGlobals", - "ambient": { + "__type__": "cc.Node", + "_name": "AppRoot", + "_objFlags": 0, + "_parent": { + "__id__": 1 + }, + "_children": [], + "_active": true, + "_components": [ + { + "__id__": 11 + } + ], + "_prefab": null, + "_lpos": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_lrot": { + "__type__": "cc.Quat", + "x": 0, + "y": 0, + "z": 0, + "w": 1 + }, + "_lscale": { + "__type__": "cc.Vec3", + "x": 1, + "y": 1, + "z": 1 + }, + "_layer": 1073741824, + "_euler": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_id": "58b/Etqn1D0LBB1esUnUos" + }, + { + "__type__": "4943dSvt9FBvLizJ1HhFOzg", + "_name": "", + "_objFlags": 0, + "node": { "__id__": 10 }, - "shadows": { - "__id__": 11 - }, - "_skybox": { - "__id__": 12 - }, - "fog": { + "_enabled": true, + "__prefab": null, + "_id": "eeXuVZFQ1KNpRron3jnCKj" + }, + { + "__type__": "cc.SceneGlobals", + "ambient": { "__id__": 13 }, - "octree": { + "shadows": { "__id__": 14 + }, + "_skybox": { + "__id__": 15 + }, + "fog": { + "__id__": 16 + }, + "octree": { + "__id__": 17 } }, { diff --git a/assets/Scenes/scene-2d.scene.meta b/assets/Scenes/Menu.scene.meta similarity index 100% rename from assets/Scenes/scene-2d.scene.meta rename to assets/Scenes/Menu.scene.meta diff --git a/assets/Scripts/AppRoot.meta b/assets/Scripts/AppRoot.meta new file mode 100644 index 0000000..e09148e --- /dev/null +++ b/assets/Scripts/AppRoot.meta @@ -0,0 +1,12 @@ +{ + "ver": "1.1.0", + "importer": "directory", + "imported": true, + "uuid": "e26cf04f-eda1-4f45-b452-329628f16eea", + "files": [], + "subMetas": {}, + "userData": { + "compressionType": {}, + "isRemoteBundle": {} + } +} diff --git a/assets/Scripts/AppRoot/AppRoot.ts b/assets/Scripts/AppRoot/AppRoot.ts new file mode 100644 index 0000000..1ab42c6 --- /dev/null +++ b/assets/Scripts/AppRoot/AppRoot.ts @@ -0,0 +1,34 @@ +import { _decorator, Component, Node, director, AudioSource } from "cc"; +import { SaveSystem } from "./SaveSystem"; +const { ccclass, property } = _decorator; + +@ccclass("AppRoot") +export class AppRoot extends Component { + @property(AudioSource) private soundSource: AudioSource; + @property(AudioSource) private musicSource: AudioSource; + + private static instance: AppRoot; + private saveSystem: SaveSystem; + + public static get Instance(): AppRoot { + return this.instance; + } + + public get SaveSystem(): SaveSystem { + return this.saveSystem; + } + + public start(): void { + if (AppRoot.Instance == null) { + AppRoot.instance = this; + director.addPersistRootNode(this.node); + this.init(); + } else { + this.destroy(); + } + } + + private init(): void { + this.saveSystem = new SaveSystem(); + } +} diff --git a/assets/Scripts/Services/ContactParams.ts.meta b/assets/Scripts/AppRoot/AppRoot.ts.meta similarity index 70% rename from assets/Scripts/Services/ContactParams.ts.meta rename to assets/Scripts/AppRoot/AppRoot.ts.meta index 1897467..45ba2d1 100644 --- a/assets/Scripts/Services/ContactParams.ts.meta +++ b/assets/Scripts/AppRoot/AppRoot.ts.meta @@ -2,7 +2,7 @@ "ver": "4.0.23", "importer": "typescript", "imported": true, - "uuid": "ee9d41d4-91f4-4d8f-a4ef-7e0df147fb35", + "uuid": "4943d4af-b7d1-41bc-b8b3-2751e114ece0", "files": [], "subMetas": {}, "userData": {} diff --git a/assets/Scripts/AppRoot/SaveSystem.ts b/assets/Scripts/AppRoot/SaveSystem.ts new file mode 100644 index 0000000..78307a0 --- /dev/null +++ b/assets/Scripts/AppRoot/SaveSystem.ts @@ -0,0 +1,21 @@ +import { sys } from "cc"; +import { UserData } from "../Game/Data/UserData"; + +export class SaveSystem { + private userDataIdentifier = "user-data"; + public save(userData: UserData): void { + sys.localStorage.setItem(this.userDataIdentifier, JSON.stringify(userData)); + } + + public load(): UserData { + const data: string = sys.localStorage.getItem(this.userDataIdentifier); + + if (!data) return new UserData(); + + try { + return JSON.parse(data); + } catch (error) { + return new UserData(); + } + } +} diff --git a/assets/Scripts/AppRoot/SaveSystem.ts.meta b/assets/Scripts/AppRoot/SaveSystem.ts.meta new file mode 100644 index 0000000..56690ab --- /dev/null +++ b/assets/Scripts/AppRoot/SaveSystem.ts.meta @@ -0,0 +1,9 @@ +{ + "ver": "4.0.23", + "importer": "typescript", + "imported": true, + "uuid": "ed50cd4b-21fa-4acc-9fee-92abaf3e2134", + "files": [], + "subMetas": {}, + "userData": {} +} diff --git a/assets/Scripts/Game/Data/UserData.ts b/assets/Scripts/Game/Data/UserData.ts new file mode 100644 index 0000000..dc2b195 --- /dev/null +++ b/assets/Scripts/Game/Data/UserData.ts @@ -0,0 +1,17 @@ +export class UserData { + public soundVolume = 0; + public musicVolume = 0; + public game = new GameData(); +} + +export class GameData { + public goldCoins = 0; + public metaUpgrades = new MetaUpgradesData(); +} + +export class MetaUpgradesData { + public maxHpLevel = 0; + public overallDamageLevel = 0; + public projectilePiercingLevel = 0; + public movementSpeedLevel = 0; +} diff --git a/assets/Scripts/Game/Data/UserData.ts.meta b/assets/Scripts/Game/Data/UserData.ts.meta new file mode 100644 index 0000000..4adfc19 --- /dev/null +++ b/assets/Scripts/Game/Data/UserData.ts.meta @@ -0,0 +1,9 @@ +{ + "ver": "4.0.23", + "importer": "typescript", + "imported": true, + "uuid": "7431ff7c-480c-4474-9434-654eda0a1a08", + "files": [], + "subMetas": {}, + "userData": {} +} diff --git a/assets/Scripts/Game/GameBootstrapper.ts b/assets/Scripts/Game/Game.ts similarity index 87% rename from assets/Scripts/Game/GameBootstrapper.ts rename to assets/Scripts/Game/Game.ts index ab70ea4..0c76e86 100644 --- a/assets/Scripts/Game/GameBootstrapper.ts +++ b/assets/Scripts/Game/Game.ts @@ -1,5 +1,6 @@ import { Camera, Component, JsonAsset, KeyCode, Vec2, _decorator } from "cc"; import { ModalWindowManager } from "../Services/ModalWindowSystem/ModalWindowManager"; +import { delay } from "../Services/Utils/AsyncUtils"; import { PlayerCollisionSystem } from "./Collision/PlayerCollisionSystem"; import { PlayerProjectileCollisionSystem } from "./Collision/PlayerProjectileCollisionSystem"; import { WeaponCollisionSystem } from "./Collision/WeaponCollisionSystem"; @@ -19,8 +20,8 @@ import { Upgrader } from "./Upgrades/Upgrader"; const { ccclass, property } = _decorator; -@ccclass("GameBootstrapper") -export class GameBootstrapper extends Component { +@ccclass("Game") +export class Game extends Component { @property(VirtualJoystic) private virtualJoystic: VirtualJoystic; @property(Player) private player: Player; @property(ProjectileLauncher) private haloProjectileLauncherComponent: ProjectileLauncher; @@ -39,15 +40,26 @@ export class GameBootstrapper extends Component { private gamePauser: Pauser = new Pauser(); + private static instance: Game; + + public static get Instance(): Game { + return this.instance; + } + public start(): void { + Game.instance = this; + this.gamePauser.pause(); + } + + public async playGame(): Promise { const settings: GameSettings = this.settingsAsset.json; this.virtualJoystic.init(); const wasd = new KeyboardInput(KeyCode.KEY_W, KeyCode.KEY_S, KeyCode.KEY_A, KeyCode.KEY_D); const arrowKeys = new KeyboardInput(KeyCode.ARROW_UP, KeyCode.ARROW_DOWN, KeyCode.ARROW_LEFT, KeyCode.ARROW_RIGHT); - const dualInput: MultiInput = new MultiInput([this.virtualJoystic, wasd, arrowKeys]); - this.player.init(dualInput, settings.player); + const multiInput: MultiInput = new MultiInput([this.virtualJoystic, wasd, arrowKeys]); + this.player.init(multiInput, settings.player); this.playerCollisionSystem = new PlayerCollisionSystem(this.player, settings.player.collisionDelay); new WeaponCollisionSystem(this.player.Weapon); @@ -80,6 +92,12 @@ export class GameBootstrapper extends Component { new GameModalLauncher(this.modalWindowManager, this.player, this.gamePauser, upgrader); this.gameUI.init(this.player); + this.gamePauser.resume(); + + await delay(10000); + this.gamePauser.pause(); + Game.instance = null; + return 1; } public update(deltaTime: number): void { diff --git a/assets/Scripts/Game/GameBootstrapper.ts.meta b/assets/Scripts/Game/Game.ts.meta similarity index 100% rename from assets/Scripts/Game/GameBootstrapper.ts.meta rename to assets/Scripts/Game/Game.ts.meta diff --git a/assets/Scripts/Game/Unit/Enemy/Enemy.ts b/assets/Scripts/Game/Unit/Enemy/Enemy.ts index c4816d0..11d82d7 100644 --- a/assets/Scripts/Game/Unit/Enemy/Enemy.ts +++ b/assets/Scripts/Game/Unit/Enemy/Enemy.ts @@ -13,12 +13,14 @@ export class Enemy extends Component { private movementType: EnemyMovementType; private health: UnitHealth = new UnitHealth(1); private deathEvent: Signal = new Signal(); - private speed: number; + private speedX: number; + private speedY: number; public setup(position: Vec3, movementType: EnemyMovementType): void { this.movementType = movementType; this.health = new UnitHealth(1); - this.speed = randomRange(40, 90); + this.speedX = randomRange(40, 90); + this.speedY = randomRange(40, 90); this.node.setWorldPosition(position); this.node.active = true; } @@ -52,8 +54,8 @@ export class Enemy extends Component { public moveBy(move: Vec3, deltaTime: number): void { const newPosition: Vec3 = this.node.worldPosition; - newPosition.x += move.x * this.speed * deltaTime; - newPosition.y += move.y * this.speed * deltaTime; + newPosition.x += move.x * this.speedX * deltaTime; + newPosition.y += move.y * this.speedY * deltaTime; this.node.setWorldPosition(newPosition); } diff --git a/assets/Scripts/Game/Unit/Enemy/EnemyMover/WaveEnemyMover.ts b/assets/Scripts/Game/Unit/Enemy/EnemyMover/WaveEnemyMover.ts index 7828ba5..1bf024d 100644 --- a/assets/Scripts/Game/Unit/Enemy/EnemyMover/WaveEnemyMover.ts +++ b/assets/Scripts/Game/Unit/Enemy/EnemyMover/WaveEnemyMover.ts @@ -11,7 +11,7 @@ export class WaveEnemyMover extends EnemyMover { let direction: Vec3 = new Vec3(); // if the enemy is added soon enough, move as a single group towards one direction - if (Vec3.distance(this.lastTargetPosition, this.targetNode.worldPosition) < 10) { + if (Vec3.equals(this.lastTargetPosition, this.targetNode.worldPosition)) { direction = this.lastDirection; } else { direction = Vec3.subtract(direction, this.targetNode.worldPosition, enemy.node.worldPosition); diff --git a/assets/Scripts/Game/Unit/Enemy/EnemySpawner/IndividualEnemySpawner.ts b/assets/Scripts/Game/Unit/Enemy/EnemySpawner/IndividualEnemySpawner.ts index a40778c..5a467d4 100644 --- a/assets/Scripts/Game/Unit/Enemy/EnemySpawner/IndividualEnemySpawner.ts +++ b/assets/Scripts/Game/Unit/Enemy/EnemySpawner/IndividualEnemySpawner.ts @@ -15,7 +15,7 @@ export class IndividualEnemySpawner { if (this.spawnTimer.tryFinishPeriod()) { const posX: number = randomRange(300, 600) * randomPositiveOrNegative(); const posY: number = randomRange(300, 600) * randomPositiveOrNegative(); - this.enemySpawner.spawnNewEnemy(posX, posY, EnemyMovementType.Launch); + this.enemySpawner.spawnNewEnemy(posX, posY, EnemyMovementType.Follow); } } } diff --git a/assets/Scripts/Game/Unit/Enemy/EnemySpawner/WaveEnemySpawner.ts b/assets/Scripts/Game/Unit/Enemy/EnemySpawner/WaveEnemySpawner.ts index 49bffa9..6b33b50 100644 --- a/assets/Scripts/Game/Unit/Enemy/EnemySpawner/WaveEnemySpawner.ts +++ b/assets/Scripts/Game/Unit/Enemy/EnemySpawner/WaveEnemySpawner.ts @@ -48,8 +48,8 @@ export class WaveEnemySpawner { private trySpawnNewGroup(): void { if (this.spawnTimer.tryFinishPeriod()) { - const defaultPosX: number = 200 * randomPositiveOrNegative(); - const defaultPosY: number = 200 * randomPositiveOrNegative(); + const defaultPosX: number = (500 + randomRange(0, 100)) * randomPositiveOrNegative(); + const defaultPosY: number = randomRange(0, 500) * randomPositiveOrNegative(); const enemies: Enemy[] = []; const side: number = Math.ceil(Math.sqrt(this.enemiesPerWave)); diff --git a/assets/Scripts/Game/Upgrades/UpgradeType.ts b/assets/Scripts/Game/Upgrades/UpgradeType.ts index aa3d579..a821744 100644 --- a/assets/Scripts/Game/Upgrades/UpgradeType.ts +++ b/assets/Scripts/Game/Upgrades/UpgradeType.ts @@ -9,5 +9,6 @@ export enum UpgradeType { export enum MetaUpgradeType { MaxHp, OverallDamage, - ProjectilePiercing + ProjectilePiercing, + MovementSpeed } diff --git a/assets/Scripts/Menu.meta b/assets/Scripts/Menu.meta new file mode 100644 index 0000000..3cbe747 --- /dev/null +++ b/assets/Scripts/Menu.meta @@ -0,0 +1,12 @@ +{ + "ver": "1.1.0", + "importer": "directory", + "imported": true, + "uuid": "4caa94da-a5e7-4535-b418-750cb2cb8d55", + "files": [], + "subMetas": {}, + "userData": { + "compressionType": {}, + "isRemoteBundle": {} + } +} diff --git a/assets/Scripts/Menu/GameRunner.ts b/assets/Scripts/Menu/GameRunner.ts new file mode 100644 index 0000000..0b9494c --- /dev/null +++ b/assets/Scripts/Menu/GameRunner.ts @@ -0,0 +1,28 @@ +import { director } from "cc"; +import { AppRoot } from "../AppRoot/AppRoot"; +import { UserData } from "../Game/Data/UserData"; +import { Game } from "../Game/Game"; +import { delay } from "../Services/Utils/AsyncUtils"; + +export class GameRunner { + private static instance: GameRunner = new GameRunner(); + + // eslint-disable-next-line @typescript-eslint/no-empty-function + private constructor() {} + + public static get Instance(): GameRunner { + return this.instance; + } + + public async playGame(): Promise { + director.loadScene("Game"); + const userData: UserData = AppRoot.Instance.SaveSystem.load(); + while (Game.Instance == null) await delay(10); + const result: number = await Game.Instance.playGame(); + userData.game.goldCoins += result; + AppRoot.Instance.SaveSystem.save(userData); + + console.log("Gold coins: " + result); + console.log("All gold coins: " + userData.game.goldCoins); + } +} diff --git a/assets/Scripts/Menu/GameRunner.ts.meta b/assets/Scripts/Menu/GameRunner.ts.meta new file mode 100644 index 0000000..0fc75fc --- /dev/null +++ b/assets/Scripts/Menu/GameRunner.ts.meta @@ -0,0 +1,9 @@ +{ + "ver": "4.0.23", + "importer": "typescript", + "imported": true, + "uuid": "c3869838-2d3a-4a22-a2f4-77d11a8226d5", + "files": [], + "subMetas": {}, + "userData": {} +} diff --git a/assets/Scripts/Menu/Menu.ts b/assets/Scripts/Menu/Menu.ts new file mode 100644 index 0000000..671b32d --- /dev/null +++ b/assets/Scripts/Menu/Menu.ts @@ -0,0 +1,10 @@ +import { _decorator, Component, Node } from "cc"; +import { GameRunner } from "./GameRunner"; +const { ccclass, property } = _decorator; + +@ccclass("Menu") +export class Menu extends Component { + public start(): void { + GameRunner.Instance.playGame(); + } +} diff --git a/assets/Scripts/Menu/Menu.ts.meta b/assets/Scripts/Menu/Menu.ts.meta new file mode 100644 index 0000000..70d7422 --- /dev/null +++ b/assets/Scripts/Menu/Menu.ts.meta @@ -0,0 +1,9 @@ +{ + "ver": "4.0.23", + "importer": "typescript", + "imported": true, + "uuid": "22c61cc5-77b8-4d45-a02d-b5f7da4ba7a9", + "files": [], + "subMetas": {}, + "userData": {} +} diff --git a/assets/Scripts/Services/ContactParams.ts b/assets/Scripts/Services/ContactParams.ts deleted file mode 100644 index 73142a6..0000000 --- a/assets/Scripts/Services/ContactParams.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { Collider2D, IPhysics2DContact } from "cc"; - -export type ContactParams = { - selfCollider: Collider2D; - otherCollider: Collider2D; - contact: IPhysics2DContact | null; -};