|
| 1 | +--- |
| 2 | +layout: sushi |
| 3 | +title: Tetris mit Blazor |
| 4 | +description: In dieser Übung programmierst du Tetris mit CSharp und Blazor |
| 5 | +--- |
| 6 | + |
| 7 | +# Tetris mit Blazor |
| 8 | + |
| 9 | +## Kostenlose Voraussetzungen |
| 10 | + |
| 11 | +* Neueste Version von [Visual Studio 2017 Community Edition](https://visualstudio.microsoft.com/free-developer-offers/) mit *ASP.NET and web development* |
| 12 | +* [ASP.NET Core Blazor Language Services](https://marketplace.visualstudio.com/items?itemName=aspnet.blazor) |
| 13 | + |
| 14 | +## Projekt anlegen |
| 15 | + |
| 16 | +* Visual Studio starten |
| 17 | + |
| 18 | +* *File* / *New* / *Project* |
| 19 | + |
| 20 | +* Neues *ASP.NET* Projekt anlegen:<br/> |
| 21 | +  |
| 22 | + |
| 23 | +* *Blazor* Projekttyp auswählen:<br/> |
| 24 | +  |
| 25 | + |
| 26 | +* Nach dem Anlegen des Projekt den Startmodus ändern:<br/> |
| 27 | +  |
| 28 | + |
| 29 | +* Probiere, das Programm mit *F5* oder *Debug* / *Start Debugging* zu starten. Es müsste ein Kommandozeilenfenster und ein Browser aufgehen. Im Browser solltest du folgendes sehen:<br/> |
| 30 | +  |
| 31 | + |
| 32 | +* Um den Debugger wieder zu beenden, beende das Kommandozeilenfenster.<br/> |
| 33 | +  |
| 34 | + |
| 35 | +Gratuliere! Du hast dein erstes Blazor-Programm zum Laufen gebracht. |
| 36 | + |
| 37 | +## Aufräumen |
| 38 | + |
| 39 | +Visual Studio hat dir einiges an Code generiert, damit du nicht ganz von vorne starten musst. Einen Teil davon brauchen wir für unser Tetris nicht. Daher müssen wir als erstes im Projekt aufräumen. |
| 40 | + |
| 41 | +* Lösche die in der folgenden Grafik durchgestrichenen Ordner und Dateien aus dem generierten Projekt:<br/> |
| 42 | +  |
| 43 | + |
| 44 | +* Lösche den Inhalt der Datei *css/site.css*. **Achtung!** Die Datei selbst muss erhalten bleiben. Lösche nur den **Inhalt**! |
| 45 | + |
| 46 | +* In *Pages/index.cshtml* muss folgender Code stehen: |
| 47 | + |
| 48 | +```cs |
| 49 | +@page "/" |
| 50 | + |
| 51 | +<h1>Tetris</h1> |
| 52 | +``` |
| 53 | + |
| 54 | +* In *Shared/MainLayout.cshtml* muss folgender Code stehen: |
| 55 | + |
| 56 | +```cs |
| 57 | +@inherits BlazorLayoutComponent |
| 58 | + |
| 59 | +@Body |
| 60 | +``` |
| 61 | + |
| 62 | +* Probiere, das Programm mit *F5* oder *Debug* / *Start Debugging* zu starten. Es müsste ein Kommandozeilenfenster und ein Browser aufgehen. Im Browser solltest du folgendes sehen:<br/> |
| 63 | +  |
| 64 | + |
| 65 | +* Um den Debugger wieder zu beenden, beende das Kommandozeilenfenster. |
| 66 | + |
| 67 | +Super! Jetzt haben wir ein sauberes Projekt und können beginnen, zu programmieren. |
| 68 | + |
| 69 | +## Spielfeld |
| 70 | + |
| 71 | +Als erstes generieren wir das Spielfeld. |
| 72 | + |
| 73 | +* Füge einen Ordner namens *Logic* zum Projekt hinzu:<br/> |
| 74 | +  |
| 75 | + |
| 76 | +* Füge in den Ordner eine Klasse namens *BoardContentExtensions.cs* hinzu:<br/> |
| 77 | +  |
| 78 | + |
| 79 | +* *BoardContentExtensions.cs* muss folgenden Code enthalten. Es handelt sich um Hilfsfunktionen, mit denen man in Schleifen das Spielfeld durchlaufen (Englisch *iterate*) kann. Lass dir von jemandem aus dem Mentorenteam den Code erklären. |
| 80 | + |
| 81 | +```cs |
| 82 | +namespace BlazorTetris.Logic |
| 83 | +{ |
| 84 | + public delegate bool CancelableIterator(int row, int col); |
| 85 | + public delegate void Iterator(int row, int col); |
| 86 | + |
| 87 | + public static class BoardContentExtensions |
| 88 | + { |
| 89 | + public static bool Iterate(this string[,] matrix, CancelableIterator iterator) |
| 90 | + { |
| 91 | + for (var row = 0; row < matrix.GetLength(0); row++) |
| 92 | + { |
| 93 | + for (var col = 0; col < matrix.GetLength(1); col++) |
| 94 | + { |
| 95 | + if (!iterator(row, col)) |
| 96 | + { |
| 97 | + return false; |
| 98 | + } |
| 99 | + } |
| 100 | + } |
| 101 | + |
| 102 | + return true; |
| 103 | + } |
| 104 | + |
| 105 | + |
| 106 | + public static void Iterate(this string[,] matrix, Iterator iterator) => |
| 107 | + Iterate(matrix, (row, col) => { iterator(row, col); return true; }); |
| 108 | + } |
| 109 | +} |
| 110 | +``` |
| 111 | + |
| 112 | +* Ändere den Code in *Pages/Index.cshtml* wie folgt: |
| 113 | + |
| 114 | +```cs |
| 115 | +@page "/" |
| 116 | +@using BlazorTetris.Logic |
| 117 | + |
| 118 | +<h1>Tetris</h1> |
| 119 | + |
| 120 | +<table> |
| 121 | + @for (var row = 0; row < ROWS; row++) |
| 122 | + { |
| 123 | + <tr> |
| 124 | + @for (var col = 0; col < COLUMNS; col++) |
| 125 | + { |
| 126 | + <td class="@board[row, col]"></td> |
| 127 | + } |
| 128 | + </tr> |
| 129 | + } |
| 130 | +</table> |
| 131 | + |
| 132 | +@if (lost) |
| 133 | +{ |
| 134 | + <h1>Verloren :-(</h1> |
| 135 | +} |
| 136 | + |
| 137 | +@functions { |
| 138 | + private const int ROWS = 16; |
| 139 | + private const int COLUMNS = 10; |
| 140 | + |
| 141 | + private string[,] board; |
| 142 | + private bool lost = false; |
| 143 | + |
| 144 | + protected override void OnInit() |
| 145 | + { |
| 146 | + InitializeBoard(); |
| 147 | + } |
| 148 | + |
| 149 | + private void InitializeBoard() |
| 150 | + { |
| 151 | + board = new string[ROWS, COLUMNS]; |
| 152 | + board.Iterate((row, col) => board[row, col] = string.Empty); |
| 153 | + } |
| 154 | +} |
| 155 | +``` |
| 156 | + |
| 157 | +* Ändere den Code in *wwwroot/css/site.css* wie folgt: |
| 158 | + |
| 159 | +```css |
| 160 | +table { |
| 161 | + border-collapse: collapse; |
| 162 | + border-spacing: 0; |
| 163 | +} |
| 164 | + |
| 165 | +td { |
| 166 | + width: 25px; |
| 167 | + height: 25px; |
| 168 | + border: 1px solid black; |
| 169 | +} |
| 170 | +``` |
| 171 | + |
| 172 | +* Probiere, das Programm mit *F5* oder *Debug* / *Start Debugging* zu starten. Es müsste ein Kommandozeilenfenster und ein Browser aufgehen. Im Browser solltest du folgendes sehen:<br/> |
| 173 | +  |
| 174 | + |
| 175 | +* Um den Debugger wieder zu beenden, beende das Kommandozeilenfenster. |
| 176 | + |
| 177 | +## Tetris Spielsteine |
| 178 | + |
| 179 | +Jetzt brauchen wir Code für die Tetris-Spielsteine. Hier zwei wichtige Links dazu: |
| 180 | + |
| 181 | +* Eine Liste von Tetris-Spielsteinen und ihrer klassischen Farben findest du unter [https://en.wikipedia.org/wiki/Tetris#Tetromino_colors](https://en.wikipedia.org/wiki/Tetris#Tetromino_colors) |
| 182 | +* Eine Liste von Farbnamen, die der Browser kennt, findest du unter [https://en.wikipedia.org/wiki/Web_colors](https://en.wikipedia.org/wiki/Web_colors) |
| 183 | +
|
| 184 | +* Erstelle eine neue Klasse *Logic/Pieces.cs* und füge folgenden Code ein. Lass dir von jemandem aus dem Mentorenteam den Code erklären. |
| 185 | + |
| 186 | +```cs |
| 187 | +using System; |
| 188 | + |
| 189 | +namespace BlazorTetris.Logic |
| 190 | +{ |
| 191 | + public class Pieces |
| 192 | + { |
| 193 | + // Color of Tetris pieces: https://en.wikipedia.org/wiki/Tetris#Tetromino_colors |
| 194 | + // Web color names: https://en.wikipedia.org/wiki/Web_colors |
| 195 | +
|
| 196 | + public static readonly string __ = string.Empty; |
| 197 | + public static readonly string IC = "I"; |
| 198 | + public static readonly string JC = "J"; |
| 199 | + |
| 200 | + public static readonly string[,] IH = { |
| 201 | + { IC, IC, IC, IC } |
| 202 | + }; |
| 203 | + public static readonly string[,] IV = { |
| 204 | + { IC }, |
| 205 | + { IC }, |
| 206 | + { IC }, |
| 207 | + { IC } |
| 208 | + }; |
| 209 | + public static readonly string[,] JH = { |
| 210 | + { JC, JC, JC, JC }, |
| 211 | + { __, __, __, JC } |
| 212 | + }; |
| 213 | + public static readonly string[,] JV = { |
| 214 | + { __, JC }, |
| 215 | + { __, JC }, |
| 216 | + { __, JC }, |
| 217 | + { JC, JC } |
| 218 | + }; |
| 219 | + public static readonly string[][,] AvailablePieces = new[] { IV, IH, JV, JH }; |
| 220 | + |
| 221 | + public static string[,] GetRandomPiece() |
| 222 | + { |
| 223 | + var random = new Random(); |
| 224 | + return (string[,])AvailablePieces[random.Next(0, AvailablePieces.Length)].Clone(); |
| 225 | + } |
| 226 | + } |
| 227 | +} |
| 228 | +``` |
| 229 | + |
| 230 | +* Wie du siehst, deckt der Code nur zwei Arten von Spielsteinen ab. Ergänze den Rest selbst. Bei Bedarf lass dir von jemandem aus dem Mentorenteam helfen. |
| 231 | + |
0 commit comments