Wątek zablokowany 2015-11-04 17:38 przez dzek69.

Gra typu snake - czy ten kod ma sens ?

0

Próbowałem snake napisać tak:

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

using namespace std;

class Plansza
{
private:
    char sciana = 219;

public:
    char tablica[23][70];

    void wypelnij()
    {
        for(int i = 0; i < 23; i++)
        {
            for(int j = 0; j < 70; j++)
            {
                tablica[i][j] = 0;
            }
        }

        for(int j = 0; j < 70; j++)
        {
            tablica[0][j] = sciana;
        }

        for(int i = 1 ; i < 23; i++)
        {
            tablica[i][0] = sciana;
            tablica[i][69] = sciana;
        }

        for(int j = 0; j < 70; j++)
        {
            tablica[22][j] = sciana;
        }
    }
    void rysuj() const
    {
        for(int i = 0; i < 23; i++)
        {
            for(int j = 0; j < 70; j++)
            {
                cout << tablica[i][j];
            }
            cout << endl;
        }
    }
};
class segment
{
public:
    int x,y;

    segment(int x, int y) : x(x), y(y) {}
};
class waz
{
public:
    vector<segment>tab;
    char znak = 219;
};

class Jedzenie
{
public:
    char znak = '@';
    int poz_x;
    int poz_y;
    Jedzenie(int x, int y) : poz_x(x), poz_y(y) {};
};

int main()
{
    Plansza mapa;
    Jedzenie jablko(40,15);
    mapa.wypelnij();
    mapa.tablica[jablko.poz_y][jablko.poz_x] = jablko.znak;

    waz Waz;
    segment pierwszy(39,15);
    Waz.tab.push_back(pierwszy);
    mapa.tablica[Waz.tab[0].y][Waz.tab[0].x] = Waz.znak;
    mapa.rysuj();
    char c = 'w';
    int a;
    int b;
    int d;
    int e;

    for(int j = 0;  ; ++j)
    {

        if(kbhit())
        {
            c = getch();
        }
        for(int i = 0; i < Waz.tab.size(); ++i)
        {
            mapa.tablica[Waz.tab[i].y][Waz.tab[i].x] = ' ';

            if(i >= 1)
            {
                d = Waz.tab[i].y;
                e = Waz.tab[i].x;
                Waz.tab[i].y = a;
                Waz.tab[i].x = b;
                mapa.tablica[Waz.tab[i].y][Waz.tab[i].x] = Waz.znak;
            }

                a = Waz.tab[i].y;
                b = Waz.tab[i].x;
                if(i >=1)
                {
                       swap(d,a);
                swap(e,b);
                }


            if(i == 0)
            {
                switch(c)
                {
                case 's' :
                    Waz.tab[0].y++;
                    break;
                case 'w' :
                    Waz.tab[0].y--;
                    break;
                case 'a' :
                    Waz.tab[0].x--;
                    break;
                case 'd' :
                    Waz.tab[0].x++;
                    break;
                }
                mapa.tablica[Waz.tab[i].y][Waz.tab[i].x] = Waz.znak;
            }

            if(Waz.tab[0].y == jablko.poz_y && Waz.tab[0].x == jablko.poz_x)
            {
                srand(time(NULL));
                Waz.tab.push_back(segment(b,a));
                jablko.poz_y = rand() % 21 + 1;
                jablko.poz_x = rand() % 68 + 1;
                mapa.tablica[jablko.poz_y][jablko.poz_x] = jablko.znak;
//                break;
            }

        }
        system("cls");
        mapa.rysuj();
    }

    return 0;
}
 
1

Wymaga nie jednej poprawki :-) Właśnie to skompilowałem (GCC 4.8.1) i jest tak. Cały ekran miga a to jest niemal nie do zniesienia, czyścisz cały ekran a potem znowu wszystko jest rysowane od nowa? Ze dwa razy wywaliło się na jakimś unhandled Win32 exception jak tym wężem poszedłem w dół. Pomijając już to że stosujesz WSAD zamiast sterowania strzałkami a tak było by lepiej, czyż nie lepiej by było rysować tylko tego węża i w razie zmiany położenia poprzednie pola po prostu kasować (tzn. wystarczy wstawienie choćby spacji w tym przypadku). Tą grę o wiele lepiej by było zrealizować w formie aplikacji desktopowej dla Windows. Kto będzie grał teraz z poziomu konsoli?

0

W code::block wąż chodzi. Nie wiem właśnie jak zastąpić te odświeżanie ekranu tak aby tylko tam gdzie wąż jest ten ekran się odświeżał, ale chyba tak nie można.

0

oczywiscie ze mozna. Zamiast odswiezac caly czas na nowo to po prostu zmieniaj te elementy ktore sie zmienily.

Musisz uzyc albo SetCursorPosition z winApi albo ncurses.

0

fasadin, a jak reszta kodu ?

