Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

1

24.09.2015, 15:44

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

Hallo,


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.


Dazu suche ich 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 vonhttp://codereview.stackexchange.com/...nake-game-in-c )



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.
»LimSHulK« hat folgendes Bild angehängt:
  • SNAKE BEISPIEL.PNG

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

2

24.09.2015, 15:48

Nun, die Randlinien sind ja nichts weiter als spezielle x/y Koordinaten, die nicht über-/unterschritten werden dürfen. Ein Spielfeld selbst wirst Du vermutlich gar nicht brauchen als interne Repräsentation, sondern nur Koordinaten für das Futter und für die Teile der Schlange.
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

Schorsch

Supermoderator

Beiträge: 5 145

Wohnort: Wickede

Beruf: Softwareentwickler

  • Private Nachricht senden

3

24.09.2015, 16:04

Geht es jetzt um die Darstellung in der Konsole oder wirklich um die interne Darstellung in deinem Code?
Für letzteres könntest du einfach ein Array nehmen (falls du schon kennst, einen std::vector) und darin die einzelnen Zellen deines Spielfeldes speichern. Um das ganze für den Anfang etwas einfacher zu machen könntest du ein zweidimensionales Array benutzen wobei die Indizes dann jeweils für X- und Y-Koordinate auf deiner Karte stehen. Die Werte die dieses Array speichern könnte wären im simpelsten Falle Boolean Werte, also einfach nur true und false. True könnte dann bedeuten dass sich an dieser Stelle ein Wandstück befindet und false dass diese Stelle leer ist. Die Kollision kannst du jetzt recht einfach testen indem du vor einer Bewegung prüfst ob das Feld noch frei ist. Wie gesagt, wenn du schon std::vector kennst dann kannst du auch einen zweidimensionalen std::vector nehmen, also einen std::vector<std::vector<bool>>. Das ganze geht auch mit einem eindimensionalen Array/Vector. Stell dir einfach vor die Zeilen stehen alle nacheinander im Array. Wenn du X-, Y-Koordinate sowie Breite deiner Karte kennst kannst du relativ einfach zum Index in dem Array/Vector umrechnen. Kannst ja mal selbst überlegen wie das wohl ginge. Vielleicht einfach mal aufmalen und überlegen, bzw an Beispielkoordinaten prüfen ob du irgendwo einen Zusammenhang siehst.
Für ersteres gibt es Bibliotheken die dir da helfen. NCurses wäre da ein Beispiel wobei es die soweit ich weiß nicht für Windows gibt. Da sollte es aber Alternativen geben die mit Google sicher gut zu finden sind.

edit: In diesem Fall hat BlueCobold natürlich recht. Solange dein Spielfeld nur ein Rechteck ist reicht es aus Breite und Höhe zu kennen. Mein Vorschlag wird erst interessant sobald du Mauern und Hindernisse innerhalb der Karte haben möchtest. Das ganze nennt sich übrigend Tilemap.
„Es ist doch so. Zwei und zwei macht irgendwas, und vier und vier macht irgendwas. Leider nicht dasselbe, dann wär's leicht.
Das ist aber auch schon höhere Mathematik.“

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

4

24.09.2015, 16:47

Für letzteres könntest du einfach ein Array nehmen (falls du schon kennst, einen std::vector) und darin die einzelnen Zellen deines Spielfeldes speichern.
Für was denn? Ein Snake hat nur Wände an den Rändern und ist dazwischen vollständig begehbar. Da braucht man gar keinen Array und keine Karte.
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

Schorsch

Supermoderator

Beiträge: 5 145

Wohnort: Wickede

Beruf: Softwareentwickler

  • Private Nachricht senden

5

24.09.2015, 17:25

Für was denn? Ein Snake hat nur Wände an den Rändern und ist dazwischen vollständig begehbar. Da braucht man gar keinen Array und keine Karte.

