diff options
| -rw-r--r-- | Penguloon/Content/Content.mgcb | 6 | ||||
| -rw-r--r-- | Penguloon/Content/Sounds/pop.wav | bin | 0 -> 38990 bytes | |||
| -rw-r--r-- | Penguloon/ContentPathManager.cs | 1 | ||||
| -rw-r--r-- | Penguloon/Enemies/BlueBalloon.cs | 16 | ||||
| -rw-r--r-- | Penguloon/Enemies/EnemyBase.cs | 23 | ||||
| -rw-r--r-- | Penguloon/Enemies/RedBalloon.cs | 1 | ||||
| -rw-r--r-- | Penguloon/Levels/IceLevel.cs | 1 | ||||
| -rw-r--r-- | Penguloon/Levels/LevelBase.cs | 11 | ||||
| -rw-r--r-- | Penguloon/Levels/Map.cs | 17 | ||||
| -rw-r--r-- | Penguloon/Levels/WaveManager.cs | 3 | ||||
| -rw-r--r-- | Penguloon/Objects/ObjectBase.cs | 33 | ||||
| -rw-r--r-- | Penguloon/Objects/PenguinObject.cs | 12 | ||||
| -rw-r--r-- | Penguloon/Penguloon.csproj | 3 | ||||
| -rw-r--r-- | Penguloon/Projectiles/ProjectileBase.cs | 80 | ||||
| -rw-r--r-- | Penguloon/Projectiles/SnowballProjectile.cs | 23 | ||||
| -rw-r--r-- | Penguloon/Scenes/GameScene.cs | 11 | ||||
| -rw-r--r-- | Penguloon/SoundManager.cs | 6 | ||||
| -rw-r--r-- | Penguloon/StaticUIValues.cs | 7 |
18 files changed, 225 insertions, 29 deletions
diff --git a/Penguloon/Content/Content.mgcb b/Penguloon/Content/Content.mgcb index 71c3b4f..3cc76a5 100644 --- a/Penguloon/Content/Content.mgcb +++ b/Penguloon/Content/Content.mgcb @@ -437,3 +437,9 @@ /processorParam:TextureFormat=Color /build:UI/border-horizontal.png +#begin Sounds/pop.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:Sounds/pop.wav + diff --git a/Penguloon/Content/Sounds/pop.wav b/Penguloon/Content/Sounds/pop.wav Binary files differnew file mode 100644 index 0000000..1a3794f --- /dev/null +++ b/Penguloon/Content/Sounds/pop.wav diff --git a/Penguloon/ContentPathManager.cs b/Penguloon/ContentPathManager.cs index f3a7ff3..8569905 100644 --- a/Penguloon/ContentPathManager.cs +++ b/Penguloon/ContentPathManager.cs @@ -62,6 +62,7 @@ namespace Penguloon public static List<string> SoundPaths { get; set; } = new List<string>() { "Sounds/click", + "Sounds/pop", }; public static List<string> TexturePathsPreLoad { get; set; } = new List<string>() diff --git a/Penguloon/Enemies/BlueBalloon.cs b/Penguloon/Enemies/BlueBalloon.cs new file mode 100644 index 0000000..2490a09 --- /dev/null +++ b/Penguloon/Enemies/BlueBalloon.cs @@ -0,0 +1,16 @@ +using Penguloon.Levels; + +namespace Penguloon.Enemies +{ + class BlueBalloon : EnemyBase + { + public BlueBalloon(Map map) : base(map) + { + this.Texture = ContentManager.GetTexture("Enemies/blue"); + this.Speed = 45f; + this.Health = 1; + this.ChildObject = typeof(RedBalloon); + this.HealthToTake = 2; + } + } +}
\ No newline at end of file diff --git a/Penguloon/Enemies/EnemyBase.cs b/Penguloon/Enemies/EnemyBase.cs index d9413b4..c67e3bc 100644 --- a/Penguloon/Enemies/EnemyBase.cs +++ b/Penguloon/Enemies/EnemyBase.cs @@ -24,6 +24,8 @@ namespace Penguloon.Enemies public Rectangle Box { get; set; } + public int HealthToTake { get; set; } + public EnemyBase(Map map) { this.Map = map; @@ -34,7 +36,8 @@ namespace Penguloon.Enemies public void Update(float deltaTime) { - Box = new Rectangle(Position.ToPoint(), new Point(Map.TileWidth, Map.TileHeight)); + int margin = 5; + Box = new Rectangle(new Point((int)Position.X + margin, (int)Position.Y + margin), new Point(Map.TileWidth - (margin * 2), Map.TileHeight - (margin * 2))); int tileX = (int)(TargetPosition.X + 2) / Map.TileWidth; int tileY = (int)(TargetPosition.Y + 2) / Map.TileHeight; @@ -67,7 +70,12 @@ namespace Penguloon.Enemies private void ReachEnd() { - Map.Level.Health--; + if (!Map.Level.Finished) + { + Map.Level.Health -= HealthToTake; + if (Map.Level.Health < 0) + Map.Level.Health = 0; + } Map.Enemies.Remove(this); } @@ -76,19 +84,22 @@ namespace Penguloon.Enemies { Health--; - if (Health <= 0) - Map.Enemies.Remove(this); + Map.Level.Money++; + Map.Level.Kills++; SpawnChild(); - // play pop sound + if (Health <= 0) + Map.Enemies.Remove(this); + + SoundManager.PlayBalloonPopSound(); } private void SpawnChild() { if (this.ChildObject == null) return; - Map.SpawnEnemy(ChildObject, Position, TargetPosition); + Map.SpawnEnemy(ChildObject, Position, TargetPosition, Map.Enemies.IndexOf(this)); } } }
\ No newline at end of file diff --git a/Penguloon/Enemies/RedBalloon.cs b/Penguloon/Enemies/RedBalloon.cs index b0f86f6..5f0c36b 100644 --- a/Penguloon/Enemies/RedBalloon.cs +++ b/Penguloon/Enemies/RedBalloon.cs @@ -10,6 +10,7 @@ namespace Penguloon.Enemies this.Speed = 45f; this.Health = 1; this.ChildObject = null; + this.HealthToTake = 1; } } }
\ No newline at end of file diff --git a/Penguloon/Levels/IceLevel.cs b/Penguloon/Levels/IceLevel.cs index 1778369..1516afe 100644 --- a/Penguloon/Levels/IceLevel.cs +++ b/Penguloon/Levels/IceLevel.cs @@ -66,6 +66,7 @@ namespace Penguloon.Levels //Map.Objects.Add(new PenguinObject(new Vector2(0, 0), Map)); Map.Objects.Add(new PenguinObject(new Vector2(Map.TileWidth * 2, Map.TileHeight * 4), Map)); + Map.Objects.Add(new PenguinObject(new Vector2(Map.TileWidth * 1, Map.TileHeight * 8), Map)); } } }
\ No newline at end of file diff --git a/Penguloon/Levels/LevelBase.cs b/Penguloon/Levels/LevelBase.cs index f4c45a8..5698cfa 100644 --- a/Penguloon/Levels/LevelBase.cs +++ b/Penguloon/Levels/LevelBase.cs @@ -14,10 +14,14 @@ namespace Penguloon.Levels public int Health { get; set; } - public int Money { get; set; } + public int Money { get; set; } = 0; public int ID { get; set; } + public int Kills { get; set; } = 0; + + public bool Finished { get; set; } = false; + public LevelBase() { @@ -42,6 +46,11 @@ namespace Penguloon.Levels { Map.Update(deltaTime); + if(Health <= 0) + { + Finished = true; + } + UpdateUnique(deltaTime, touchLocations); } diff --git a/Penguloon/Levels/Map.cs b/Penguloon/Levels/Map.cs index 0e3dde6..05d1669 100644 --- a/Penguloon/Levels/Map.cs +++ b/Penguloon/Levels/Map.cs @@ -94,26 +94,33 @@ namespace Penguloon.Levels if(Enemies.Count == 0 && WaveManager.DoneSpawning && WaveManager.RoundActive) { WaveManager.RoundActive = false; + Level.Money += (WaveManager.CurrentWave * 11); } } - public void SpawnEnemy(Type childObject, Vector2 position, Vector2 targetPosition) + public void SpawnEnemy(Type childObject, Vector2 position, Vector2 targetPosition, int index) { - AddEnemyToList(position, targetPosition, childObject); + AddEnemyToList(position, targetPosition, childObject, 0); } public void SpawnEnemy(Type childObject) { - AddEnemyToList(SpawnPoint, SpawnPointTargetPos, childObject); + AddEnemyToList(SpawnPoint, SpawnPointTargetPos, childObject, 0); } - private void AddEnemyToList(Vector2 pos, Vector2 target, Type type) + private void AddEnemyToList(Vector2 pos, Vector2 target, Type type, int index) { if (type == typeof(RedBalloon)) { var b = new RedBalloon(this); b.Position = pos; b.TargetPosition = target; - Enemies.Insert(0, b); + Enemies.Insert(index, b); + } + if (type == typeof(BlueBalloon)) + { + var b = new BlueBalloon(this); + b.Position = pos; b.TargetPosition = target; + Enemies.Insert(index, b); } } } diff --git a/Penguloon/Levels/WaveManager.cs b/Penguloon/Levels/WaveManager.cs index 1a425a1..60ba210 100644 --- a/Penguloon/Levels/WaveManager.cs +++ b/Penguloon/Levels/WaveManager.cs @@ -26,7 +26,8 @@ namespace Penguloon.Levels private void CreateWaves() { - Waves.Add(new Wave(new List<Tuple<Type, int>>() { new Tuple<Type, int>(typeof(RedBalloon), 5) }, 500)); + Waves.Add(new Wave(new List<Tuple<Type, int>>() { new Tuple<Type, int>(typeof(BlueBalloon), 250) }, 50)); + Waves.Add(new Wave(new List<Tuple<Type, int>>() { new Tuple<Type, int>(typeof(RedBalloon), 10) }, 500)); } public void StartSpawningEnemies() diff --git a/Penguloon/Objects/ObjectBase.cs b/Penguloon/Objects/ObjectBase.cs index a16f70c..c72788e 100644 --- a/Penguloon/Objects/ObjectBase.cs +++ b/Penguloon/Objects/ObjectBase.cs @@ -1,6 +1,7 @@ using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; using Penguloon.Levels; +using Penguloon.Projectiles; using System; using System.Collections.Generic; using System.Linq; @@ -23,8 +24,12 @@ namespace Penguloon.Objects public int TileSpanX { get; set; } public int TileSpanY { get; set; } + public List<ProjectileBase> Projectiles { get; set; } = new List<ProjectileBase>(); + public Map Map { get; set; } + public Rectangle Box { get; set; } + public ObjectBase(Vector2 position, Map map) { this.Map = map; @@ -41,18 +46,25 @@ namespace Penguloon.Objects if (Contains(Map.Enemies[i].Box.Center.ToVector2())) { Rotation = (float)GetRotation(Map.Enemies[i].Box.Center.ToVector2()); - return; + + if ((DateTime.Now - LastAttack).TotalMilliseconds > AttackSpeedMS) + { + LastAttack = DateTime.Now; + SpawnUnique(); + } + + break; } } - if ((DateTime.Now - LastAttack).TotalMilliseconds > AttackSpeedMS) - { - LastAttack = DateTime.Now; - UpdateUnique(deltaTime); - } + for (int i = 0; i < Projectiles.Count; i++) + Projectiles[i].Update(deltaTime); + + UpdateUnique(deltaTime); } public abstract void UpdateUnique(float deltaTime); + public abstract void SpawnUnique(); public void Draw(float deltaTime) { @@ -67,6 +79,13 @@ namespace Penguloon.Objects Map.TileWidth * TileSpanX, Map.TileHeight * TileSpanY); + // Draw projectiles before drawing the object + for (int i = 0; i < Projectiles.Count; i++) + Projectiles[i].Draw(deltaTime); + + DrawUnique(deltaTime); + + // Draw object Map.ParentScene.Main.SpriteBatch.Draw(Texture, destinationRectangle: rec, rotation: (float)rot, @@ -74,8 +93,6 @@ namespace Penguloon.Objects Map.ParentScene.Main.SpriteBatch.Draw(RangeCircle, destinationRectangle: new Rectangle((int)rec.X - ((int)Range), (int)rec.Y - ((int)Range), (int)Range * 2, (int)Range * 2)); - - DrawUnique(deltaTime); } public abstract void DrawUnique(float deltaTime); diff --git a/Penguloon/Objects/PenguinObject.cs b/Penguloon/Objects/PenguinObject.cs index 14ad30a..adbdc7e 100644 --- a/Penguloon/Objects/PenguinObject.cs +++ b/Penguloon/Objects/PenguinObject.cs @@ -1,5 +1,7 @@ using Microsoft.Xna.Framework; using Penguloon.Levels; +using Penguloon.Projectiles; +using System.Collections.Generic; namespace Penguloon.Objects { @@ -11,16 +13,22 @@ namespace Penguloon.Objects this.TileSpanX = 1; this.TileSpanY = 1; this.Range = Map.TileWidth * 2; + this.AttackSpeedMS = 1000; } public override void DrawUnique(float deltaTime) { - + } public override void UpdateUnique(float deltaTime) { - + + } + + public override void SpawnUnique() + { + Projectiles.Add(new SnowballProjectile(this, this.Rotation)); } } }
\ No newline at end of file diff --git a/Penguloon/Penguloon.csproj b/Penguloon/Penguloon.csproj index f353077..4fe58f9 100644 --- a/Penguloon/Penguloon.csproj +++ b/Penguloon/Penguloon.csproj @@ -66,11 +66,14 @@ <Compile Include="ContentPathManager.cs" /> <Compile Include="Controls\Button.cs" /> <Compile Include="Controls\ControlBase.cs" /> + <Compile Include="Enemies\BlueBalloon.cs" /> <Compile Include="Enemies\EnemyBase.cs" /> <Compile Include="Enemies\RedBalloon.cs" /> <Compile Include="Levels\WaveManager.cs" /> <Compile Include="Objects\ObjectBase.cs" /> <Compile Include="Objects\PenguinObject.cs" /> + <Compile Include="Projectiles\ProjectileBase.cs" /> + <Compile Include="Projectiles\SnowballProjectile.cs" /> <Compile Include="Scenes\GameScene.cs" /> <Compile Include="Controls\LevelSelector.cs" /> <Compile Include="Enums.cs" /> diff --git a/Penguloon/Projectiles/ProjectileBase.cs b/Penguloon/Projectiles/ProjectileBase.cs new file mode 100644 index 0000000..4221569 --- /dev/null +++ b/Penguloon/Projectiles/ProjectileBase.cs @@ -0,0 +1,80 @@ +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using Penguloon.Objects; +using System; + +namespace Penguloon.Projectiles +{ + public abstract class ProjectileBase + { + public Vector2 Position { get; set; } + public Vector2 Size { get; set; } + + public float RotationAngle { get; set; } + + public float RotationSpeed { get; set; } + + public float Rotation { get; set; } + + public float Speed { get; set; } + + public int MaxBalloonPops { get; set; } + + public int BaloonsPopped { get; set; } = 0; + + public Texture2D Texture { get; set; } + + public ObjectBase ParentObject { get; set; } + + public ProjectileBase(ObjectBase ParentObject, float RotationAngle) + { + this.ParentObject = ParentObject; + this.RotationAngle = RotationAngle; + } + + public void Draw(float deltaTime) + { + Rectangle rec = new Rectangle(new Point((int)Position.X + (int)Size.X / 2, (int)Position.Y + (int)Size.Y / 2), Size.ToPoint()); + + if(Texture != null) + ParentObject.Map.Level.ParentScene.Main.SpriteBatch.Draw(Texture, + destinationRectangle: rec, + rotation: Rotation, + origin: new Vector2(Texture.Width / 2, Texture.Height / 2)); + } + + public void Update(float deltaTime) + { + Rotation += RotationSpeed * deltaTime; + + Vector2 direction = new Vector2((float)Math.Cos(RotationAngle), + (float)Math.Sin(RotationAngle)); + direction.Normalize(); + Position += direction * Speed * deltaTime; + + CheckForCollion(); + } + + private void CheckForCollion() + { + Rectangle projectileRec = new Rectangle(Position.ToPoint(), Size.ToPoint()); + + for(int i = 0; i < ParentObject.Map.Enemies.Count; i++) + { + if (projectileRec.Intersects(ParentObject.Map.Enemies[i].Box)) + { + ParentObject.Map.Enemies[i].GetHit(); + + this.BaloonsPopped++; + + // Remove object if it has hit maximum amount of targets + if(BaloonsPopped >= MaxBalloonPops) + { + ParentObject.Projectiles.Remove(this); + return; + } + } + } + } + } +}
\ No newline at end of file diff --git a/Penguloon/Projectiles/SnowballProjectile.cs b/Penguloon/Projectiles/SnowballProjectile.cs new file mode 100644 index 0000000..9f72794 --- /dev/null +++ b/Penguloon/Projectiles/SnowballProjectile.cs @@ -0,0 +1,23 @@ +using Microsoft.Xna.Framework; +using Penguloon.Objects; + +namespace Penguloon.Projectiles +{ + public class SnowballProjectile : ProjectileBase + { + public SnowballProjectile(ObjectBase ParentObject, float RotationAngle) : base(ParentObject, RotationAngle) + { + this.Texture = ContentManager.GetTexture("Bullets/penguin-ammo"); + this.Speed = 250f; + this.RotationSpeed = 5f; + this.Size = new Vector2(ParentObject.Map.TileWidth / 2, ParentObject.Map.TileHeight / 2); + this.MaxBalloonPops = 1; + + Rectangle parentRec = new Rectangle(ParentObject.Position.ToPoint(), + new Point(ParentObject.TileSpanX * ParentObject.Map.TileWidth, ParentObject.TileSpanY * ParentObject.Map.TileHeight)); + + this.Position = new Vector2(ParentObject.Position.X + (parentRec.Width / 2) - (Size.X / 2), + ParentObject.Position.Y + (parentRec.Height / 2) - (Size.Y / 2)); + } + } +}
\ No newline at end of file diff --git a/Penguloon/Scenes/GameScene.cs b/Penguloon/Scenes/GameScene.cs index ac8ea9f..3ab7c28 100644 --- a/Penguloon/Scenes/GameScene.cs +++ b/Penguloon/Scenes/GameScene.cs @@ -93,11 +93,14 @@ namespace Penguloon.Scenes public override void Update(float deltaTime, TouchLocation[] touchLocations) { - base.Update(deltaTime, touchLocations); - - StartRoundBtn.Update(deltaTime, touchLocations); + // We shouldn't update controls when the game is finished to prevent the user from placing any more objects + if (!Level.Finished) + { + base.Update(deltaTime, touchLocations); + StartRoundBtn.Update(deltaTime, touchLocations); + } - if (StartRoundBtn.ControlState == ControlState.Disabled && !Level.Map.WaveManager.RoundActive) + if (StartRoundBtn.ControlState == ControlState.Disabled && !Level.Map.WaveManager.RoundActive && !Level.Finished) { StartRoundBtn.ControlState = ControlState.Idle; Level.Map.WaveManager.FinishRound(); diff --git a/Penguloon/SoundManager.cs b/Penguloon/SoundManager.cs index 4ee40c8..8ec0ca7 100644 --- a/Penguloon/SoundManager.cs +++ b/Penguloon/SoundManager.cs @@ -28,5 +28,11 @@ namespace Penguloon BtnClick.Play(); } + + public static void PlayBalloonPopSound() + { + SoundEffect popEffect = ContentManager.GetSound("Sounds/pop"); + popEffect.Play(0.5f, 0f, 0f); + } } }
\ No newline at end of file diff --git a/Penguloon/StaticUIValues.cs b/Penguloon/StaticUIValues.cs index 015ffc0..e675ea5 100644 --- a/Penguloon/StaticUIValues.cs +++ b/Penguloon/StaticUIValues.cs @@ -34,12 +34,15 @@ namespace Penguloon { ScreenViewport = main.GraphicsDevice.Viewport.Bounds.Size.ToVector2(); - if(ScreenViewport.X >= 2440) + IngameUIWidth = 250; + + if (ScreenViewport.X >= 2440) { LevelSelectorHeight = 600; LoadingProgressbarSize = new Vector2((int)(800 * 2), (int)(150 * 2)); MenuButtonSize = new Vector2(800, 150); MenuFont = "Fonts/GWENT/72"; + IngameUIWidth = 350; } else if (ScreenViewport.X >= 1920) { @@ -47,6 +50,7 @@ namespace Penguloon MenuButtonSize = new Vector2((int)(800 * 1), (int)(150 * 1)); LoadingProgressbarSize = new Vector2((int)(800 * 1.3), (int)(150 * 1.3)); MenuFont = "Fonts/GWENT/72"; + IngameUIWidth = 350; } else if (ScreenViewport.X >= 1280) { @@ -69,7 +73,6 @@ namespace Penguloon LoadingProgressbarPosition = new Vector2((ScreenViewport.X - LoadingProgressbarSize.X) / 2, ScreenViewport.Y - LoadingProgressbarSize.Y - 200); LoadingProgressbarValuePosition = new Vector2(LoadingProgressbarPosition.X + 5, LoadingProgressbarPosition.Y + 5); - IngameUIWidth = 250; SnowflakeSize = 100; IngameUITextAreaHeight = 120; IngameUIPlayButtonHeight = 120; |
