Brauche Hilfe bei einfachem Snake !

Friedfischer

Grünschnabel
Hallo!
Ich bin schon so weit, dass ich bei einem ganz einfachen Snake, die Schlange bewegen kann, und sie auch das mach, was sie machen soll. Nur habe ich jetzt noch genau 2 Probleme:

Wie kann ich, nachdem die Schlange einen Punkt gefressen hat, einen neuen setzen?
Wie kann ich das Spiel abbrechen, wenn sie sich selber frisst?
Wenn ich nach z.B. links lenke, kann ich wieder nach rechts lenken, und sie dreht um...

Müsste es bis Mittwoch schaffen.
Bitte helft mir so, dass auch ich es schaffe ;-)

Ich danke euch sehr im Voraus!
Ich weiß, dass ich hier jetzt viel verlange, aber ich möchte es auch kapieren, wies wirklich geht!
Wenn jemand so freundlich ist, und mir hilft :D , dann soll es bitte nur so unkompliziert als möglich sein!
Ich sag es immer wieder, aber Danke im Voraus!
Hier ist das, was ich bis jetzt habe:

C++:
#include <iostream>
#include <conio>
#include <cstdio>
#include <iomanip>
#include <cdos>
#include <cstdlib>
#include <cstring>
#include <vcl>
#include <ctime>
#pragma hdrstop
#pragma argsused

//------------------------- Variblendeklaration -------------------------------
HANDLE console_output = GetStdHandle(STD_OUTPUT_HANDLE);
int zahl1, zahl2;
void snake_show(void);
void DrawFrame(int x1,int y1,int x2,int y2,int line);
struct snake_pos
{
    int x_pos;
    int y_pos;
    char sign;
};

int dx=1, dy=0, x=30, y=10;
void snake_move(int xdir, int ydir, snake_pos snake2[]);
snake_pos snake1[]={{x,y,'\x20'},
                    {x+1,y,'\xB1'},
                    {x+2,y,'\xB1'},
                    {x+3,y,'\xB1'},
                    {x+4,y,'\xB1'},
                    {x+5,y,'\xDB'}};

//-------------------------- Unterprogramme ----------------------------------
void DrawFrame(int x1,int y1,int x2,int y2, int line)
{
   int temp;
   if (x1>x2)
   {
      temp=x1;
      x1=x2;
      x2=temp;
   }
   if (y1>y2)
   {
      temp=y1;
      y1=y2;
      y2=temp;
   }

   if (line==2)
   {
      gotoxy(x1,y1);
      cout<<'\xC9'<<setw(x2-x1)<<setfill('\xCD')<<'\xBB';
      gotoxy(x1,y2);
      cout<<'\xC8'<<setw(x2-x1)<<setfill('\xCD')<<'\xBC';
      for (int i=y1+1;i<=y2-1;i++)
      {
         gotoxy(x1,i);
         cout<<'\xBA';
         gotoxy(x2,i);
         cout<<'\xBA';
      }
   }
}


void snake_show(void)
{
    for(int i=0; i<6;i++)
    {
        gotoxy(snake1[i].x_pos,snake1[i].y_pos);
        cout<<snake1[i].sign;
    }

}

void snake_move(int xdir, int ydir, snake_pos snake2[])
{
    snake2[5].x_pos+=xdir;
    snake2[5].y_pos+=ydir;
    for(int i=0; i<5; i++)
    {
        snake2[i].x_pos=snake2[i+1].x_pos;
        snake2[i].y_pos=snake2[i+1].y_pos;
    }
}

//--------------------------------Hauptprogramm---------------------------------

int main(int argc, char* argv[])
{
    clrscr();
    _setcursortype(_NOCURSOR);
    SetConsoleTextAttribute(console_output,14);
    DrawFrame(1,1,80,22,2);

    time_t sekunden = time(NULL);
    tm *uhr = localtime(&sekunden);
    SetConsoleTextAttribute(console_output,7);
    gotoxy(2,23);
    cout <<"Startzeit: "<<uhr->tm_hour<<":"<<uhr->tm_min<<":"<<uhr->tm_sec<<" Uhr";
    gotoxy(2,25);
    cout <<"Datum:     "<<uhr->tm_wday+25<<"."<<uhr->tm_mon+1<<"."<<uhr->tm_year+1900;

    do
    {
        randomize();

        do
        {
            zahl1 = random(78);
            zahl2 = random(22);
            gotoxy(zahl1,zahl2);
        }
        while(zahl1<2||zahl2<2);
        SetConsoleTextAttribute(console_output, 12);
        cout<<"O";
        SetConsoleTextAttribute(console_output, 10);
        for(int k=0; k<1; k++)
        {
            k--;
            Sleep(200);
            if(kbhit())
            {

                switch(getch())
                {
                    case 77:  dx=1; dy=0;  break;
                    case 75:  dx=-1; dy=0; break;
                    case 72:  dx=0;  dy=-1;break;
                    case 80:  dx=0;  dy=1; break;
                }
            }

            gotoxy(1,25);
            snake_move(dx,dy,snake1);     snake_show();

            if(snake1[5].x_pos>=80 | snake1[5].x_pos<=1 | snake1[5].y_pos>=22 | snake1[5].y_pos<=1)
            {
                gotoxy(30,10);
                cout<<"GAME OVER !";
                break;
            }
        }
    }
    while(getch()!='q');
    return 0;
}
 