In der klassischen Variante ja. Es gibt aber einige Snake Versionen welche Hindernisse auf der Karte haben. Teilweise auch Karten aufgebaut wie bei Pacman. Auf Nokia Handys gab es zum Beispiel früher mal Snake2 welches solche Karten hatte. Da reicht dann eine einfache Begrenzung der Karte nicht aus.
„Es ist doch so. Zwei und zwei macht irgendwas, und vier und vier macht irgendwas. Leider nicht dasselbe, dann wär's leicht.
Das ist aber auch schon höhere Mathematik.“

6

24.09.2015, 19:17

Erstmal danke an Euch beide.
Da ich die std::vektor (das std:: kann man doch weg lassen, wenn man am Anfang des Codes using namespace std; schreibt, oder?) Arrays noch nicht kenne, habe ich mich an der Methode mit 2 - dimensionalen Arrays versucht. Dazu mein Code (hierfür Unwichtiges wurde weggelassen):

Quellcode

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
//Funktionsprototypen
void initk();   //Karte initialisieren

...
...
...

//Kartenkonstanten
const int KHoehe = 20;
const int KBreite = 20;

struct S_Karte
{
    bBesetzt;
};
S_Karte Karte[KBreite][KHoehe];
.........

void initk() //Karte initialisieren
{
    for (int y = 0; y < KHoehe; y++)
    {
        for (int x = 0; x < KBreite; x++)
        {
            Karte[x][y].bBesetzt = false;
        }
    }
}


Damit ist jedes Feld als bBesetzt = false ; also als nicht besetzt makiert, oder?
Nun die Frage: Wie besetze ich die Randfelder? Also wie kann ich 1. einzelne Felder eines Arrays als besetzt makieren (also die Randfelder); 2. auf diese Felder zurückgreifen (schnell gesagt: "if der Schlangenkopf befindet sich auf einem bBesetzt = false Feld des Arrays S_Karte Karte[KBreite][KHoehe], dann Zeige "Game Over")?

7

24.09.2015, 19:40

1. einzelne Felder eines Arrays als besetzt makieren (also die Randfelder);

Am einfachsten wäre wohl eine if-Abfrage um Karte[x][y].bBesetzt = false; herum zu bauen, wenn Feld == Rand dann Karte[x][y].bBesetzt = true;
Dazu musst du dir natürlich überlegen was alles die Randfelder sind und dieses dann Logisch verknüpfen.

2. auf diese Felder zurückgreifen

Das machst du ja schon in dem von dir geposteten Code Karte[x][y].bBesetzt wenn du wissen willst ob sich da der Kopf der Schlange befindet must du die Schlangenkopf-Koordinaten einsetzten und kannst prüfen ob dieses Feld schon besetzt ist.

Übrigens:

C-/C++-Quelltext

1
2
3
4
struct S_Karte
{
    bBesetzt;
};

Da fehlt was.
Wer aufhört besser werden zu wollen hört auf gut zu sein!

aktuelles Projekt:Rickety Racquet

MitgliedXYZ

Alter Hase

Beiträge: 1 369

Wohnort: Bayern

  • Private Nachricht senden

8

24.09.2015, 19:41

Die Spielfeld Begrenzungsfelder sollten so durchlaufbar sein:

C#-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public void randfelderAlsBesetztMarkieren()
{
for (int x = 0; x < spielfeldBreite; x++)
{
//Den oberen Rand als besetzt markieren
Karte[x][0].besetzt = true;

//Den unteren Rand als besetzt markieren
Karte[x][spielfeldHoehe - 1] = true;
}

for (int y = 0; y < spielfeldHoehe; y++)
{
//Den linken Rand als besetzt markieren
Karte[0][y].besetzt = true;

//Den rechten Rand als besetzt markieren
Karte[spielfeldBreite - 1][y].besetzt = true;
}
}

9

24.09.2015, 20:32

Super, ich danke euch!

Die Besetzung des Randes funktioniert mit den for-Schleifen sehr gut und ich habe es verstanden, besser geht es nicht :)
Zudem habe ich die Arrays jetzt einigermaßen drauf.

Da fehlt was.
Habe ich wohl vergessen zu kopieren, das bool stand in der Datei genau da wo es sollte :)

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

10

24.09.2015, 20:41

Statt rohen Arrays wäre std::array definitiv besser.
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

Werbeanzeige