diff --git a/Entities/DDOSEntity.cs b/Entities/DDOSEntity.cs new file mode 100644 index 0000000..dc893af --- /dev/null +++ b/Entities/DDOSEntity.cs @@ -0,0 +1,52 @@ +using SlatedGameToolkit.Framework.Graphics.Textures; +using SlatedGameToolkit.Framework.Utilities.Collections.Pooling; +using System.Drawing; +namespace SkinnerBox.Entities +{ + public class DDOSEntity : Entity, IPoolable + { + private float speed; + public DDOSEntity(ITexture texture) : base(texture) + { + Width = 0.5f; + this.Color = Color.Red; + } + + public void Initialize(float xPos, float length, float speed, float delay) + { + Height = length; + X = xPos; + this.mesh.X = X; + this.speed = speed; + this.Y += delay * speed; + mesh.Y = Y; + } + + public void Update(float delta) { + Y -= speed * delta; + } + public void Reset() + { + Height = 0; + Y = Game.HEIGHT_UNITS; + mesh.Y = Y; + speed = 0; + } + } + + public struct DDOSSPawnInfo + { + public float speed; + public float interval; + public float intervalDeviation; + public float timeRemaining; + + public DDOSSPawnInfo(float speed, float interval, float intervalDeviation, float timeRemaining) + { + this.speed = speed; + this.interval = interval; + this.intervalDeviation = intervalDeviation; + this.timeRemaining = timeRemaining; + } + } +} \ No newline at end of file diff --git a/Entities/DownloadEntity.cs b/Entities/DownloadEntity.cs index 489f958..e8bad4f 100644 --- a/Entities/DownloadEntity.cs +++ b/Entities/DownloadEntity.cs @@ -9,7 +9,7 @@ namespace SkinnerBox.Entities public class DownloadEntity : Entity, IPoolable { private readonly float unitSize = 1/2f; - private readonly float unitPerProgressTexture = 0.5f; + private readonly float unitPerProgressTexture = 0.4f; public float stepSize; public TransitionValue progressValue; public RectangleMesh progressMesh; @@ -53,7 +53,7 @@ namespace SkinnerBox.Entities public void Reset() { Size = 1; - progressValue.HardSet(0); + progressValue.HardSet(0.1f); timeElapsed.HardSet(0); stepSize = 0; upTime = 0; diff --git a/States/GameOverState.cs b/States/GameOverState.cs index 9acc4d1..14f949b 100644 --- a/States/GameOverState.cs +++ b/States/GameOverState.cs @@ -1,9 +1,11 @@ using System; using System.Drawing; using System.Numerics; +using SDL2; using SlatedGameToolkit.Framework.AssetSystem; using SlatedGameToolkit.Framework.Graphics.Render; using SlatedGameToolkit.Framework.Graphics.Text; +using SlatedGameToolkit.Framework.Input.Devices; using SlatedGameToolkit.Framework.StateSystem; using SlatedGameToolkit.Framework.StateSystem.States; @@ -35,11 +37,13 @@ namespace SkinnerBox.States titleFont.PrepareCharacterGroup("GameOvr!".ToCharArray()); this.font.PixelHeight = 48; font.PrepareCharacterGroup("01234567890.Your Stats: Score,ServerUp-timedownloadservedpacketssentWebsitePDRLN%que".ToCharArray()); + Keyboard.keyboardUpdateEvent += KeyChanged; return true; } public bool Deactivate() { + Keyboard.keyboardUpdateEvent -= KeyChanged; return true; } @@ -66,7 +70,7 @@ namespace SkinnerBox.States font.WriteLine(renderer, 1.95f, Game.HEIGHT_UNITS * 0.46f, "Packets Received: " + totalPackets + " Packet Loss: " + Math.Round((100f * (1f - ((float) packetsReceived / totalPackets))), 1) + "%", Color.Black); font.WriteLine(renderer, 1.95f, Game.HEIGHT_UNITS * 0.39f, "Downloads Served: " + downloadsServed, Color.Black); font.WriteLine(renderer, 1.95f, Game.HEIGHT_UNITS * 0.32f, "Downloads Requested: " + totalDownloads, Color.Black); - + font.WriteLine(renderer, 1.5f, 1.5f, "Press space to reset...", Color.Black); renderer.End(); } @@ -82,5 +86,11 @@ namespace SkinnerBox.States public void Update(double timeStep) { } + + public void KeyChanged(SDL.SDL_Keycode keycode, bool pressed) { + if (keycode == SDL.SDL_Keycode.SDLK_SPACE && !pressed) { + manager.ChangeState("Main"); + } + } } } \ No newline at end of file diff --git a/States/GamePlayState.cs b/States/GamePlayState.cs index 46064bd..8cda935 100644 --- a/States/GamePlayState.cs +++ b/States/GamePlayState.cs @@ -52,6 +52,11 @@ namespace SkinnerBox.States private DownloadSpawnInfo downloadSpawnInfo; private const float downloadSafeMargin = 1.5f; #endregion + + //DDOS entities. + private ObjectPool ddosPool; + private List activeDDOS = new List(); + private DDOSSPawnInfo dDOSSpawnInfo; #region PlayerStats private int speedBoost = 0; @@ -76,6 +81,7 @@ namespace SkinnerBox.States packetPool = new ObjectPool(CreatePacket); warningPool = new ObjectPool(createWarning); downloadPool = new ObjectPool(createDownload); + ddosPool = new ObjectPool(createDDOS); this.font = font; this.gameOverState = gameOverState; } @@ -91,13 +97,14 @@ namespace SkinnerBox.States speedMesh = new RectangleMesh(bandwithMesh.Bounds, (ITexture)assets["ram.png"], Color.White); random = new Random(); - packetSpawnInfo = new PacketSpawnInfo(2, 1, (float)(random.NextDouble() * Game.WIDTH_UNITS), 1f, 0.2f, 2f); + packetSpawnInfo = new PacketSpawnInfo(2, 1, (float)(random.NextDouble() * Game.WIDTH_UNITS), 1f, 0.2f, 0.75f); downloadSpawnInfo = new DownloadSpawnInfo(4, 6, 3, 1, 4, 2); + dDOSSpawnInfo = new DDOSSPawnInfo(28, 3f, 2f, 245f); score = 0; timeElapsed.HardSet(0); - server.Size = 4; - bandwithBoost = server.Size; - speedBoost = 0; + server.Speed = 4; + bandwithBoost = 0; + speedBoost = 3; stability = totalStability; packetsReceived = 0; totalPackets = 0; @@ -121,6 +128,10 @@ namespace SkinnerBox.States return new DownloadEntity((Texture)assets["drag.png"], (Texture)assets["downloadbar.png"]); } + public DDOSEntity createDDOS() { + return new DDOSEntity((Texture)assets["beam.png"]); + } + public bool Deactivate() { Keyboard.keyboardUpdateEvent -= KeyInputListener; @@ -168,7 +179,12 @@ namespace SkinnerBox.States } #endregion renderer.Draw(server); - + #region DDOSRender + foreach (DDOSEntity ddos in activeDDOS) + { + renderer.Draw(ddos); + } + #endregion #region StatusRender for (int i = 0; i < bandwithBoost + speedBoost; i++) { @@ -220,7 +236,7 @@ namespace SkinnerBox.States for(int i = 0; i < packetSpawnInfo.perSpawn; i++) { PacketEntity packet = packetPool.Retrieve(); packet.CenterX = packetSpawnInfo.batchLocation; - packet.Y = i * packet.Height + packetSpawnInfo.range + Game.HEIGHT_UNITS + packetSpawnInfo.speed * (2/3f); + packet.Y = i * packet.Height + packetSpawnInfo.range + Game.HEIGHT_UNITS + packetSpawnInfo.speed; packet.velocity = packetSpawnInfo.speed; packet.Color = Color.Blue; totalPackets++; @@ -230,12 +246,12 @@ namespace SkinnerBox.States //Spawn Warning WarningEntity warning = warningPool.Retrieve(); warning.CenterX = packetSpawnInfo.batchLocation; - warning.LifeTime = packetSpawnInfo.interval * (2/3f); + warning.LifeTime = 1f; warning.Y = Game.HEIGHT_UNITS - warning.Height; activeWarnings.Add(warning); //Prepare next batch - float change = (float)((float)(random.NextDouble() - 1/2f) * packetSpawnInfo.jumpDistance * 2); + float change = (float)((random.NextDouble() - 1/2f) * packetSpawnInfo.jumpDistance * 2); if (packetSpawnInfo.batchLocation + change > Game.WIDTH_UNITS - packetSafeMargin || packetSpawnInfo.batchLocation + change < packetSafeMargin) { packetSpawnInfo.batchLocation -= change; } else { @@ -261,7 +277,7 @@ namespace SkinnerBox.States if (packet.Y >= Game.HEIGHT_UNITS && packet.velocity < 0) { score += -2 * packet.velocity; packetsReceived++; - stability += 0.05f; + stability += 0.025f; packetPool.Release(packet); activePackets.RemoveAt(i); i--; @@ -276,7 +292,7 @@ namespace SkinnerBox.States if (activeDownloads.Count < downloadSpawnInfo.maximumAmount) { DownloadEntity download = downloadPool.Retrieve(); download.Size = (int)(downloadSpawnInfo.generalSize + ((random.NextDouble() - 1/2f) * 2f * downloadSpawnInfo.sizeRange)); - download.X = (float)(random.NextDouble() * (Game.WIDTH_UNITS - download.Width)); + download.X = (float)(random.NextDouble() * (Game.WIDTH_UNITS - download.Width - 2 * downloadSafeMargin) + downloadSafeMargin); download.Y = (float)(downloadSafeMargin + random.NextDouble() * (Game.HEIGHT_UNITS - 2 * downloadSafeMargin)); download.stepSize = downloadSpawnInfo.stepSize; download.upTime = downloadSpawnInfo.upTime; @@ -326,6 +342,50 @@ namespace SkinnerBox.States } } #endregion + #region DDOSUpdate + dDOSSpawnInfo.timeRemaining -= (float)timeStep; + if (dDOSSpawnInfo.timeRemaining <= 0) { + dDOSSpawnInfo.timeRemaining = (float)(dDOSSpawnInfo.interval + random.NextDouble() * dDOSSpawnInfo.intervalDeviation); + DDOSEntity ddos = ddosPool.Retrieve(); + ddos.Initialize(server.CenterX, 1.5f * Game.HEIGHT_UNITS, dDOSSpawnInfo.speed, 2f); + activeDDOS.Add(ddos); + + for (int i = 0; i < 4; i++) + { + //Spawn Warning + WarningEntity warning = warningPool.Retrieve(); + warning.CenterX = ddos.CenterX; + warning.LifeTime = 1f; + warning.Y = Game.HEIGHT_UNITS - i * (warning.Height + 1f); + activeWarnings.Add(warning); + + } + } + for (int i = 0; i < activeDDOS.Count; i++) + { + DDOSEntity ddos = activeDDOS[i]; + ddos.Update((float)timeStep); + if (ddos.HitBox.IntersectsWith(server.HitBox)) { + stability -= (float) (10f * timeStep); + } + for (int p = 0; p < activePackets.Count; p++) + { + PacketEntity packet = activePackets[p]; + if (packet.velocity > 0 && ddos.HitBox.IntersectsWith(packet.HitBox)) { + activePackets.RemoveAt(p); + packetPool.Release(packet); + p--; + } + } + + if (ddos.Y <= 0 - ddos.Height) { + ddosPool.Release(ddos); + activeDDOS.RemoveAt(i); + i--; + continue; + } + } + #endregion #region WarningCleanup for (int i = 0; i < activeWarnings.Count; i++) { @@ -342,27 +402,29 @@ namespace SkinnerBox.States //packet curve packetSpawnInfo.perSpawn = (int)(0.5f * (Math.Pow(timeElapsed.Value, 0.5f) + 1)); packetSpawnInfo.speed = (float)((0.025f * Math.Pow(timeElapsed.Value, 1.1f)) + 1f); - if (packetSpawnInfo.range < 4) { - packetSpawnInfo.range = (float)(0.1f * (Math.Pow(timeElapsed.Value, 1.15f)) + 2f); - if (packetSpawnInfo.range > 4) packetSpawnInfo.range = 4; + if (packetSpawnInfo.jumpDistance < 2f) { + packetSpawnInfo.jumpDistance = (float)(0.0018f * (Math.Pow(timeElapsed.Value, 1.1f)) + 0.75f); + if (packetSpawnInfo.jumpDistance > 2f) packetSpawnInfo.jumpDistance = 2f; } - if (packetSpawnInfo.interval > 0.3f) { - packetSpawnInfo.interval = (float) (-0.0055 * timeElapsed.Value) + 2f; - if (packetSpawnInfo.interval < 0.3f) packetSpawnInfo.interval = 0.3f; + if (packetSpawnInfo.interval > 0f) { + packetSpawnInfo.interval = (float) (-0.0075 * timeElapsed.Value) + 2f; + if (packetSpawnInfo.interval < 0f) packetSpawnInfo.interval = 0f; } //download curve - if (downloadSpawnInfo.maximumAmount < 4) { + if (downloadSpawnInfo.maximumAmount < 5) { downloadSpawnInfo.maximumAmount = (int)(0.02f * timeElapsed.Value + 1); } if (downloadSpawnInfo.upTime > 3) { downloadSpawnInfo.upTime = (float)(8 + (-0.1f * Math.Pow(timeElapsed.Value, 0.8f))); if (downloadSpawnInfo.upTime < 3) downloadSpawnInfo.upTime = 3; } - if (downloadSpawnInfo.period > 1.5f) { + if (downloadSpawnInfo.period > 1f) { downloadSpawnInfo.period = (float) (-0.006 * timeElapsed.Value) + 4; - if (packetSpawnInfo.interval < 1.5f) packetSpawnInfo.interval = 1.5f; + if (packetSpawnInfo.interval < 1f) packetSpawnInfo.interval = 1f; } + + //ddos curve #endregion #region BoundaryChecking if (stability > totalStability) { diff --git a/States/MenuState.cs b/States/MenuState.cs index fe8c44b..d62363c 100644 --- a/States/MenuState.cs +++ b/States/MenuState.cs @@ -33,7 +33,7 @@ namespace SkinnerBox.States this.titleFont.PixelHeight = 40; this.titleFont.PrepareCharacterGroup("By: Reslate".ToCharArray()); boldFont.PixelHeight = 60; - boldFont.PrepareCharacterGroup("Press any key to start...".ToCharArray()); + boldFont.PrepareCharacterGroup("Press space to start...".ToCharArray()); return true; } @@ -87,8 +87,11 @@ namespace SkinnerBox.States assets.Load("drag.png"); assets.Load("usage.png"); assets.Load("health.png"); + assets.Load("beam.png"); assets.Load("ram.png"); + Texture downloadBarTex = (Texture)assets["downloadbar.png"]; + downloadBarTex.SetNearestFilter(true, true); //Set up bold TTF boldFont = new BitmapFont("resources/BigShouldersDisplay-Black.ttf", textureSizes: 512); @@ -114,7 +117,7 @@ namespace SkinnerBox.States renderer.Draw(serverUnit); - this.boldFont.WriteLine(renderer, 1.15f, Game.HEIGHT_UNITS / 2, "Press any key to start...", Color.Black); + this.boldFont.WriteLine(renderer, 1.15f, Game.HEIGHT_UNITS / 2, "Press space to start...", Color.Black); renderer.End(); } @@ -124,7 +127,7 @@ namespace SkinnerBox.States public void KeyInput(SDL.SDL_Keycode keys, bool pressed) { - if (pressed) + if (!pressed && keys == SDL.SDL_Keycode.SDLK_SPACE) { manager.ChangeState("GamePlayState"); } diff --git a/resources/beam.png b/resources/beam.png new file mode 100644 index 0000000..72ff452 Binary files /dev/null and b/resources/beam.png differ