WriteConsoleOutputCharacter Рисование лишних пикселей пустого пространства - PullRequest
0 голосов
/ 09 сентября 2018

Я разрабатывал ролевую видеоигру в консоли.

Моя проблема в том, что я сначала рисую всю карту с помощью writeconsoleoutput сразу, а затем использую writeconsoleoutputcharacter, чтобы перерисовать то, что необходимо. Но я обнаружил, что он рисует дополнительный пиксель толщиной с правой стороны. Это по существу стирает один пиксель с плитки на правой стороне.

Кто-нибудь знает способ заставить его прекратить рисовать символ и добавить пробел в 1 пиксель справа от символа.

РЕДАКТИРОВАТЬ: ОДИН ИЗ РАБОТЫ, КОТОРЫЙ Я НАЙДЕН, - ПЕРЕЗАГРУЗИТЬ ЛИНИИ, НА КОТОРЫХ ИГРАЕТ ШАГ ИГРОКА, НО ЭТО НЕ СОВЕРШЕННО ОДИН РАЗ, КОГДА Я МОГУ ЗАМЕТИТЬ ФЛЕЙКЕР. Было бы предпочтительнее просто перерисовывать символы на индивидуальной основе без каких-либо пикселей, прикрепленных в конце. или где-нибудь еще. Код, используемый для печати символа

void printchar(char character, COORD location,short color)
{
    const char *pointer = &character;
    //short LENGTH = 1;
    DWORD dwWritten = 0;
    std::vector<WORD> attributes;attributes.clear();;
    setAttributesChar(color,attributes);//Pushes back the color
    if(attributes.size() == 1)
    {    WriteConsoleOutputAttribute(GetStdHandle(STD_OUTPUT_HANDLE),&attributes[0], attributes.size(), location, &dwWritten);
        WriteConsoleOutputCharacter(GetStdHandle(STD_OUTPUT_HANDLE), pointer, attributes.size(), location, &dwWritten); 
    }
}

void setAttributesChar(short color,std::vector<WORD> &attributes)
{
    switch(color)
    {
    case DEFAULTCOLOR:
        attributes.push_back(FOREGROUND_INTENSE_WHITE);return;
    case HOVEREDCOLOR:
        attributes.push_back(FOREGROUND_GREEN);return;
    case RED:
        attributes.push_back(FOREGROUND_RED);return;
    case GOLD:
        attributes.push_back(FOREGROUND_INTENSE_YELLOW);return;
    case REDWHITE:
        attributes.push_back(COMBINED_REDWHITE);return;
    case YELLOWPURPLE:
        attributes.push_back(COMBINED_YELLOWPURPLE);return;
    case NPCCOLOR:
        attributes.push_back(FOREGROUND_INTENSE_CYAN);return;
    case PURPLE:
        attributes.push_back(FOREGROUND_MAGENTA);return;
    case REDPURPLE:
        attributes.push_back(COMBINED_REDPURPLE);return;
    case BLUE:
        attributes.push_back(FOREGROUND_BLUE);return;
    case BLUEPURPLE:
        attributes.push_back(COMBINED_BLUEPURPLE);return;
    case INTENSEGREEN:
        attributes.push_back(FOREGROUND_INTENSE_GREEN);return;
    case REDGREEN:
        attributes.push_back(COMBINED_REDGREEN);return;
    case BWHITE:
        attributes.push_back(BACKGROUND_WHITE);return;
    }
}

Пример:

ПЕРЕД ХАРАКТЕРОМ ХОДИТЕ НАД ДОРОГОЙ: ПЕРЕД ИЗОБРАЖЕНИЕМ

ПОСЛЕ ХАРАКТЕРА, НАХОДЯЩЕГОСЯ НА ДОРОГЕ: ПОСЛЕ ИЗОБРАЖЕНИЯ

EXECUTABLE LINK: EXECUTABLE

Я создал рабочий пример, который вы, ребята, можете скомпилировать (при условии, что вы используете окна), чтобы увидеть, что происходит. В ней я создаю консоль, устанавливаю размер, заполняю экран символом аски 223. Затем я использую Writeconsoleoutchar для печати зеленого символа 223. Вы можете увидеть дополнительную нарисованную черную линию пикселей.

#include <windows.h>
#include <cwchar>
#include <vector>
enum COLORS{HOVEREDCOLOR};
void setAttributesChar(short color,std::vector<WORD> &attributes)
{
    switch(color)
    {
    case HOVEREDCOLOR:
        attributes.push_back(FOREGROUND_GREEN);return;
    }
}
void printchar(char character, COORD location,short color)
{
    const char *pointer = &character;
    //short LENGTH = 1;
    DWORD dwWritten = 0;
    std::vector<WORD> attributes;attributes.clear();;
    setAttributesChar(color,attributes);//Pushes back the color
    if(attributes.size() ==1)
    {      WriteConsoleOutputAttribute(GetStdHandle(STD_OUTPUT_HANDLE),&attributes[0], attributes.size(), location, &dwWritten);
        WriteConsoleOutputCharacter(GetStdHandle(STD_OUTPUT_HANDLE), pointer, attributes.size(), location, &dwWritten); 
    }
}
#define SCREENWIDTH 1550
#define SCREENHEIGHT 850
void SETWINDOWUP(DWORD &SIZE)
{
    CONSOLE_SCREEN_BUFFER_INFO info;
    MoveWindow(GetConsoleWindow(),0,0,SCREENWIDTH,SCREENHEIGHT,true);         //MOVE WINDOW TO 0,0 AND MAKE 1600 BY 880
   ::SetWindowPos(GetConsoleWindow(), HWND_TOPMOST, 0, 0, 0,0,     SWP_DRAWFRAME | SWP_NOREPOSITION | SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW); //SET WNDOWS POSITION COMPARED TO OTHER WINDOWS IN DRAW ORDER
::SetWindowPos(GetConsoleWindow(),HWND_NOTOPMOST, 0, 0, 0, 0, SWP_DRAWFRAME | SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW);
HANDLE hout = GetStdHandle( STD_OUTPUT_HANDLE);
GetConsoleScreenBufferInfo(hout,&info);
COORD newBuffersize =
{
    info.srWindow.Right - info.srWindow.Left + 1,
    info.srWindow.Bottom - info.srWindow.Top + 1
};
SetConsoleScreenBufferSize(hout,newBuffersize);
SIZE = info.dwSize.X * info.dwSize.Y;
//EDIT REGULATED FONT SIZE
CONSOLE_FONT_INFOEX cfi;
std::wcscpy(cfi.FaceName, L"Lucida Console"); // Choose your font
cfi.FontFamily = FF_DONTCARE;
cfi.nFont = 0;
cfi.dwFontSize.X = 0;
cfi.dwFontSize.Y = 25;                  // Height
cfi.FontWeight = FW_BOLD;
cfi.cbSize = sizeof(cfi);
SetCurrentConsoleFontEx(GetStdHandle(STD_OUTPUT_HANDLE), false, &cfi);
}
int main()
{
Sleep(500);DWORD SIZE = 0;SETWINDOWUP(SIZE);
DWORD charswritten;COORD start = {0,0};TCHAR CHARACTER = 223;
    FillConsoleOutputCharacter(GetStdHandle(STD_OUTPUT_HANDLE),CHARACTER,SIZE,start,&charswritten);
Sleep(500);
printchar(223,{6,5},HOVEREDCOLOR);
Sleep(500);
return 0;
};
...