public static bool Move(Description2D d2d, double deltaX, double deltaY, List <Description2D> walls) { bool undo = false; d2d.ChangeCoordsDelta(deltaX, 0); if (Program.Collision(d2d, walls)) { undo = true; for (int i = 0; i < Math.Abs(deltaX); i++) { d2d.ChangeCoordsDelta(-Math.Clamp(deltaX, -1, 1), 0); if (!Program.Collision(d2d, walls)) { break; } } } d2d.ChangeCoordsDelta(0, deltaY); if (Program.Collision(d2d, walls)) { undo = true; for (int i = 0; i < Math.Abs(deltaY); i++) { d2d.ChangeCoordsDelta(0, -Math.Clamp(deltaY, -1, 1)); if (!Program.Collision(d2d, walls)) { break; } } } return(!undo); }
public static void Platformer(Location location, object obj) { if (obj == null) { return; } Description2D d2d = obj as Description2D; double speed = 3 * (Program.Referee.Piles[Rule.RuleType.SPEED].FirstOrDefault()?.Action(location, obj) ?? 1); List <Description2D> walls = location.GetEntities <Wall>().Select(w => w as Description2D).ToList(); d2d.ChangeCoordsDelta(0, 1); bool onGround = Program.Collision(d2d, walls); d2d.ChangeCoordsDelta(0, -1); if (!onGround) { if (velocity < 10) { velocity += 1.0; } } if (Program.Keyboard[(int)Actions.RIGHT].IsDown()) { Move(d2d, speed, 0, walls); } if (Program.Keyboard[(int)Actions.UP].IsPress()) { if (d2d.Y + velocity >= ((Description2D)location.Description).Height || onGround) { velocity = -10; } } if (Program.Keyboard[(int)Actions.LEFT].IsDown()) { Move(d2d, -speed, 0, walls); } if (d2d.Y + velocity <= ((Description2D)location.Description).Height) { //d2d.ChangeCoordsDelta(0, velocity); if (!Move(d2d, 0, velocity, walls)) { velocity = 0; } } else { d2d.SetCoords(d2d.X, ((Description2D)location.Description).Height); velocity = 0; } }
private void Tick(Location location, Entity entity) { if (Program.Engine.Location.GetEntities <DialogBox>().Any()) { return; } if (sound == null) { Boom(); } Description2D d2d = entity.Description as Description2D; d2d.ChangeCoordsDelta(Math.Cos(dir) * 8, Math.Sin(dir) * 8); foreach (T enemy in location.GetEntities <T>()) { if (d2d.IsCollision(enemy)) { location.RemoveEntity(enemy.Id); } } if (Program.Collision(d2d, location.GetEntities <Wall>().Select(w => (Description2D)w).ToList())) { location.RemoveEntity(Id); } }
public static void SetupCredits() { Engine.SetLocation(new Location(new Description2D(0, 0, ScreenWidth, ScreenHeight))); int time = Program.ScreenHeight / 2 + 8; TickHandler t = null; CreditsFinished = false; t = (s, o) => { if (time-- <= 0) { Engine.TickEnd -= t; CreditsFinished = true; } }; Engine.TickEnd += t; Action <Location, Entity> scroll = (loc, ent) => { Description2D entd = ent.Description as Description2D; if (time > 0) { entd.ChangeCoordsDelta(0, -1); } }; int y = Program.ScreenHeight / 2; Engine.AddEntity(Text.Create("Credits", new Font("Arial", 32, FontStyle.Underline), ScreenWidth / 2, y + 16).AddTickAction(scroll)); Engine.AddEntity(Text.Create("Developed by", new Font("Arial", 16, FontStyle.Underline), ScreenWidth / 2, y + 64).AddTickAction(scroll)); Engine.AddEntity(Text.Create("Nicholas Denaro", new Font("Arial", 12), ScreenWidth / 2, y + 96).AddTickAction(scroll)); Engine.AddEntity(Text.Create("Art by", new Font("Arial", 16, FontStyle.Underline), ScreenWidth / 2, y + 128).AddTickAction(scroll)); Engine.AddEntity(Text.Create("System.Drawing.Common", new Font("Arial", 12), ScreenWidth / 2, y + 160).AddTickAction(scroll)); Engine.AddEntity(Text.Create("Special thanks to", new Font("Arial", 16, FontStyle.Underline), ScreenWidth / 2, y + 192).AddTickAction(scroll)); Engine.AddEntity(Text.Create("My faithful Twitch chat <3", new Font("Arial", 10), ScreenWidth / 2, y + 224).AddTickAction(scroll)); }
public override void SetupLevel() { bool wobbleDialog = false; Entity movingEnemy = null; Program.Level = 5; Program.Engine.SetLocation(new Location(new Description2D(0, 0, Program.ScreenWidth, Program.ScreenHeight))); Stack <Action> deck = new Stack <Action>(); Action spawnPowerups = () => { Program.Engine.AddEntity(Powerup.Create("platformer", 224 - 8, Program.ScreenHeight / 2 + 80)); Program.Engine.AddEntity(Powerup.Create("top-down", 256 - 8, Program.ScreenHeight / 2 + 80)); Program.Engine.AddEntity(Powerup.Create("platformer", 288 - 8, Program.ScreenHeight / 2 + 80)); Entity ent = Powerup.Create("top-down", 314 - 8, Program.ScreenHeight / 2 + 80); ent.TickAction = (loc, e) => { if (!wobbleDialog && ((Description2D)movingEnemy.Description).Distance((Description2D)e.Description) < 12) { Program.Engine.AddEntity(DialogBox.Create("It'll be hard to keep my orientation.\nBetter keep an eye on it.")); wobbleDialog = true; } }; Program.Engine.AddEntity(ent); }; deck.Push(spawnPowerups); deck.Push(spawnPowerups); deck.Push(spawnPowerups); deck.Push(spawnPowerups); deck.Push(spawnPowerups); deck.Push(spawnPowerups); Program.Referee.ClearRules(); Program.Referee.AddRule(Rule.Rules["Goal victory"]); Program.Referee.AddRule(Rule.Rules["Enemy hurty"]); Program.Referee.AddRule(Rule.Rules["Any pickup Powerup"]); Program.Referee.AddRule(Rule.Rules["control Player"]); Program.Referee.AddRule(Rule.Rules["platformer"]); Program.Engine.AddEntity(DialogBox.Create("Something seems different.")); SinWaveSound sound = new SinWaveSound(true, 80, 44100 / Program.TPS * 30, 0, 44100 / Program.TPS * 5, 100, 44100 / Program.TPS * 5, 70, 44100 / Program.TPS * 5, 150, 44100 / Program.TPS * 30, 0, 44100 / Program.TPS * 5, 120, 44100 / Program.TPS * 5, 100, 44100 / Program.TPS * 30, 0, 44100 / Program.TPS * 5, 80, 44100 / Program.TPS * 5, 100, 44100 / Program.TPS * 5, 60, 44100 / Program.TPS * 5, 120, 44100 / Program.TPS * 30, 0, 44100 / Program.TPS * 5, 90, 44100 / Program.TPS * 5, 150, 44100 / Program.TPS * 5); sound.SetWaveFormat(44100, 2); Entity deckFlipper = new Entity(new Description2D(0, 0, 0, 0)); int timer = 0; deckFlipper.TickAction = (loc, ent) => { if (Program.Engine.Location.GetEntities <DialogBox>().Any() || Program.Engine.Location.GetEntities <Banner>().Any()) { return; } if (Program.Referee.IsStarted && deck.Any() && timer++ % (Program.TPS * 3.3) == 0) { deck.Pop().Invoke(); } }; Program.Engine.AddEntity(deckFlipper); Program.Engine.AddEntity(Player.Create(Program.ScreenWidth / 2 - 32, Program.ScreenHeight - 24)); Program.Engine.AddEntity(Goal.Create(Program.ScreenWidth - 64, Program.ScreenHeight / 2)); Program.Engine.AddEntity(Enemy.Create(Program.ScreenWidth - 64 - 16, Program.ScreenHeight / 2)); Program.Engine.AddEntity(Enemy.Create(Program.ScreenWidth - 64, Program.ScreenHeight / 2 - 16)); Program.Engine.AddEntity(Enemy.Create(Program.ScreenWidth - 64 + 16, Program.ScreenHeight / 2)); Program.Engine.AddEntity(Enemy.Create(Program.ScreenWidth - 64, Program.ScreenHeight / 2 + 16)); //border Program.Engine.AddEntity(Wall.Create(0, 0, 16, Program.ScreenHeight)); Program.Engine.AddEntity(Wall.Create(Program.ScreenWidth, 0, 16, Program.ScreenHeight)); Program.Engine.AddEntity(Wall.Create(0, 0, Program.ScreenWidth, 16)); Program.Engine.AddEntity(Wall.Create(0, Program.ScreenHeight, Program.ScreenWidth + 16, 16)); //others Program.Engine.AddEntity(Wall.Create(0, Program.ScreenHeight / 2 + 32, 80, 16)); Program.Engine.AddEntity(Wall.Create(80, Program.ScreenHeight / 2 + 80, 112, 16)); Program.Engine.AddEntity(Wall.Create(112, Program.ScreenHeight / 2 + 32, 64, 16)); Program.Engine.AddEntity(Wall.Create(176, Program.ScreenHeight / 2 - 80, 16, 208)); Entity ent = Powerup.Create("clicky attack", 32, 32); bool dialogShown = false; ent.TickAction = (loc, e) => { if (!dialogShown && loc.GetEntities <Player>().First().Distance((Description2D)e.Description) < 12) { Program.Engine.AddEntity(DialogBox.Create("I bet I can use this to clear a path.")); dialogShown = true; } }; Program.Engine.AddEntity(ent); Program.Engine.AddEntity(Powerup.Create("Enemy pickup Powerup", 176, 24)); movingEnemy = Enemy.Create(224, Program.ScreenHeight / 2 + 80); double deltaX = 0.5f; movingEnemy.TickAction += (loc, ent) => { if (Program.Engine.Location.GetEntities <DialogBox>().Any()) { return; } Description2D d2d = movingEnemy.Description as Description2D; if (d2d.X == Program.ScreenWidth - 16 || d2d.X == 208) { deltaX = -deltaX; } d2d.ChangeCoordsDelta(deltaX, 0); }; Program.Engine.AddEntity(movingEnemy); Program.Engine.AddEntity(HeadsUpDisplay.Create()); Program.Referee.Start(); Program.WavProvider.AddMixerInput((ISampleProvider)sound); Program.WavPlayer.Play(); }
public static void VVVVVVPlatformer(Location location, object obj) { if (obj == null) { return; } Description2D d2d = obj as Description2D; List <Description2D> walls = location.GetEntities <Wall>().Select(w => w as Description2D).ToList(); d2d.ChangeCoordsDelta(0, Math.Clamp(velocityDirection, -1, 1)); bool onGround = Program.Collision(d2d, walls); d2d.ChangeCoordsDelta(0, Math.Clamp(-velocityDirection, -1, 1)); double speed = 3 * (Program.Referee.Piles[Rule.RuleType.SPEED].FirstOrDefault()?.Action(location, obj) ?? 1); //.Aggregate(1.0, (a, rule) => rule.Action(location) * a ); if (!onGround) { velocity += velocityDirection; } velocity = Math.Clamp(velocity, -10, 10); // Rule.List.Contains(playstyle type value=top/down) if (Program.Keyboard[(int)Actions.RIGHT].IsDown()) { Move(d2d, speed, 0, walls); } if (Program.Keyboard[(int)Actions.UP].IsPress()) { if (onGround || d2d.Y + velocity >= ((Description2D)location.Description).Height || d2d.Y + velocity <= 0) { velocityDirection = -velocityDirection; velocity = velocityDirection * 4; } } if (Program.Keyboard[(int)Actions.LEFT].IsDown()) { Move(d2d, -speed, 0, walls); } if (velocityDirection > 0) { if (d2d.Y + velocity <= ((Description2D)location.Description).Height) { if (!Move(d2d, 0, velocity, walls)) { velocity = 0; } } else { d2d.SetCoords(d2d.X, ((Description2D)location.Description).Height); } } else { if (d2d.Y + velocity >= 0) { if (!Move(d2d, 0, velocity, walls)) { velocity = 0; } } else { d2d.SetCoords(d2d.X, 0); } } }
private void Tick(Location location, Entity entity) { if (Program.Engine.Location.GetEntities <DialogBox>().Any()) { return; } if (sound == null) { sound = new SinWaveSound(true, 120, 44100 / Program.TPS * 20, 150, 44100 / Program.TPS * 30, 120, 44100 / Program.TPS * 10f, 0, 44100 / Program.TPS * 10f, 180, 44100 / Program.TPS * 5, 150, 44100 / Program.TPS * 20, 100, 44100 / Program.TPS * 30, 180, 44100 / Program.TPS * 10f, 0, 44100 / Program.TPS * 10f, 200, 44100 / Program.TPS * 5); sound.SetWaveFormat(44100, 2); Program.WavProvider.AddMixerInput((ISampleProvider)sound); Program.WavPlayer.Play(); } foreach (Bullet <BulletNull> bullet in location.GetEntities <Bullet <BulletNull> >()) { if (bullet.IsCollision(this)) { health -= 1; location.RemoveEntity(bullet.Id); } } if (health == 80 && !firstTransitionShown) { Program.Engine.AddEntity(DialogBox.Create($"[{machineName}] Try this on for size. >=^)")); savedHealth = 81; savedStealAttack = stealAttack; savedShiftRoom = shiftRoom; Program.Referee.AddRule("platformer"); attackTimerMax = 30; Program.Referee.AddRule(Rule.Rules["Goal hurty"]); firstTransitionShown = true; sound.Silent = true; sound = new SinWaveSound(true, 120, 44100 / Program.TPS * 10, 150, 44100 / Program.TPS * 15, 180, 44100 / Program.TPS * 5, 200, 44100 / Program.TPS * 5, 0, 44100 / Program.TPS * 15, 200, 44100 / Program.TPS * 5, 180, 44100 / Program.TPS * 10, 200, 44100 / Program.TPS * 15, 150, 44100 / Program.TPS * 5, 0, 44100 / Program.TPS * 15, 150, 44100 / Program.TPS * 10, 100, 44100 / Program.TPS * 15, 180, 44100 / Program.TPS * 5, 150, 44100 / Program.TPS * 5, 0, 44100 / Program.TPS * 15); sound.SetWaveFormat(44100, 2); Program.WavProvider.AddMixerInput((ISampleProvider)sound); Program.WavPlayer.Play(); } if (health == 70 && stealAttack == 0) { Program.Engine.AddEntity(DialogBox.Create($"[{machineName}] Quit it with that. >=^(")); Program.Referee.AddRule("no attack. haha."); location.AddEntity(Powerup.Create("shoot Boss", Program.ScreenWidth - 64, Program.ScreenHeight - 16)); stealAttack++; } if (health == 69) { attackTimerMax = 60; } if (health == 60 && !shiftRoom) { Program.Engine.AddEntity(DialogBox.Create($"[{machineName}] I bet you can't handle\nthis. >=^)")); savedHealth = 61; savedStealAttack = stealAttack; savedShiftRoom = shiftRoom; Program.Referee.AddRule("vvvvvv-platformer"); attackTimerMax = 60; Program.Referee.AddRule(Rule.Rules["Powerup hurty"]); Program.Referee.AddRule("be fast"); shiftRoom = true; for (int i = 0; i < 4; i++) { Entity wall = Powerup.Create("pop SPAWN", Program.ScreenWidth / 2 - 80 + i * 16, Program.ScreenHeight / 2); centerWalls.Add(wall.Id); location.AddEntity(wall); } attackTimerMax = 30; sound.Silent = true; sound = new SinWaveSound(true, 80, 44100 / Program.TPS * 30, 150, 44100 / Program.TPS * 15, 120, 44100 / Program.TPS * 30, 80, 44100 / Program.TPS * 7.5f, 0, 44100 / Program.TPS * 7.5f, 80, 44100 / Program.TPS * 7.5f, 120, 44100 / Program.TPS * 30); sound.SetWaveFormat(44100, 2); Program.WavProvider.AddMixerInput((ISampleProvider)sound); Program.WavPlayer.Play(); } if (health == 50 && stealAttack == 1) { Program.Engine.AddEntity(DialogBox.Create($"[{machineName}] I'll just take that\nagain. >=^D")); Program.Referee.AddRule("no attack. haha."); Entity trigger = Powerup.Create("shoot Boss", Program.ScreenWidth - 128, Program.ScreenHeight / 2); Guid triggerId = trigger.Id; trigger.AddTickAction((loc, ent) => { if (loc.GetEntities <Player>().First().Distance((Description2D)ent.Description) < 20) { Program.Referee.AddRule("shoot Boss"); loc.RemoveEntity(triggerId); } }); location.AddEntity(trigger); stealAttack++; } if (health == 40 && shiftRoom) { Program.Engine.AddEntity(DialogBox.Create($"[{machineName}] Why don't you\njust go? [ o\\ _ /o ]")); savedHealth = 41; savedStealAttack = stealAttack; savedShiftRoom = shiftRoom; Program.Referee.AddRule("pop SPEED"); Program.Referee.AddRule("top-down"); Program.Referee.AddRule("Enemy hurty"); attackTimer = 30; attackTimerMax = 30; shiftRoom = false; foreach (Guid guid in centerWalls) { location.RemoveEntity(guid); } double dir = location.GetEntities <Player>().First().Direction(new Point(Program.ScreenWidth / 2, Program.ScreenHeight / 2)) + Math.PI / 4; centerWalls.Clear(); for (int j = 0; j < 4; j++) { for (int i = 0; i < 12; i++) { int xoffset = (int)(Math.Cos(dir + j * Math.PI / 2) * i * 16); int yoffset = (int)(Math.Sin(dir + j * Math.PI / 2) * i * 16); Entity rotaty = Enemy.Create(Program.ScreenWidth / 2 + xoffset, Program.ScreenHeight / 2 + yoffset).AddTickAction((loc, ent) => { if (Program.Engine.Location.GetEntities <DialogBox>().Any()) { return; } Description2D enemyd = ent.Description as Description2D; double instantdir = enemyd.Direction(new Point(Program.ScreenWidth / 2, Program.ScreenHeight / 2)); double dist = enemyd.Distance(new Point(Program.ScreenWidth / 2, Program.ScreenHeight / 2)); enemyd.ChangeCoordsDelta(Math.Cos(instantdir + Math.PI / 2) * dist / 50, Math.Sin(instantdir + Math.PI / 2) * dist / 50); }); centerWalls.Add(rotaty.Id); location.AddEntity(rotaty); } sound.Silent = true; sound = new SinWaveSound(true, 60, 44100 / Program.TPS * 2, 80, 44100 / Program.TPS * 2, 100, 44100 / Program.TPS * 2, 120, 44100 / Program.TPS * 2, 0, 44100 / Program.TPS * 10, 100, 44100 / Program.TPS * 2, 120, 44100 / Program.TPS * 2, 140, 44100 / Program.TPS * 2, 160, 44100 / Program.TPS * 2, 0, 44100 / Program.TPS * 10, 140, 44100 / Program.TPS * 2, 160, 44100 / Program.TPS * 2, 180, 44100 / Program.TPS * 2, 200, 44100 / Program.TPS * 2, 0, 44100 / Program.TPS * 10); sound.SetWaveFormat(44100, 2); Program.WavProvider.AddMixerInput((ISampleProvider)sound); Program.WavPlayer.Play(); } } if (health == 30 && stealAttack == 2) { Program.Engine.AddEntity(DialogBox.Create($"[{machineName}] Good luck getting\nit back. [ x\\ _ /o ]")); Program.Referee.AddRule("no attack. haha."); location.AddEntity(Powerup.Create("shoot Boss", Program.ScreenWidth - 128, Program.ScreenHeight / 2)); stealAttack++; } if (health == 20 && !finalTransitionShown) { Program.Engine.AddEntity(DialogBox.Create($"[{machineName}] STO0oOOo0oOO0OPPpP")); savedHealth = 21; savedStealAttack = stealAttack; savedShiftRoom = shiftRoom; Program.Referee.AddRule("pop DEATH"); Program.Referee.AddRule("pop DEATH"); Program.Referee.AddRule("pop DEATH"); Program.Referee.AddRule("pop DEATH"); foreach (Guid guid in centerWalls) { location.RemoveEntity(guid); } attackTimer = 10; attackTimerMax = 10; originalWindowPosition = window.Position; finalTransitionShown = true; sound.Silent = true; sound = new SinWaveSound(true, 100, 44100 / Program.TPS * 10, 0, 44100 / Program.TPS * 10); sound.SetWaveFormat(44100, 2); Program.WavProvider.AddMixerInput((ISampleProvider)sound); Program.WavPlayer.Play(); } if (health == 0) { location.RemoveEntity(this.Id); Program.Engine.AddEntity(DialogBox.Create($"[{machineName}] NOOOOooOooooOooooooo...")); location.AddEntity(Banner.Create("you win")); if (windowAction != null) { Program.Engine.TickEnd -= windowAction; } window.Position = originalWindowPosition; health--; savedHealth = 100; savedStealAttack = 0; savedShiftRoom = false; sound.Silent = true; } if (health <= 0) { window.Position = originalWindowPosition; if (windowAction != null) { Program.Engine.TickEnd -= windowAction; } } if (attackTimer-- == 0) { attackTimer = attackTimerMax; //top-down if (health > 80) { int count = 6; for (int i = 0; i < count; i++) { double dir = this.Direction(location.GetEntities <Player>().First()) + (Math.PI / 3) - (i * 1.0 / count) * (Math.PI * 2.0 / 3) + (Program.Random.NextDouble() - 0.5) * Math.PI / 10; location.AddEntity(Enemy.Create((int)this.X, (int)this.Y).AddTickAction((l, e) => { if (Program.Engine.Location.GetEntities <DialogBox>().Any()) { return; } ((Description2D)e.Description).ChangeCoordsDelta(2 * Math.Cos(dir), 2 * Math.Sin(dir)); Enemy ed = (Enemy)e.Description; if (ed.X < 0 || ed.Y < 0 || ed.X > Program.ScreenWidth || ed.Y > Program.ScreenHeight) { l.RemoveEntity(ed.Id); } })); } } // platformer else if (health > 60) { attackTimer += Program.Random.Next(-10, 10); for (int i = 0; i < 3; i++) { location.AddEntity(Goal.Create(Program.ScreenWidth, Program.ScreenHeight - 16 - 16 * i).AddTickAction((l, e) => { if (Program.Engine.Location.GetEntities <DialogBox>().Any()) { return; } ((Description2D)e.Description).ChangeCoordsDelta(-5, 0); })); } } // vvvvvv-platformer else if (health > 40) { int y = attackTop ? 0 : Program.ScreenHeight / 2; for (int i = 0; i < 6; i++) { location.AddEntity(Powerup.Create("pop SPAWN", Program.ScreenWidth, y + 16 + 16 * i).AddTickAction((l, e) => { if (Program.Engine.Location.GetEntities <DialogBox>().Any()) { return; } ((Description2D)e.Description).ChangeCoordsDelta(-5, 0); })); } attackTop = !attackTop; } // top-down spinny else if (health > 20) { int yPos = Program.Random.Next(16, Program.ScreenHeight - 16); double delta = 0; location.AddEntity(Enemy.Create(Program.ScreenWidth, yPos).AddTickAction((l, e) => { if (Program.Engine.Location.GetEntities <DialogBox>().Any()) { return; } ((Description2D)e.Description).ChangeCoordsDelta(-delta, 0); delta += 0.25; })); } // just wait else { int velocity = (20 - health) * 2; double direction = Program.Random.NextDouble() * Math.PI * 2; if (windowAction != null) { Program.Engine.TickEnd -= windowAction; } location.AddEntity(Goal.Create(Program.Random.Next(16, Program.ScreenWidth - 16), Program.Random.Next(16, Program.ScreenHeight - 16))); location.AddEntity(Powerup.Create("pop SPEED", Program.Random.Next(16, Program.ScreenWidth - 16), Program.Random.Next(16, Program.ScreenHeight - 16))); location.AddEntity(Enemy.Create(Program.Random.Next(16, Program.ScreenWidth - 16), Program.Random.Next(16, Program.ScreenHeight - 16))); windowAction = (s, gs) => { if (Program.Engine.Location.GetEntities <DialogBox>().Any()) { return; } double shake = Program.Random.NextDouble() * Math.PI / 8; window.Position = window.Position .WithX((int)Math.Clamp(window.Position.X + Math.Cos(direction + shake - Math.PI / 4) * velocity, 0, 1920 - Program.ScreenWidth * Program.Scale)) .WithY((int)Math.Clamp(window.Position.Y + Math.Sin(direction + shake - Math.PI / 4) * velocity, 0, 1080 - Program.ScreenHeight * Program.Scale)); }; Program.Engine.TickEnd += windowAction; } } }