sterowanie kursorem po konsoli, migający ekran

0

Napisałem program który umożliwia sterowanie kursorem po konsoli. Jednak za każdym razem jak wciśniemy kursor to wszystko działa dobrze, jednak mapa się odświeża i wygląda to nieestetycznie. Najlepiej jak wkleicie program do kompilatora i sami zobaczycie:

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

using namespace std;

int main()
{
    char kursor[50][80];
    char c1;
    int i = 9, j = 9;


    for (int y = 0; y < 50; y++)
    for (int x = 0; x < 80; x++)
    kursor[y][x] = ' ';

    kursor[i][j] = '_';

do
{

system("cls");
    for (int y = 0; y < 50; y++)
    for (int x = 0; x < 80; x++)
    cout << kursor[y][x];


        c1 = getch();

kursor[i][j] = ' ';

        if (c1 == 72) i--;
        if (c1 == 80) i++;
        if (c1 == 77) j++;
        if (c1 == 75) j--;

kursor[i][j] = '_';

}while(c1 != 27);
}

0

Widzę, że program i tak zależny jest od Windows'a więc użyj WinAPI. Zawartość całej tablicy można w prosty i szybki sposób przenieść na konsolę funkcją WriteConsoleOutputCharacter.

char tablica[25][80]; // tablica wszystkich znaków

DWORD cWritten; 
COORD coord= { 0, 0 }; 
WriteConsoleOutputCharacterA(GetStdHandle(STD_OUTPUT_HANDLE), tablica, 80 * 25 - 1, coord, &cWritten);

Dlaczego 80 * 25 - 1 (dlaczego -1)? Bo nie można nic wpisać w prawy dolny róg konsoli bo wtedy utworzy nam nową pustą linijkę na dole i wszystko przesunie się o jeden wiersz w górę.

No i konsola nie koniecznie musi mieć 80x25 znaków.

0

Ale ja nie znam się na obsłudze WinAPI.

0

To się naucz. W czym problem? To w tym przypadku zwykłe wywoływanie funkcji.

Zamiast zapisywać za każdym razem cały ekran, lepiej będzie pisać tylko po tych komórkach, które się zmieniły. W tym przypadku będzie to pozycja, z której kursor się przesunął (trzeba tam "narysować" tło) oraz nowa pozycja kursora. Zrobisz to za pomocą SetConsoleCursorPosition i wypisaniem znaków za pomocą standardowych funkcji do obsługi IO albo od razu przez WriteConsoleOutput.

0

Czyli rozumiem, że już nie chcesz się kształcić i twój aktualny poziom programowania Ci wystarcza?

0

Wywołać funkcji nie umiesz? Pokazałem ci jak...

0

Bibliotekę graficzną miałem przerabiać dopiero po skończeniu paru innych tematów, i myślałem o Allegro. Pisząc ten program miałem nadzieje że obecne informacje które posiadam są wystarczające.

0

Jeżeli spotykamy się z nowym problemem to prawie nigdy obecnie posiadane informacje nie są wystarczające. Po to mamy dokumentacje, żeby się douczyć.

0

adf nic mi nie mówi twoje wywołanie funkcji, nie wiem co gdzie umieścić. Szukam po necie i nic.

0

Ta funkcja, tak jak pisałem, wyświetli zawartość tablicy znaków char na ekran konsoli. Zastąpi cały fragment odpowiedzialny za wyświetlanie.
Tutaj znajdziesz szczegóły odnośnie funkcji: WriteConsoleOutputCharacter

0

Takie ustawienie powoduje błąd


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

using namespace std;

int main()
{
    char kursor[25][80];
    char c1;
    char wskaznik;
    int i = 9, j = 9;



    for (int y = 0; y < 50; y++)
    for (int x = 0; x < 80; x++)
    kursor[y][x] = ' ';

    kursor[i][j] = '_';

do
{

system("cls");

DWORD cWritten;
COORD coord= { 0, 0 };
WriteConsoleOutputCharacterA(GetStdHandle(STD_OUTPUT_HANDLE), kursor, 80 * 25 - 1, coord, &cWritten);


        c1 = getch();

kursor[i][j] = ' ';

        if (c1 == 72) i--;
        if (c1 == 80) i++;
        if (c1 == 77) j++;
        if (c1 == 75) j--;

kursor[i][j] = '_';

}while(c1 != 27);
}
0

Złota łopata ląduje do Lorda Dominika!

Czy wszyscy "programiści" na forum muszą być takimi ujami?
Widzicie, że gość dopiero zaczyna przygodę z programowaniem i już na niego naskakujecie: "to się naucz", nauczy się, ale w swoim czasie. Ty też wszystko wiedziałeś po miesiącu nauki? Wskaźniki poznałeś drugiego dnia nauki, a wielowątkowe programy obiektowe pisałeś tydzień później?

"Czyli rozumiem, że już nie chcesz się kształcić i twój aktualny poziom programowania Ci wystarcza?" Ten wniosek wysunąłeś na podstawie tego, że zaczął szukać pomocy na forum "dla programistów"? Powinniście zmienić nazwę na "4buffoons.net".

