Eseguire 2 azioni contemporaneamente

di il
10 risposte

Eseguire 2 azioni contemporaneamente

Salve a tutti sto cercando di creare un piccolo videogioco in c simile a the impossibile game(ovviamente la grafica non è la stessa e neanche il gameplay) e ho scritto questo:

#include<stdio.h>
#include<stdlib.h>
#include<windows.h>
void gotoxy(int x,int y)
{
     HANDLE stdHandle;
     COORD coord;
     coord.X=x;
     coord.Y=y;
     stdHandle=GetStdHandle(STD_OUTPUT_HANDLE);
     SetConsoleCursorPosition(stdHandle,coord);
     SetConsoleTextAttribute(stdHandle,FOREGROUND_BLUE | FOREGROUND_GREEN);
}
int main()
{
  int continua=1;
  int x=4,y=14;
  char c;
  int j; 
  int i;
  int a;
  int b=14;
  int m;
  int n;
  int r;
  gotoxy(x,y);
  putchar(219);
  for(j=0;j<80;j++){
     for(i=15;i<16;i++)
     {
         gotoxy(j,i);
         putchar(219);
     }
  }
  while(continua==1)
  {
     if(kbhit())
     {
         c=getch();
         gotoxy(x,y);
         putchar(32);
         switch(c)
         {
           
               case 'w': case 'W':
                                  for(m=0;m<3;m++)  //ciclo per il salto del quadratino
                                  {
                                      y--;
                                      gotoxy(x,y);
                                      putchar(219);
                                      _sleep(60);
                                      gotoxy(x,y);
                                      putchar(32);
                                  }
                                  for(n=0;n<3;n++)  //ciclo per la discesa del quadratino
                                  {
                                      y++;
                                      gotoxy(x,y);
                                      putchar(219);
                                      _sleep(60);
                                      gotoxy(x,y);
                                      putchar(32);
                                  }
                                  x=4;
                                  y=14;
                                  gotoxy(x,y);
                                  putchar(219);
   DA QUA------------>   for(a=70;a>2;a--){       //cicli per il blocco in movimento
                                      for(b=14;b<15;b++){
                                          
                                          gotoxy(a,b);
                                          putchar(219);
                                          _sleep(30);
                                          gotoxy(a,b);
                                          putchar(32);
                                          }
 A QUA ---------------->   }
                                  
                                  break;
         }
       
      }
   }
   fflush(stdin);
   getchar();
   return 0;
}
quando premo W il quadratino salta però nello stesso momento deve passare anche il blocco in movimento e non so come fare quindi devo poter eseguire un azione cioè il salto del quadratino e nello stesso momento il programma deve far muovere il blocco.
Nel codice sorgente ho messo DA QUA , A QUA per il pezzo di codice che dovrebbe essere eseguito e nello stesso momento dare la possibilità a me di saltare con W ma non so come fare!!

