diff --git a/DoomDeathmatch/src/Component/MVC/Health/HealthController.cs b/DoomDeathmatch/src/Component/MVC/Health/HealthController.cs index a84cb0f..2c2780b 100644 --- a/DoomDeathmatch/src/Component/MVC/Health/HealthController.cs +++ b/DoomDeathmatch/src/Component/MVC/Health/HealthController.cs @@ -32,7 +32,7 @@ public class HealthController : Engine.Scene.Component.Component /// Initializes a new instance of the class with an optional starting health value. /// /// Initial health value. Defaults to 100. - public HealthController(float parHealth = 100) + public HealthController(float parHealth) { _healthModel = new HealthModel(parHealth); } diff --git a/DoomDeathmatch/src/Scene/GameConstants.cs b/DoomDeathmatch/src/Scene/GameConstants.cs new file mode 100644 index 0000000..4a4cce4 --- /dev/null +++ b/DoomDeathmatch/src/Scene/GameConstants.cs @@ -0,0 +1,80 @@ +namespace DoomDeathmatch.Scene; + +public static class GameConstants +{ + #region Enemies + + #region Demon + + public const int DEMON_BASE_SCORE = 50; + public const float DEMON_BASE_HEALTH = 150; + public const float DEMON_BASE_SPEED = 8; + + public const float DEMON_FOLLOW_RADIUS = 1.5f; + public const float DEMON_CLOSE_COOLDOWN_ATTACK_RADIUS = 1.75f; + public const float DEMON_CLOSE_COOLDOWN_ATTACK_COOLDOWN = 1.75f; + public const float DEMON_CLOSE_COOLDOWN_ATTACK_DAMAGE = 10f; + + public const int IMP_BASE_SCORE = 200; + public const float IMP_BASE_HEALTH = 300; + public const float IMP_BASE_SPEED = 7; + public const float IMP_FOLLOW_RADIUS = 10f; + + #endregion + + #region Imp + + public const float IMP_CLOSE_CONTINUOUS_ATTACK_RADIUS = 1.75f; + public const float IMP_CLOSE_CONTINUOUS_ATTACK_DAMAGE = 10f; + + public const float IMP_FIREBALL_ATTACK_COOLDOWN = 4f; + public const float IMP_FIREBALL_ATTACK_DAMAGE = 35f; + public const float IMP_FIREBALL_ATTACK_SPEED = 25f; + public const float IMP_FIREBALL_ATTACK_SIZE = 0.5f; + + #endregion + + public const int ENEMY_DEMON_SPAWN_WEIGHT = 6; + public const int ENEMY_IMP_SPAWN_WEIGHT = 4; + public const float ENEMY_SPAWN_RATE_SECONDS = 2f; + + #endregion + + #region Weapons + + #region Pistol + + public const int PISTOL_MAX_AMMO = 30; + public const int PISTOL_BASE_DAMAGE = 30; + + #endregion + + #region Shotgun + + public const int SHOTGUN_MAX_AMMO = 10; + public const int SHOTGUN_BASE_DAMAGE = 5; + public const float SHOTGUN_SHOOT_PATTERN_ANGLE_DEGREES = 10f; + public const uint SHOTGUN_SHOOT_PATTERN_COUNT = 40; + + #endregion + + #endregion + + #region Player + + public const float PLAYER_BASE_HEALTH = 100; + public const float PLAYER_BASE_SPEED = 10; + + #endregion + + #region Consumables + + public const int CONSUMABLE_HEALTH_PACK_SPAWN_WEIGHT = 2; + public const int CONSUMABLE_WEAPON_PISTOL_SPAWN_WEIGHT = 4; + public const int CONSUMABLE_WEAPON_SHOTGUN_SPAWN_WEIGHT = 3; + public const float CONSUMABLE_SPAWN_RATE_SECONDS = 5f; + + public const float HEALTH_PACK_BASE_HEALING = 75f; + + #endregion +} \ No newline at end of file diff --git a/DoomDeathmatch/src/Scene/GameOver/GameOverScene.cs b/DoomDeathmatch/src/Scene/GameOver/GameOverScene.cs index b1727be..a62c4a2 100644 --- a/DoomDeathmatch/src/Scene/GameOver/GameOverScene.cs +++ b/DoomDeathmatch/src/Scene/GameOver/GameOverScene.cs @@ -14,20 +14,20 @@ public static class GameOverScene { var scene = new Engine.Scene.Scene(); - var (cameraObject, camera) = UiUtil.CreateOrthographicCamera(scene); + var (cameraObject, camera) = UiPrefabs.CreateOrthographicCamera(scene); var (uiContainerObject, uiContainer) = - UiUtil.CreateBackgroundUi(scene, new UiContainerComponent { Camera = camera }); + UiPrefabs.CreateBackgroundUi(scene, new UiContainerComponent { Camera = camera }); - var (logoObject, logoUi) = UiUtil.CreateLogoUi(scene, uiContainer); + var (logoObject, logoUi) = UiPrefabs.CreateLogoUi(scene, uiContainer); logoUi.Offset = new Vector2(0, 3f); scene.AddChild(uiContainerObject, logoObject); var (resultUiObject, resultUi, _) = - UiUtil.CreateTextUi(scene, uiContainer, UiUtil.GetDoomFont(), $"Ваш результат: {parScore}"); + UiPrefabs.CreateTextUi(scene, uiContainer, UiPrefabs.GetDoomFont(), $"Ваш результат: {parScore}"); var (nameUiObject, nameUi, (_, nameTextRenderer)) = - UiUtil.CreateTextUi(scene, uiContainer, UiUtil.GetDoomFont(), "Имя: "); + UiPrefabs.CreateTextUi(scene, uiContainer, UiPrefabs.GetDoomFont(), "Имя: "); var nameInputComponent = new TextInputComponent { IsActive = true }; nameInputComponent.OnInput += parName => @@ -37,7 +37,7 @@ public static class GameOverScene nameUiObject.AddComponent(nameInputComponent); var (nextUiObject, nextUi, _) = - UiUtil.CreateTextUi(scene, uiContainer, UiUtil.GetDoomFont(), "Далее"); + UiPrefabs.CreateTextUi(scene, uiContainer, UiPrefabs.GetDoomFont(), "Далее"); nextUi.OnClick += _ => { if (string.IsNullOrEmpty(nameInputComponent.Input)) @@ -49,10 +49,10 @@ public static class GameOverScene EngineUtil.SceneManager.TransitionTo(MainScene.Create); }; - var (selectorObject, selector) = UiUtil.CreateSelectorUi(scene, + var (selectorObject, selector) = UiPrefabs.CreateSelectorUi(scene, new SelectorComponent { Children = { nextUi }, SelectKey = KeyboardButtonCode.Enter }, RenderLayer.HUD); - var (stackObject, stack) = UiUtil.CreateStackUi(scene, + var (stackObject, stack) = UiPrefabs.CreateStackUi(scene, new StackComponent { Offset = new Vector2(0, -1f), Container = uiContainer, Children = { resultUi, nextUi } }); stackObject.Transform.Size.Xy = new Vector2(1f, 6f); diff --git a/DoomDeathmatch/src/Scene/Main/MainScene.cs b/DoomDeathmatch/src/Scene/Main/MainScene.cs index 17df75c..1bf3471 100644 --- a/DoomDeathmatch/src/Scene/Main/MainScene.cs +++ b/DoomDeathmatch/src/Scene/Main/MainScene.cs @@ -15,12 +15,12 @@ public static class MainScene { var scene = new Engine.Scene.Scene(); - var (cameraObject, camera) = UiUtil.CreateOrthographicCamera(scene); + var (cameraObject, camera) = UiPrefabs.CreateOrthographicCamera(scene); var (uiContainerObject, uiContainer) = - UiUtil.CreateBackgroundUi(scene, new UiContainerComponent { Camera = camera }); + UiPrefabs.CreateBackgroundUi(scene, new UiContainerComponent { Camera = camera }); - var (logoObject, logoUi) = UiUtil.CreateLogoUi(scene, uiContainer); + var (logoObject, logoUi) = UiPrefabs.CreateLogoUi(scene, uiContainer); logoUi.Offset = new Vector2(0, 3f); scene.AddChild(uiContainerObject, logoObject); @@ -53,18 +53,18 @@ public static class MainScene var parentObject = GameObjectUtil.CreateGameObject(parScene); var (playUiObject, playUi, _) = - UiUtil.CreateTextUi(parScene, parUiContainer, UiUtil.GetDoomFont(), "Играть"); + UiPrefabs.CreateTextUi(parScene, parUiContainer, UiPrefabs.GetDoomFont(), "Играть"); var (leadersUiObject, leadersUi, _) = - UiUtil.CreateTextUi(parScene, parUiContainer, UiUtil.GetDoomFont(), "Лидеры"); + UiPrefabs.CreateTextUi(parScene, parUiContainer, UiPrefabs.GetDoomFont(), "Лидеры"); var (rulesUiObject, rulesUi, _) = - UiUtil.CreateTextUi(parScene, parUiContainer, UiUtil.GetDoomFont(), "Правила"); + UiPrefabs.CreateTextUi(parScene, parUiContainer, UiPrefabs.GetDoomFont(), "Правила"); var (exitUiObject, exitUi, _) = - UiUtil.CreateTextUi(parScene, parUiContainer, UiUtil.GetDoomFont(), "Выход"); + UiPrefabs.CreateTextUi(parScene, parUiContainer, UiPrefabs.GetDoomFont(), "Выход"); - var (stackObject, stack) = UiUtil.CreateStackUi(parScene, + var (stackObject, stack) = UiPrefabs.CreateStackUi(parScene, new StackComponent { Offset = new Vector2(0, -1f), Container = parUiContainer, Children = { playUi, leadersUi, rulesUi, exitUi } @@ -76,7 +76,7 @@ public static class MainScene rulesUi.OnClick += _ => parMenuController.SelectMenuItem("rules"); exitUi.OnClick += _ => EngineUtil.Close(); - var (selectorObject, selector) = UiUtil.CreateSelectorUi(parScene, + var (selectorObject, selector) = UiPrefabs.CreateSelectorUi(parScene, new SelectorComponent { Children = { playUi, leadersUi, rulesUi, exitUi } }); parScene.AddChild(parentObject, selectorObject); @@ -95,11 +95,11 @@ public static class MainScene { var parentObject = GameObjectUtil.CreateGameObject(parScene); - var (backUiObject, backUi, _) = UiUtil.CreateTextUi(parScene, parUiContainer, - UiUtil.GetDoomFont(), "Назад"); + var (backUiObject, backUi, _) = UiPrefabs.CreateTextUi(parScene, parUiContainer, + UiPrefabs.GetDoomFont(), "Назад"); backUi.OnClick += _ => parMenuController.SelectMenuItem("main"); - var (stackObject, stack) = UiUtil.CreateStackUi(parScene, + var (stackObject, stack) = UiPrefabs.CreateStackUi(parScene, new StackComponent { Offset = new Vector2(0, -1.5f), Container = parUiContainer }); stackObject.Transform.Size.Xy = new Vector2(1f, 6f); @@ -112,7 +112,7 @@ public static class MainScene stack.Children.Add(backUi); - var (selectorObject, selector) = UiUtil.CreateSelectorUi(parScene, new SelectorComponent { Children = { backUi } }); + var (selectorObject, selector) = UiPrefabs.CreateSelectorUi(parScene, new SelectorComponent { Children = { backUi } }); parScene.AddChild(parentObject, selectorObject); parScene.AddChild(parentObject, stackObject); @@ -153,12 +153,12 @@ public static class MainScene ]); var (nameUiObject, nameUi, _) = - UiUtil.CreateTextUi(parScene, uiComponent, UiUtil.GetDoomFont(), parName); + UiPrefabs.CreateTextUi(parScene, uiComponent, UiPrefabs.GetDoomFont(), parName); nameUi.Anchor = Anchor.CenterLeft; nameUi.Center = Anchor.Center; var (scoreUiObject, scoreUi, _) = - UiUtil.CreateTextUi(parScene, uiComponent, UiUtil.GetDoomFont(), parScore); + UiPrefabs.CreateTextUi(parScene, uiComponent, UiPrefabs.GetDoomFont(), parScore); scoreUi.Anchor = Anchor.CenterRight; scoreUi.Center = Anchor.Center; @@ -173,18 +173,18 @@ public static class MainScene { var parentObject = GameObjectUtil.CreateGameObject(parScene); - var (backUiObject, backUi, _) = UiUtil.CreateTextUi(parScene, parUiContainer, - UiUtil.GetDoomFont(), "Назад"); + var (backUiObject, backUi, _) = UiPrefabs.CreateTextUi(parScene, parUiContainer, + UiPrefabs.GetDoomFont(), "Назад"); backUi.OnClick += _ => parMenuController.SelectMenuItem("main"); - var (rulesObject, rulesUi, _) = UiUtil.CreateTextUi(parScene, parUiContainer, - UiUtil.GetDoomFont(), "Правила"); + var (rulesObject, rulesUi, _) = UiPrefabs.CreateTextUi(parScene, parUiContainer, + UiPrefabs.GetDoomFont(), "Правила"); - var (stackObject, stack) = UiUtil.CreateStackUi(parScene, + var (stackObject, stack) = UiPrefabs.CreateStackUi(parScene, new StackComponent { Offset = new Vector2(0, -1f), Container = parUiContainer, Children = { rulesUi, backUi } }); stackObject.Transform.Size.Xy = new Vector2(1f, 6f); - var (selectorObject, selector) = UiUtil.CreateSelectorUi(parScene, new SelectorComponent { Children = { backUi } }); + var (selectorObject, selector) = UiPrefabs.CreateSelectorUi(parScene, new SelectorComponent { Children = { backUi } }); parScene.AddChild(parentObject, selectorObject); diff --git a/DoomDeathmatch/src/Scene/Play/PlayScene.cs b/DoomDeathmatch/src/Scene/Play/PlayScene.cs index 15d26d1..0105776 100644 --- a/DoomDeathmatch/src/Scene/Play/PlayScene.cs +++ b/DoomDeathmatch/src/Scene/Play/PlayScene.cs @@ -33,9 +33,9 @@ public static class PlayScene { var scene = new Engine.Scene.Scene(); - var (hudCameraObject, hudCamera) = UiUtil.CreateOrthographicCamera(scene, RenderLayer.HUD); + var (hudCameraObject, hudCamera) = UiPrefabs.CreateOrthographicCamera(scene, RenderLayer.HUD); var (uiContainerObject, uiContainer) = - UiUtil.CreateContainerUi(scene, new UiContainerComponent { Camera = hudCamera }); + UiPrefabs.CreateContainerUi(scene, new UiContainerComponent { Camera = hudCamera }); var menuController = new MenuControllerComponent(); var menuControllerObject = GameObjectUtil.CreateGameObject(scene, [ @@ -100,14 +100,14 @@ public static class PlayScene new ObjectSpawner(new WeightedRandomValueProvider( new List<(int, IValueProvider)> { - (6, GeneratorValueProvider.Create(() => + (GameConstants.ENEMY_DEMON_SPAWN_WEIGHT, GeneratorValueProvider.Create(() => EnemyPrefab.Create(EngineUtil.SceneManager.CurrentScene!, EnemyData.Demon))), - (4, + (GameConstants.ENEMY_IMP_SPAWN_WEIGHT, GeneratorValueProvider.Create(() => EnemyPrefab.Create(EngineUtil.SceneManager.CurrentScene!, EnemyData.Imp))) }), monsterVector3ValueProvider, - new TickableTimerCondition(2f))) + new TickableTimerCondition(GameConstants.ENEMY_SPAWN_RATE_SECONDS))) ] ); @@ -127,16 +127,16 @@ public static class PlayScene new ObjectSpawner(new WeightedRandomValueProvider( new List<(int, IValueProvider)> { - (2, GeneratorValueProvider.Create(() => + (GameConstants.CONSUMABLE_HEALTH_PACK_SPAWN_WEIGHT, GeneratorValueProvider.Create(() => { var gameController = EngineUtil.SceneManager.CurrentScene!.FindFirstComponent()!; return ConsumablePrefab.Create(EngineUtil.SceneManager.CurrentScene, - new HealthPackConsumable(75), + new HealthPackConsumable(GameConstants.HEALTH_PACK_BASE_HEALING), gameController.PlayerController.Camera.GameObject.Transform ); })), - (4, GeneratorValueProvider.Create(() => + (GameConstants.CONSUMABLE_WEAPON_PISTOL_SPAWN_WEIGHT, GeneratorValueProvider.Create(() => { var gameController = EngineUtil.SceneManager.CurrentScene!.FindFirstComponent()!; @@ -145,7 +145,7 @@ public static class PlayScene gameController.PlayerController.Camera.GameObject.Transform ); })), - (3, GeneratorValueProvider.Create(() => + (GameConstants.CONSUMABLE_WEAPON_SHOTGUN_SPAWN_WEIGHT, GeneratorValueProvider.Create(() => { var gameController = EngineUtil.SceneManager.CurrentScene!.FindFirstComponent()!; @@ -156,7 +156,7 @@ public static class PlayScene })) }), consumableVector3ValueProvider, - new TickableTimerCondition(5f))) + new TickableTimerCondition(GameConstants.CONSUMABLE_SPAWN_RATE_SECONDS))) ] ); @@ -216,7 +216,7 @@ public static class PlayScene var parentObject = GameObjectUtil.CreateGameObject(parScene); var (bottomContainerObject, bottomContainer) = - UiUtil.CreateContainerUi(parScene, new UiContainerComponent { Container = parUiContainer }); + UiPrefabs.CreateContainerUi(parScene, new UiContainerComponent { Container = parUiContainer }); bottomContainer.Anchor = Anchor.BottomCenter; bottomContainer.Center = Anchor.BottomCenter; bottomContainerObject.AddComponent(new Box2DRenderer @@ -230,7 +230,7 @@ public static class PlayScene bottomContainerObject.Transform.Size.Y = 1.5f; parScene.AddChild(parentObject, bottomContainerObject); - var (gunObject, (gunUi, gunSprite)) = UiUtil.CreateSpriteUi(parScene, bottomContainer, + var (gunObject, (gunUi, gunSprite)) = UiPrefabs.CreateSpriteUi(parScene, bottomContainer, null, RenderLayer.HUD); gunObject.Transform.Scale = new Vector3(5); gunUi.Anchor = Anchor.TopCenter; @@ -239,7 +239,7 @@ public static class PlayScene parScene.AddChild(bottomContainerObject, gunObject); var (healthObject, healthUi, (_, healthTextRenderer)) = - UiUtil.CreateTextUi(parScene, bottomContainer, UiUtil.GetDoomFont(), "Здоровье: 000", + UiPrefabs.CreateTextUi(parScene, bottomContainer, UiPrefabs.GetDoomFont(), "Здоровье: 000", Align.Center, RenderLayer.HUD); healthObject.Transform.Scale = new Vector3(0.75f); @@ -248,7 +248,7 @@ public static class PlayScene parScene.AddChild(bottomContainerObject, healthObject); var (ammoObject, ammoUi, (_, ammoTextRenderer)) = - UiUtil.CreateTextUi(parScene, bottomContainer, UiUtil.GetDoomFont(), "Патроны: 00/00", + UiPrefabs.CreateTextUi(parScene, bottomContainer, UiPrefabs.GetDoomFont(), "Патроны: 00/00", Align.Center, RenderLayer.HUD); ammoObject.Transform.Scale = new Vector3(0.75f); @@ -257,7 +257,7 @@ public static class PlayScene parScene.AddChild(bottomContainerObject, ammoObject); var (weaponObject, weaponUi, (_, weaponTextRenderer)) = - UiUtil.CreateTextUi(parScene, bottomContainer, UiUtil.GetDoomFont(), "Оружие: ОРУЖИЕОР", + UiPrefabs.CreateTextUi(parScene, bottomContainer, UiPrefabs.GetDoomFont(), "Оружие: ОРУЖИЕОР", Align.Center, RenderLayer.HUD); weaponObject.Transform.Scale = new Vector3(0.75f); @@ -266,7 +266,7 @@ public static class PlayScene parScene.AddChild(bottomContainerObject, weaponObject); var (topContainerObject, topContainer) = - UiUtil.CreateContainerUi(parScene, new UiContainerComponent { Container = parUiContainer }); + UiPrefabs.CreateContainerUi(parScene, new UiContainerComponent { Container = parUiContainer }); topContainer.Anchor = Anchor.TopCenter; topContainer.Center = Anchor.TopCenter; topContainerObject.AddComponent( @@ -279,14 +279,14 @@ public static class PlayScene parScene.AddChild(parentObject, topContainerObject); var (timerObject, timerUi, (_, timerTextRenderer)) = - UiUtil.CreateTextUi(parScene, topContainer, UiUtil.GetDoomFont(), "Время: 00:00", + UiPrefabs.CreateTextUi(parScene, topContainer, UiPrefabs.GetDoomFont(), "Время: 00:00", parRenderLayer: RenderLayer.HUD); timerUi.Anchor = Anchor.CenterLeft; timerUi.Center = Anchor.CenterLeft; parScene.AddChild(topContainerObject, timerObject); var (scoreObject, scoreUi, (_, scoreTextRenderer)) = - UiUtil.CreateTextUi(parScene, topContainer, UiUtil.GetDoomFont(), "Счет: 00000", + UiPrefabs.CreateTextUi(parScene, topContainer, UiPrefabs.GetDoomFont(), "Счет: 00000", parRenderLayer: RenderLayer.HUD); scoreUi.Anchor = Anchor.CenterRight; scoreUi.Center = Anchor.CenterRight; @@ -305,34 +305,34 @@ public static class PlayScene { var parentObject = GameObjectUtil.CreateGameObject(parScene); - var (backgroundObject, backgroundUiContainer) = UiUtil.CreateBackgroundUi(parScene, + var (backgroundObject, backgroundUiContainer) = UiPrefabs.CreateBackgroundUi(parScene, new UiContainerComponent { Container = parUiContainer }, new Vector4(0, 0, 0, 0.9f), RenderLayer.HUD); backgroundObject.AddComponent(new CopySizeComponent { Target = parUiContainer.GameObject.Transform }); parScene.AddChild(parentObject, backgroundObject); - var (logoObject, logoUi) = UiUtil.CreateLogoUi(parScene, backgroundUiContainer, RenderLayer.HUD); + var (logoObject, logoUi) = UiPrefabs.CreateLogoUi(parScene, backgroundUiContainer, RenderLayer.HUD); logoUi.Offset = new Vector2(0, 3f); parScene.AddChild(parentObject, logoObject); - var (backUiObject, backUi, _) = UiUtil.CreateTextUi(parScene, backgroundUiContainer, - UiUtil.GetDoomFont(), "Назад", + var (backUiObject, backUi, _) = UiPrefabs.CreateTextUi(parScene, backgroundUiContainer, + UiPrefabs.GetDoomFont(), "Назад", parRenderLayer: RenderLayer.HUD); backUi.OnClick += _ => EngineUtil.SceneManager.CurrentScene!.FindFirstComponent()!.Unpause(); - var (exitUiObject, exitUi, _) = UiUtil.CreateTextUi(parScene, backgroundUiContainer, - UiUtil.GetDoomFont(), "Выход", + var (exitUiObject, exitUi, _) = UiPrefabs.CreateTextUi(parScene, backgroundUiContainer, + UiPrefabs.GetDoomFont(), "Выход", parRenderLayer: RenderLayer.HUD); exitUi.OnClick += _ => EngineUtil.SceneManager.TransitionTo(MainScene.Create); - var (stackObject, stack) = UiUtil.CreateStackUi(parScene, + var (stackObject, stack) = UiPrefabs.CreateStackUi(parScene, new StackComponent { Offset = new Vector2(0, -1f), Container = backgroundUiContainer, Children = { backUi, exitUi } }); stackObject.Transform.Size.Xy = new Vector2(1f, 6f); - var (selectorObject, selector) = UiUtil.CreateSelectorUi(parScene, + var (selectorObject, selector) = UiPrefabs.CreateSelectorUi(parScene, new SelectorComponent { Children = { backUi, exitUi } }, RenderLayer.HUD); parScene.AddChild(parentObject, selectorObject); diff --git a/DoomDeathmatch/src/Scene/Play/Prefab/EnemyPrefab.cs b/DoomDeathmatch/src/Scene/Play/Prefab/EnemyPrefab.cs index b783ffb..dc7c556 100644 --- a/DoomDeathmatch/src/Scene/Play/Prefab/EnemyPrefab.cs +++ b/DoomDeathmatch/src/Scene/Play/Prefab/EnemyPrefab.cs @@ -21,7 +21,7 @@ public static class EnemyPrefab { public static GameObject Create(Engine.Scene.Scene parScene, EnemyData parEnemyData) { - var enemyHealthTextRenderer = new TextRenderer { Font = UiUtil.GetDoomFont(), Text = "Здоровье: 000" }; + var enemyHealthTextRenderer = new TextRenderer { Font = UiPrefabs.GetDoomFont(), Text = "Здоровье: 000" }; var enemyBox2DRenderer = new Box2DRenderer(); var enemyObject = GameObjectUtil.CreateGameObject(parScene, @@ -69,13 +69,13 @@ public static class EnemyPrefab } public static GameObject CreateFireball(Engine.Scene.Scene parScene, Vector3 parPosition, - Vector3 parVelocity, float parDamage, Transform? parBillboardTarget = null) + Vector3 parVelocity, float parSize, float parDamage, Transform? parBillboardTarget = null) { var rigidbodyComponent = new RigidbodyComponent(); rigidbodyComponent.Velocity += parVelocity; var fireballObject = GameObjectUtil.CreateGameObject(parScene, - new Transform { Translation = parPosition, Size = new Vector3(0.5f) }, + new Transform { Translation = parPosition, Size = new Vector3(parSize) }, [ rigidbodyComponent, new Box2DRenderer { Texture = EngineUtil.AssetResourceManager.Load("texture/fireball.png") }, @@ -83,7 +83,7 @@ public static class EnemyPrefab new FireballComponent { Damage = parDamage }, new AABBColliderComponent { - Collider = new AABBCollider { Size = new Vector3(0.25f) }, + Collider = new AABBCollider { Size = new Vector3(parSize) }, ColliderGroups = { "fireball" }, ExcludeColliderCollideGroups = { "enemy", "fireball", "consumable" } } diff --git a/DoomDeathmatch/src/Scene/Play/Prefab/PlayerPrefab.cs b/DoomDeathmatch/src/Scene/Play/Prefab/PlayerPrefab.cs index c47def2..0201034 100644 --- a/DoomDeathmatch/src/Scene/Play/Prefab/PlayerPrefab.cs +++ b/DoomDeathmatch/src/Scene/Play/Prefab/PlayerPrefab.cs @@ -14,12 +14,12 @@ public static class PlayerPrefab { public static GameObject Create(Engine.Scene.Scene parScene, WeaponView parWeaponView, HealthView parHealthView) { - var (perspectiveCameraObject, perspectiveCamera) = UiUtil.CreatePerspectiveCamera(parScene); + var (perspectiveCameraObject, perspectiveCamera) = UiPrefabs.CreatePerspectiveCamera(parScene); perspectiveCameraObject.Transform.Translation.Z = 2; var playerObject = GameObjectUtil.CreateGameObject(parScene, [ new PlayerMovementComponent(), - new MovementController { Speed = 10f }, + new MovementController { Speed = GameConstants.PLAYER_BASE_SPEED }, new RigidbodyComponent(), new DragComponent { Drag = 10f, Multiplier = new Vector3(1, 1, 0) }, @@ -36,7 +36,7 @@ public static class PlayerPrefab new WeaponController(), parWeaponView, - new HealthController(), + new HealthController(GameConstants.PLAYER_BASE_HEALTH), parHealthView ]); diff --git a/DoomDeathmatch/src/UiUtil.cs b/DoomDeathmatch/src/Scene/UiPrefabs.cs similarity index 96% rename from DoomDeathmatch/src/UiUtil.cs rename to DoomDeathmatch/src/Scene/UiPrefabs.cs index 1a0dda2..0946a9f 100644 --- a/DoomDeathmatch/src/UiUtil.cs +++ b/DoomDeathmatch/src/Scene/UiPrefabs.cs @@ -9,9 +9,9 @@ using Engine.Scene.Component.BuiltIn.Renderer; using Engine.Util; using OpenTK.Mathematics; -namespace DoomDeathmatch; +namespace DoomDeathmatch.Scene; -public static class UiUtil +public static class UiPrefabs { public static Font GetDoomFont() { @@ -52,10 +52,10 @@ public static class UiUtil }; var uiComponent = new UiContainerComponent { Container = parContainer }; outerObject.AddComponent(uiComponent); - outerObject.AddComponent(new Box2DRenderer - { - Color = new Vector4(0, 0, 1, 1), RenderLayer = parRenderLayer ?? RenderLayer.DEFAULT - }); + // outerObject.AddComponent(new Box2DRenderer + // { + // Color = new Vector4(0, 0, 1, 1), RenderLayer = parRenderLayer ?? RenderLayer.DEFAULT + // }); var innerObject = new GameObject { Transform = { Translation = new Vector3(0, 0, -1) } }; // var innerUiComponent = new UiComponent { Container = uiComponent }; diff --git a/DoomDeathmatch/src/Script/Model/Enemy/Attack/ObjectSpawnAttackBehavior.cs b/DoomDeathmatch/src/Script/Model/Enemy/Attack/ObjectSpawnAttackBehavior.cs index 4e22678..6ffbbab 100644 --- a/DoomDeathmatch/src/Script/Model/Enemy/Attack/ObjectSpawnAttackBehavior.cs +++ b/DoomDeathmatch/src/Script/Model/Enemy/Attack/ObjectSpawnAttackBehavior.cs @@ -1,5 +1,6 @@ using DoomDeathmatch.Component.MVC.Enemy; using DoomDeathmatch.Component.MVC.Health; +using DoomDeathmatch.Script.Provider; using Engine.Scene; using Engine.Util; @@ -13,7 +14,7 @@ public class ObjectSpawnAttackBehavior : CooldownAttackBehavior /// /// The function used to spawn an object based on the enemy and target controllers. /// - private readonly Func _objectSpawnFunc; + private readonly IValueProvider _objectValueProvider; /// /// Initializes a new instance of the class. @@ -21,14 +22,14 @@ public class ObjectSpawnAttackBehavior : CooldownAttackBehavior /// The enemy controller. /// The health controller of the target. /// The cooldown duration between spawns. - /// The function used to create the spawned object. + /// The function used to create the spawned object. public ObjectSpawnAttackBehavior(EnemyController parEnemyController, HealthController parHealthController, float parCooldown, - Func parObjectSpawnFunc) : base(parEnemyController, + IValueProvider parObjectValueProvider) : base(parEnemyController, parHealthController, parCooldown) { - _objectSpawnFunc = parObjectSpawnFunc; + _objectValueProvider = parObjectValueProvider; } /// @@ -40,7 +41,7 @@ public class ObjectSpawnAttackBehavior : CooldownAttackBehavior /// protected override bool ActivateAttack() { - var enemyObject = _objectSpawnFunc(_enemyController, _healthController); + var enemyObject = _objectValueProvider.GetValue(); EngineUtil.SceneManager.CurrentScene!.Add(enemyObject); return true; diff --git a/DoomDeathmatch/src/Script/Model/Enemy/EnemyData.cs b/DoomDeathmatch/src/Script/Model/Enemy/EnemyData.cs index 466391e..5506942 100644 --- a/DoomDeathmatch/src/Script/Model/Enemy/EnemyData.cs +++ b/DoomDeathmatch/src/Script/Model/Enemy/EnemyData.cs @@ -1,6 +1,9 @@ -using DoomDeathmatch.Scene.Play.Prefab; +using DoomDeathmatch.Scene; +using DoomDeathmatch.Scene.Play.Prefab; using DoomDeathmatch.Script.Model.Enemy.Attack; using DoomDeathmatch.Script.Model.Enemy.Movement; +using DoomDeathmatch.Script.Provider; +using Engine.Scene; using Engine.Util; using OpenTK.Mathematics; @@ -20,13 +23,16 @@ public class EnemyData Id = "demon", Name = "Демон", Texture = "texture/demon.png", - BaseHealth = 150, - BaseScore = 50, - BaseSpeed = 8, - MovementBehavior = new FollowPlayerMovementBehavior(1.5f), + BaseScore = GameConstants.DEMON_BASE_SCORE, + BaseHealth = GameConstants.DEMON_BASE_HEALTH, + BaseSpeed = GameConstants.DEMON_BASE_SPEED, + MovementBehavior = new FollowPlayerMovementBehavior(GameConstants.DEMON_FOLLOW_RADIUS), AttackBehaviorCreator = new FuncAttackBehaviorCreator( (parEnemyController, parHealthController) => - new CloseCooldownAttackBehavior(parEnemyController, parHealthController, 1.75f, 2.5f, 10) + new CloseCooldownAttackBehavior(parEnemyController, parHealthController, + GameConstants.DEMON_CLOSE_COOLDOWN_ATTACK_RADIUS, + GameConstants.DEMON_CLOSE_COOLDOWN_ATTACK_COOLDOWN, + GameConstants.DEMON_CLOSE_COOLDOWN_ATTACK_DAMAGE) ) }; @@ -39,31 +45,36 @@ public class EnemyData Id = "imp", Name = "Имп", Texture = "texture/imp.png", - BaseHealth = 300, - BaseScore = 200, - BaseSpeed = 7, - MovementBehavior = new FollowPlayerMovementBehavior(10f), + BaseScore = GameConstants.IMP_BASE_SCORE, + BaseHealth = GameConstants.IMP_BASE_HEALTH, + BaseSpeed = GameConstants.IMP_BASE_SPEED, + MovementBehavior = new FollowPlayerMovementBehavior(GameConstants.IMP_FOLLOW_RADIUS), AttackBehaviorCreator = new FuncAttackBehaviorCreator( (parEnemyController, parHealthController) => new CompositeAttackBehavior(parEnemyController, parHealthController, [ - new CloseContinuousAttackBehavior(parEnemyController, parHealthController, 1.75f, 10f), - new ObjectSpawnAttackBehavior(parEnemyController, parHealthController, 4f, - (parEnemyController, parHealthController) => + new CloseContinuousAttackBehavior(parEnemyController, parHealthController, + GameConstants.IMP_CLOSE_CONTINUOUS_ATTACK_RADIUS, + GameConstants.IMP_CLOSE_CONTINUOUS_ATTACK_DAMAGE), + new ObjectSpawnAttackBehavior(parEnemyController, parHealthController, + GameConstants.IMP_FIREBALL_ATTACK_COOLDOWN, + GeneratorValueProvider.Create(() => { var direction = (parHealthController.GameObject.Transform.Translation - parEnemyController.GameObject.Transform.Translation).Normalized(); - var fireballObject = EnemyPrefab.CreateFireball(EngineUtil.SceneManager.CurrentScene!, + var fireballObject = EnemyPrefab.CreateFireball( + EngineUtil.SceneManager.CurrentScene!, parEnemyController.GameObject.Transform.Translation + new Vector3(0, 0f, 1.75f), - direction * 25, - 35, + GameConstants.IMP_FIREBALL_ATTACK_SPEED * direction, + GameConstants.IMP_FIREBALL_ATTACK_SIZE, + GameConstants.IMP_FIREBALL_ATTACK_DAMAGE, parHealthController.GameObject.Transform ); return fireballObject; - } + }) ) ] ) @@ -85,16 +96,16 @@ public class EnemyData /// public string Texture { get; private init; } = ""; - /// - /// The base health of the enemy. - /// - public float BaseHealth { get; private init; } - /// /// The base score awarded for defeating this enemy. /// public int BaseScore { get; private init; } + /// + /// The base health of the enemy. + /// + public float BaseHealth { get; private init; } + /// /// The base speed of the enemy. /// diff --git a/DoomDeathmatch/src/Script/Model/Weapon/WeaponData.cs b/DoomDeathmatch/src/Script/Model/Weapon/WeaponData.cs index 8bc34d9..32fc7a3 100644 --- a/DoomDeathmatch/src/Script/Model/Weapon/WeaponData.cs +++ b/DoomDeathmatch/src/Script/Model/Weapon/WeaponData.cs @@ -1,4 +1,5 @@ -using OpenTK.Mathematics; +using DoomDeathmatch.Scene; +using OpenTK.Mathematics; namespace DoomDeathmatch.Script.Model.Weapon; @@ -11,17 +12,20 @@ public class WeaponData /// Data for the "Pistol" weapon. /// public static WeaponData Pistol => - new(30) + new(GameConstants.PISTOL_MAX_AMMO) { Id = "pistol", Name = "Пистолет", + Damage = GameConstants.PISTOL_BASE_DAMAGE, IdleTexture = "texture/pistol/idle.png", FireAnimationDuration = 0.25f, FireAnimation = { - "texture/pistol/fire1.png", "texture/pistol/fire2.png", "texture/pistol/fire3.png", "texture/pistol/fire4.png" + "texture/pistol/fire1.png", + "texture/pistol/fire2.png", + "texture/pistol/fire3.png", + "texture/pistol/fire4.png" }, - Damage = 30, ShootPattern = new LineShootPattern() }; @@ -29,15 +33,18 @@ public class WeaponData /// Data for the "Shotgun" weapon. /// public static WeaponData Shotgun => - new(10) + new(GameConstants.SHOTGUN_MAX_AMMO) { Id = "shotgun", Name = "Дробовик", + Damage = GameConstants.SHOTGUN_BASE_DAMAGE, IdleTexture = "texture/shotgun/idle.png", FireAnimationDuration = 0.1f, FireAnimation = { "texture/shotgun/fire1.png", "texture/shotgun/fire2.png" }, - Damage = 5, - ShootPattern = new RandomFlatSpreadShootPattern(MathHelper.DegreesToRadians(10), 40) + ShootPattern = + new RandomFlatSpreadShootPattern( + MathHelper.DegreesToRadians(GameConstants.SHOTGUN_SHOOT_PATTERN_ANGLE_DEGREES), + GameConstants.SHOTGUN_SHOOT_PATTERN_COUNT) }; /// diff --git a/DoomDeathmatch/src/Script/ObjectSpawner.cs b/DoomDeathmatch/src/Script/ObjectSpawner.cs index ffa9fec..f2fadb2 100644 --- a/DoomDeathmatch/src/Script/ObjectSpawner.cs +++ b/DoomDeathmatch/src/Script/ObjectSpawner.cs @@ -46,10 +46,6 @@ public class ObjectSpawner : IUpdate _condition.OnTrue += Spawn; } - /// - /// Updates the state of the spawner, evaluating the condition to determine if a new object should spawn. - /// - /// The time elapsed since the last update, in seconds. public void Update(double parDeltaTime) { _condition.Update(parDeltaTime);