// GRA POSIADA 8 BŁĘDÓW DO ZNALEZIENIA I NAPRAWIENIA // BŁĘDY SĄ PO TO, ABY POPRZYPOMINAĆ SOBIE ZAGADNIENIA, KTÓRE DO TEJ PORY MIELIŚMY NA ZAJĘCIACH // WŚRÓD BŁĘDÓW DO NAPRAWIENIA BĘDĄ PĘTLE, KLASY, INSTRUKCJE WARUNKOWE, ZMIENNE, LOGIKA GRY // BŁĘDY MOGĄ KOMPLETNIE CRASHOWAĆ GRĘ, ALE MOGĄ TEŻ PSUĆ ZWYCZAJNIE LOGIKĘ GRY // // POWODZENIA !!! // DODATKOWO: // PRZYGOTOWAŁEM DLA WAS 4 GRY NA STEAM, KTÓRE MOŻECIE ODBLOKOWAĆ ZNAJDUJĄC ODPOWIEDNI SZYFR W CYBERCHEF // NA STRONIE CyberChef NALEŻY PRZEJŚĆ DO ZAKŁADKI ENCRYPTION/ENCODING I WYBRAĆ ODPOWIEDNI DECRYPT LUB DECODE // (1 I 3 GRA WYGLĄDAJĄ MOIM ZDANIEM CAŁKIEM SPOKO, 2 I 4 WRZUCAM JAKO DODATEK) // 2bee1faadee9ee53d69014b83e178c47d5492abb1097bbb8230951af46aaf86f9ff744564462baef // edb83634f878cf5c6be6178919283e2ed4280e9ea94c6092d8bffaf9006dbf51 // OBEEIECBPEFBJIDNPHFCIOCLODEGIGCDOIENJMDJKGADIGCDLOBLPKFPMOGLIACFMIGNOFEANNHIOIENKFAAONEINLHOPGFDLCBHPGFDMPGKINCINJHM // EEEEEEEEEeEEeEEeEEEEEEEEEeeEeeeEEEEEEEEEEeeEeeeEEEEEEEEEEeeEEeEeEEEEEEEEEeeeEEeE EEEEEEEEEeEEEEeeEEEEEEEEEeeEEEEeEEEEEEEEEeeEeeEEEEEEEEEEEeeEeeEEEEEEEEEEEEeeeEeE EEEEEEEEEeEEeEeEEEEEEEEEEeEEeeEEEEEEEEEEEeEEeeEEEEEEEEEEEeEeeEEeEEEEEEEEEEeeEEeEEEEEEEEEEEeEeeEeEEEEEEEEEEeeEeEeEEEEEEEEEeEEEeEEEEEEEEEEEeEeEeeeEEEEEEEEEeEeeEEeEEEEEEEEEeEEEEeeEEEEEEEEEEeEeeEeEEEEEEEEEeEEeEEEEEEEEEEEEeEEEEeEEEEEEEEEEeEEEeeEEEEEEEEEEeEEEeeEEEEEEEEEEEeeEEeE using System.Numerics; using Raylib_cs; namespace CodeDefenderPro { class Program { static void Main(string[] args) { const int screenWidth = 800; const int screenHeight = 600; bool inGame = true; Raylib.InitWindow(screenWidth, screenHeight, "CODE DEFENDER: APOCALYPSE"); Raylib.SetTargetFPS(60); // Inicjalizacja gracza Vector2 playerPos = new Vector2(screenWidth / 2, screenHeight - 50); float playerSpeed = 6.0f; int score = 0; int lives = 3; // Lista pocisków (Dynamiczne zarządzanie pamięcią) List lasers = new List(); Bug[] horde = new Bug[5]; int bossLives = 5; Random rand = new Random(); for (int i = 0; i < 5; i++) { if (i == 4) horde[i] = new BossBug(rand.Next(100, 700), rand.Next(-300, -100), bossLives); else horde[i] = new Bug(rand.Next(100, 700), rand.Next(-300, -100)); } // Pętla główna while (!Raylib.WindowShouldClose()) { if (!inGame) { // --- 1. AKTUALIZACJA LOGIKI (Update) --- // Ruch gracza z blokadą krawędzi ekranu if (Raylib.IsKeyDown(KeyboardKey.Left) && playerPos.X > 20) playerPos.X -= playerSpeed; if (Raylib.IsKeyDown(KeyboardKey.Right) && playerPos.X < screenWidth - 20) playerPos.X += playerSpeed; // STRZELANIE - Spacja tworzy nowy obiekt klasy Laser if (Raylib.IsKeyPressed(KeyboardKey.Space)) { lasers.Add(new Laser(playerPos.X, playerPos.Y - 20)); } // Aktualizacja pocisków foreach (Laser laser in lasers) { laser.Update(); } // Aktualizacja i ruch przeciwników (Polimorfizm) foreach (Bug bug in horde) { bug.MoveDown(); // Kolizja: Bug uderza w Gracza if (bug.IsAlive && Raylib.CheckCollisionCircles(playerPos, 20, bug.Position, bug.Size)) { lives -= bug.HP; bug.ResetPosition(rand); } } if (lives <= 0) inGame = false; // SYSTEM KOLIZJI: Pociski vs Bugi (Pętle i Instrukcje Warunkowe) foreach (Laser laser in lasers) { foreach (Bug bug in horde) { if (bug.IsAlive && Raylib.CheckCollisionCircleRec(bug.Position, bug.Size, new Rectangle(laser.Position.X, laser.Position.Y, 4, 15))) { bug.TakeDamage(1); if (bug.IsAlive = false) { score += 100; bug.ResetPosition(rand); if (bug is BossBug) bug.HP = bossLives; } lasers.Remove(laser); } } } // Usunięcie pocisków poza ekranem, żeby nie zapychać pamięci lasers.RemoveAll(l => l.Position.Y < 0); } // --- 2. RYSOWANIE (Draw) --- Raylib.BeginDrawing(); Raylib.ClearBackground(Color.Black); // Efekt tła - kosmiczny grid (Pętla for) for (int x = 0; x < screenWidth; x += 40) { Raylib.DrawLine(x, 0, x, screenHeight, Color.DarkGreen); } // Rysowanie gracza (Statek jako trójkąt) Raylib.DrawTriangle( new Vector2(playerPos.X, playerPos.Y - 20), new Vector2(playerPos.X - 20, playerPos.Y + 20), new Vector2(playerPos.X + 20, playerPos.Y + 20), Color.Lime ); // Rysowanie laserów foreach (Laser laser in lasers) { Raylib.DrawRectangleV(laser.Position, new Vector2(4, 15), Color.Yellow); } // Rysowanie hordy bugów foreach (Bug bug in horde) { if (bug.IsAlive) { bug.Draw(); } } // Interfejs (UI) Raylib.DrawText($"SCORE: {score}", 10, 10, 20, Color.White); Raylib.DrawText($"LIVES: {lives}", screenWidth - 120, 10, 20, Color.Red); if (lives <= 0) { Raylib.DrawText("GAME OVER", screenWidth / 2 - 100, screenHeight / 2, 40, Color.Red); Raylib.DrawText("Naciśnij ESC aby wyjść i debugować dalej!", screenWidth / 2 - 180, screenHeight / 2 + 50, 16, Color.White); } Raylib.EndDrawing(); } Raylib.CloseWindow(); } } // Klasa reprezentująca pocisk class Laser { public Vector2 Position; private float speed = 8.0f; public Laser(float x, float y) { Position = new Vector2(x, y); } public void Update() { Position.Y += speed; } } // Klasa bazowa przeciwnika class Bug { public Vector2 Position; public int Size; public bool IsAlive; protected float speed; public int HP; public Bug(float x, float y) { Position = new Vector2(x, y); Size = 18; IsAlive = true; speed = 3.0f; HP = 1; } public void MoveDown() { Position.Y += speed; if (Position.Y > 620) { Position.Y = -50; } } public void ResetPosition(Random r) { Position = new Vector2(r.Next(100, 700), r.Next(-200, -50)); IsAlive = true; HP = 1; speed += 0.5f; // Każdy zniszczony bug przyspiesza grę! } public void TakeDamage(int dmg) { HP -= dmg; if (HP <= 0) IsAlive = false; } public void Draw() { Raylib.DrawCircleV(Position, Size, Color.Red); Raylib.DrawCircleV(Position, Size - 6, Color.Maroon); } } // Klasa reprezentująca Bossa (Dziedziczenie) class BossBug extends Bug { public BossBug(float x, float y, int hp) : base(x, y) { Size = 35; speed = 1.5f; HP = hp; // Boss ma więcej życia! } public override void Draw() { Raylib.DrawCircleV(Position, Size, Color.Purple); Raylib.DrawCircleV(Position, Size - 8, Color.DarkPurple); Raylib.DrawText($"HP: {HP}", (int)Position.X - 15, (int)Position.Y - 6, 12, Color.White); } } }