Gra snake niestety bez ciała.

0

Witam ponownie. Zabrałem się dzisiaj za pisanie gry - Snake. Niestety mam pewne problemy z ciałem węża. Chciałbym aby poruszało się za nim. Czy moglibyście dać jakieś wskazówki na ten temat? Oto mój kod:
main.cpp

#include "snake.h"
#include <conio.h>
using namespace std;

int main()
{
    char RUCH;

    SsSnake GAME;
    while (GAME.PLAY())
    {
    GAME.Set_Snake();
    GAME.Show_Map();
    GAME.ruch();
    Sleep(100);
    cls();
    }
    cin.get();
    cin.get();
    return 0;
}

snake.h

#ifndef SNAKE_H_INCLUDED
#define SNAKE_H_INCLUDED

#include <iostream>
#include <windows.h>
#include <ctime>
#include <cstdlib>
#include <conio.h>

using namespace std;
class SsSnake
{
private:
    enum WEZU {Puste_Pole = ' ', Snake = 'o', Nagroda = 'x', Body = 'B'};
    int Size_Snake;
    unsigned int Punkty;
    int x;
    int y;
    int x_award;
    int y_award;
    int level;
    char Move;
    double czas;
    WEZU PLANSZA[21][51];
    int pozx[50];
    int pozy[50];
    void cut_snake();
    int Max_Ciala;
    void Body_Snake();
public:
    SsSnake();
    ~SsSnake() {delete [] pozx; delete [] pozy;}
    void Reset_Map();
    void Show_Map() const;
    void Set_Snake();
    void Set_Award();
    bool PLAY();
    void ruch();
};

void cls();
#endif // SNAKE_H_INCLUDED

snake.cpp

#include "snake.h"

SsSnake::SsSnake() : x(10), y(25), Size_Snake(0), Punkty(0), level(1), czas(0), Max_Ciala(0), Move('w') //konstruktor
{
    Reset_Map();
    Set_Award();
}
void SsSnake::Reset_Map() //resetuje mape
{
    for (int i = 0; i<20;i++)
        for (int j = 0; j<50;j++)
            PLANSZA[i][j] = Puste_Pole;

        for (int i = 0; i< 50; i++)
        {
            pozx[i] = 0;
            pozy[i] = 0;
        }
}
void SsSnake::Show_Map() const //wyswietla mape!
{
    cout << "===SsSnake!=== ";
    cout << "Punkty: "<<Punkty<<" level: "<<level<<" Dlugosc: "<<Size_Snake<<"\n";
    cout << "|-------------------------------------------------|\n";
    for (int i = 0; i<20;i++)
    {
        for (int j = 0; j<50;j++)
        {
            cout << (char) PLANSZA[i][j];
        }
        cout << endl;
    }
    cout << "|-------------------------------------------------|\n";
    cout << "X: "<<x<<" Y: "<<y<<" N: "<<x_award<<" M: "<<y_award<<endl;
}

void SsSnake::Set_Snake() // ustawia pozycje glowy weza
{
    cut_snake();
    PLANSZA[x][y] = Snake;
}
void SsSnake::Set_Award() // ustawia nagrode
{
    srand(time(NULL));
    for (int i = 0; i<20;i++)
        for (int j = 0; j<50;j++)
            if (PLANSZA[i][j] == Puste_Pole)
                {
                x_award = rand() % 20 + 0;
                y_award = rand() % 50 + 0;
                }
    Size_Snake +=1;
    PLANSZA[x_award][y_award] = Nagroda;
}

bool SsSnake::PLAY()
{
        if (x > 20 || y >50 || x<0 || y<0) //Wyjscie poza mape - skucha!
    {
        cout << "Skucha!\nLiczba punktow: "<<Punkty<<"\nLevel:"<<level<<"\nDlugosc Twojego snake: "<<Size_Snake;
        return false;
    }

    for (int i = 0; i<20;i++) //Jesli glowa najedzie na cialo - SKUCHA! CHUJA NIE DZIALA!
    {
        for (int j = 0; j<50;j++)
        {
            if ( false ) //uderzyl w siebie jak to ma dzialac? :O
                {
                    cout << "Ugryzles sie!\nLiczba punktow: "<<Punkty<<"\nLevel:"<<level<<"\nDlugosc Twojego snake: "<<Size_Snake;
                    return false;
                }
        }
    }

    return true;
}

void SsSnake::ruch() //WASD
{
    if (kbhit())
        Move = getch();

    switch(Move)
    {
    case 'A':
    case 'a': y-=1;
        break;
    case 'D':
    case 'd': y+=1;
        break;
    case 'W':
    case 'w': x-=1;
        break;
    case 'S':
    case 's': x+=1;
    }

    if (x == x_award && y == y_award) // ustawia nagrode po zjedeniu jej!
    {
        Punkty = Punkty + 100 + Punkty * 0.1 * level;
        Set_Award();
        if (Size_Snake % level*level == 0)
            level +=1;
    }

    for (int i = 0; i<20;i++)   //zmienia glowe snake na cialo!
        for (int j = 0; j<50;j++)
            if (PLANSZA[i][j] == Snake)
                PLANSZA[i][j] = Body;
}



