Mit Conio in Konsole farbige Symbole schreiben



  • Hi, ich habe mich demletzt mit C beschäftigt,
    und viele Bücher darüber gelesen, und wollte mal ein kleines Consolen Game machen, für den Einstieg der Praxis in C, und habe folgenden Code verfasst, aber in die Console will einfach keine Farbe, weshalb, könnt ihr mir da helfen, ich sehe keinen Fehler, der Compiler gibt auch keinen Fehler aus, ich nutzte Windows Vista, falls das bedeutungsvoll sein sollte :

    /**
    *   Code by Kevin Riehl (alias Developer_X 2010)
    */
    ///////////////
    #include <windows.h>
    #include <stdlib.h>
    #include <string.h>
    #include <stdio.h>
    #include <conio.h>
    #include <process.h>
    
    #define boolean short
    #define true 1
    #define false 0
    
    ///Global Variables//////////
    boolean ever_played = false;
    
    HANDLE  console_output;
    HANDLE  screen_updater;
    HANDLE  handle_runner;
    
    CONSOLE_SCREEN_BUFFER_INFO csbiInfo;
    /////////////////////////////
    
    ///Functions//////
    void game_dialog();
    void game();
    void init();
    //////////////////
    
    ///Ask the User to Play////
    void game_dialog()
    {
        while(true)
        {
            system("Cls");
            printf("::Willkommen zu BallBlocks:: \n");
            printf("- \n");
    
            if(ever_played==true)
                printf("<1> Nochmal Spielen \n");
            else
                printf("<1> Spielen \n");
    
            printf("<2> Beenden \n");
            printf("-\n");
            int answer = 0;
            while(answer!=1&&answer!=2)
            {
                answer = 0;
                fflush(stdin);
                printf("Geben Sie ihre Wahl an : ");
                scanf("%d",&answer);
            }
    
            printf("Ihre Wahl war %d.\n",answer);
            if(answer == 1)
            {
                game();
            }
            else
            {
                break;
            }
        }
    }
    /////////////////////
    
    ///This is the game Function//////
    ///which keeps the game running///
    void game()
    {
        init();
        Sleep(5000);
    
    //    CloseHandle( screen_updater );
    //    CloseHandle( handle_runner );
    //    CloseHandle( console_output );
    }
    //////////////////
    
    //Inits the Game and prepares variables
    void makeBackground()
    {
        COORD back;
        back.X = 5;
        back.Y = 5;
    
        WORD    color_attribute = 0xCB;
        char    symbol = 5;
        DWORD   Dummy;
    
        system("Cls");
        WaitForSingleObject(screen_updater,INFINITE);
        int i = 0;
        for(i = 0;i<10;i++)
        {
            color_attribute =  0x04;
            back.X = i+1;
            WriteConsoleOutputCharacter(console_output,&symbol,1,back,&Dummy);
        }
        ReleaseMutex(screen_updater);
    }
    void init()
    {
        int thread = 0;
        thread++;
        ever_played = true;
    
        console_output = GetStdHandle(STD_OUTPUT_HANDLE);
        GetConsoleScreenBufferInfo( console_output, &csbiInfo );
        system("Cls");
        screen_updater = CreateMutex(NULL,FALSE,NULL);
        handle_runner = CreateMutex( NULL, TRUE, NULL );
    
        makeBackground();
    }
    //////////////////
    
    ///Main///////////
    int main()
    {
        game_dialog();
    
        return 0;
    }
    ///////////////////
    

    danke und m.f.G. Developer_X
    :xmas2: :xmas1: :xmas2:



  • Nur mit color_attribute = 0x04 wirst du nicht weit kommen.
    Du musst damit noch irgendwas machen. Als Parameter beim Funktionsaufruf oder in eine struct schreiben o.Ä.

    PS: Das Thema ist doch etwas an ANSI-C vorbei. :xmas1:



  • Ich habe aus einem anderen Code gelernt, wie so etwas geht, und da hat es auch funktioniert, dort sah der Code so aus:

    // sample_multithread_c_program.c
    // compile with: /c
    //
    //  Bounce - Creates a new thread each time the letter 'a' is typed.
    //  Each thread bounces a happy face of a different color around
    //  the screen. All threads are terminated when the letter 'Q' is
    //  entered.
    //
    
    #include <windows.h>
    #include <stdlib.h>
    #include <string.h>
    #include <stdio.h>
    #include <conio.h>
    #include <process.h>
    
    #define MAX_THREADS  32
    
    // The function getrandom returns a random number between
    // min and max, which must be in integer range.
    #define getrandom( min, max ) (SHORT)((rand() % (int)(((max) + 1) - \
                                   (min))) + (min))
    
    #define C     261
    #define Cis   277
    #define D     293
    #define Dis   311
    #define E     329
    #define F     349
    #define Fis   369
    #define G     391
    #define Gis   415
    #define A     440
    #define Ais   466
    #define H     493
    #define Takt  1700
    
    int main( void );                    // Thread 1: main
    void KbdFunc( void  );               // Keyboard input, thread dispatch
    void BounceProc( void * MyID );      // Threads 2 to n: display
    void ClearScreen( void );            // Screen clear
    void ShutDown( void );               // Program shutdown
    void WriteTitle( int ThreadNum );    // Display title bar information
    void playMusic( void * MyID );       // Threads 2 to n: music
    
    HANDLE  hConsoleOut;                 // Handle to the console
    HANDLE  hRunMutex;                   // "Keep Running" mutex
    HANDLE  hScreenMutex;                // "Screen update" mutex
    int     ThreadNr;                    // Number of threads started
    CONSOLE_SCREEN_BUFFER_INFO csbiInfo; // Console information
    
    void playMusic( void *pMyID )
    {
        while(1){
        Sleep(Takt / 4);
        Beep(E * 2, Takt / 4);
        Beep(H * 1, Takt / 8);
        Beep(C * 2, Takt / 8);
        Beep(D * 2, Takt / 4);
        Beep(C * 2, Takt / 8);
        Beep(H * 1, Takt / 8);
        Beep(A * 1, Takt / 4);
        Beep(A * 1, Takt / 8);
        Beep(C * 2, Takt / 8);
        Beep(E * 2, Takt / 8);
        Beep(E * 2, Takt / 8);
        Beep(D * 2, Takt / 8);
        Beep(C * 2, Takt / 8);
        Beep(H * 1, Takt / 2.5);
        Beep(C * 2, Takt / 8);
        Beep(D * 2, Takt / 4);
        Beep(E * 2, Takt / 4);
        Beep(C * 2, Takt / 4);
        Beep(A * 1, Takt / 4);
        Beep(A * 1, Takt / 4);
        Sleep(Takt / (8 / 3));
        Beep(D * 2, Takt / 3.25);
        Beep(F * 2, Takt / 8);
        Beep(A * 2, Takt / 8);
        Beep(A * 2, Takt / 8);
        Beep(G * 2, Takt / 8);
        Beep(F * 2, Takt / 8);
        Beep(E * 2, Takt / 3);
        Beep(C * 2, Takt / 8);
        Beep(E * 2, Takt / 8);
        Beep(E * 2, Takt / 8);
        Beep(D * 2, Takt / 8);
        Beep(C * 2, Takt / 8);
        Beep(H * 1, Takt / 4);
        Beep(H * 1, Takt / 8);
        Beep(C * 2, Takt / 8);
        Beep(D * 2, Takt / 4);
        Beep(E * 2, Takt / 4);
        Beep(C * 2, Takt / 4);
        Beep(A * 1, Takt / 4);
        Beep(A * 1, Takt / 4);
        }
    }
    
    int main() // Thread One
    {
        // Get display screen information & clear the screen.
        hConsoleOut = GetStdHandle( STD_OUTPUT_HANDLE );
        GetConsoleScreenBufferInfo( hConsoleOut, &csbiInfo );
        ClearScreen();
    
        // Create the mutexes and reset thread count.
        hScreenMutex = CreateMutex( NULL, FALSE, NULL );  // Cleared
        hRunMutex = CreateMutex( NULL, TRUE, NULL );      // Set
        ThreadNr = 0;
    
        // Start waiting for keyboard input to dispatch threads or exit.
        KbdFunc();
    
        // All threads done. Clean up handles.
        CloseHandle( hScreenMutex );
        CloseHandle( hRunMutex );
        CloseHandle( hConsoleOut );
    }
    
    void ShutDown( void ) // Shut down threads
    {
        while ( ThreadNr > 0 )
        {
            // Tell thread to die and record its death.
            ReleaseMutex( hRunMutex );
            ThreadNr--;
        }
    
        // Clean up display when done
        WaitForSingleObject( hScreenMutex, INFINITE );
        ClearScreen();
    }
    
    void KbdFunc( void ) // Dispatch and count threads.
    {
        int         KeyInfo;
    
                ThreadNr++;
                _beginthread( playMusic, 0, &ThreadNr );
        do
        {
            KeyInfo = _getch();
            if ( tolower( KeyInfo ) == 'a' &&
                 ThreadNr < MAX_THREADS )
            {
                ThreadNr++;
                _beginthread( BounceProc, 0, &ThreadNr );
                printf("%d",ThreadNr );
            }
        } while( tolower( KeyInfo ) != 'q' );
    
        ShutDown();
    }
    
    void BounceProc( void *pMyID )
    {
        char    MyCell, OldCell;
        WORD    MyAttrib, OldAttrib;
        char    BlankCell = 0x20;
        COORD   Coords, Delta;
        COORD   Old = {0,0};
        DWORD   Dummy;
        char    *MyID = (char*)pMyID;
    
        // Generate update increments and initial
        // display coordinates.
        srand( (unsigned int) *MyID * 3 );
    
        Coords.X = getrandom( 0, csbiInfo.dwSize.X - 1 );
        Coords.Y = getrandom( 0, csbiInfo.dwSize.Y - 1 );
        Delta.X = getrandom( -3, 3 );
        Delta.Y = getrandom( -3, 3 );
    
        // Set up "happy face" & generate color
        // attribute from thread number.
        if( *MyID > 16)
            MyCell = 0x01;          // outline face
        else
            MyCell = 0x02;          // solid face
        MyAttrib =  *MyID & 0x0F;   // force black background
    
        do
        {
            // Wait for display to be available, then lock it.
            WaitForSingleObject( hScreenMutex, INFINITE );
    
            // If we still occupy the old screen position, blank it out.
            ReadConsoleOutputCharacter( hConsoleOut, &OldCell, 1,
                                        Old, &Dummy );
            ReadConsoleOutputAttribute( hConsoleOut, &OldAttrib, 1,
                                        Old, &Dummy );
            if (( OldCell == MyCell ) && (OldAttrib == MyAttrib))
                WriteConsoleOutputCharacter( hConsoleOut, &BlankCell, 1,
                                             Old, &Dummy );
    
            // Draw new face, then clear screen lock
            WriteConsoleOutputCharacter( hConsoleOut, &MyCell, 1,
                                         Coords, &Dummy );
            WriteConsoleOutputAttribute( hConsoleOut, &MyAttrib, 1,
                                         Coords, &Dummy );
            ReleaseMutex( hScreenMutex );
    
            // Increment the coordinates for next placement of the block.
            Old.X = Coords.X;
            Old.Y = Coords.Y;
            Coords.X += Delta.X;
            Coords.Y += Delta.Y;
    
            // If we are about to go off the screen, reverse direction
            if( Coords.X < 0 || Coords.X >= csbiInfo.dwSize.X )
            {
                Delta.X = -Delta.X;
            //    Beep( 400, 50 );
            }
            if( Coords.Y < 0 || Coords.Y > csbiInfo.dwSize.Y )
            {
                Delta.Y = -Delta.Y;
            //   Beep( 600, 50 );
            }
        }
        // Repeat while RunMutex is still taken.
        while ( WaitForSingleObject( hRunMutex, 75L ) == WAIT_TIMEOUT );
    }
    
    void ClearScreen( void )
    {
        DWORD    dummy;
        COORD    Home = { 0, 0 };
        FillConsoleOutputCharacter( hConsoleOut, ' ',
                                    csbiInfo.dwSize.X * csbiInfo.dwSize.Y,
                                    Home, &dummy );
    }
    

    Ich weiß ja nicht wo der Unterschied ist, außer dass
    bei diesem Code hier, aus dem ich gelernt habe, noch ein Pointer dann ein & und dann 0xXX war, ich habe das übrigstens auch noch nie gesehen. Diese Schreibweise kenn ich gar nicht, kannst du sie mir erklären,
    danke,
    m.f.G. DX



  • Dieser Thread wurde von Moderator/in rüdiger aus dem Forum C (C89 und C99) in das Forum DOS und Win32-Konsole verschoben.

    Im Zweifelsfall bitte auch folgende Hinweise beachten:
    C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?

    Dieses Posting wurde automatisch erzeugt.



  • Hallo,

    Ein Unterschied ist noch, dass du nicht WriteConsoleOutputAttribute() benutzt.

    Developer_X schrieb:

    ... noch ein Pointer dann ein & und dann 0xXX war, ich habe das übrigstens auch noch nie gesehen. Diese Schreibweise kenn ich gar nicht, kannst du sie mir erklären,
    danke,

    Meinst du das hier ?

    MyAttrib =  *MyID & 0x0F;   // force black background
    

    Der Inhalt der Speicherzelle auf die MyID zeigt wird mit dem Wert 0x0F (15) bitweise verundet und dann der Variablen MyAttrib zugewiesen.

    Ganz normales C.

    Da ich den Kram mit GetConsoleScreenBufferInfo() nicht kenne hier nur eine Vermutung:
    - Du schreibst direkt in den Bildschirmspeicher. Der ist 80x25 Anzeigestellen groß.
    - Jede Anzeigestelle besteht aus einem Speichplatz für das Zeichen und einen Platz für das Attribut (Farbe, blinken).

    Wenn dem so ist, wäre das Buch PC-Intern von Data-Becker etwas für dich.
    Findet sich evtl. auch in der Bibliothek.



  • Das ist inzwischen oft abhängig vom Betriebssystem und Compiler.

    Dein Quelltext weist auf einen Microsoft-Compiler hin?

    Hier mal ein einfaches Beispiel für bunten Text:

    // Einfache Consolen-Farb-Demo
    // möglich sind bei der Umsetzung Abhängigkeiten von Compiler und/oder Betriebssystem
    
    #include <stdio.h>
    #include <windows.h>
    
    // 'textcolor' direct verstehen eigendlich
    // nur borland dos c/c++ compiler, siehe "conio.h",
    // oder einige addon-bibliotheken.
    // Schaut mal genau was eure suchfunk-
    // tionen herausfinden 'textcolor' oder
    // 'irgendetwastextcolor' ;)
    
    //---------
    void textcolor( WORD color )           //Funktion fuer Farbe
    {
        SetConsoleTextAttribute( GetStdHandle( STD_OUTPUT_HANDLE ), color );
    }
    //  wenn einmal im quelltext 'textcolor', dann um sichere ergebnisse zu haben
    //  sehr ausgiebig testen!
    //---------
    
    int main()
    {
        printf("test");
        textcolor(2);
        printf("\n test in 2");
        textcolor(32);
        printf("\n test in 32");
        textcolor(95);
        printf("\n test in 95");
        textcolor(10);
        printf("\n test in 10");
        int selbst; // C99 -> sonst weiter oben ;)
        printf("\n geben sie eine eigene Farbe an - max.255: "); // max.255 prüfen
        scanf("%i", &selbst);
        textcolor(selbst);
        printf("\n Diese farbe ist: %i \n", selbst);
    
        return(0);
    }
    

    Spielkartensymbole sind auch möglich.

    MfG f.-th.



  • Ich danke euch beiden vielmalst für die Antworten!
    Mein Problem ist halt, ich habe mein C-Buch durch, und wollte mal
    praktisch einsteigen in C, ich kann nämlich Java, und hatte mir, aus
    Gründen der 3D Entwicklung für C++ entschieden, doch wollte ich erst einmal
    mit C beginnen, und muss sagen, das ist eine schöne Sprache.
    Aufjeden fall wurde im Buch nichts über dergleichen von Farbiger Konsole
    berichtet, leider, und den Code, aus dem ich lernen musste war, na wer hätte das gedacht, aus dem MSDN, MicroSoftDeveloperNetwork.

    Danke euch, eine Frage nur, gibt es auch eine so einfache Methode an einem Bestimmten Stelle ein Char einzufügen?

    Danke für eure Hilfen, m.f.G. Developer_X



  • Das ist extrem Systemabhängig und hat erstmal nichts mit C zu tun.

    Das einfachste ist sich das Bild in einem Array zu merken und komplett neu
    auszugeben.

    Du musst auch nicht erst C und dann C++ lernen. Da sind verschiedene Sprachen (bei denen ein paar Schlüsselwörter gleich sind 😃 ).



  • Developer_X schrieb:

    ich kann nämlich Java, und hatte mir, aus
    Gründen der 3D Entwicklung für C++ entschieden, doch wollte ich erst einmal
    mit C beginnen, und muss sagen, das ist eine schöne Sprache.

    Mir scheint, du kennst dich mit C noch nicht so gut aus 😃 .
    Wie DirkB sagte, musst du nicht mit C anfangen und außerdem solltest du nicht gleich mit plattformabhängiger Programmierung und farbiger Konsole anfangen. Viel wichtiger ist es, Grundlagen und Techniken zu erlernen und dann schleunigst auf C++ umzusteigen 😉 .


Anmelden zum Antworten