1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
|
#include <windows.h>
#include <conio.h> // für _getch()
#include <fstream>
using namespace std; // Namensraum in fstream
// Höhe und Breite des Spielfedes
#define HEIGHT 10
#define WIDTH 20
// Prototypen
//
// Cursor sichtbar|unsichtbar machen bzw. Größe einstellen
void setCursorInfo(bool bVisible, DWORD CursorSize);
// Cursorposition bestimmen
void gotoxy(int x, int y);
// Gibt nach eingabe von w,a,s,d die aktuelle Cursorposition zurück
COORD aktCursorPos(char chAuswahl, COORD CursorPos);
// Schreibt je nach Auswahl an der aktuellen Cursorposition das bestimmte Zeichen
// in das CHAR_INFO Array
CHAR_INFO setGround(char chAuswahl, COORD CursorPos, CHAR_INFO Ground[HEIGHT][WIDTH]);
// Zeichnet das CHAR_INFO Array in den ConsoleScreenBuffer und setzt die Cursorposition
// dahin wo zuletzt gezeichnet wurde
void zeichneGround(CHAR_INFO Ground[HEIGHT][WIDTH], COORD CursorPos);
// Schreibt einen Text aus einem char Array mit der angegebenen Satzlänge an die
// Position xy
void writeText(unsigned short int x, unsigned short int y, const char* lpBuffer, DWORD nNumberOfChars );
// zeichneInfo fasst die writeText Funktionen für die Ausgabe der Auswahlmöglichkeiten
// zusammen
void zeichneInfo();
// saveMap speichert das CHAR_INFO Array in eine Datei mit dem Dateinamen aDateiname
int saveMap( CHAR_INFO Ground[HEIGHT][WIDTH], char aDateiname[] );
// Das Hauptprogramm
//
int main ()
{
setCursorInfo(TRUE, 100);
// Deklarierung des CHAR_INFO Arrays für das Spielfeld
CHAR_INFO Ground[HEIGHT][WIDTH];
// Diese for-Schleife füllt das Spielfeld damit eine einheitliche
// blaue Fläche angezeigt wird
for(int i=0; i<HEIGHT; i++)
{
for(int j=0; j<WIDTH; j++)
{
Ground[i][j].Attributes = BACKGROUND_BLUE;
Ground[i][j].Char.AsciiChar = ' ';
}
}
// Deklaration und Zuweisung der Variablen CursorPos und chAuswahl
COORD CursorPos = {0,0}; // Die Cursor Position
char chAuswahl = 0; // Eine Variable für die Auswahl
// Diese do-while Schleife läuft solange bis 6 für beenden gedrückt wurde
// und verzweigt je nach Auswahl auf die einzelnen Funktionen
do
{
if( chAuswahl == 'w' || chAuswahl == 'a' ||
chAuswahl == 's' || chAuswahl == 'd' )
{
// Cursorposition aktuallisieren
CursorPos = aktCursorPos(chAuswahl, CursorPos);
}
else if( chAuswahl == '1' || chAuswahl == '2' ||
chAuswahl == '3' || chAuswahl == '4' )
{
// Spielfeld besetzen
Ground[CursorPos.Y][CursorPos.X] = setGround(chAuswahl, CursorPos, Ground);
}
else if( chAuswahl == '5' )
{
// Map speichern
saveMap(Ground, "PacmanMap");
}
// Die Auswahlmöglichkeiten ausgeben
zeichneInfo();
// Das Spielfeld ausgeben
zeichneGround(Ground, CursorPos);
// Abfrage der Auswahlmöglichkeiten
chAuswahl = _getch();
} while (chAuswahl != '6');
setCursorInfo(FALSE, 1);
gotoxy(0,HEIGHT+2);
return 0;
} // ENDE von main
// Beschreibung s.o.
void setCursorInfo(bool bVisible, DWORD CursorSize)
{
HANDLE hConOut = GetStdHandle( STD_OUTPUT_HANDLE );
CONSOLE_CURSOR_INFO CursorInfo;
CursorInfo.bVisible = bVisible;
CursorInfo.dwSize = CursorSize;
SetConsoleCursorInfo( hConOut, &CursorInfo );
}
// Beschreibung s.o.
void gotoxy(int x, int y)
{
HANDLE hConsoleOutput = GetStdHandle( STD_OUTPUT_HANDLE );
COORD CursorPos = {x,y};
SetConsoleCursorPosition ( hConsoleOutput, CursorPos );
}
// Beschreibung s.o.
COORD aktCursorPos(char chAuswahl, COORD CursorPos)
{
switch(chAuswahl)
{
case 'w': // hoch
if(CursorPos.Y > 0)
CursorPos.Y--;
break;
case 'a': // links
if(CursorPos.X > 0)
CursorPos.X--;
break;
case 's': // runter
if(CursorPos.Y < HEIGHT-1)
CursorPos.Y++;
break;
case 'd': // rechts
if(CursorPos.X < WIDTH-1)
CursorPos.X++;
break;
}
return CursorPos;
}
// Beschreibung s.o.
CHAR_INFO setGround(char chAuswahl, COORD CursorPos, CHAR_INFO Ground[HEIGHT][WIDTH])
{
switch(chAuswahl)
{
case '1': // Wand
Ground[CursorPos.Y][CursorPos.X].Char.AsciiChar = ' ';
Ground[CursorPos.Y][CursorPos.X].Attributes = BACKGROUND_BLUE | BACKGROUND_INTENSITY;
// Erkennungstöne für Wand
Beep(50,50);
Beep(70,50);
break;
case '2': // Punkt
Ground[CursorPos.Y][CursorPos.X].Char.AsciiChar = 7;
Ground[CursorPos.Y][CursorPos.X].Attributes = FOREGROUND_GREEN | FOREGROUND_INTENSITY;
// Erkennungstöne für Punkt
Beep(250,50);
Beep(300,50);
break;
case '3': // Diamant
Ground[CursorPos.Y][CursorPos.X].Char.AsciiChar = 4;
Ground[CursorPos.Y][CursorPos.X].Attributes = FOREGROUND_GREEN | FOREGROUND_INTENSITY;
// Erkennungstöne für Diamant
Beep(550,50);
Beep(500,50);
Beep(550,50);
Beep(500,50);
break;
case '4': // Leer
Ground[CursorPos.Y][CursorPos.X].Char.AsciiChar = ' ';
Ground[CursorPos.Y][CursorPos.X].Attributes = 0;
break;
}
// Gibt das aktuallisierte Feld zurück
return Ground[CursorPos.Y][CursorPos.X];
}
// Beschreibung s.o.
void zeichneGround(CHAR_INFO Ground[HEIGHT][WIDTH], COORD CursorPos)
{
HANDLE hConOut = GetStdHandle( STD_OUTPUT_HANDLE );
COORD GroundSize = {WIDTH,HEIGHT};
COORD upperLeft = {0,0};
SMALL_RECT rect = {0,0,80,24};
WriteConsoleOutputA( hConOut, &Ground[0][0], GroundSize, upperLeft, &rect );
SetConsoleCursorPosition( hConOut, CursorPos );
}
// Beschreibung s.o.
void writeText(unsigned short int x, unsigned short int y, const char* lpBuffer,
DWORD nNumberOfChars )
{
HANDLE hConsoleOutput = GetStdHandle( STD_OUTPUT_HANDLE );
SetConsoleTextAttribute( hConsoleOutput, FOREGROUND_GREEN | FOREGROUND_INTENSITY );
COORD CursorPos = {x,y};
SetConsoleCursorPosition ( hConsoleOutput, CursorPos );
WriteConsoleA( hConsoleOutput, lpBuffer, nNumberOfChars, NULL, NULL );
}
// Beschreibung s.o.
void zeichneInfo()
{
const char Text1[] = "1 - Mauer";
const char Text2[] = "2 - Punkt";
const char Text3[] = "3 - Diamant";
const char Text4[] = "4 - Leer";
const char Text5[] = "5 - Map speichern";
const char Text6[] = "6 - Beenden";
writeText(WIDTH+1,0,&Text1[0],sizeof(Text1));
writeText(WIDTH+1,2,&Text2[0],sizeof(Text2));
writeText(WIDTH+1,4,&Text3[0],sizeof(Text3));
writeText(WIDTH+1,6,&Text4[0],sizeof(Text4));
writeText(WIDTH+1,8,&Text5[0],sizeof(Text5));
writeText(WIDTH+1,10,&Text6[0],sizeof(Text6));
}
// Beschreibung s.o.
int saveMap( CHAR_INFO Ground[HEIGHT][WIDTH], char aDateiname[] )
{
// Öffnen einer Datei zum schreiben im Binärmodus
ofstream Output (aDateiname,ios::binary);
if (Output == NULL)
{
// Fehlermeldung wenn die Datei nicht geöffnet werden konnte
const char Text[] = "Fehler! Datei konnte nicht geoeffnet werden.";
writeText(0,HEIGHT+1,&Text[0],sizeof(Text));
return 3;
}
// Diese for-Schleife schreibt die einzelnen Zeichen in die PacmanMap Datei
for(int i=0; i<HEIGHT; i++)
{
for(int j=0; j<WIDTH; j++)
{
Output.write ((char*) &Ground[i][j], sizeof(Ground[i][j]));
}
}
const char Text[] = "Datei wurde gespeichert!";
writeText(0,HEIGHT+1,&Text[0],sizeof(Text));
// kurz warten...
DWORD Zeit = GetTickCount()/1000+2;
while(GetTickCount()/1000<=Zeit){}
// Die Nachricht "Datei wurde gespeichert!" wieder vom Screen entfernen
const char Text1[] = " ";
writeText(0,HEIGHT+1,&Text1[0],sizeof(Text1));
// Schließen der Datei
Output.close ();
return 0;
}
|