Vánoční nadílka Vánoční nadílka
Vánoční akce! Daruj lepší budoucnost blízkým nebo sobě. Až +50 % zdarma na dárkové poukazy. Více informací

Diskuze: Hra tanky

C a C++ C a C++ Hra tanky American English version English version

Aktivity (1)
Avatar
maros55
Člen
Avatar
maros55:15. října 17:00

Zdravím, momentálne som dostal v škole zadanie na hru tanky v jazyku C. Keďže som v programovaní takmer úplný začiatočník, chcel som sa opýtať či tu náhodou nie je niekto, kto má tento kód alebo aspoň časť kódu k dispozícii aspoň pred inšpiráciu, pretože pre mňa je to úplne španielska dedina a nemám ani predstavu. Za každú radu, pomoc poprípade kontakt na niekoho kto by mi stým vedel pomôcť budem veľmi vďačný. Vopred ďakujem.

Zkusil jsem: Momentálne som si zaplatil kurz programovania a hľadal na internete nejaké tutoriály, no bez výsledku.

Chci docílit: Problém sa snažím vyriešiť kvôli tomu, aby som mohol naďalej pokračovať v štúdiu.

 
Odpovědět 15. října 17:00
Avatar
DarkCoder
Člen
Avatar
Odpovídá na maros55
DarkCoder:15. října 18:14

Chceš-li, abychom Ti jakkoli pomohli, je třeba být konkrétnější. Pod pojmem hra "Tanky" si mohu představit mnoho variant. Od klasické 2D akce ala Worms, přes pozemní variantu lodí, tankovou bitvu v bludišti, až po 3D akci ala World of Tanks. Zde vidíš, že možností je spousta. Zadání je komplexnější a předpokládá se, že něco už v C umíš. Tudíž bys měl být schopen sestavit alespoň hlavní kostru programu. A abychom se zapojili i my, je třeba, aby si nám zde prezentoval to co už máš. Tedy svůj kód který si sám zpracoval, na kterém se dá stavět.

Nahoru Odpovědět  +2 15. října 18:14
"„Učíš-li se proto, aby sis zapamatoval, zapomeneš. Učíš-li se proto, abys porozuměl, zapamatuješ si."
Avatar
maros55
Člen
Avatar
maros55:15. října 18:25

Ospravedlňujem sa zabudol som to lepšie špecifikovať.

  1. Hra má byť na princípe hry Scorched Earth. Po spustení programu má byť umožnení zvoliť si počet hráčov a ich mená.
  2. Následne sa zo súboru načíta herný plán (pozície tankov možu byť v jednotlivých plánoch pevne dané alebo náhodne generované).
  3. Tanky sa vo výstreloch pravidelne striedajú a pre výpočet trajektórie strely bude využitá rovnica šikmého vrhu spoločne s následnou aproximáiou k najbližšiemu bodu v matici.
  4. Ničenie zeme nieje potrebné implementovať, čiže ked strela zasiahne povrch, tak sa nič nestane nedeformuje sa.

Ja som z tohoto programu nespravil ešte nič, vôbec si ani neviem predstaviť ako by to malo vyzerať, preto som sa chcel obrátiť na toto fórum či by sa tu nenašiel niekto, kto by mi ukázal nejakú cestu, nasmeroval ma.

 
Nahoru Odpovědět 15. října 18:25
Avatar
Panda38
Redaktor
Avatar
Panda38:15. října 18:47

Ještě je otázka, zda se má jednat o grafický program s vizualizací, nebo jen o dialogový program. A v jakém překladači má být vytvořený. Ze zadání mám dojem, že se jedná o konzolový program, tedy by to mohl být celkem jednoduchý program. K překladu buď GCC nebo MS VC++. První krok by byl založení konzolového projektu - dosáhnout toho, aby jsi uměl přeložit a spustit jednoduchý program "int main() { printf("Ahoj"); return 0; }". Potom se naučit používat funkci pro uživatelský vstup scanf - stačí umět převzít text a ten pak vytisknout na obrazovku. V programu by se vytvořilo pole struktur struct, které bude obsahovat pozice tanků a jejich stav poškození. V hlavní funkci main by bylo nejdříve zadání hráčů se scanf a načtení herního plánu (funkce fopen, fread, fclose). Pak by běžela hlavní smyčka for(), ve které se budou obsluhovat jednotlivý hráči: Vypsání stavu hry pro hrajícího hráče (stav jeho tanku, vzdálenosti a stavy nepřátel). Zadání úhlu a síly úderu se scanf. Následuje výpočet místa dopadu a podle toho aktualizace stavu ostatních tanků. Výpis poškození printf a pokračuje opět smyčka pro dalšího hráče.

 
Nahoru Odpovědět 15. října 18:47
Avatar
Luboš Satik Běhounek
Autoredaktor
Avatar
Odpovídá na maros55
Luboš Satik Běhounek:15. října 18:47