10 Risposte

  • Re: Eseguire 2 azioni contemporaneamente

    Di base dovresti avere una funzione che aggiorna la schermata video, indipendentemente dai tasti premuti, richiamata in maniera periodica dal tuo ciclo principale.
    Dovresti avere poi una funzione che controlla l'input, in questo caso da tastiera, che si occupa di segnalare degli "eventi" alla funzione di aggiornamento video.
    Queste due funzioni andrebbero richiamate dal ciclo principale più o meno in questo modo
    while(1)
    {
    gestisciInput();
    gestisciVideo();
    Sleep(10);
    }
    
    L'unica sleep che dovresti avere dovrebbe essere quella di temporizzazione nel ciclo principale; prova a ragionare in questo modo e ti dovresti semplificare tantissimo il lavoro.
  • Re: Eseguire 2 azioni contemporaneamente

    Ok grazie per i consigli ma credo che ci mettero un bel pò per applicare quello che mi hai detto dato che ancora non ho studiato le funzioni.
  • Re: Eseguire 2 azioni contemporaneamente

    Non hai ancora studiato le funzioni ma sai già creare un gioco con grafica (per quanto semplice)?
  • Re: Eseguire 2 azioni contemporaneamente

    Dato che i giochi per console mi piacciono molto,di do una base su cui lavorare.
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <stdarg.h>
    #include <string.h>
    #include <conio.h>
    #include <windows.h>
    
    #define MAN_STARTX 10
    #define MAN_STARTY 15
    #define MAN_LIFE 3
    #define MAN_JMP 6
    #define MAN_CHAR 219
    #define MAN_COLOR 12
    #define WORLD_Y 16
    #define WORLD_CHAR 177
    #define WORLD_COLOR 42
    #define CONSOLE_WIDTH 80
    
    ///BASE WINDOWS CONSOLE FUNCTION
    
    void gotoxy (short x,short y)
    {
        COORD coord = {x, y};
        HANDLE hconsole  = GetStdHandle(STD_OUTPUT_HANDLE);
        if (hconsole == INVALID_HANDLE_VALUE) return;
        SetConsoleCursorPosition (hconsole,coord );
    }
    
    void cls()
    {
        CONSOLE_SCREEN_BUFFER_INFO csbi;
        const COORD startCoords = {0,0};
        DWORD dummy;
        HANDLE hconsole  = GetStdHandle(STD_OUTPUT_HANDLE);
        if (hconsole == INVALID_HANDLE_VALUE) return;
        GetConsoleScreenBufferInfo(hconsole,&csbi);
        FillConsoleOutputAttribute(hconsole,0,csbi.dwSize.X * csbi.dwSize.Y,startCoords,&dummy);
        FillConsoleOutputCharacter(hconsole,' ',csbi.dwSize.X * csbi.dwSize.Y,startCoords,&dummy);
        gotoxy(0,0);
    }
    
    void textcolor(unsigned short color)
    {
        HANDLE hconsole  = GetStdHandle(STD_OUTPUT_HANDLE);
        if (hconsole == INVALID_HANDLE_VALUE) return;
        SetConsoleTextAttribute(hconsole,color);
    }
    
    void printfk(char* format,...)
    {
        va_list ap;
        va_start(ap,format);
    
        char data[32];
        char* pdata;
        int vap;
        char* pcap;
        double dap;
        int* piap;
        int process;
        while (*format != '\0')
        {
            if (*format != '%')
            {
                putchar(*format);
                ++format;
            }
            else
            {
                pdata = data;
                process = 0;
                while (*format != '\0')
                {
                    *pdata++ = *format++;
                    switch (*format)
                    {
                        case 'd':
                        case 'i':
                        case 'o':
                        case 'u':
                        case 'x':
                        case 'X':
                        case 'c':
                            vap = va_arg(ap,int);
                            *pdata++ = *format++;
                            *pdata = '\0';
                            printf(data,vap);
                            process = 1;
                        break;
                        case 's':
                            pcap = va_arg(ap,char*);
                            *pdata++ = *format++;
                            *pdata = '\0';
                            printf(data,pcap);
                            process = 1;
                        break;
                        case 'e':
                        case 'f':
                        case 'g':
                            dap = va_arg(ap,double);
                            *pdata++ = *format++;
                            *pdata = '\0';
                            printf(data,dap);
                            process = 1;
                        break;
                        case 'p':
                        case 'n':
                            piap = va_arg(ap,int*);
                            *pdata++ = *format++;
                            *pdata = '\0';
                            printf(data,piap);
                            process = 1;
                        break;
                        case '%':
                            *pdata++ = *format++;
                            *pdata = '\0';
                            printf(data);
                            process = 1;
                        break;
                        case 'k':
                            if (pdata - data == 1)
                                vap = va_arg(ap,int);
                            else
                            {
                                *pdata = '\0';
                                data[0] = '0';
                                vap = atoi(data);
                            }
                            ++format;
                            textcolor(vap);
                            process = 1;
                        break;
                    }//switch %
                    if (process) break;
                }//while %
            }//is %
        }//every char format
    
        va_end(ap);
    }
    
    
    int main()
    {
        int manx,many,manjmp,manstj;
        int oldx,oldy;
        int life;
        int i;
        int mov;
    
        cls();
        //draw world
        gotoxy(0,WORLD_Y);
        for (i = 0; i < CONSOLE_WIDTH ;i++)
            printfk("%k%c",WORLD_COLOR,WORLD_CHAR);
        gotoxy(0,25);
    
        //property
        manx = MAN_STARTX;
        many = MAN_STARTY;
        oldx = manx - 1;
        oldy = many;
        manjmp = 0;
        manstj = 0;
        life = MAN_LIFE;
        //gioco fino a che ho delle vite
        while(life)
        {
            //game:
            //controllo movimenti
            if(kbhit())
            {
                mov = _getch();
    
                if (mov == 'd' && manx < CONSOLE_WIDTH)
                    ++manx;
                else if (mov == 'a' && manx > 0)
                    --manx;
                else if (mov == 'w' && many == MAN_STARTY && manstj == 0)
                    {manjmp = 0;manstj = 1;}
            }
    
            //eseguo salto
            if (manstj == 1)
            {
                --many;
                if (++manjmp == MAN_JMP) manstj = -1;
            }
            else if (manstj == -1)
            {
                ++many;
                if (--manjmp == 0) manstj = 0;
            }
    
            //omino
            if ( oldx != manx || oldy != many )
            {
                gotoxy(oldx,oldy);
                printfk("%7k ");
                gotoxy(manx,many);
                printfk("%k%c",MAN_COLOR,MAN_CHAR);
                gotoxy(0,25);
            }
    
            oldx = manx;
            oldy = many;
    
            Sleep(50);
        }
    
       return 0;
    }
    
    Cerca di mantenere un'identazione corretta.
    Cerca di comprendere il piu possibile per il resto sono qui.
  • Re: Eseguire 2 azioni contemporaneamente

    @dvaosta: io finora so poco del linguaggio ho studiato il cicli for,while,do while, scanf, printf, switch, random poi i tipi di variabili e so qualcosa riguardo gli array però le funzioni non le ho ancora studiate infatti il codice sorgente che ho messo non funziona come dovrebbe io ho cercato di fare un gioco con quello che so che è molto poco per creare un gioco. Questa parte di codice non l'ho scritta io la metto ogni volta che voglio fare qualcosa con la grafica e so come usare un pò la libreria windows.h anche se ripeto non conosco bene cosa voglia dire questo pezzo di sorgente (apparte i colori):
    
    void gotoxy(int x,int y)
    {
         HANDLE stdHandle;
         COORD coord;
         coord.X=x;
         coord.Y=y;
         stdHandle=GetStdHandle(STD_OUTPUT_HANDLE);
         SetConsoleCursorPosition(stdHandle,coord);
         SetConsoleTextAttribute(stdHandle,FOREGROUND_BLUE | FOREGROUND_GREEN);
    }
    
    so solo come usarlo per creare forme geometriche oppure un giochino come quello che ho fatto sopra anche se ripeto che non funziona.
  • Re: Eseguire 2 azioni contemporaneamente

    @vbextreme: Grazie mille per il sorgente ma credo che ci vorrà un bel pò prima che riesca a capirlo perchè molte cose che hai scritto non mi sono chiare ad esempio io la libreria conio.h e stdarg.h non le ho mai usate e non so neanche a cosa servono. Ma avrei una domanda a cosa servono tutti i case che hai messo nello switch? Ad esempio hai messo:
    
                        case 'd':
                        case 'i':
                        case 'o':
                        case 'u':
                        case 'x':
                        case 'X':
                        case 'c':
                            vap = va_arg(ap,int);
                            *pdata++ = *format++;
                            *pdata = '\0';
                            printf(data,vap);
                            process = 1;
                        break;
    
  • Re: Eseguire 2 azioni contemporaneamente

    Tutti quei case senza brake servono a far sì che il codice si seguito venga eseguito qualunque lettera venga digitata tra quelle in quei case.

    Comunque ti consiglio di studiare almeno le basi del c, altrimenti difficilmente potrai personalizzare da solo le animazioni (anche se sai stampare delle figure, non serve a niente se non sai farle muovere come vuoi).

    ciao
  • Re: Eseguire 2 azioni contemporaneamente

    Evita di comprendere tutte le mie funzioni al di fuori del main,sono cose un pelo piu avanzate.
    La conio.h serve per la funzione kbhit che è dichiarata proprio li.

    Il codice presentato però è troppo grossolano.
    Presenta un primo bug della kbhit,ovvero che durante il salto diventa difficile spostarsi perchè la funzione attende diversi millisecondi per scatenare la continua pressione del tasto.Per risolvere questo problema si può usare l'api GetAsyncKeyState,questo porterà ad un'altro piccolo bug ma momentaneamente non importante.

    Il vero problema è la gestione del livello e l'unica maniera "decente" è quella dell'uso di una matrice che ci aiuti nel capire cosa c'è nel livello.
    Creata questa matrice sarà facile capire se abbiamo la terra sotto i piedi oppure abbiamo raggiunto la porta di fine livello.

    Guarda qu:
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <stdarg.h>
    #include <string.h>
    #include <windows.h>
    
    #define MAN_LIFE 3
    #define MAN_JMP 6
    #define MAN_CHAR 'O'
    #define MAN_COLOR 153
    
    #define WORLD_CHAR '#'
    #define WORLD_COLOR 42
    
    #define OBJ_PORT_CHAR '8'
    #define OBJ_PORT_COLOR 14
    
    #define CONSOLE_WIDTH 80
    #define CONSOLE_HEIGHT 24
    
    #define KEYDOWN 0x8000
    
    ///BASE WINDOWS CONSOLE FUNCTION
    
    void gotoxy (short x,short y)
    {
        COORD coord = {x, y};
        HANDLE hconsole  = GetStdHandle(STD_OUTPUT_HANDLE);
        if (hconsole == INVALID_HANDLE_VALUE) return;
        SetConsoleCursorPosition (hconsole,coord );
    }
    
    void cls()
    {
        CONSOLE_SCREEN_BUFFER_INFO csbi;
        const COORD startCoords = {0,0};
        DWORD dummy;
        HANDLE hconsole  = GetStdHandle(STD_OUTPUT_HANDLE);
        if (hconsole == INVALID_HANDLE_VALUE) return;
        GetConsoleScreenBufferInfo(hconsole,&csbi);
        FillConsoleOutputAttribute(hconsole,0,csbi.dwSize.X * csbi.dwSize.Y,startCoords,&dummy);
        FillConsoleOutputCharacter(hconsole,' ',csbi.dwSize.X * csbi.dwSize.Y,startCoords,&dummy);
        gotoxy(0,0);
    }
    
    void textcolor(unsigned short color)
    {
        HANDLE hconsole  = GetStdHandle(STD_OUTPUT_HANDLE);
        if (hconsole == INVALID_HANDLE_VALUE) return;
        SetConsoleTextAttribute(hconsole,color);
    }
    
    void printfk(char* format,...)
    {
        va_list ap;
        va_start(ap,format);
    
        char data[32];
        char* pdata;
        int vap;
        char* pcap;
        double dap;
        int* piap;
        int process;
        while (*format != '\0')
        {
            if (*format != '%')
            {
                putchar(*format);
                ++format;
            }
            else
            {
                pdata = data;
                process = 0;
                while (*format != '\0')
                {
                    *pdata++ = *format++;
                    switch (*format)
                    {
                        case 'd':
                        case 'i':
                        case 'o':
                        case 'u':
                        case 'x':
                        case 'X':
                        case 'c':
                            vap = va_arg(ap,int);
                            *pdata++ = *format++;
                            *pdata = '\0';
                            printf(data,vap);
                            process = 1;
                        break;
                        case 's':
                            pcap = va_arg(ap,char*);
                            *pdata++ = *format++;
                            *pdata = '\0';
                            printf(data,pcap);
                            process = 1;
                        break;
                        case 'e':
                        case 'f':
                        case 'g':
                            dap = va_arg(ap,double);
                            *pdata++ = *format++;
                            *pdata = '\0';
                            printf(data,dap);
                            process = 1;
                        break;
                        case 'p':
                        case 'n':
                            piap = va_arg(ap,int*);
                            *pdata++ = *format++;
                            *pdata = '\0';
                            printf(data,piap);
                            process = 1;
                        break;
                        case '%':
                            *pdata++ = *format++;
                            *pdata = '\0';
                            printf(data);
                            process = 1;
                        break;
                        case 'k':
                            if (pdata - data == 1)
                                vap = va_arg(ap,int);
                            else
                            {
                                *pdata = '\0';
                                data[0] = '0';
                                vap = atoi(data);
                            }
                            ++format;
                            textcolor(vap);
                            process = 1;
                        break;
                    }//switch %
                    if (process) break;
                }//while %
            }//is %
        }//every char format
    
        va_end(ap);
    }
    
    
    int main()
    {
        //LIVELLO1
        char maplevel1[CONSOLE_HEIGHT][CONSOLE_WIDTH + 1];
        strcpy(maplevel1[0] ,"                                                                                ");
        strcpy(maplevel1[1] ,"                                                                                ");
        strcpy(maplevel1[2] ,"                                                                                ");
        strcpy(maplevel1[3] ,"                                                                                ");
        strcpy(maplevel1[4] ,"                                                                                ");
        strcpy(maplevel1[5] ,"                                                                                ");
        strcpy(maplevel1[6] ,"                                                                                ");
        strcpy(maplevel1[7] ,"                                                                                ");
        strcpy(maplevel1[8] ,"                                                                                ");
        strcpy(maplevel1[9] ,"                                                                                ");
        strcpy(maplevel1[10],"                                                                                ");
        strcpy(maplevel1[11],"                                                                                ");
        strcpy(maplevel1[12],"                                                8                               ");
        strcpy(maplevel1[13],"                                                #                               ");
        strcpy(maplevel1[14],"                                        ###                                     ");
        strcpy(maplevel1[15],"                                #####                                           ");
        strcpy(maplevel1[16],"                       ######                                                   ");
        strcpy(maplevel1[17],"                                                                                ");
        strcpy(maplevel1[18],"          O                                                                     ");
        strcpy(maplevel1[19],"################################################################################");
        strcpy(maplevel1[20],"                                                                                ");
        strcpy(maplevel1[21],"                                                                                ");
        strcpy(maplevel1[22],"                                                                                ");
        strcpy(maplevel1[23],"                                                                                ");
    
        int manx,many,manjmp,manstj;
        int oldx,oldy;
        int startlevelx;
        int startlevely;
        int life;
        //int mov;
        int endlevel;
    
        //property
        manx = 0;
        many = 0;
        oldx = 0;
        oldy = 0;
        manjmp = 0;
        manstj = 0;
        life = MAN_LIFE;
        endlevel = 0;
    
        //drawlevel
        cls();
        int iy,ix;
        for (iy = 0 ; iy < CONSOLE_HEIGHT; iy++)
        {
            for (ix = 0; ix < CONSOLE_WIDTH - 0;ix++ )
            {
                if (maplevel1[iy][ix] == WORLD_CHAR)
                {
                    printfk("%k%c",WORLD_COLOR,WORLD_CHAR);
                }
                else if (maplevel1[iy][ix] == MAN_CHAR)
                {
                    manx = ix;
                    many = iy;
                    oldx = manx;
                    oldy = many;
                    startlevelx = manx;
                    startlevely = many;
                    maplevel1[iy][ix] = ' ';
                    printfk("%k%c",MAN_COLOR,MAN_CHAR);
                }
                else if (maplevel1[iy][ix] == OBJ_PORT_CHAR)
                {
                    printfk("%k%c",OBJ_PORT_COLOR,OBJ_PORT_CHAR);
                }
                else
                {
                    printfk("%7k%c",maplevel1[iy][ix]);
                }
            }
        }
    
        //gioco fino a che ho delle vite
        while(life && !endlevel)
        {
            //game:
            //Leggo Movimenti
            if (GetAsyncKeyState('A') & KEYDOWN)
                --manx;
            else if (GetAsyncKeyState('D') & KEYDOWN)
                ++manx;
            if ( (GetAsyncKeyState('W') & KEYDOWN) && manstj == 0 )
                manstj = 1;
    
            //eseguo salto
            if (manstj == 1)
            {
                --many;
                if (++manjmp == MAN_JMP) manstj = -1;
            }
            else if (manstj == -1)
            {
                ++many;
                --manjmp;
            }
    
            //controllo collisioni out of border
            if (manx >= CONSOLE_WIDTH)
                manx = CONSOLE_WIDTH - 1 ;
            else if (manx < 0)
                manx = 0;
            if (many < 0)
                many = 0;
            else if (many >= CONSOLE_HEIGHT)
                manx = CONSOLE_WIDTH - 1 ;
    
            //collisione con obj port
            if (maplevel1[many][manx] == OBJ_PORT_CHAR)
                endlevel = 1;
    
            //collisione terreno durante salto
            if (manstj == -1)
            {
                //se ho la terra sotto fermo la caduta
                if (maplevel1[many + 1][manx] == WORLD_CHAR)
                {
                    //se ho saltato troppo muoio
                    if (manjmp < -4)
                    {
                        --life;
                        manx = startlevelx;
                        many = startlevely;
                    }
                    manstj = 0;
                    manjmp = 0;
                }
            }
            else if (manstj == 1)
            {
                //se ho la terra sopra la testa non posso superarla
                if (maplevel1[many-1][manx] == WORLD_CHAR)
                    ++many;
            }
    
            //controllo collisione terra sotto i piedi
            if ( manstj == 0 && maplevel1[many+1][manx] != WORLD_CHAR)
                manstj = -1;
    
            //disegno omino
            if ( oldx != manx || oldy != many )
            {
                gotoxy(oldx,oldy);
                printfk("%7k ");
                gotoxy(manx,many);
                printfk("%k%c",MAN_COLOR,MAN_CHAR);
                gotoxy(0,0);
            }
    
            oldx = manx;
            oldy = many;
    
            Sleep(50);
        }
    
        cls();
        printfk("%7k");
        if (life == 0)
            printf("MORTO");
        else
            printf("COMPLIMENTI");
    Sleep(1500);//bug GetAsincKeyState
        return 0;
    }
    
    Ora il tuo compito potrebbe essere nell'implementare un vettore cubico per la gestione di piu livelli.
    E della risoluzione del bug nella gestione jamp omarino che a volte cancella il terreno di gioco(lasciata volontariamente)

    L'ndentazione vista sul forum è un pelo scorretta, ma se fai "seleziona tutto" e poi lo copi nel tuo ide si ripristina la corretta tabulazione.
  • Re: Eseguire 2 azioni contemporaneamente

    Dimenticavo la stdarg serve per "interpretare" il parametro "..."

    La funzione printfk fa le stesse cose di printf solo che aggiunge il parametro %k per la gestione dei colori.
    Lo si può usare in due maniere:
    %[numero]k esempio: printfk("%7k");
    in questo modo setti il colore di default della console.
    Oppure lo puoi usare con un parametro int.
    printfk("%k",colore);

    %k quindi non stampa niente,dice solo che da li in poi si userà k colore.
  • Re: Eseguire 2 azioni contemporaneamente

    Ok devo ancora studiare i vettori, le funzioni, le matrici e un bel pò di roba ci vorrà un pò di tempo ma poi se riuscirò a realizzare il gioco che voglio sarò più che soddisfatto quindi ne vale la pena ti dico ancora grazie per il sorgente appena faccio progressi con il "progetto" e sono abbastanza avanti con questo gioco posto il sorgente per confrontarlo con voi del forum.
Devi accedere o registrarti per scrivere nel forum
10 risposte