• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

uniezależnienie ruchu gracza a przeciwnika (konsolowa gierka w c++)

Object Storage Arubacloud
0 głosów
270 wizyt
pytanie zadane 9 marca 2017 w C i C++ przez Jakub 0 Pasjonat (23,120 p.)

Hej ,już prawie skończyłem pisać swoją pierwszą banalną grę w c++ ,polega ona na omijaniu spadających meteorytów . Mówię że prawie ją napisałem bo chociaż na tą porę wszystko działa ok to nie wiem jak uniezależnić ruch gracza od przeciwnika . Mianowicie przeciwnik (meteoryt) robi ruch tylko w tym momencie kiedy jakiś ruch wykonuje gracz . Chce natomiast by meteoryty spadały cały czas niezależnie czy gracz wykonuje jakiś ruch(klika klawisz sterowania) Wiem że może napisałem trochę niezrozumiale ale na dole podałem kod gry , jak ktoś go skompiluje to będzie wiedział co mam na myśli , poza tym wiem że kod wygląda okropnie ale będę go poprawiać jak ukończę projekt :) Dziękuje za wszelkie komentarze i poświęcenie czasu na pomoc . Pozdrawiam :)

 

#include <iostream>
#include <windows.h>
#include <conio.h>
#include <time.h>
#include <stdio.h>

using namespace std;

void fail(int p)
{
    system("cls");
    cout<<"koniec gry ,no niestety ):"<<endl;
    cout<<"suma zdobytych ponktow : "<<p<<endl;
    cout<<"ale dobrze ci szlo (:";
    getchar();getchar();
    exit(0);

}

void game_end(int px,int py,int mx,int my,int mx2,int my2,int mx3 ,int my3,int &p) //sprawdzenie czy meteoryty nie sa rowne graczowi
{
    if((px==mx||px==mx2||px==mx3)&&(py==my||py==my2||py==my3))
    {
        fail(p);
    }
}

void terrain_generator(int player_x,int player_y ,int monster_x ,int monster_y ,int monster_x2 ,int monster_y2, int monster_x3 ,int monster_y3)
{
    int z = 20;                 //generowanie planszy (tablic)
    char pole[z][z];

    char player_intervace = 254;
    char monster_intervace = 15;

    for(int i=0; i<z; i++)
    {
        for(int j=0; j<z; j++)
        {
            pole[i][j]='.';
        }
    }

    pole[player_x][player_y]=player_intervace;

    pole[monster_x][monster_y]=monster_intervace;
    pole[monster_x2][monster_y2]=monster_intervace;
    pole[monster_x3][monster_y3]=monster_intervace;

    for(int i=0; i<z; i++)
    {
        for(int j=0; j<z; j++)
        {
            cout<<pole[i][j];
        }
        cout<<endl;
    }
}

void try_only_monster_y_generator(int &monster_x, int &monster_y ,int &monster_x2, int &monster_y2, int &monster_x3, int &monster_y3)
{
        srand(time(NULL)); //nadawanie meteorytom losowych wartości

        monster_x=0;
        monster_x2=0;
        monster_x3=0;

        monster_y=rand()%20;
        monster_y2=rand()%20;
        monster_y3=rand()%20;

}

void monster_logic(int &monster_x, int &monster_y ,int &monster_x2, int &monster_y2 ,int &monster_x3, int &monster_y3 ,int player_x ,int player_y)
{
    if(monster_x>18 || monster_x2>18 || monster_x3>18) try_only_monster_y_generator(monster_x, monster_y ,monster_x2, monster_y2 ,monster_x3, monster_y3);
    else monster_x++; monster_x2++; monster_x3++; //ruch meteorytow dopuki nie są na samym dole
}

int render_monsters_for_start()
{
    srand(time(NULL)); //generowanie meteorytow na sam poczatek gry
    int x = rand()%20;
    return x;
}

void gra()
{
    int player_x = 17; //poczatkowe pozycje elementow
    int player_y = 10;

    int monster_x = 0;
    int monster_y = render_monsters_for_start();

    int monster_x2 = 0;
    int monster_y2 = render_monsters_for_start();

    int monster_x3 = 0;
    int monster_y3 = render_monsters_for_start();

    char znak;

    int punkty=0;

    while(true) //gowna petla gry
    {
        system("cls");

        terrain_generator(player_x,player_y,monster_x,monster_y,monster_x2,monster_y2,monster_x3,monster_y3);
        monster_logic(monster_x,monster_y,monster_x2,monster_y2,monster_x3,monster_y3,player_x,player_y); //ruch potworow
        game_end(player_x,player_y,monster_x,monster_y,monster_x2,monster_y2,monster_x3,monster_y3,punkty);

        znak = getch();


        if(znak=='A') //gdy jest wcisniety caps-lock
        {
            znak='a';
        }
        if(znak=='D')
        {
            znak='d';
        }


        switch(znak) //poruszanie graczem
        {
        case 'a':
        {
            if(player_y>0) player_y--;
            else player_y = 0;
        }
        break;

        case 'd':
        {
            if(player_y<19) player_y++;
            else player_y = 19;
        }
        break;
        }

        punkty++;
    }
}