1
  1. main za duzy
  2. raz uzywasz vectora raz tablicy. Plansza tez powinna uzywac vectora
  3. magic numbers
  4. segment? To chyba powinno byc nazwane inaczej. http://sjp.pwn.pl/sjp/segment;2575048.html powinno nazwac sie wspolrzedne
  5. raz klasy nazwane raz z malej. Jaki masz codestyle wkoncu?
  6. dziwna zaleznosc klasy jedzenie. Czemu jedzenie ma poz_x a nie segment? (aka wspolrzedne)
  7. fora raczej nie uzywa sie do nieskonczonej petli, raczej sie uzywa do tego while
  8. nazywanie zmiennych... a b c d d e s awasd. Niech one mowia co robia
  9. dziwne formatowanie. (nie masz zadnej reguly co do formatowania kodu)
  10. do losowania nie powinno sie uzywac juz srand powinno sie uzywac tego http://www.cplusplus.com/reference/random/
  11. zamiast czyscic i rysowac od poczatku rysuj tylko to co sie zmienilo.
  12. wyrzucaj zakomentowany kod. Jezeli Ci potrzebny jest (zebys nie zapomnial) to zacznij uzywac kontroli wersji (np github)
0
nowicjusz35 napisał(a):

W code::block wąż chodzi. Nie wiem właśnie jak zastąpić te odświeżanie ekranu tak aby tylko tam gdzie wąż jest ten ekran się odświeżał, ale chyba tak nie można.

Po prostu ten wąż ma np. kilka segmentów. I jak się przesunie np. w prawo, to ostatni jego segment zastępujesz po prostu spacją i tak co każdy krok kolejno. To po prostu takie zamazywanie. Tak ogólnie to już sam print w takiej aplikacji konsolowej diabelsko obciąża pod względem wydajności taką appkę. Po co masz na nowo obrysowywać (a właściwie to robić print) całej planszy kiedy ta się nie zmienia? Robisz zmiany tylko na tym wężu a ostatnie segmenty (ogon) po prostu zamazujesz spacjami co kolejny krok.

1

@nowicjusz35 - zasada przesuwania węża jest bardzo prosta, tym bardziej, jeśli obsługa węża jest podstawowa i nie ma żadnych dodatkowych efektów; Podstawa to trzymanie współrzędnych dwóch modułów - głowy oraz ogona, a także bieżącego kierunku, w którym głowa węża podąża;

Po każdej "klatce" pobierasz z bufora klawisz - jeśli istnieje, dokonujesz translacji klawisza na kierunek; Następnie obliczasz nowe współrzędne głowy węża na podstawie uzyskanego kierunku; Jeżeli pole, na które ma wejść głowa węża jest wolne - przestawiasz współrzędne głowy, pozostałych modułów i ogona; Jeżeli jest to murek lub moduł węża - następuje koniec gry; Jeśli jest to moduł z jedzeniem, dodajesz nowy moduł do ciała węża;

I teraz tak - jeśli głowa wlazła w murek lub w moduł ciała węża, kończysz rozgrywkę; Jeżeli pole jest puste, przerysowujesz tylko trzy moduły - głowy (w nowym miejscu), karku (modułu za głową, aby nadpisać znak głowy w poprzedniej klatce) oraz ogona (nadpisując przedostatni moduł węża), a na koniec wypisujesz znak spacji w miejscu, gdzie w poprzedniej klatce był ogon; Czyli w każdej klatce rysujesz 4 znaki, a nie wszystkie jakie widać na ekranie konsoli;

Jeżeli głowa wchodzi w miejsce jedzenia, to wystarczy przerysować dwa moduły - głowy i karku, bo moduł ogona pozostaje w tej samej pozycji; W takim przypadku rysujesz tylko dwa znaki, a trzecim jest znak jedzenia, który rysujesz w wylosowanym nowym miejscu na planszy;
____Sam pisałem takią gierkę (która jeszcze pełną gierką nie jest, ale pograć można); Węża zrobiłem jako tablicę, gdzie element o indeksie 0 to głowa, a ostatni to ogon; Po zjedzeniu kulki (czy co tam masz) przesuwa się ostatni element o jedno miejsce dalej w tablicy; Każdy moduł posiada swój typ (u mnie to enum) oraz współrzędne, które po każdym ruchu są przepisywane; Dzięki temu przy losowaniu miejsca na jedzonko można łatwo sprawdzić, czy nowa pozycja znajduje się na ciele węża (pętla po wszystkich modułach węża i porównanie współrzędnych jedzenia oraz poszczególnych modułów węża);

Ty tego w ogóle nie sprawdzasz, więc będzie duży problem i trzeba to naprawić; Spróbuj zrobić w ten sposób, a w dalszych etapach pisania tej gry będzie o wiele łatwiej; Tym bardziej, jeśli pokusisz się na jakieś ciekawe ficzery - sam dodałem możliwość przechodzenia przez moduły ciała węża (oprócz głowy i ogona), w których znajdowało się jedzenie (te moduły rysowane są jaśniejszym kolorem).

0

Wróce jeszcze do tego tematu, bo obecnie nie mam czasu.

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