Nejdriv musis vymyslet, jak budes hru reprezentovat. Teren v takovyhle hre bych resil pres dvourozmerny (jde to i jednorozmernym) pole bodu, kde mas ulozeny, jestli je tam plno/prazdno, pripadne i treba barva pixelu terenu.

Tohle cely potrebujes nejak cyklicky vykreslovat.

Pak budes potrebovat vymyslet, jak reprezentovat jednotlivy hrace/tanky. Takze si pro ne udelat nejspis tridu, kde bude treba barva nebo textura tanku, jmeno, jak ma otocenou hlaven, jak je poskozeny apod.

Ten pak pridas do vykreslovani hned za kresleni terenu.

Pak jeste budou potreba projektily a taky neco pro rizeni hry, kde bude treba ulozeno, ktery hrac je na rade apod.

Pole (nebo treba i vectory) ovladas? Vykreslovat na obrazovku nejak umis?

Nahoru Odpovědět 15. října 18:47
https://www.facebook.com/peasantsandcastles/
Avatar
maros55
Člen
Avatar
maros55:15. října 21:24

Luboš Satik Běhounek -> polia sa práve učím, čiže viem zhruba na akom princípe to pracuje.
Vykreslovanie na obrazovku, neviem čo sa tým myslí, ako výpis niečoho na obrazovku ?

Zatiaľ vám veľmi pekne ďakujem, už aspoň viem čo si mám na internete pozrieť a ako by som aspoň mal začať.

 
Nahoru Odpovědět 15. října 21:24
Avatar
Peter Mlich
Člen
Avatar
Peter Mlich:23. října 11:15

google = tank game c code
https://www.codewithc.com/…e-c-project/

Kdyz bych omezil nektere podminky, tak se jedna jen o

  • poloha tanku, x,y, oblast cile
  • otoceni hlavne
  • strela, jeji poloha
  • detekce kolize s tankem
  • detekce kolize se spodni lajnou obrazovky

Pokud si to chces komplikovat, pridej teren, linii pixelu, ktere ho ohranicuji.
Pri kolizi budes muset upravit cast linie.
Kolizi muzes detekovat podle bodu trajektorie. Pro prvni detekci staci obdelnicek i, i+1 pixely trajektorie. Pokud nemas trajektorie pixel po pixelu, a najde-li se mozna kolize, budes muset pristoupit ke zjemneni trajektorie mezi temito body na pixely a znovu detekovat pro ne kolize.
Uplne jednoduche by mohlo byt, kdyby vzdalenost bodu trajektorie neprekrocila sirku tanku. Pak ti staci detekovat jen prvni druh kolize s tanky.
Samozrejme, muzes jit zrovna do 1px trajektorie, dnesni pc by to meli zvladnout :)

 
Nahoru Odpovědět 23. října 11:15
Avatar
Peter Mlich
Člen
Avatar
Peter Mlich:24. října 11:42

https://mlich.zam.slu.cz/x/js-tanks.htm
Takovy pokus. By sis to musel prepsat ale do cecka :)
Mezerou strili.
Sipkami meni sklon hlavne.
Jsou tam nejake chybky, ktere treba doladit a neni tam pc inteligence. A tusim ani tank nevybuchne. A taky spoustu promennych navic, protoze jsem prepisoval jiny kod. Ale jako zaklad by to mohlo byt pouzitelne. (nebo, kdyz leti strela, zmenis sklon hlavne, tak tam prebiram uhel z playera, coz je taky chyba)

Nicmene skolni projekty neresime za jine.

Editováno 24. října 11:42
 
Nahoru Odpovědět  +1 24. října 11:42
Avatar
Peter Mlich
Člen
Avatar
Peter Mlich:2. listopadu 15:12

Mel jsem cas, trochu jsem to upravil. Uz to strili relativne ok.
https://mlich.zam.slu.cz/x/js-tanks.htm

 
Nahoru Odpovědět 2. listopadu 15:12
Avatar
maros55
Člen
Avatar
maros55:29. listopadu 14:20