void menu()
{
    cout<<"witamy"<<endl;
    system("pause");
    system("cls");
}

int main()
{
    menu();
    gra();
    return 0;
}

 

 

komentarz 9 marca 2017 przez Jakub 0 Pasjonat (23,120 p.)
jak ktoś nie wie o co chodzi z tym algorytmem poruszania na tablicach to tu jest link do innego mojego wpisu :)

https://forum.pasja-informatyki.pl/233582/nietypowy-sposob-tworzenia-mapy-w-c#a233607

1 odpowiedź

+2 głosów
odpowiedź 9 marca 2017 przez tangarr Mędrzec (154,860 p.)
wybrane 9 marca 2017 przez Jakub 0
 
Najlepsza
Przy pomocy funkcji kbhit możesz sprawdzić czy buforze klawiatury znajdują się znaki do wczytania. Funkcji getch używasz tylko wtedy gdy kbhit zwróci 1. Powinieneś dodać sleepa w głównej pętli, żeby ustawić prędkość gry.
komentarz 9 marca 2017 przez Jakub 0 Pasjonat (23,120 p.)
dzięki , poczytam o tej funkcji (:
komentarz 9 marca 2017 przez rafal.budzis Szeryf (85,260 p.)

Trochę nie do końca. Sleep jest złym pomysłem prawdziwą pętle czasu rzeczywistego buduje się w inny sposób. Jeśli zastosujemy sleep może wyjść sytuacja ze gracz naciśnie przycisk gdy gra będzie uśpiona i gra zupełnie nie zareaguje na interakcje gracza. Prawdziwa pętle czasu rzeczywistego robimy za pomocą zapisywania czasu i sumowania czasu miedzy pętlami. Mini przykład 

var sumaCzasu = 0;

while(true){
     sumaCzasu += roznicaCzasuOdPoprzedniegoWykonaniaPętli();
    //pobieranie klawisza i interakacja z graczem

    if(sumaCzasu > 20 ){
         sumaCzasu -= 20;
         // zmiana pozycji wrogów po 20 milisekundach
    }

}

 

komentarz 9 marca 2017 przez tangarr Mędrzec (154,860 p.)
To jeszcze mu napisz jak ma zrobić podwójne buforowanie w konsoli i mu wytłumacz dlaczego jego gra zżera 100% CPU :)
komentarz 9 marca 2017 przez rafal.budzis Szeryf (85,260 p.)
Wiesz to wpływa bardzo znacząco na rozgrywkę bez tego gra będzie się ścinała i za chwile będzie pytanie jak ją zoptymalizować. To są podstawy tworzenia gier a ty mi mówisz ze to na wyrost ? Przekonaj mnie jakimś lepszym argumentem :P
komentarz 9 marca 2017 przez tangarr Mędrzec (154,860 p.)

Zrobiłem mały eksperyment. Bufor klawiatury działa pomimo sleepa.

#include <stdio.h>
#include <conio.h>
#include <windows.h>

int main() {
    printf("sleep na 5s\n");
    Sleep(5000);
    printf("...\n");
    while (kbhit()) {
        int c = getch();
        printf("key: %d\n", c);
    }
    return 0;
}

Gra nie będzie ścinać, ale nieumiejętne skonstruowanie pętli może spowodować skolejkowanie wielu rozkazów (w efekcie czego wrażenie nieresponsywności programu)

komentarz 9 marca 2017 przez Jakub 0 Pasjonat (23,120 p.)

użyłem tej funkcji ale mi nie działa poprawnie bo teraz nie ma możliwości sterowania graczem, nie wiem co zrobiłem źle, na dole jest kod , będę wdzięczny za wytłumaczenie

 

#include <iostream>
#include <windows.h>
#include <conio.h>
#include <time.h>
#include <stdio.h>

using namespace std;

void fail(int p)
{
    system("cls");
    cout<<"koniec gry ,no niestety ):"<<endl;
    cout<<"suma zdobytych ponktow : "<<p<<endl;
    cout<<"ale dobrze ci szlo (:";
    getchar();
    getchar();
    exit(0);

}

void game_end(int px,int py,int mx,int my,int mx2,int my2,int mx3,int my3,int &p)  //sprawdzenie czy meteoryty nie sa rowne graczowi
{
    if((px==mx||px==mx2||px==mx3)&&(py==my||py==my2||py==my3))
    {
        fail(p);
    }
}

void terrain_generator(int player_x,int player_y,int monster_x,int monster_y,int monster_x2,int monster_y2, int monster_x3,int monster_y3)
{
    int z = 20;                 //generowanie planszy (tablic)
    char pole[z][z];

    char player_intervace = 254;
    char monster_intervace = 15;

    for(int i=0; i<z; i++)
    {
        for(int j=0; j<z; j++)
        {
            pole[i][j]='.';
        }
    }

    pole[player_x][player_y]=player_intervace;

    pole[monster_x][monster_y]=monster_intervace;
    pole[monster_x2][monster_y2]=monster_intervace;
    pole[monster_x3][monster_y3]=monster_intervace;

    for(int i=0; i<z; i++)
    {
        for(int j=0; j<z; j++)
        {
            cout<<pole[i][j];
        }
        cout<<endl;
    }
}

