Gelöst || Konsolengame beschleunigen?

Hey :)
Bin neu hier und hab gleich ne Frage q:
Also die Programmiersprache ist C++ und ich hab ein pseudo-Konsolengame gemacht, das später evtl. auch noch ausgebaut wird. Wollte eig. nur mal sehen, wie man in C++ i-welche ASCII-Zeichen in nem Char-Array bewegt.

Achja:
Entwicklungsumgebung: Dec-C++ (und der dazugehörige Compiler)
OS: Windows

Also, hier erstmal der Code: (Und habt Nachsicht, ich programmiere erst seid kurzem c++)

Code:
#include <windows.h>
#include <Winuser.h>
#include <string>
#include <fstream>
#include <iostream> 

using namespace std;

string Ende(){
       system("cls");
       cout << "Gewonnen" << endl;
       system("PAUSE");
       return 0;
       };
       

int main()
{
 //Feldgroesse:
    int y = 20;
    int x = 40;    

    char Feld[y][x];
 //Feld füllen:    
    for (int j=0; j<y; ++j){
             for (int i=0; i<x; ++i){
                   Feld[j][i] = '.';
             }
    }
    
    for (int k=0; k<y; ++k){
        Feld[k][x-1] = '\0';
        }

    //Startposition festlegen
    int Sy = 1;
    int Sx = 1;
    Feld[Sy][Sx] = 'o';
    
    //Ziel festlegen
    Feld[15][30] = 'Z';
    
    
    
    //Feld ausgeben
    for (int z=0; z<y; ++z){
        cout << Feld[z] << endl;
        }
    
    
  while(1)
    {
        //Verhindert CPU Auslastung 5ms sleep
        Sleep(5);

        
        //Tasten einlesen
        
        for(int i = 8; i < 191; i++)
        {
           if(GetAsyncKeyState(i)&1 ==1)
           {
                if (i == 87){
                      //Taste "W" gedrückt
                      
                      if (Sy != 0){
                      if (Feld[Sy-1][Sx] == 'Z'){
                                         Ende();
                                         }
                      Feld[Sy-1][Sx] = 'o';
                      Feld[Sy][Sx] = '.';
                      Sy = Sy -1;
                      
                      //neues Feld ausgeben
                       system("cls");
                       for (int z=0; z<y; ++z){
                          cout << Feld[z] << endl;
                       }
                      }  
                  }
                if (i == 65) {
                      //Taste "A" gedrückt
                      if (Sx != 0){
                      if (Feld[Sy][Sx-1] == 'Z'){
                                         Ende();
                                         }
                      Feld[Sy][Sx-1] = 'o';
                      Feld[Sy][Sx] = '.';
                      Sx = Sx -1;
                      
                      //neues Feld ausgeben
                       system("cls");
                       for (int z=0; z<y; ++z){
                          cout << Feld[z] << endl;
                          }
                       }                      
                      }
                if (i == 83){
                      //Taste "S" gedrückt
                      if(Sy != y-1) {
                      if (Feld[Sy+1][Sx] == 'Z'){
                                         Ende();
                                         }
                      Feld[Sy+1][Sx] = 'o';
                      Feld[Sy][Sx] = '.';
                      Sy = Sy +1;
                      
                      //neues Feld ausgeben
                       system("cls");
                       for (int z=0; z<y; ++z){
                          cout << Feld[z] << endl;
                          }
                       }
                      }
                if (i == 68) {
                      //Taste "D" gedrückt                 
                      if(Sx != x-2){
                      if (Feld[Sy][Sx+1] == 'Z'){
                                         Ende();
                                         }
                      Feld[Sy][Sx+1] = 'o';
                      Feld[Sy][Sx] = '.';
                      Sx = Sx +1;
                      
                      //neues Feld ausgeben
                       system("cls");
                       for (int z=0; z<y; ++z){
                          cout << Feld[z] << endl;
                                     }
                                               }
                       
                       }

           }
           }        
        }
    }

Steuerung ist WASD :)

So: mein Problem ist jetzt, dass ich das Array "Feld" bei jedem Tastendruck komplett erneut ausgeben muss, damit sich das Bild aktualisiert. Aber deswegen is das Spiel auch ziemlich langsam und in der Konsole sieht man oft ein "flackern" (also bei mir auf jedenfall ).
Meine Frage wär jetzt, wie man das ganze beschleunigen könnte, dass man das Array nicht immer neu laden muss.