Ahojte, takto som pokročil s kodom, no neviem ako mám v konzolovom okne nastaviť farbu tankom (X su tanky) tak, aby sa zhodovalo s menami, ktoré su napísané vedľa mapy. Napr. že hráč 1 bude červený, tak tak nejaký tank bude červený, potom ďalšie meno bude zelené, tak nejaký tank bude zelený atď. Ďakujem za odpoveď.

// mapa.cpp : Tento soubor obsahuje funkci main. Provádění programu se tam zahajuje a ukončuje.
//

#include "pch.h"
#include <conio.h>
#include <stdlib.h>
#include <stdio.h>
#include <windows.h>
#include <math.h>
#include <ctime>

#define WIDTH 63
#define HEIGHT 27
#define M_PI 3.14159265358979323846
#define degreesToRadians(angleDegrees) ((angleDegrees) * M_PI / 180.0) // *180)/3.1415926535897932384626433832795;
#define max 10

typedef struct tank {           // uprava do void fukcie a tej do kniznice
        char meno[20];
        WORD farba = FOREGROUND_BLUE | FOREGROUND_RED | FOREGROUND_GREEN;
        int xPoz;
        int yPoz;
        bool naRade = false;

        // HP ; volba generovani nahodne mapy 2- volba mapy ze suboru
};


//funkce pro skryti kursoru v konzoli
void showConsoleCursor(bool showFlag)
{
        HANDLE out = GetStdHandle(STD_OUTPUT_HANDLE);
        CONSOLE_CURSOR_INFO cursorInfo;
        GetConsoleCursorInfo(out, &cursorInfo);
        cursorInfo.bVisible = showFlag;
        SetConsoleCursorInfo(out, &cursorInfo);
}

int **createMatrix(int m, int n) {
        int** matrix = new int*[m];
        for (int i = 0; i < m; i++)
        {
                matrix[i] = new int[n];
                for (int j = 0; j < n; j++) {
                        matrix[i][j] = 0;
                }
        }
        return matrix;
};

int loadFromFile(int **matrix, char *filename) {
        FILE *file;
        fopen_s(&file, filename, "r");
        if (file == NULL)
                return 1;

        char c;
        int i = 0;
        int j = 0;

        while ((c = fgetc(file)) != EOF && i < HEIGHT) {
                if (c == '\n') {
                        i++;
                        j = 0;
                        continue;
                }

                if (j > WIDTH - 1) {
                        continue;
                }

                switch (c) {
                case '0':
                        matrix[i][j] = 1;
                        break;

                default:
                        matrix[i][j] = 0;
                }
                j++;
        }
        fclose(file);
        return 0;
}


void initMatrix(int **matrix, int rows, int columns, int poceth, tank *hraci) {
        int* heights = new int[columns];
        heights[0] = (int)rows / 3;
        for (int i = 1; i < columns; i++) {
                heights[i] = heights[i - 1] + (rand() % 3) - 1;
                if (heights[i] < 3) {
                        heights[i] = 3;
                }
        }

        for (int i = 0; i < rows; i++)
        {
                for (int j = 0; j < columns; j++)
                {
                        if (rows - heights[j] >= i) {
                                matrix[i][j] = 0;
                        }
                        else {
                                matrix[i][j] = 1;
                        }
                        /*
                        for (int k = 0; k < poceth; k++) {
                                if ((hraci[k].xPoz == j) && ((rows - heights[j]) == i)) {
                                        matrix[i][j] = 2;
                                        hraci[k].yPoz = i;
                                }
                        }*/
                }
        }
}

void printMatrix(int **matrix, int m, int n) {
        HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
        COORD cur = { 0, 0 };
        SetConsoleCursorPosition(hConsole, cur);
        CONSOLE_SCREEN_BUFFER_INFO consoleInfo;
        WORD saved_attributes;

        GetConsoleScreenBufferInfo(hConsole, &consoleInfo);
        saved_attributes = consoleInfo.wAttributes;

        GetConsoleScreenBufferInfo(hConsole, &consoleInfo);
        saved_attributes = consoleInfo.wAttributes;
        int stringSize = ((n * 2) + 2) * m;
        char *matrixString = new char[stringSize];

        SetConsoleTextAttribute(hConsole, FOREGROUND_RED | FOREGROUND_GREEN);
        printf("/");
        for (int i = 0; i < n; i++) { printf("-"); }
        printf("\\\n");

        for (int i = 0; i < m; i++)
        {
                printf("|");
                for (int j = 0; j < n; j++)
                {
                        switch (matrix[i][j]) {
                        case 0: {printf(" "); break; }
                        case 1: {SetConsoleTextAttribute(hConsole, FOREGROUND_RED | FOREGROUND_GREEN);
                                printf("0");
                                break; }
                        case 2: {SetConsoleTextAttribute(hConsole, FOREGROUND_GREEN); printf("X"); break; }
                        case 3: {SetConsoleTextAttribute(hConsole, FOREGROUND_RED); printf("o"); break; }
                        }

                }
                SetConsoleTextAttribute(hConsole, FOREGROUND_RED | FOREGROUND_GREEN);
                printf("|\n");
        }
        SetConsoleTextAttribute(hConsole, FOREGROUND_RED | FOREGROUND_GREEN);
        printf("\\");
        for (int i = 0; i < n; i++) { printf("-"); }
        printf("/\n");
}