void try_only_monster_y_generator(int &monster_x, int &monster_y,int &monster_x2, int &monster_y2, int &monster_x3, int &monster_y3)
{
    srand(time(NULL)); //nadawanie meteorytom losowych wartoœci

    monster_x=0;
    monster_x2=0;
    monster_x3=0;

    monster_y=rand()%20;
    monster_y2=rand()%20;
    monster_y3=rand()%20;

}

void monster_logic(int &monster_x, int &monster_y,int &monster_x2, int &monster_y2,int &monster_x3, int &monster_y3,int player_x,int player_y)
{
    if(monster_x>18 || monster_x2>18 || monster_x3>18) try_only_monster_y_generator(monster_x, monster_y,monster_x2, monster_y2,monster_x3, monster_y3);
    else monster_x++;
    monster_x2++;
    monster_x3++; //ruch meteorytow dopuki nie s¹ na samym dole
}

int render_monsters_for_start()
{
    srand(time(NULL)); //generowanie meteorytow na sam poczatek gry
    int x = rand()%20;
    return x;
}

void gra()
{
    int player_x = 17; //poczatkowe pozycje elementow
    int player_y = 10;

    int monster_x = 0;
    int monster_y = render_monsters_for_start();

    int monster_x2 = 0;
    int monster_y2 = render_monsters_for_start();

    int monster_x3 = 0;
    int monster_y3 = render_monsters_for_start();

    char znak = 0;

    int punkty=0;

    while(true) //gowna petla gry
    {
        do
        {
            znak = kbhit();

            system("cls");
            Sleep(10);
            terrain_generator(player_x,player_y,monster_x,monster_y,monster_x2,monster_y2,monster_x3,monster_y3);
            monster_logic(monster_x,monster_y,monster_x2,monster_y2,monster_x3,monster_y3,player_x,player_y); //ruch potworow
            game_end(player_x,player_y,monster_x,monster_y,monster_x2,monster_y2,monster_x3,monster_y3,punkty);

            if(znak=='a'||znak=='s'||znak=='d'||znak=='w') kbhit()==1;

        }while(kbhit()==0);

        if(znak=='A') //gdy jest wcisniety caps-lock
        {
            znak='a';
        }
        if(znak=='D')
        {
            znak='d';
        }


        switch(znak) //poruszanie graczem
        {
        case 'a':
        {
            if(player_y>0) player_y--;
            else player_y = 0;
        }
        break;

        case 'd':
        {
            if(player_y<19) player_y++;
            else player_y = 19;
        }
        break;
        }

        punkty++;
    }
}

void menu()
{
    cout<<"witamy"<<endl;
    system("pause");
    system("cls");
}

int main()
{
    menu();
    gra();
    return 0;
}

 

komentarz 9 marca 2017 przez Jakub 0 Pasjonat (23,120 p.)
sprawdziłem jak się poruszają "znaki" bez użycia spowolnienia programu ,jest ok bez funkcji sleep itp
komentarz 9 marca 2017 przez Jakub 0 Pasjonat (23,120 p.)
na razie nie przeszkadza mi zła optymalizacja bo to jest moja pierwsza gra i nie wymagam od nie zbyt wiele :) , na razie chce się dowiedzieć dlaczego nie działa mi poprawnie funkcja kbhit :) . Podałem powyżej kod programu po zmianie ,dziękuje za komentarze
1
komentarz 9 marca 2017 przez tangarr Mędrzec (154,860 p.)
system("cls");   
terrain_generator(player_x,player_y,monster_x,monster_y,monster_x2,monster_y2,monster_x3,monster_y3);
monster_logic(monster_x,monster_y,monster_x2,monster_y2,monster_x3,monster_y3,player_x,player_y); //ruch potworow
game_end(player_x,player_y,monster_x,monster_y,monster_x2,monster_y2,monster_x3,monster_y3,punkty);
Sleep(10);

if (kbhit()==0) { // nie wcisnieto klawisza
        continue;
}
znak = getch();
komentarz 9 marca 2017 przez Jakub 0 Pasjonat (23,120 p.)

wow , dzięki laugh właśnie o to mi chodziło , teraz sobie to tylko muszę ułożyć w głowie :)

Podobne pytania

0 głosów
0 odpowiedzi 113 wizyt
0 głosów
2 odpowiedzi 121 wizyt
pytanie zadane 15 marca 2018 w Algorytmy przez revizor451 Obywatel (1,930 p.)
0 głosów
0 odpowiedzi 2,047 wizyt
pytanie zadane 11 listopada 2016 w C i C++ przez Undisputed Gaduła (3,040 p.)

92,572 zapytań

141,423 odpowiedzi

319,645 komentarzy

61,959 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...