void SsSnake::cut_snake() // nie dziala
{
    for (int i = 0; i<20;i++){
        for (int j = 0; j<50;j++){
             for (int k = 0; k <=Size_Snake;k++){
            if (PLANSZA[i][j] != Nagroda && PLANSZA[i][j] != PLANSZA[pozx[k]][pozy[k]]){
                PLANSZA[i][j] = Puste_Pole;
            }
            }
        }
    }
}

void SsSnake::Body_Snake() //nie wiem jak ma dzialac..
{
    pozx[Max_Ciala] = x;
    pozy[Max_Ciala] = y;
    if (Max_Ciala == Size_Snake)
        Max_Ciala = 0;
    else
        Max_Ciala++;
}

void cls()
{
   COORD coordScreen = {0,0};
   DWORD cCharsWritten;
   CONSOLE_SCREEN_BUFFER_INFO csbi;
   DWORD dwConSize;
   HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
   GetConsoleScreenBufferInfo(hConsole, &csbi);
   dwConSize = csbi.dwSize.X*csbi.dwSize.Y;
   FillConsoleOutputCharacter(hConsole,(TCHAR)' ',dwConSize,coordScreen,&cCharsWritten);
   GetConsoleScreenBufferInfo(hConsole,&csbi);
   FillConsoleOutputAttribute(hConsole,csbi.wAttributes,dwConSize,coordScreen,&cCharsWritten);
   SetConsoleCursorPosition(hConsole,coordScreen);
}

Proszę tylko o wskazówki postaram się zrobić resztę samemu.
Z góry dziękuje za pomoc! :)

1
  1. lista jednokierunkowa że współrzędnymi ciała (głowa jest końcem).
  2. na każdym kroku dodajesz do głowy i zabierasz z ogona
  3. po zjedzeniu nagrody przez kilka ruchów nie zabierasz z ogona
0

Czy listę jednokierunkową mam porównywać z planszą?
I jak mam z niej usuwać nie potrzebny już ogon?

0

"lista jednokierunkowa że współrzędnymi ciała" - którego słowa nie rozumiesz?

0

Rozumiem już to. Ale kiedy wąż się przesuwa współrzędne się zmieniają. Stare mają być nadpisywane przez nowe tak?

1

Do ciała użyj listy (lepsza by była kolejka, gdyby dało się po niej iterować):

#include <list>

using namespace std;

struct Point
{
  int x, y;
};

...
list<Point> snake;
...

jak poruszasz się do przodu to:
snake.push_front(Point(x, y)); // x,y miejsce (nowe miejsce)
snake.pop_back(); // jesli w danej iteracji polkneles jedzonko to pomin ta linie

jak chcesz narysować całego snake-a od zera (możesz nie malować całego tylko samą głowę i tyłek co kratkę) to tak:

for (list<Point>::iterator it = snake.begin(); it != snake.end(); ++it)
{
  draw_segment(*it); // *it jest typu Point
}

fajnie by było opakować snake-a klasą Snake i dać mu tylko kilka metod:
void move_up()
...
void move_right()
const list<Point>& get_segments() const

0

Dzięki Panowie i Panie! Wprawdzie nie skorzystałem z waszych propozycji w pełni ale bardzo mi pomogliście! :D Może gra nie wygląda cudnie ale uwaga uwaga działa! :)

0
krwq napisał(a):

Do ciała użyj listy (lepsza by była kolejka, gdyby dało się po niej iterować):

#include <list>

using namespace std;

struct Point
{
  int x, y;
};

...
list<Point> snake;
...

jak poruszasz się do przodu to:
snake.push_front(Point(x, y)); // x,y miejsce (nowe miejsce)
snake.pop_back(); // jesli w danej iteracji polkneles jedzonko to pomin ta linie

jak chcesz narysować całego snake-a od zera (możesz nie malować całego tylko samą głowę i tyłek co kratkę) to tak:

for (list<Point>::iterator it = snake.begin(); it != snake.end(); ++it)
{
  draw_segment(*it); // *it jest typu Point
}

fajnie by było opakować snake-a klasą Snake i dać mu tylko kilka metod:
void move_up()
...
void move_right()
const list<Point>& get_segments() const

Ok, ale co z planszą? Tzn. planszę też stworzyć jako listę i tego węża w nią wpisać? Bo ten wąż musi gdzieś się znaleźć... No i jak listę wyświetlić jako tablicę dwuwymiarową, by x i y działało tak jak osie X i Y? Pozdro.

0

Wypełnij tablice dwuwymiarowa, najpierw trawą (całość), później barierką (na krawędziach), następnie iterując wzdłuż węża - "wypełniasz wężem" po czym całość na ekran.

0
_13th_Dragon napisał(a):

Wypełnij tablice dwuwymiarowa, najpierw trawą (całość), później barierką (na krawędziach), następnie iterując wzdłuż węża - "wypełniasz wężem" po czym całość na ekran.

To wiem, ale jak ma przebiegać sam ruch węża? Jak zrobić podążanie każdego osobnego segmentu? Przydałby się jakiś przykładowy kod (łatwiej się z takiego uczyć) - to, co podał krwq nie wystarcza...

1 użytkowników online, w tym zalogowanych: 0, gości: 1