void printTanks(tank *hraci, int poceth, int columns)
{
        HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);

        for (int i = 0; i < poceth; i++)
        {
                COORD cur = { columns + 10, 5 + i };
                SetConsoleCursorPosition(hConsole, cur);
                if (hraci[i].naRade) {
                        SetConsoleTextAttribute(hConsole, hraci[i].farba | BACKGROUND_GREEN | BACKGROUND_BLUE | BACKGROUND_RED | BACKGROUND_INTENSITY);
                }
                else {
                        SetConsoleTextAttribute(hConsole, hraci[i].farba);
                }
                printf("%s", hraci[i].meno);
                SetConsoleTextAttribute(hConsole, FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY);
        }
}

float posx(float t, float vx, int x) {
        return vx * t + x;
}


float posy(float t, float vy, int y) {
        return  -(-0.5 * 10 * t*t) - (vy*t) + y;
}


double vx(float v, float angle) {
        return  v * cos(degreesToRadians(angle));
}


double vy(float v, float angle) {
        return  v * sin(degreesToRadians(angle));
}

void tankHit(tank *hraci, int *poceth, int x, int y) {
        for (int i = 0; i < *poceth; i++) {
                if (hraci[i].xPoz == x && hraci[i].yPoz == y) {
                        for (int j = i + 1; j < *poceth; j++) {
                                hraci[j - 1] = hraci[j];
                        }
                }
        }
        (*poceth)--;
}

void ShowConsoleCursor(bool visible)
{
        HANDLE out = GetStdHandle(STD_OUTPUT_HANDLE);
        CONSOLE_CURSOR_INFO cursorInfo;
        GetConsoleCursorInfo(out, &cursorInfo);
        cursorInfo.bVisible = visible;
        SetConsoleCursorInfo(out, &cursorInfo);
}


void shoot(int **matrix, int initx, int inity, float initVelocity, float angle, tank *hraci, int *poceth, int m, int n) {
        ShowConsoleCursor(false);
        int oldx = 0, oldy = 0;
        double velx = vx(initVelocity, angle);
        double vely = vy(initVelocity, angle);
        float t = 0;
        int x = initx;
        int y = inity;
        int tmpState = 0;
        do {
                float positx = posx(t, velx, initx);
                float posity = posy(t, vely, inity);

                x = (int)round(positx);
                y = (int)round(posity);

                if (y > HEIGHT - 1 || y <= 0 || x > WIDTH - 1 || x <= 0) {
                        break;
                }

                if (oldx == x && oldy == y) {
                        Sleep(20);
                        t += 0.04;
                        continue;
                }
                oldx = x; oldy = y;

                switch (matrix[y][x]) {
                case 0:
                        matrix[y][x] = 3;
                        printMatrix(matrix, m, n);
                        matrix[y][x] = 0;
                        break;

                case 2:
                        tmpState = matrix[y][x];
                        matrix[y][x] = 0;
                        tankHit(hraci, poceth, x, y);
                        printMatrix(matrix, m, n);
                        break;

                case 1:
                        tmpState = matrix[y][x];
                        matrix[y][x] = 0;
                        if (matrix[y][x - 1] == 2) {
                                matrix[y][x - 1] = 0;
                                matrix[y][x] = 2;
                                for (int i = 0; i < *poceth; i++) {
                                        if (hraci[i].xPoz == x) {
                                                hraci[i].yPoz = y;
                                        }
                                }
                        }
                        break;
                }
                Sleep(10);
                t += 0.06;
        } while (tmpState != 2 && tmpState != 1 && y < HEIGHT - 1 && y >= 0 && x < WIDTH - 1 && x >= 0);
        printMatrix(matrix, m, n);
        printTanks(hraci, *poceth, n);
        ShowConsoleCursor(true);
}


