|
所在平台: Udemy |
课程主页: https://www.udemy.com/course/csharp-zbuduj-wlasnego-tetrisa-kompletny-przewodnik/
课程评论:没有评论
您好!这是一门关于使用 C# 从零开始构建经典游戏《俄罗斯方块》的 Coursera 课程。 **课程概述:** 本课程旨在教授您游戏开发中的 C# 编程技巧。您将学习如何从基本功能逐步构建出一个完整的《俄罗斯方块》游戏,并深入理解游戏开发中的关键概念。课程内容将涵盖从最小可行产品(MVP)的实现,到更高级的游戏机制和性能优化。 **学习内容:** 1. **分层架构和最佳实践:** * 项目结构:Tetris.Domain (游戏逻辑和模型)、Tetris.Application (游戏规则和应用逻辑)、Tetris.Infrastructure (外部组件集成)、Tetris.Presentation (WPF 用户界面)。 * SOLID 原则:单一职责、开闭、里氏替换、接口隔离、依赖倒置。 * 关注点分离 (SoC)。 * KISS (保持简洁)。 * DRY (不要重复自己)。 * YAGNI (你不会需要它)。 * 内聚与耦合。 2. **最小可行产品 (MVP) 实现:** * 棋盘表示(网格)。 * 单个方块的表示。 * 方块下落机制。 * 基本用户界面(WPF)。 * 重点在于测试基本机制,而非立即添加高级功能。 3. **单元测试和 TDD:** * 使用 xUnit、Moq 和 FluentAssertions 为游戏代码(例如 GameBoard、GameService)编写单元测试。 * 测试内容包括:棋盘创建、单元格状态、方块放置、边界条件、方块生成、方块下落、满行获取等。 4. **添加不同类型的方块:** * 运用多态性来管理不同形状的方块,使代码更清晰、更具弹性。 5. **应用工厂方法模式 (Factory Method):** * 将方块的创建逻辑与主代码分离,提高可管理性和可扩展性。 * 引入 `GameBlockType` 枚举和 `IGameBlockFactory` 接口,实现 `CreateGameBlock` 和 `CreateRandomGameBlock` 方法。 * 将 `IGameBoard` 移动到 `Interfaces` 文件夹以优化代码组织。 6. **实现方块旋转:** * 处理方块旋转时的碰撞检测(与墙壁和已有方块)。 * 修改 `GameBlock` 类以支持旋转。 * 在 `GameService` 中添加 `CanRotate`、`RotateCurrentBlock`、`MoveBlockLeft` 和 `MoveBlockRight` 方法。 * 引入 `IRotationStrategy` 接口,并实现不同旋转策略(90度顺时针、180度、逆时针、随机)。 7. **添加满行检测、消除及计分系统:** * 实现检测并移除已填满的行,并使上方的方块下移。 * 根据消除的行数计算分数。 * 实时更新 UI 显示的分数和已消除行数。 * **应用观察者模式 (Observer Pattern):** 以便 UI 能够响应游戏状态的变化(如分数更新、游戏结束通知),实现游戏逻辑与 UI 的解耦。 8. **添加得分保存和 Top 5 排行榜:** * 实现保存玩家得分的功能。 * 显示 Top 5 的高分榜。 * **应用备忘录模式 (Memento Pattern):** 用于保存玩家分数的状态,以便在需要时恢复到之前的得分列表状态,防止意外修改。 这门课程将带您全面掌握 C# 游戏开发的核心技术,并学到许多重要的软件设计原则和模式。
Chcesz nauczyć się programowania gier w C#? Zbuduj od podstaw kultowego Tetrisa i poznaj kluczowe koncepcje programowania! W tym kursie przeprowadzimy Cię przez cały proces - od minimalnej wersji gry (MVP) po bardziej zaawansowane mechaniki i optymalizację.Czego się nauczysz?Rozpoczniemy od implementacji z podziałem na warstwy i utrzymaniem najlepszych praktyk programowania. Zaczniemy od utworzenie projektu w Visual Studio z odpowiednimi warstwami:Tetris.Domain: Logika gry i modele.Tetris.Application: Zasady działania gry, logika aplikacji.Tetris.Infrastructure: Integracja z zewnętrznymi komponentami (jeśli będzie potrzebne).Tetris.Presentation: WPF - interfejs użytkownika.Krok 1. MVP naszej gry Tetris, skupiamy się na najbardziej podstawowych elementach gry, takich jak:Reprezentacja planszy jako siatki.Jeden prosty klocek.Mechanika opadania bloku w dół.Podstawowy interfejs (np. wyświetlanie planszy w WPF).Nie dodajemy od razu zaawansowanych funkcji, takich jak różne kształty klocków, poziomy trudności czy interakcje gracza, ponieważ najważniejsze jest przetestowanie podstawowej mechaniki. Gdy MVP działa poprawnie i spełnia oczekiwania, możemy zacząć rozwijać bardziej zaawansowane funkcjonalności.Następnie przeanalizujemy kod pod kątem zgodności z najlepszymi praktykami i zasadami:1. SOLID· Single Responsibility Principle (SRP):· Open/Closed Principle (OCP):· Liskov Substitution Principle (LSP):· Interface Segregation Principle (ISP):· Dependency Inversion Principle (DIP):2. Separation of Concerns (SoC)3. KISS (Keep It Simple, Stupid)4. DRY (Don't Repeat Yourself)5. YAGNI (You Aren't Gonna Need It)6. Cohesion i CouplingKrok 2. Dodamy testy jednostkowe zgodnie z podejściem TDD dla naszego kodu gry Tetris.Stworzymy testy dla głównych komponentów, zaczynając od podstawowych funkcjonalności.Testy naszej planszy do gry - klasy GameBoard:Sprawdzenie poprawnego tworzenia planszy czyli - Testy konstruktoraWeryfikacja, czy komórki są początkowo puste - Testy metody IsCellEmptyTestowanie umieszczania bloków na planszy - Testy metody PlaceBlockTesty warunków brzegowychTesty naszego serwisu - klasy GameService:Sprawdzenie poprawnego tworzenia nowych bloków - SpawnBlockTestowanie ruchu bloków w dół - MoveBlockDownWeryfikacja zachowania przy osiągnięciu dnaSprawdzenie poprawnego zbierania wszystkich bloków na planszy - GetBlocksTesty będą wykorzystywać:xUnit jako framework testowyMoq do mockowania zależnościFluentAssertions do czytelniejszych asercjiKrok 3 Dodanie różnych typów blokówDodanie różnych typów bloków w projekcie wymaga wprowadzenia odpowiednich modyfikacji w kodzie, które będą zgodne z zasadami projektowymi. W szczególności zastosujemy polimorfizm, co pozwoli na efektywne zarządzanie różnymi kształtami bloków. Dzięki temu nasz kod stanie się bardziej czytelny, elastyczny i zgodny z najlepszymi praktykami programowania.Krok 4 Zastosowanie wzorca Factory Method.Cel wzorca:Oddzielenie logiki tworzenia klocków od reszty kodu, co ułatwi zarządzanie i rozszerzanie aplikacji.Zamiast tworzyć obiekty GameBlock bezpośrednio w różnych miejscach kodu, będziemy korzystać z fabryki (GameBlockFactory), co poprawia czytelność i elastyczność kodu.Plan działań:Przeniesiemy IGameBoard do folderu Interfaces, aby lepiej uporządkować kod nasz kod.Dodamy GameBlockType (enum) - reprezentujący różne typy klocków (I, O, T, S, Z, J, L).Stworzymy interfejs IGameBlockFactory, który określi, jak powinna działać fabryka klocków.Zaimplementujemy GameBlockFactory, która będzie:Tworzyć klocek na podstawie zadanego typu (CreateGameBlock).Tworzyć losowy klocek (CreateRandomGameBlock).Dzięki temu jeśli w przyszłości dodamy nowe typy klocków, wystarczy zmodyfikować fabrykę, zamiast zmieniać kod w wielu miejscach!Krok 5 Dodanie obsługi obracania klocków za pomocą klawiatury.Aby poprawnie zaimplementować obrót klocków w grze, należy uwzględnić kolizje zarówno ze ścianami planszy, jak i innymi blokami. Jeśli obrót nie jest możliwy, kształt klocka powinien pozostać bez zmian.Plan Implementacji:1. Modyfikacja klasy GameBlock- Istniejąca metoda Rotate zostanie dostosowana tak, aby zwracała obrócony kształt klocka.2. Aktualizacja klasy GameService- Dodanie metody CanRotate, która sprawdzi, czy obrót jest możliwy.- Implementacja RotateCurrentBlock do obsługi rotacji klocka.- Dodanie metod MoveBlockLeft i MoveBlockRight w kontekście obrotów.3. Dodanie Strategi- Dodamy interfejs IRotationStrategy. - Dodamy implementację strategii standardowej rotacji klocka o 90 stopni w prawo.- Dodamy implementacja braku rotacji dla klocka.- Dodamy Rotacja o 180 stopni- Dodamy Obracanie klocek przeciwnie do ruchu wskazówek zegara- Dodamy Rotację Losową, wybiera jedną z dostępnych strategii rotacjiKrok 6 Dodanie logiki detekcji i usuwania pełnych linii i dodanie punktacjiDodamy logike detekcji i usuwania pełnych linii oraz punktację do naszej gry. Zacznijmy od stworzenia odpowiednich elementów w domenie.Implementacja zapewnia:- Prawidłowe wykrywanie pełnych linii - system skutecznie identyfikuje wiersze wypełnione klockami.- Usuwanie linii i przesuwanie klocków w dół - po usunięciu pełnych linii pozostałe klocki są automatycznie przesuwane w dół.- Naliczanie punktów według zadanej tabeli - wynik jest aktualizowany zgodnie z liczbą usuniętych linii i przyjętymi zasadami punktacji.- Wyświetlanie aktualnego wyniku - UI natychmiast odświeża wynik oraz licznik usuniętych linii po każdej zmianie.Zastosuj wzorzec Observer PatternObserver Pattern idealnie pasuje do powiadamiania UI o zmianach w grze. Observer Pattern pozwoli na oddzielenie logiki gry od interfejsu użytkownika. Dzięki temu UI będzie reagować na zmiany, takie jak:- Aktualizacja punktacji- Licznik usuniętych linii- Czy Możliwość dodania innych zmian (np. Informowanie o końcu gry co teraz też dodamy)Krok 7 Dodanie Zapisywania wyników i wyswietlania Top 5Dodamy funkcjonalność zapisywania wyników oraz ich wyświetlania w formie listy Top 5 najlepszych rezultatów. Dzięki temu gracze będą mogli śledzić swoje osiągnięcia oraz rywalizować o najwyższe miejsca w rankingu. Następnie Dodamy teraz wzorzec Memento, który pozwala na zapamiętanie stanu wyników graczy w danym momencie - HighScoreMementoDzięki temu można cofnąć się do wcześniejszego stanu listy wyników bez ryzyka ich przypadkowej zmiany.