C++ C++ Spielfeld bzw. Rahmen in der Konsole

LimSHulK

Cadet 1st Year
Registriert
Aug. 2015
Beiträge
11
Hallo liebe Community,

ich möchte meine C++ Kenntnisse nun mal testen, indem ich ein kleines SNAKE Spiel in der Konsole schreibe. Also ohne Framework, ohne SDL und wie das ganze alles heisst.

Ich besitze das Buch "C++ für Spieleprogrammierer" von Heiko Kalista und bin mit Kapitel 4 fertig.

Jedoch habe ich ein Problem: Das Spiel braucht logischerweise ein Spielfeld. Dies sollte in etwa so aussehen:

Code:
XXXXX
X   X
X   X
XXXXX
Die Größe möchte ich mit Variablen im Spiel verändern können, also sollten es Variablen wie "int KBreite = " und "int KLeange = " sein

Nur wie mache ich dies ohne das gesamte Spielfeld über cout auszugeben?
 
Wie sonst willst du das Spielfeld ausgeben ohne irgendwelche libraries (ncurses würde sich hier trotzdem anbieten)? Vor allem wenn du das einigermaßen ohne Flacker hinbekommen willst.

Ich denke du musst bei jeder Bewegung der Schlange das komplette Spielfeld via cout neu ausgeben. Mir fällt auf Anhieb keine Funktion für Cursorbewegung in der Standard Library ein.
 
Ich hab mal Snake für die Konsole programmiert, dort sah mein Spielfeld im Code so aus, ach im Vorfeld noch sorry für die scheiß Formatierung, aber per Copy und Paste macht er es leider nicht anders :-( aber müsste trotzdem lesbar sein!:

Code:
/*23 x 15
	A----------B
	|		          |
	|		          |
	|		          |
	C----------D
	*/

	Point A{  0	, 0 };
	Point B{ 22	, 0 };
	Point C{  0	, 14 };
	Point D{ 22	, 14 };
	int h = 0; 
	int w = 0;

//A---B
	for (h = A.y; h <= B.y; h++)
		{
		for (w = A.x; w < B.x; w++)
			{	
			if ((w == 0) || (w == width - 1)) setFieldAtXY(w, h, Field_Type::border, '-');
			else setFieldAtXY(w, h, Field_Type::border, '-');
			}
		}

//A---C

	for (h = A.y; h <= C.y; h++)
		{
		for (w = A.x; w <= C.x ; w++)
			{
			if ((w == 0) || (w == width - 1)) setFieldAtXY(w, h, Field_Type::border, '|');
			else setFieldAtXY(w, h, Field_Type::border, '-');
			}
		
		}

//C---D
	for (h = C.y ; h <= D.y; h++)
		{
		for (w = C.x; w < D.x; w++)
			{
			setFieldAtXY(w, h, Field_Type::border, '-');
			}	
		}

//B---D
		for (h = B.y ; h <= D.y; h++)
			{
			setFieldAtXY(w, h, Field_Type::border, '|');
			}

//Die Ecken
		setFieldAtXY(A.x, A.y, Field_Type::border, '+');
		setFieldAtXY(B.x, B.y, Field_Type::border, '+');
		setFieldAtXY(C.x, C.y , Field_Type::border, '+');
		setFieldAtXY(D.x, D.y , Field_Type::border, '+');


		setFieldAtXY(7, 7, Field_Type::apple);

Die Funktion setFieldAtXY wandelt die xy koordinate in einen index um, den man hätte, wenn das Feld nicht 2-Dimensional (x,y) wäre, sondern eine lange Kette. Das Spielfeld ist also tatsächlich ein Array ;-) und wie schon jemand oben richtig meinte, muss es jeden Durchlauf mit std::cout << neu gezeichnet werden.

Code:
void Grid::setFieldAtXY(int x, int y, Field_Type type, char sign)
	{
	int index = x + (width * y);
	fields[index].fieldType = type; 
	if (type == Field_Type::border) fields[index].sign = sign;
	}
 
Zuletzt bearbeitet:
Naja, wenns nicht portabel sein soll kann man auch platformspezifische Komandos verwenden um an beliebige Stellen in der Konsole zu schreiben.
 
Wie ist das Buch so? Klingt interessant.
 
Ich habe das Kalista-Buch auch mal (durch)gelesen. Für Anfänger ist es eigentlich die beste Lektüre. Er erklärt nie Sprachkonzepte (z.B. eine Schleife) ins Blaue hinein sondern immer an einem konkreten Computerspielbeispiel. Dadurch bleibt vieles sofort hängen. Darüber hinaus hat der Autor einen guten Programmierstil. Das erkennt man finde ich schon daran, dass das Buch zwar auf Deutsch geschrieben ist, der Code jedoch auf englisch ist, da er sagt, dass weltweit der meiste Code in englisch geschrieben wird und man sich das daher schon gleich angewöhnen sollte da es einem später erleichtert fremden Code zu lesen etc. All solche feinen kleinen Tipps stecken drin, daher absolut empfehlenswert
 
Meine letzte C++ Berührung ist schon fast 13 Jahre her deswegen dachte ich mir dass ich da mal wieder reinschnuppern könnte.
 
Das Buch ist sehr zu empfehlen, auch die komplizierteren Dinge sind einfach und verständlich erklärt.

Aber zum Thema:
Die Frage war nicht deutlich gestellt, tut mir leid. Ich hatte Zeitdruck und habe sie noch schnell auf dem Tablet geschrieben.
Ich suche eine Möglichkeit, ein leeres, also sozusagen nur die Umrisse eines Rechtecks bzw. Quadrates, Spielfeld zunächst initialisieren zu können (also intern darstellen), danach prüfen zu können, ob der Schlangenkopf (bei mir genannt: SxPos und SyPos) sich auf der Randlinie (sozusagen "in der Wand" ist) befindet und zuletzt soll das ganze natürlich ausgegeben werden.
Im Anhang ist ein Bild, wie es in etwa aussehen kann. (Der Code ist von http://codereview.stackexchange.com/questions/66481/snake-game-in-c ) SNAKE BEISPIEL.PNG


Falls erwünscht, kann ich gerne noch den bisherigen Code schicken, dieser beinhaltet jedoch so gut wie nichts ausser das bisherige Menü im Switch-Case Stil
 
Zuletzt bearbeitet:
verstehe jetzt dein Problem nicht, der Code den ich dir gezeigt habe macht doch genau das was du willst.
 
Falls die Verwirrung daher kommt: Du prüfst Kollisionen normaler weise nicht dadurch, dass du irgendwelche Zeichen auf der Konsole prüfst. Stattdessen vergleichst du die Koordinaten deiner Schlange einfach mit der Größe des Spielfelds. Generell sollte die gesamte Spiellogik komplett unabhängig von der Ausgabe erfolgen.
 
Zurück
Oben