Wär nett, wenn jmd. Bescheid weiß :p

slightlyNERD :)
 
Ganz einfach -> Vor dem kompilieren atmest du tief Luft ein; dann sagst du gaaanz laut "Hokus Pokus .. widibus" und kompilierst

xD

Ne sorry

ALso ich würd das so machen, dass ich ne extra Matrix anlege, die die alten Eingaben (Chars) beinhaltet. Dann würde ich einfach vor dem Zeichnen prüfen, ob die Stellen mit der Matrix gleich sind -> falls ja, dann nicht schreiben ansonsten ganz normal schreiben :)
Ich weiß jetzt aber nicht, ob es in C++ GotoXY usw gibt...

MfG
 
Original von Extinction
Ich weiß jetzt aber nicht, ob es in C++ GotoXY usw gibt...
Ja, gibt es. Haupttodesursache von Programmierern, da dies oft die Steinigung durch andere Programmierer bewirkt... X(

Ja Spitze :)
Also, ich möchte schon noch bisschen leben :p
Bin doch noch sooo jung :(

Ja, kay, und wenn ich kein gotoxy verwenden darf/ will? :p


@bad_alloc:
Jetzt schon :)
Danke, ist schonmal bisschen besser, aber flackert trotzdem noch bisschen :)
 
Ich nehme an du willst direkt Zeichen auf der Konsole ersetzten. In C++ geht das meines Wissens nach nicht, da müsstest du bei C# oder VB gucken.
Allerdings gibt es auch spezielle Bibliotheken für "Konsolen - GUIs" für einige Skripsprachen (c't 3/08?). Möglicherweise hat jemand soetwas für C++ portiert.

EDIT: giFT wäre eine Möglichkeit unter Unix, für Windows musst du ggf etwas suchen.
 
Ich gehe mal davon aus, dass mit GotoXY nicht das aus BASIC bekannte GOTO mit Sprungmarken gemeint ist (das hätte den schlimmsten Tod verdient), sondern eine Routine zum Setzen der Cursorposition (die heisst z.B. in nCurses auch gotoxy(int, int)). Wenn die Windows Kommandozeile VT100 kompatibel ist, kannst du einfach ein
Code:
 printf("%c[%02d;%02df", 0x1b, y, x);
benutzen, um die Position des Cursors zu setzen, y und x sind dabei halt vorzeichenlose Ganzzahlen die die Spalte und Zeile angeben,(1,1) ist dabei oben links.

Der Code stammt aus einem Projekt von mir, dass allerdings in C geschrieben ist, evtl. gibts da für C++ noch schönere Arten, das auszudrücken :)
 
Das setzen der Cursorposition unter Windows geht am einfachsten mit der API Funktion SetConsoleCursorPosition.
Ein Codebeispiel dazu hat Google hier gefunden.
 
RE: Konsolengame beschleunigen?

DAAAAAANKE, loose :)
Jetzt klappts prima.

Ich hab jetzt mal den Anfang von "Console Space Invaders" draus gmacht :)

Der Code:

Code:
#include <windows.h>
#include <Winuser.h>
#include <string>
#include <fstream>
#include <iostream> 
#include <stdio.h>
#include <conio.h>

using namespace std;


void gotoxy( int column, int line )
  {
  COORD coord;
  coord.X = column;
  coord.Y = line;
  SetConsoleCursorPosition(
    GetStdHandle( STD_OUTPUT_HANDLE ),
    coord
    );
  }

int wherex()
  {
  CONSOLE_SCREEN_BUFFER_INFO csbi;
  COORD                      result;
  if (!GetConsoleScreenBufferInfo(
         GetStdHandle( STD_OUTPUT_HANDLE ),
         &csbi
         ))
    return -1;
  return result.X;
  }

int wherey()
  {
  CONSOLE_SCREEN_BUFFER_INFO csbi;
  COORD                      result;
  if (!GetConsoleScreenBufferInfo(
         GetStdHandle( STD_OUTPUT_HANDLE ),
         &csbi
         ))
    return -1;
  return result.Y;
  }