Zuletzt bearbeitet:

Wie kann ich, nachdem die Schlange einen Punkt gefressen hat, einen neuen setzen?
Wie kann ich das Spiel abbrechen, wenn sie sich selber frisst?
Wenn ich nach z.B. links lenke, kann ich wieder nach rechts lenken, und sie dreht um...

Müsste es bis morgen schaffen.
Bitte helft mir so, dass auch ich es verstehe, da ich noch kein Profi bin.

Danke im Voraus ! :)
 
Zuletzt bearbeitet:
Ich gehe mal davon aus, daß mit
Code:
randomize();
 
        do
        {
            zahl1 = random(78);
            zahl2 = random(22);
            gotoxy(zahl1,zahl2);
        }
        while(zahl1<2||zahl2<2);
        SetConsoleTextAttribute(console_output, 12);
        cout<<"O";
dieser Punkt gesetzt wird, den die Schlange fressen soll. Wenn sie also mit ihrem Kopf (also ihrer Position) auf den Koordinaten dieses Punktes steht, dann reicht es, die oben angeführten Zeilen erneut auszuführen, um einen neuen Punkt zu setzen.
Allerdings solltest du dann noch beim Setzen des neuen Punktes sicherstellen, daß er nicht an einen Punkt gesetzt wird, an dem die Schlange schon war.

Was das Problem mit dem Umkehren der Schlange angeht:
Ich würde mir einfach in der main()-Schleife eine Variable anlegen, in der ich den letzten Tastendruck des Spielers speicher. Diesen könnte ich einfach im Bewegungsswitch abfragen und entsprechend reagieren:
Code:
int lastKey = 0;
for(int k=0; k<1; k++)
        {
            k--;
            Sleep(200);
            if(kbhit())
            {
 
                switch(getch())
                {
                    case 77:  if (lastKey == 75)
                                     gameover();
                                   else
                                   {
                                      lastKey = 77;
                                      dx=1; 
                                      dy=0;  
                                   }
                                   break;
                    case 75:  if (lastKey == 77)
                                     gameover();
                                   else
                                   {
                                      lastKey = 75;
                                      dx=-1; 
                                      dy=0;  
                                   }
                                   break;
                    case 72:  if (lastKey == 80)
                                     gameover();
                                   else
                                   {
                                      lastKey = 72;
                                      dx=0; 
                                      dy=-1;  
                                   }
                                   break;
                    case 80:  if (lastKey == 72)
                                     gameover();
                                   else
                                   {
                                      lastKey = 80;
                                      dx=0; 
                                      dy=1;  
                                   }
                                   break;
                }
            }
 
            gotoxy(1,25);
            snake_move(dx,dy,snake1);     snake_show();
 
            if(snake1[5].x_pos>=80 | snake1[5].x_pos<=1 | snake1[5].y_pos>=22 | snake1[5].y_pos<=1)
            {
                gotoxy(30,10);
                cout<<"GAME OVER !";
                break;
            }
        }

Was den letzten Punkt angeht: Das ist eigentlich das echte Kernproblem des Spiels. Ob die Schlange sich selbst erwischt hat oder nicht, muß irgendwie abgefragt werden. Dazu gäbe es theoretisch zwei Möglichkeiten:
1. Vor dem Setzen eines Schlagenzeichens (Kopf, Körper, Schwanz) fragst du ab, ob an den Koordinaten des neu zu zeichnenden Punktes bereits ein Schlangenkörper oder Schwanz vorhanden ist. Wenn ja -> Game Over.
2. Du merkst dir die Schlangenbewegungen in einem Array, was dann nichts anderes darstellt, als eine Speicherabbildung des Bildschirms. In dem Array könntest du für jedes von der Schlange schon besuchte Feld einen Wert hinterlegen. Beim Neuzeichnen schaust du, ob an der neuen Position im Array schon ein Wert vorhanden ist. Wenn ja -> Game Over.

Ich persönlich würde Methode 2 wählen, da sich damit dann auch leicht das Problem mit dem Neuzeichnen eines Punktes, nachdem der alte gefressen wurde, auf einem Feld, welches noch nicht von der Schlange belegt ist, erledigen ließe.

Ich hoffe, ich konnte etwas helfen.
 
Vielen Dank!
Geholfen hast du mir, auch, wenn ich es gestern von allein geschafft habe. jedoch ist deines "stylischer" und unkomplizierter. Danke!
 

Neue Beiträge

Zurück