"Wywołać funkcji nie umiesz? Pokazałem ci jak..." Nie zauważyłeś, że w jego programie nie ma, ani jednej własnej procedury? Ani jednej własnej funkcji. Może nawet nie wie czym są funkcje, a wywołanie for'a jest dla niego automatyczne i nigdy nie zastanawiał się, że to jest funkcja. Więc po co ten poniżający ton? Ty też zaczynałeś programowanie od STL'a i obiektówki?

To wygląda jakbyście chcieli zniechęcić go do nauki programowania, dlaczego? Może się boicie konkurencji? W takim razie jak miernymi programistami musicie być?

poza tym po co pokazujecie uchwyty czary mary i inne śmieszne rzeczy, skoro problem można rozwiązać w prosty sposób używając samego coni.h, który jak widzicie został podany. Każda odpowiedź powinna być podana w przystępny sposób do odbiorcy, skoro widzicie jak wygląda jego program to bazując na własnym doświadczeniu powinniście wiedzieć na jakim poziomie jest jego nauka i na podstawie tego podać mu najprostsze rozwiązanie, które wygląda tak:

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

using namespace std;

void gotoxy(int x, int y) // Funkcja za pomocą której przemieszczamy kursor dowolnie po konsoli
{
    COORD coord; // na razie nie ma znaczenia
    coord.X = x; // na razie nie ma znaczenia
    coord.Y = y; // na razie nie ma znaczenia
    SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord); // na razie nie ma znaczenia
}



int main()
{
    int x=0;
    int y=0;
    int c1;

    gotoxy(x,y); // ustawienie kursora na wartości x=0 i y=0
    cout << "_";
    for(;;)
    {

        c1 = getch();
        gotoxy(x,y);
        cout << " ";

        if (c1 == 119 && y>0) y--; // w
        if (c1 == 115 && y < 25) y++; // s
        if (c1 == 97 && x > 0) x--; // a
        if (c1 == 100 && x < 25) x++; // d

        gotoxy(x,y);
        cout << "_";
    }

    return 0;
}

Też oczywiście podczas deklaracji funkcji gotoxy(int x, int y); Mamy "dziwne" rzeczy, ale nie musimy przecież wiedzieć co one robią bo nie to jest naszym problemem, jedyne czego potrzebujemy to NAUCZENIE SIĘ jak korzystać z funkcji gotoxy(int x, int y); Czyli po prostu wpisujemy w (argumentach) funkcji koordy gdzie chcemy umiejscowić kursor. Ja kurat zrobiłem sterowanie na WSAD i tylko z wyłączonym CapsLockiem, ale przecież nie o to chodzi by robić program idealny. Better done than perfect.

Ogólnie zachowanie wasze jest strasznie bucowate i mam nadzieję, że nie będę miał wątpliwej przyjemności tworzenia z państwem wspólnego projektu.

0

Jeszcze troszkę wykopię:

WriteConsoleOutputCharacterA(GetStdHandle(STD_OUTPUT_HANDLE), kursor, 80 * 25 - 1, coord, &cWritten);

Błąd jest w drugim argumencie tej funkcji. Ponieważ owa funkcja przyjmuje argument typu

const char *

, a nie zwykłą tablicę char x[][];
By to naprawić trzeba wykonać jeden z dwóch zabiegów, albo zrzutować argument "kursor" do char* w ten sposób:

WriteConsoleOutputCharacterA(GetStdHandle(STD_OUTPUT_HANDLE),(const char*)kursor, 80 * 25 - 1, coord, &cWritten);

Kompilator to łyknie, ale sam program raczej nie zadziała, bo praktycznie zawsze zabawa wskaźnikami w ten sposób powoduje wyjście poza pamięć.

Albo sam argument "kursor" zamienić na tablicę wskaźników... to nie jest zbyt bystry pomysł jeśli się nigdy nie korzystało z tablicy, ale można pomóc:

Zamienić:

char kursor[25][80];

na:

const char *kursor;

Oczywiście, kompilator łyknie, a program się nie wysypie, ale straci całkowicie swoją funkcjonalność ponieważ taki zapis:

  kursor[i][j] = '_';

Nie będzie mieć sensu w przypadku deklarowania wskaźnika na

char

.

Reasumując:
Fragment kodu Pana adf cośtam:

char tablica[25][80]; // tablica wszystkich znaków
 
DWORD cWritten; 
COORD coord= { 0, 0 }; 
WriteConsoleOutputCharacterA(GetStdHandle(STD_OUTPUT_HANDLE), tablica, 80 * 25 - 1, coord, &cWritten);

jest BŁĘDNA, bo podaje argument typu dwuwymiarowej tablicy znaków, do funkcji, która za argument przyjmuje CIĄG znaków, a nie MACIERZ!

Więc panie bufonie wygląda na to, że to ty nie umiesz wywołać funkcji skoro podajesz złe argumenty, nie starając się nawet ich zrzutować co i tak skończyłoby się out of range i wysypaniem programu.
Nie wiem, może na szybko wziąłeś jakiś pierwszy lepszy poradnik przepisałeś z niego wszystko krok po kroku, a potem chciałeś zademonstrować jak to wspaniałomyślnie wykorzystasz "skomplikowaną" funkcję do rozwiązania trywialnego problemu, samemu popełniając błąd przy podawaniu argumentów do funkcji zmieniając typ const char * na char ** brawo...

1 użytkowników online, w tym zalogowanych: 0, gości: 1