int main()
{
 //Feldgroesse:
    int y = 20;
    int x = 40;    

    char Feld[y][x];
 //Feld füllen:    
    for (int j=0; j<y; ++j){
             for (int i=0; i<x; ++i){
                   Feld[j][i] = ' ';
             }
    }
    
    for (int k=0; k<y; ++k){
        Feld[k][x-1] = '\0';
        }

    //Startposition festlegen
    int Sy = y-1;
    int Sx = x/2-3; 
    
    Feld[Sy][Sx] = '/';
    Feld[Sy][Sx+1] = '%';
    Feld[Sy][Sx+2] = '%';
    Feld[Sy][Sx+3] = '\\';
    Feld[Sy-1][Sx+1] = '|';
    Feld[Sy-1][Sx+2] = '|';
    Feld[Sy-2][Sx+1] = '/';
    Feld[Sy-2][Sx+2] = '\\';
    
  
    
    
    //Feld ausgeben
    for (int z=0; z<y; ++z){
        cout << Feld[z] << endl;
        }
    
    
  while(1)
    {
        //Verhindert CPU Auslastung 5ms sleep
        Sleep(5);

        
        //Tasten einlesen
        
        
        for(int i = 8; i < 191; i++)
        {
           if(GetAsyncKeyState(i)&1 ==1)
           {
                if (i == 65) {
                      //Taste "A" gedrückt
                  if (Sx != 0)
                  {
                      gotoxy(Sx-1,Sy);
                      cout << "/%%\\ ";
                      gotoxy(Sx,Sy-1);
                      cout << "|| ";
                      gotoxy(Sx,Sy-2);
                      cout << "/\\ ";
                      gotoxy(0,y);
                      --Sx;
                  }
                }
                      
                      
                if (i == 68) {
                      //Taste "D" gedrückt                 
                  if(Sx != x-5){
                      gotoxy(Sx,Sy);
                      cout << " /%%\\";
                      gotoxy(Sx+1,Sy-1);
                      cout << " ||";
                      gotoxy(Sx+1,Sy-2);
                      cout << " /\\";
                      gotoxy(0,y);
                      ++Sx;
                        }
                    }

                  if (i == 32) {
                      //Leertaste gedrückt
                      int bx = Sx;
                      int by = Sy;
                      gotoxy(bx+1,by-3);
                      cout << "**";
                      
                      for(int i=4; i<y; ++i)
                      {
                      Sleep(20);
                      gotoxy(bx+1,by-4);
                      cout << "**";
                      gotoxy(bx+1,by-3);
                      cout << "  ";
                      --by;
                      }
                      gotoxy(Sx+1,0);
                      cout << "  ";
                      gotoxy(0,y);
                      //bullet Bullet erstellen und Bullet.shoot mit koordinaten aufrufen!
                      }
                   }
                 }        
    }
}

Find ich bis jetz eig. ganz okay :)

Aaaaaaaber:
Ich kann mich jetzt, während ich schieße, nicht bewegen und nicht nochmal schießen... Is ja auch klar.
Hatte auch schon mal die ganze Tastaturabfrage wieder in die "for-Schleife" kopiert.
Find ich aber doof.
Kann man das nicht i-wie ganz leicht, durchsichtig und auch noch rel. elegant lösen.
Vllt. mit ner Funktion (Tastenabfrage) und dann per Rekursion immer wieder auf sich selbst zugreifend? Nja, weiß nich genau. Aber habt ihr ne Idee, wies möglichst einfach geht?
Danke.

Und noch kurz was: Wo ist eig. der Unterschied zwischen "cout << " "; " und " printf(""); " ?

slightlyNERD
 
Ah, okay :)
Hab ich mir schon i-wie gedacht.
Aber ich fands immer komisch, dass man, wenn man nach nem c++-code fragt, oft i-was mit "printf" sieht oder in nem c++-board was von printf steht.

Das find ich eh immer blöd, dass das alles vermischt wird. (C/C++)
 
Naja, C++ ist halt eine Übermenge von C, und da die meisten Leute, die mit C++ rumturnen, vorher C gelernt haben, benutzen sie die Sachen, die sie dort gelernt haben, weiter.
 
Zurück
Oben