diff --git a/Assets/Art/wood.json b/Assets/Art/wood.json new file mode 100644 index 0000000..29e15ec --- /dev/null +++ b/Assets/Art/wood.json @@ -0,0 +1,53 @@ +{ "frames": [ + { + "filename": "Wood1-0", + "frame": { "x": 1, "y": 1, "w": 26, "h": 10 }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { "x": 0, "y": 0, "w": 26, "h": 10 }, + "sourceSize": { "w": 26, "h": 10 }, + "duration": 100 + }, + { + "filename": "Wood2-1", + "frame": { "x": 29, "y": 1, "w": 26, "h": 10 }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { "x": 0, "y": 0, "w": 26, "h": 10 }, + "sourceSize": { "w": 26, "h": 10 }, + "duration": 100 + }, + { + "filename": "Wood3-2", + "frame": { "x": 1, "y": 13, "w": 26, "h": 10 }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { "x": 0, "y": 0, "w": 26, "h": 10 }, + "sourceSize": { "w": 26, "h": 10 }, + "duration": 100 + }, + { + "filename": "Wood4-3", + "frame": { "x": 29, "y": 13, "w": 26, "h": 10 }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { "x": 0, "y": 0, "w": 26, "h": 10 }, + "sourceSize": { "w": 26, "h": 10 }, + "duration": 100 + } + ], + "meta": { + "app": "https://www.aseprite.org/", + "version": "1.3-rc6-x64", + "image": "wood.png", + "format": "RGBA8888", + "size": { "w": 56, "h": 24 }, + "scale": "1", + "frameTags": [ + { "name": "Wood1", "from": 0, "to": 0, "direction": "forward", "color": "#000000ff" }, + { "name": "Wood2", "from": 1, "to": 1, "direction": "forward", "color": "#000000ff" }, + { "name": "Wood3", "from": 2, "to": 2, "direction": "forward", "color": "#000000ff" }, + { "name": "Wood4", "from": 3, "to": 3, "direction": "forward", "color": "#000000ff" } + ] + } +} diff --git a/Assets/Art/wood.png b/Assets/Art/wood.png new file mode 100644 index 0000000..c782905 Binary files /dev/null and b/Assets/Art/wood.png differ diff --git a/Assets/Aseprite/wood.ase b/Assets/Aseprite/wood.ase new file mode 100644 index 0000000..cb7a8fb Binary files /dev/null and b/Assets/Aseprite/wood.ase differ diff --git a/Assets/Audio/sfx_ShipHit_01.ogg b/Assets/Audio/sfx_ShipHit_01.ogg new file mode 100644 index 0000000..22f5124 Binary files /dev/null and b/Assets/Audio/sfx_ShipHit_01.ogg differ diff --git a/Assets/Audio/sfx_ShipHit_02.ogg b/Assets/Audio/sfx_ShipHit_02.ogg new file mode 100644 index 0000000..0a573b7 Binary files /dev/null and b/Assets/Audio/sfx_ShipHit_02.ogg differ diff --git a/Assets/Audio/sfx_ShipHit_03.ogg b/Assets/Audio/sfx_ShipHit_03.ogg new file mode 100644 index 0000000..6dccfcf Binary files /dev/null and b/Assets/Audio/sfx_ShipHit_03.ogg differ diff --git a/Assets/lavanda.rgs b/Assets/lavanda.rgs new file mode 100644 index 0000000..37aff80 Binary files /dev/null and b/Assets/lavanda.rgs differ diff --git a/Components/Ship.cs b/Components/Ship.cs index 52da3a1..b667342 100644 --- a/Components/Ship.cs +++ b/Components/Ship.cs @@ -23,6 +23,7 @@ internal class Ship internal float MaxSpeed = 500f; internal float HullHealth = 100f; + internal float WindInSail; // 1 - steering only, drifts in the wind. // 2 - Steering and rowing diff --git a/Components/Wood.cs b/Components/Wood.cs new file mode 100644 index 0000000..8292954 --- /dev/null +++ b/Components/Wood.cs @@ -0,0 +1,12 @@ +using System.Numerics; + +namespace NovemberPirates.Components +{ + internal class Wood + { + internal float Duration; + internal float Elapsed; + internal Vector2 Target; + internal float Speed; + } +} diff --git a/Entities/Archetypes/PickupBuilder.cs b/Entities/Archetypes/PickupBuilder.cs index 23da725..724ef0a 100644 --- a/Entities/Archetypes/PickupBuilder.cs +++ b/Entities/Archetypes/PickupBuilder.cs @@ -23,5 +23,21 @@ internal static void CreateCrewMember(World world, Vector2 position) entity.Set(crewMember); entity.Set(sprite); } + + internal static void CreateWood(World world, Vector2 position) + { + var entity = world.Create(); + var wood = new Wood(); + var spread = 100; + wood.Target = position + new Vector2(Random.Shared.Next(-spread, spread), Random.Shared.Next(-spread, spread)); + wood.Duration = 25f; + wood.Speed = 10f; + + var sprite = new Sprite(TextureKey.Wood, "Assets/Art/wood", 1f, true); + sprite.Position = position; + + entity.Set(wood); + entity.Set(sprite); + } } } diff --git a/Scenes/BaseScene.cs b/Scenes/BaseScene.cs index 05e47b2..b249bbb 100644 --- a/Scenes/BaseScene.cs +++ b/Scenes/BaseScene.cs @@ -4,7 +4,7 @@ namespace NovemberPirates.Scenes { - internal class BaseScene + internal abstract class BaseScene { internal World World = World.Create(); diff --git a/Scenes/Levels/Systems/CannonBallSystem.cs b/Scenes/Levels/Systems/CannonBallSystem.cs index 62151be..3510b71 100644 --- a/Scenes/Levels/Systems/CannonBallSystem.cs +++ b/Scenes/Levels/Systems/CannonBallSystem.cs @@ -42,6 +42,11 @@ internal override void Update(World world) { ship.HullHealth -= 5; EffectsBuilder.CreateExplosion(world, end); + world.Create(new AudioEvent + { + Key = AudioKey.CannonHitShip, + Position = sprite.Position + }); destroyed = true; ship.BoatCondition = ship.HullHealth switch { @@ -51,22 +56,22 @@ internal override void Update(World world) < 75 => BoatCondition.Good, _ => BoatCondition.Good }; + var shouldSpawnWood = Random.Shared.Next(0, 100) < 30; + if (shouldSpawnWood) + { + PickupBuilder.CreateWood(world, sprite.Position); + } shipSprite.Texture = ShipSpriteBuilder.GenerateBoat(new BoatOptions(ship)).Texture; } }); if (destroyed) world.Destroy(entity); - else + else if (cannonball.Elapsed > cannonball.Duration) { - if (cannonball.Elapsed > cannonball.Duration) - { - var sound = world.Create(); - sound.Set(new AudioEvent() { Key = AudioKey.CannonHitWater, Position = sprite.Position }); - world.Destroy(entity); - } + world.Create(new AudioEvent() { Key = AudioKey.CannonHitWater, Position = sprite.Position }); + world.Destroy(entity); } - }); } } diff --git a/Scenes/Levels/Systems/EnemyControlSystem.cs b/Scenes/Levels/Systems/EnemyControlSystem.cs index a4816ad..aad9ce2 100644 --- a/Scenes/Levels/Systems/EnemyControlSystem.cs +++ b/Scenes/Levels/Systems/EnemyControlSystem.cs @@ -37,7 +37,7 @@ internal override void Update(World world) ship.Crew -= 1; ship.HullHealth += 1; var sound = world.Create(); - sound.Set(new AudioEvent() { Key = AudioKey.CrewHitWater }); + sound.Set(new AudioEvent() { Key = AudioKey.CrewHitWater, Position = sprite.Position }); PickupBuilder.CreateCrewMember(world, sprite.Position); } } @@ -183,7 +183,7 @@ internal override void Update(World world) ship.Sail = SailStatus.Closed; sprite.Texture = ShipSpriteBuilder.GenerateBoat(new BoatOptions(ship)).Texture; } - Console.WriteLine($"{new BoatOptions(ship).ToString()} {ship.Crew} {ship.HullHealth} "); + //Console.WriteLine($"{new BoatOptions(ship).ToString()} {ship.Crew} {ship.HullHealth} "); }); } } diff --git a/Scenes/Levels/Systems/PlayerControlSystem.cs b/Scenes/Levels/Systems/PlayerControlSystem.cs index 613927a..7be0549 100644 --- a/Scenes/Levels/Systems/PlayerControlSystem.cs +++ b/Scenes/Levels/Systems/PlayerControlSystem.cs @@ -26,12 +26,22 @@ internal override void Update(World world) if (Raylib.IsKeyPressed(KeyboardKey.KEY_W)) { + var priorSail = playerShip.Sail; playerShip.Sail = (SailStatus)Math.Min(Enum.GetValues().Length - 1, (int)playerShip.Sail + 1); + + if (priorSail != playerShip.Sail && playerShip.Sail >= SailStatus.Half) + world.Create().Set(new AudioEvent() { Key = AudioKey.SailOpen, Position = sprite.Position }); + boatChanged = true; } if (Raylib.IsKeyPressed(KeyboardKey.KEY_S)) { + var priorSail = playerShip.Sail; playerShip.Sail = (SailStatus)Math.Max(0, (int)playerShip.Sail - 1); + + if (priorSail != playerShip.Sail && playerShip.Sail >= SailStatus.Rowing) + world.Create().Set(new AudioEvent() { Key = AudioKey.SailClose, Position = sprite.Position }); + boatChanged = true; } if (Raylib.IsKeyDown(KeyboardKey.KEY_A)) diff --git a/Scenes/Levels/Systems/ShipControlSystem.cs b/Scenes/Levels/Systems/ShipControlSystem.cs index 786694c..2ca23fc 100644 --- a/Scenes/Levels/Systems/ShipControlSystem.cs +++ b/Scenes/Levels/Systems/ShipControlSystem.cs @@ -53,6 +53,11 @@ internal override void Update(World world) < 75 => 0.1f, _ => 0f, }; + + if (windInSail == 1f && windInSail != ship.WindInSail && ship.Sail >= SailStatus.Half) + world.Create(new AudioEvent() { Key = AudioKey.WindInSail, Position = sprite.Position }); + + ship.WindInSail = windInSail; //singleton.DebugText += $"Boat Angle:{boatAngle.ToString("0.0")}\nWind Angle: {windAngle.ToString("0.0")}\nAngle Diff: {angleDiff.ToString("0.0")}\nWind In Sail: {windInSail.ToString("0.0")}"; var windStrength = wind.WindStrength * windInSail; diff --git a/Scenes/Menus/MainMenu/MainMenuScene.cs b/Scenes/Menus/MainMenu/MainMenuScene.cs index 13f2ffa..3a6360a 100644 --- a/Scenes/Menus/MainMenu/MainMenuScene.cs +++ b/Scenes/Menus/MainMenu/MainMenuScene.cs @@ -27,7 +27,39 @@ public MainMenuScene() Order = 1 }); - + + World.Create(new UiButton + { + Text = "How to Play", + Action = () => + { + NovemberPiratesEngine.Instance.ActiveScene = new HowToPlayScene(); + }, + Order = 2 + }); + + World.Create(new UiButton + { + Text = "Credits", + Action = () => + { + NovemberPiratesEngine.Instance.ActiveScene = new CreditsScene(); + }, + Order = 3 + }); + + + World.Create(new UiButton + { + Text = "Exit", + Action = () => + { + Environment.Exit(0); + //NovemberPiratesEngine.Instance.ActiveScene = new HowToPlayScene(); + }, + Order = 5 + }); + } diff --git a/Scenes/Menus/Systems/MenuSystem.cs b/Scenes/Menus/Systems/MenuSystem.cs index fbb9d85..2174ecb 100644 --- a/Scenes/Menus/Systems/MenuSystem.cs +++ b/Scenes/Menus/Systems/MenuSystem.cs @@ -9,10 +9,12 @@ namespace NovemberPirates.Scenes.Menus.Systems { internal class MenuSystem : GameSystem { + internal override void Update(World world) { } internal override void UpdateNoCamera(World world) { + //RayGui.GuiLoadStyle("Assets/lavanda.rgs"); var query = new QueryDescription().WithAny(); var centerPoint = new Vector2(Raylib.GetScreenWidth() / 2, Raylib.GetScreenHeight() / 2); @@ -20,6 +22,11 @@ internal override void UpdateNoCamera(World world) var dummyrect = new Rectangle(centerPoint.X - 200, centerPoint.Y - 150, 400, 400); RayGui.GuiDummyRec(dummyrect, ""); var index = 0; + + RayGui.GuiSetStyle((int)GuiControl.DEFAULT, (int)GuiDefaultProperty.TEXT_SIZE, 48); + RayGui.GuiSetStyle((int)GuiControl.LABEL, (int)GuiControlProperty.TEXT_ALIGNMENT, 1); + + RayGui.GuiSetStyle((int)GuiControl.BUTTON, (int)GuiControlProperty.TEXT_ALIGNMENT, 0); world.Query(in query, (entity) => { index++; @@ -31,20 +38,19 @@ internal override void UpdateNoCamera(World world) var rect = new Rectangle(centerPoint.X - 100, 200 + 50 * titleComponent.Order, 200, 100); //RayGui.GuiTextBox(text, centerPoint.X - 200, centerPoint.Y - 200, 24, Raylib.ORANGE); - RayGui.GuiSetStyle((int)GuiControl.LABEL, (int)GuiControlProperty.TEXT_ALIGNMENT, 1); // TODO fix font size - var font = RayGui.GuiGetFont(); - font.baseSize = 48; - RayGui.GuiSetFont(font); RayGui.GuiLabel(rect, text); } + RayGui.GuiSetStyle((int)GuiControl.BUTTON, (int)GuiControlProperty.TEXT_ALIGNMENT, 1); + + RayGui.GuiSetStyle((int)GuiControl.DEFAULT, (int)GuiDefaultProperty.TEXT_SIZE, 24); if (entity.Has()) { var button = entity.Get(); - var rect = dummyrect with { x = dummyrect.x + 100, y = dummyrect.y + 50 * button.Order, width = 200, height = 60 }; + var rect = dummyrect with { x = dummyrect.x + 100, y = dummyrect.y + (60 * button.Order), width = 200, height = 50 }; if (RayGui.GuiButton(rect, button.Text)) { diff --git a/Utilities/AudioManager.cs b/Utilities/AudioManager.cs index 751c569..b22f804 100644 --- a/Utilities/AudioManager.cs +++ b/Utilities/AudioManager.cs @@ -17,6 +17,12 @@ internal void LoadAllAudio() Raylib.LoadSound("Assets/Audio/sfx_CannonFire_03.ogg"), Raylib.LoadSound("Assets/Audio/sfx_CannonFire_04.ogg"), }); + AudioStore.Add(AudioKey.CannonHitShip, new[] + { + Raylib.LoadSound("Assets/Audio/sfx_ShipHit_01.ogg"), + Raylib.LoadSound("Assets/Audio/sfx_ShipHit_02.ogg"), + Raylib.LoadSound("Assets/Audio/sfx_ShipHit_03.ogg"), + }); AudioStore.Add(AudioKey.CannonHitWater, new[] { Raylib.LoadSound("Assets/Audio/sfx_CannonHitWater.ogg") @@ -33,7 +39,7 @@ internal void LoadAllAudio() { Raylib.LoadSound("Assets/Audio/sfx_Wind.ogg") }); - AudioStore.Add(AudioKey.CollectWood, new[] { + AudioStore.Add(AudioKey.CollectWood, new[] { // TODO Raylib.LoadSound("Assets/Audio/sfx_CollectWood_01.ogg"), Raylib.LoadSound("Assets/Audio/sfx_CollectWood_02.ogg"), Raylib.LoadSound("Assets/Audio/sfx_CollectWood_03.ogg"), @@ -76,5 +82,6 @@ internal enum AudioKey SailClose, SailOpen, WindInSail, + CannonHitShip, } } diff --git a/Utilities/ShipSpriteBuilder.cs b/Utilities/ShipSpriteBuilder.cs index 6737b88..2f19a13 100644 --- a/Utilities/ShipSpriteBuilder.cs +++ b/Utilities/ShipSpriteBuilder.cs @@ -134,9 +134,7 @@ internal static Sprite GenerateBoat(BoatOptions options) }; sprite.Play("idle"); - //Raylib.ExportImage(Raylib.LoadImageFromTexture(sprite.Texture), options.ToKey() + ".png"); - - //TextureManager.Instance.TextureCache.Add(options.ToKey(), renderTexture.texture); + TextureManager.Instance.TextureCache.Add(options.ToKey(), renderTexture.texture); return sprite; } diff --git a/Utilities/TextureManager.cs b/Utilities/TextureManager.cs index cff18db..f857bb8 100644 --- a/Utilities/TextureManager.cs +++ b/Utilities/TextureManager.cs @@ -33,6 +33,7 @@ private void LoadTextures() TextureStore.Add(TextureKey.Fire, Raylib.LoadTexture("Assets/Art/fire1.png")); TextureStore.Add(TextureKey.WhitePixel, Raylib.LoadTexture("Assets/Art/whitepixel.png")); TextureStore.Add(TextureKey.Crew, Raylib.LoadTexture("Assets/Art/crew.png")); + TextureStore.Add(TextureKey.Wood, Raylib.LoadTexture("Assets/Art/wood.png")); } internal Texture GetTexture(TextureKey key) @@ -70,5 +71,6 @@ internal enum TextureKey Crew, HullSmall, HullMedium, + Wood, } }