int main()
{
        srand((int)time(NULL));
        tank hraci[max];

        printf("Zadaj pocet hracov : ");
        int poceth;
        int znak;

        do {
                poceth = getchar();
        } while (poceth < 50 || poceth > 55);
        poceth -= 48;

        for (int i = 0; i < poceth; i++)
        {
                printf("\n Zadaj meno %d. hraca :", i + 1);
                scanf_s("%s", &hraci[i].meno, 19);
        };


        for (int i = 0; i < poceth; i++) {
                printf("\nhrac %d : %s \n", i + 1, hraci[i].meno);
        };

        int m, n;
        int **matrix;


        do {
                printf("Vyber si moznost - Stlac 1 pre random mapu alebo Stlac 2 pre nacitanie mapy z 3 vytvorenych: ");
                scanf_s("%d", &m);
                printf("Zadal si zle cislo, mozes len alebo 2. Zadaj este raz.\n");
        } while (m != 1 && m != 2);
        if (m == 1) {
                printf("zadaj velkost mapy: ");
                scanf_s("%d %d", &m, &n);
                matrix = createMatrix(m, n);
                initMatrix(matrix, m, n, poceth, hraci);
        }
        else {
                char mapa[10] = { "mapaX.txt" };
                int randMap = 1;
                randMap = rand() % 3 + 1;
                mapa[4] = randMap + 48;
                m = HEIGHT; n = WIDTH;
                matrix = createMatrix(m, n);
                if (loadFromFile(matrix, mapa) == 1) {
                        printf("Mapa  %s sa nenasla \n", mapa);
                        getchar();
                        return 1;
                }
        }
        system("cls");

        for (int i = 0; i < poceth; i++) {
                bool zhoda = false;
                int x = rand() % n;
                for (int j = 0; j < i; j++) {
                        if (x == hraci[j].xPoz) { zhoda = true; break; }
                }
                if (!zhoda) {
                        hraci[i].xPoz = x;
                        for (int j = 0; j < m; j++) {
                                if (matrix[j][x] == 0 && matrix[j + 1][x] == 1) {
                                        hraci[i].yPoz = j;
                                        matrix[j][x] = 2;
                                        break;
                                }
                        }
                }
                else {
                        i--;
                }
                printf("rand x je : %d\n", x);
        }

        printMatrix(matrix, m, n);
        showConsoleCursor(false);
        printTanks(hraci, poceth, n);

        int j = 0;
        while (poceth > 1) {
                for (int i = 0; i < poceth; i++) {

                        hraci[j].naRade = false;
                        hraci[i].naRade = true;
                        j = i;
                        printMatrix(matrix, m, n);
                        printTanks(hraci, poceth, n);

                        HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
                        COORD cur = { n + 10, 15 + poceth };
                        SetConsoleCursorPosition(hConsole, cur);
                        float velocity = 0;
                        float angle = 0;

                        printf("Zadaj silu strely: ");
                        scanf_s("%f", &velocity);

                        cur = { cur.X, cur.Y + 1 };
                        SetConsoleCursorPosition(hConsole, cur);
                        printf("Zadaj uhol:");
                        scanf_s("%f", &angle);
                        shoot(matrix, hraci[i].xPoz, hraci[i].yPoz - 1, velocity, angle, hraci, &poceth, m, n);
                        system("cls");
                }
        }

        system("cls");
        printf("Vyhral hrac %s, Gratulujeme !\n", hraci[0].meno);
        system("pause");
}

// Spuštění programu: Ctrl+F5 nebo nabídka Ladit > Spustit bez ladění
// Ladění programu: F5 nebo nabídka Ladit > Spustit ladění

// Tipy pro zahájení práce:
//   1. K přidání nebo správě souborů použijte okno Průzkumník řešení.
//   2. Pro připojení ke správě zdrojového kódu použijte okno Team Explorer.
//   3. K zobrazení výstupu sestavení a dalších zpráv použijte okno Výstup.
//   4. K zobrazení chyb použijte okno Seznam chyb.
//   5. Pokud chcete vytvořit nové soubory kódu, přejděte na Projekt > Přidat novou položku. Pokud chcete přidat do projektu existující soubory kódu, přejděte na Projekt > Přidat existující položku.
//   6. Pokud budete chtít v budoucnu znovu otevřít tento projekt, přejděte na Soubor > Otevřít > Projekt a vyberte příslušný soubor .sln.
 
Nahoru Odpovědět 29. listopadu 14:20
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 10 zpráv z 10.