diff --git a/Financial_Freedom/Financial_Freedom/Bossfight.cs b/Financial_Freedom/Financial_Freedom/Bossfight.cs new file mode 100644 index 0000000000000000000000000000000000000000..c78f13a0c57691a7df1debbff3c8b74c0bfa0e6c --- /dev/null +++ b/Financial_Freedom/Financial_Freedom/Bossfight.cs @@ -0,0 +1,334 @@ +using System; +using FarseerPhysics.Dynamics; +using FarseerPhysics.Dynamics.Joints; +using Jypeli; +using Jypeli.Assets; +using Jypeli.Controls; +using Jypeli.Effects; +using Jypeli.Widgets; + +public class Bossfight : PhysicsGame +{ + private PlatformCharacter tero; + private AssaultRifle playerWeapon; + private PlatformCharacter2 boss; + private IntMeter bossHealth; + private IntMeter playerHealth; + private Timer projectileTimer; + private Timer bossMovementTimer; + private double bossMoveSpeed = 150; + + private PhysicsObject bottomWall; + + private Weapon rifle = new AssaultRifle(20, 5); + + private bool startBoss = false; + + private GameObject bossHealthBar; + private GameObject bossHealthBackground; + private GameObject playerHealthBar; + private GameObject playerHealthBackground; + + + public override void Begin() + { + IsFullScreen = true; + Level.Size = new Vector(5000, 1500); // Larger level for sidescrolling + + bottomWall = PhysicsObject.CreateStaticObject(Level.Width, 200.0); + bottomWall.Y = Level.Bottom + 100.0; + bottomWall.Color = Color.Gray; + bottomWall.Tag = "reuna"; + Add(bottomWall); + Level.CreateBorders(1.0, true); + Level.CreateLeftBorder(1.0, true).Tag = "reuna"; + Level.CreateRightBorder(1.0, true).Tag = "reuna"; + Level.CreateTopBorder(1.0, true).Tag = "reuna"; + + Level.Background.Image = LoadImage("CasinoEntrance.png"); + Level.Background.FitToLevel(); + Gravity = new Vector(0, -800); // Stronger gravity for better platform feel + + CreateBoss(); + CreatePlayer(); + Camera.Follow(tero); // Camera follows player for sidescrolling + Camera.StayInLevel = true; + + CreatePlatforms(); + CreateHealthBars(); + SetupCollisions(); + SetupControls(); + StartBossBehavior(); + } + + private void CreateHealthBars() + { + // Boss health bar background + bossHealthBackground = new Widget(Screen.Width -100, 50); + bossHealthBackground.Color = Color.Gray; + bossHealthBackground.Position = new Vector(0, Screen.Top - 75); + Add(bossHealthBackground); + + // Boss health bar foreground + bossHealthBar = new Widget(Screen.Width -100, 50); + bossHealthBar.Color = Color.Red; + bossHealthBar.Position = bossHealthBackground.Position; + Label bossHealthLabel = new Label(600, 200) + { + Text = "Boss Health", + TextScale = new Vector(2,2), + TextColor = Color.White, + Position = new Vector(0,0) + + }; + Add(bossHealthBar); + bossHealthBar.Add(bossHealthLabel); + + // Player health bar background + playerHealthBackground = new Widget(300, 30); + playerHealthBackground.Color = Color.Gray; + playerHealthBackground.Position = new Vector(Screen.Left + 170, Screen.Top - 50); + Add(playerHealthBackground); + + // Player health bar foreground + playerHealthBar = new Widget(300, 30); + playerHealthBar.Color = Color.Green; + playerHealthBar.Position = playerHealthBackground.Position; + Add(playerHealthBar); + } + + protected override void Update(Time time) + { + base.Update(time); + if (bossHealth != null && playerHealth != null) {UpdateHealthBars();} + + // Get mouse position relative to the player + Vector mousePos = Mouse.PositionOnWorld; + Vector direction = mousePos - tero.Position; + + // Calculate angle (in radians) and convert to degrees + float angle = (float)Math.Atan2(direction.Y, direction.X); + rifle.Angle = Angle.FromRadians(angle); + + if (rifle.Ammo.Value == 0){Timer.SingleShot(5.0, () => rifle.Ammo.Value = 30);} + } + + private void UpdateHealthBars() + { + if (bossHealthBar != null && bossHealthBackground != null) + UpdateHealthBar(bossHealth, bossHealthBar, bossHealthBackground); + + if (playerHealthBar != null && playerHealthBackground != null) + UpdateHealthBar(playerHealth, playerHealthBar, playerHealthBackground); + } + + private void UpdateHealthBar(IntMeter meter, GameObject bar, GameObject background) + { + if (meter == null || bar == null || background == null) return; + + double healthPercent = (double)meter.Value / meter.MaxValue; + bar.Width = background.Width * healthPercent; + bar.Position = new Vector( + background.Left + (bar.Width / 2), + background.Position.Y + ); + } + + private void CreatePlatforms() + { + // Floating platforms + for (int i = 1; i < 6; i++) + { + PhysicsObject platform = new PhysicsObject(200, 40); + platform.Position = new Vector(Screen.Left+i*(Screen.Width/6), -50); + platform.Color = Color.Green; + platform.MakeStatic(); + Add(platform); + } + } + + public void CreatePlayer() + { + rifle = new AssaultRifle(100, 66); + rifle.Image = LoadImage("ch661.png"); + + tero = new PlatformCharacter(75, 120); + tero.Shape = Shape.Rectangle; + tero.Color = Color.Blue; + tero.Position = new Vector(0, -200); + playerHealth = new IntMeter(100, 0, 100); + + + tero.Weapon = rifle; + tero.Weapon.Ammo.Value = 25; + tero.Weapon.FireRate = 50; + tero.CollisionIgnoreGroup = 1; + playerHealth = new IntMeter(100, 0, 100); + tero.Image = LoadImage("tero.png"); + + tero.Weapon.ProjectileCollision += OnProjectileHit; + tero.Weapon.Tag = "PlayerProjectile"; + + Add(tero); + tero.Add(rifle); + } + + private void CreateBoss() + { + boss = new PlatformCharacter2(120, 240); + boss.Shape = Shape.Rectangle; + boss.Color = Color.Red; + boss.Position = new Vector(600, 300); + boss.CollisionIgnoreGroup = 2; + boss.Mass = 10.0; + bossHealth = new IntMeter(500, 0, 300); + Add(boss); + } + + private void SetupCollisions() + { + // Player projectiles hitting boss + //AddCollisionHandler(boss, tero.Weapon.Shoot(), OnProjectileHit); + + // Boss projectiles hitting player + AddCollisionHandler(tero, typeof(PhysicsObject), OnPlayerHitByProjectile); + + + } + + private void OnProjectileHit(PhysicsObject projectile, PhysicsObject target) + { + if (projectile.Tag as string == "PlayerProjectile" && target == boss) + { + bossHealth.Value -= 1; + projectile.Destroy(); + ShowBossDamageEffect(); + CheckBossDefeat(); + } + + if (projectile.Tag as string == "PlayerProjectile" && target.Tag.ToString() == "reuna") + { + projectile.Destroy(); + } + + } + + private void OnPlayerHitByProjectile(PhysicsObject projectile, PhysicsObject target) + { + if (projectile.Tag as string == "BossProjectile" && target == tero) + { + playerHealth.Value -= 20; + projectile.Destroy(); + ShowPlayerDamageEffect(); + CheckPlayerDeath(); + } + } + + private void ShowBossDamageEffect() + { + boss.Color = Color.Orange; + Timer.SingleShot(0.2, () => boss.Color = Color.Red); + } + + private void ShowPlayerDamageEffect() + { + tero.Color = Color.DarkRed; + Timer.SingleShot(0.2, () => tero.Color = Color.Blue); + } + + private void CheckBossDefeat() + { + if (bossHealth.Value <= 0) + { + MessageDisplay.Add("VICTORY!"); + Exit(); + } + } + + private void CheckPlayerDeath() + { + if (playerHealth.Value <= 0) + { + MessageDisplay.Add("GAME OVER"); + Exit(); + } + } + + private void StartBossBehavior() + { + // Projectile attack pattern + projectileTimer = new Timer(1.5); + projectileTimer.Timeout += ShootProjectiles; + projectileTimer.Start(); + + // Movement pattern + bossMovementTimer = new Timer(3.0); + bossMovementTimer.Timeout += MoveBoss; + bossMovementTimer.Start(); + + startBoss = true; + } + + private void MoveBoss() + { + + } + + private void ShootProjectiles() + { + for (int i = 0; i < 3; i++) + { + PhysicsObject projectile = new PhysicsObject(30, 30) + { + Shape = Shape.Circle, + Color = Color.Yellow, + Position = boss.Position, + Tag = "BossProjectile", + IgnoresGravity = false, + CollisionIgnoreGroup = 1 // Don't collide with other boss projectiles + }; + + // Add velocity towards player + Vector direction = (tero.Position - boss.Position).Normalize(); + projectile.Velocity = direction * 300; + + Add(projectile); + Timer.SingleShot(5.0, projectile.Destroy); + } + } + + + + private void SetupControls() + { + Keyboard.Listen(Key.A, ButtonState.Down, () => tero.X -= 12, "Move left"); + Keyboard.Listen(Key.D, ButtonState.Down, () => tero.X += 12, "Move right"); + Keyboard.Listen(Key.W, ButtonState.Down, () => tero.Jump(500.0), "Jump"); + + // Safe shooting + Mouse.Listen(MouseButton.Left, ButtonState.Down, () => + { + ShootWeapon(rifle); + }, "Shoot"); + + Keyboard.Listen(Key.Escape, ButtonState.Pressed, Exit, "Quit"); + } + + void ShootWeapon(Weapon weapon) { + if (weapon == null) + { + Console.WriteLine("Weapon is null!"); // Log error + return; + } + PhysicsObject bullet = weapon.Shoot(); + if (bullet != null) { + bullet.Size *= 1 ; // Customize projectile size + bullet.Velocity *= 12; + bullet.MaximumLifetime = TimeSpan.FromSeconds(1); + bullet.IgnoresGravity = false; + bullet.Tag = "PlayerProjectile"; + bullet.CollisionIgnoreGroup = 1; + } + } + +} \ No newline at end of file diff --git a/Financial_Freedom/Financial_Freedom/Content/ch661.png b/Financial_Freedom/Financial_Freedom/Content/ch661.png new file mode 100644 index 0000000000000000000000000000000000000000..313715ab48805dc7c60c7fa79c493c64662ee579 Binary files /dev/null and b/Financial_Freedom/Financial_Freedom/Content/ch661.png differ diff --git a/Financial_Freedom/Financial_Freedom/Financial_Freedom.cs b/Financial_Freedom/Financial_Freedom/Financial_Freedom.cs index e69c80b657b5f21818798401afe49968f564b46d..e88c388c2c005c018363bdc99a27a831977bdaf4 100644 --- a/Financial_Freedom/Financial_Freedom/Financial_Freedom.cs +++ b/Financial_Freedom/Financial_Freedom/Financial_Freedom.cs @@ -24,15 +24,15 @@ using Key = Jypeli.Key; using MouseButton = Jypeli.MouseButton; using Window = Jypeli.Window; -/// @author Miklas, Joonatan, Santeri -/// @version 0.69.420 -/// <summary> -/// Pelissä koitetaan pelastaa pelaajan poika joka on joutunut venäläisen mafian kidnappaamaksi. -/// He vaativat lunnasrahoja joita sinulla ei ole ja päätät suunnata kasinolle tienaamaan -/// Kasinolla voit voittaa 10000000% rahastasi takaisin mutta hävitä vain 100% joten sehän on kannattavaa +// @author Miklas, Joonatan, Santeri +// @version 0.69.420 +// <summary> +// Pelissä koitetaan pelastaa pelaajan poika joka on joutunut venäläisen mafian kidnappaamaksi. +// He vaativat lunnasrahoja joita sinulla ei ole ja päätät suunnata kasinolle tienaamaan +// Kasinolla voit voittaa 10000000% rahastasi takaisin mutta hävitä vain 100% joten sehän on kannattavaa -/// Pelaa erilaisia minipelejä kasvattaen rahamäärääsi kohti miljardia 1 000 000 000€ -/// Kontrollit on peleissä näytetty merkinnöillä (*nappi*), peli vaatii suurimmilta osin näppäimistöä mutta joskus joudut käyttämään myös hiirtäsi. +// Pelaa erilaisia minipelejä kasvattaen rahamäärääsi kohti miljardia 1 000 000 000€ +// Kontrollit on peleissä näytetty merkinnöillä (*nappi*), peli vaatii suurimmilta osin näppäimistöä mutta joskus joudut käyttämään myös hiirtäsi. /* Credits: @@ -45,7 +45,6 @@ using Window = Jypeli.Window; //minimi/maksimipanokset, slots ei minimiä mutta joku maksimi koska muuten op, plinko pieni minimi ei maksimia (ehkä) //bj suurempi minimi ei max, cf sama?? -//ruletti namespace Financial_Freedom{ @@ -132,6 +131,9 @@ public class RBetAmounts public class Financial_Freedom : PhysicsGame //alustellaan muuttujat { + // Track boss fight condition + public bool PlayerReachedBossCondition { get; private set; } + private double yTs = 1; // Yleinen Takaisinsaanti private double tsplinko = (1); //suurinpiirtein takaisinsaantikerroin plinkoalustoissa 0.85 kontrollikerroin DoubleMeter pistelaskuri; //heitäppä villi veikkaus mikä tämä voisi olla @@ -236,6 +238,17 @@ public class Financial_Freedom : PhysicsGame private Image[] coinFlipImages = LoadImages( "coin1", "coin2", "coin3", "coin4", "coin5", "coin6", "coin7", "coin8" ); + private void CheckBossCondition() + { + if (pistelaskuri != null) + { + if (pistelaskuri.Value >= 100000) + { + PlayerReachedBossCondition = true; + } + } + } + public override void Begin() // pelin alku { IsFullScreen = true; @@ -380,6 +393,8 @@ public class Financial_Freedom : PhysicsGame { base.Update(time); + CheckBossCondition(); + UpdateDoorPopup(); TarkistaRahaTavoite(); TarkistaScore(); @@ -445,7 +460,9 @@ public class Financial_Freedom : PhysicsGame private void Casinoentry() { Level.Background.Image = LoadImage("Casinoentrance.png"); + Level.Size = Screen.Size; Level.Background.FitToLevel(); + Level.CreateBorders(); ovet = new List<GameObject>(); @@ -494,7 +511,8 @@ public class Financial_Freedom : PhysicsGame /// <summary> /// Pelin "aloitusruutuu" jossa valitaan mitä peliä halutaan pelata. /// </summary> - void PelinValintaa() + + /*void PelinValinta() { Gravity = new Vector(0, 0); @@ -504,11 +522,11 @@ public class Financial_Freedom : PhysicsGame var pakka = LuoPakka(); SekoitaPakka(pakka); - /*MiniPeliLogo(this,250, 325, - 400, Level.Top - 300, "Plinko", 1); + MiniPeliLogo(this,250, 325, - 400, Level.Top - 300, "Plinko", 1); MiniPeliLogo(this,250, 325, 0, Level.Top - 300, "Blackjack", 2); MiniPeliLogo(this,250, 325, 400, Level.Top - 300, "Ruletti", 3); MiniPeliLogo(this,250,325, -200, -200, "Slots", 4); - MiniPeliLogo(this,250,325, 200, -200, "Coinflip", 5);*/ + MiniPeliLogo(this,250,325, 200, -200, "Coinflip", 5); Keyboard.Listen(Key.Space, ButtonState.Down, AddRaha, "antaa rahaa"); Keyboard.Listen(Key.D2, ButtonState.Pressed, async () => await BlackJack(), "Menee peliin BlackJack"); Keyboard.Listen(Key.D1, ButtonState.Pressed, async () => await Plinko(), "Menee peliin Plinko"); @@ -516,9 +534,9 @@ public class Financial_Freedom : PhysicsGame Keyboard.Listen(Key.D4, ButtonState.Pressed, async () => await Slots(), "Menee peliin Slots"); Keyboard.Listen(Key.D5, ButtonState.Pressed, async () => await Coinflip(), "Menee peliin Coinflip"); Keyboard.Listen(Key.Escape, ButtonState.Pressed, Exit, "Lopeta peli"); - } + }*/ - public async Task PelinValinta() + public void PelinValinta() { ClearControls(); ClearGameObjects(); @@ -528,6 +546,7 @@ public class Financial_Freedom : PhysicsGame Gravity = new Vector(0, 0); Level.Background.Image = taustakuvaPV; Level.Background.FitToLevel(); + Level.CreateBorders(); LuoPistelaskuri(); var pakka = LuoPakka(); @@ -583,10 +602,9 @@ public class Financial_Freedom : PhysicsGame Keyboard.Listen(Key.Space, ButtonState.Pressed, SelectDoor, "Select a door"); Keyboard.Listen(Key.Enter, ButtonState.Pressed, SelectDoor, "Select a door"); - - // controllit Keyboard.Listen(Key.A, ButtonState.Down, () => tero.X -= 12, "Move left"); Keyboard.Listen(Key.D, ButtonState.Down, () => tero.X += 12, "Move right"); + Keyboard.Listen(Key.R, ButtonState.Down, AddRaha, "antaa rahaa"); } void CreatePelaaja() @@ -612,7 +630,7 @@ public class Financial_Freedom : PhysicsGame case 3: return "Ruletti"; case 4: return "Slots"; case 5: return "Coinflip"; - case 6: return "Ulos"; + case 6: {if(pistelaskuri.Value >= 100000){return "Kelpaisiko mafiapomoille 100k$?";} return "Ulos"; } case 7: return "Mene kasinoon sisälle"; default: return "Unknown"; } @@ -3085,9 +3103,14 @@ public class Financial_Freedom : PhysicsGame void CasinoExit() { peliKesken = 0; - ClearControls(); - ClearGameObjects(); - Defeat(); + //if (pistelaskuri.Value > 10000) { ClearAll(); var mafiapomo = new Bossfight(); mafiapomo.Boss();} + if (pistelaskuri.Value > 100000){Exit();} + else + { + ClearControls(); + ClearGameObjects(); + Defeat(); + } } async Task Voitto() diff --git a/Financial_Freedom/Financial_Freedom/Financial_Freedom.csproj b/Financial_Freedom/Financial_Freedom/Financial_Freedom.csproj index b63c1dee1da79a7cce5d71027d3a69dbc1265ece..b3362f4da639a14e8425c48024c0abedc1e3f2ed 100644 --- a/Financial_Freedom/Financial_Freedom/Financial_Freedom.csproj +++ b/Financial_Freedom/Financial_Freedom/Financial_Freedom.csproj @@ -392,10 +392,19 @@ <None Update="Content\CasinoEntrance.png"> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> </None> + <None Update="Content\ch661.png"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </None> </ItemGroup> <ItemGroup> <None Remove="Content\toplistsave.txt" /> </ItemGroup> + <ItemGroup> + <Compile Update="Bossfight.cs"> + <CopyToOutputDirectory>Never</CopyToOutputDirectory> + </Compile> + </ItemGroup> + </Project> diff --git a/Financial_Freedom/Financial_Freedom/Ohjelma.cs b/Financial_Freedom/Financial_Freedom/Ohjelma.cs index c3c291d58d15a05610a6ccd5f413d90c1081933b..5afaf05d37670d8ea288a8c540af3ed048297002 100644 --- a/Financial_Freedom/Financial_Freedom/Ohjelma.cs +++ b/Financial_Freedom/Financial_Freedom/Ohjelma.cs @@ -19,8 +19,28 @@ namespace Financial_Freedom [STAThread] static void Main() { - using var game = new Financial_Freedom(); + bool shouldLaunchBossFight = false; + + using (var ff = new Financial_Freedom()) + { + ff.Run(); + // Check condition AFTER main game completes + shouldLaunchBossFight = ff.PlayerReachedBossCondition; + } + + // Then conditionally launch boss fight + if (shouldLaunchBossFight) + { + using (var bossGame = new Bossfight()) + { + bossGame.Run(); + } + } + + /*using var game = new Financial_Freedom(); game.Run(); + using var game2 = new Bossfight(); + game2.Run();*/ } } } \ No newline at end of file