控制台窗口中的 C++ 像素

问题描述 投票:0回答:7

在使用 Code::Blocks v10.05 的 C++ 中,如何在控制台屏幕上绘制单个像素?这很容易吗,还是只画一个矩形会更容易?怎样给它上色?

抱歉,我无法从 SOF、HF 甚至 cplusplus.com 获取任何代码来工作。这是屏幕上的《超级马里奥世界》人物。我认为该游戏是16位的,并且适用于SNES系统。 C::B 说我需要 C::B 的 SDK。它说“afxwin.h”不存在。可以下载吗?

这就是我想做的:

Image I'm trying to create

c++ console codeblocks pixel
7个回答
27
投票

这取决于您的操作系统。我想你是在 Windows 平台上编程,因此你可以使用 SetPixel 但你必须使用“windows.h”来获取控制台句柄,所以这里有一个绘制 cos() 函数的示例:

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

using namespace std;

#define PI 3.14

int main() 
{
    //Get a console handle
    HWND myconsole = GetConsoleWindow();
    //Get a handle to device context
    HDC mydc = GetDC(myconsole);

    int pixel =0;

    //Choose any color
    COLORREF COLOR= RGB(255,255,255); 

    //Draw pixels
    for(double i = 0; i < PI * 4; i += 0.05)
    {
        SetPixel(mydc,pixel,(int)(50+25*cos(i)),COLOR);
        pixel+=1;
    }

    ReleaseDC(myconsole, mydc);
    cin.ignore();
    return 0;
}

您还可以使用其他一些库,例如:conio.h allegro.h sdl等


20
投票

如果您愿意让图像看起来是块状的,您可以利用 控制台代码页中的块字符。

  • = '\xDB' = U+2588 全块
  • = '\xDC' = U+2584 下半块
  • = '\xDF' = U+2580 上半块
  • 和空间

通过将半块与彩色文本结合使用,您可以将 80×25 控制台窗口变成 80×50 16 色显示。 (这是 QBasic 版本的 Nibbles 使用的方法。)

然后,您只需将图像转换为 16 色调色板和相当小的尺寸。

Mario in 8 lines and 10 columns of


2
投票

windows.h
提供了
SetPixel()
函数来打印窗口指定位置的像素。函数的一般形式为

SetPixel(HDC hdc, int x, int y, COLORREF& color);

其中,x和y是要显示的像素的坐标,color是像素的颜色。

重要:要使用 Code::blocks IDE 打印机器中的像素,请在链接器设置中添加链接库

libgdi32.a
(通常位于
MinGW\lib
内部)。


1
投票

控制台是一种文本设备,因此通常您不会写入单个像素。您可以创建一种特殊字体并选择它作为控制台的字体,但它将是单色的。有一些库可以简化控制台 UI 的编写(例如 Curses),但我相信除了显示精灵之外,您还可以考虑更多类似游戏的功能。

如果您想编写游戏,我建议您查看一些图形/游戏框架/库,例如SDL


1
投票

我在 code::blocks 中使用 windows.h 绘制了直线。我无法详细解释它,但我可以为您提供代码和程序来在 code::blocks 中编译它。

  1. 进入设置菜单并选择编译器和调试器。
  2. 单击链接器选项卡并添加链接库 libgdi32.a,该链接库位于 C:\Program Files\CodeBlocks\MinGW\lib 目录。

现在编译这个程序

#include <windows.h>

#include <cmath>

#define ROUND(a) ((int) (a + 0.5))

/* set window handle */

static HWND sHwnd;

static COLORREF redColor=RGB(255,0,0);

static COLORREF blueColor=RGB(0,0,255);

static COLORREF greenColor=RGB(0,255,0);


void SetWindowHandle(HWND hwnd){

sHwnd=hwnd;

}

/* SetPixel */

void setPixel(int x,int y,COLORREF& color=redColor){

if(sHwnd==NULL){

    MessageBox(NULL,"sHwnd was not initialized !","Error",MB_OK|MB_ICONERROR);

    exit(0);

}

HDC hdc=GetDC(sHwnd);

SetPixel(hdc,x,y,color);

ReleaseDC(sHwnd,hdc);

return;

// NEVERREACH //

}


void drawLineDDA(int xa, int ya, int xb, int yb){

   int dx = xb - xa, dy = yb - ya, steps, k;

   float xIncrement, yIncrement, x = xa, y = ya;

   if(abs(dx) > abs(dy)) steps = abs(dx);

   else steps = abs(dy);

   xIncrement = dx / (float) steps;

   yIncrement = dy / (float) steps;

   setPixel(ROUND(x), ROUND(y));

   for(int k = 0; k < steps; k++){

    x += xIncrement;

    y += yIncrement;

    setPixel(x, y);

 }

}

/* Window Procedure WndProc */

LRESULT CALLBACK WndProc(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam){

 switch(message){

    case WM_PAINT:

        SetWindowHandle(hwnd);

        drawLineDDA(10, 20, 250, 300);

        break;

    case WM_CLOSE: // FAIL THROUGH to call DefWindowProc

        break;

    case WM_DESTROY:

        PostQuitMessage(0);

        return 0;

    default:

    break; // FAIL to call DefWindowProc //

  }

 return DefWindowProc(hwnd,message,wParam,lParam);

}

int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int      iCmdShow){

static TCHAR szAppName[] = TEXT("Straight Line");

WNDCLASS wndclass;

wndclass.style         = CS_HREDRAW|CS_VREDRAW ;

wndclass.lpfnWndProc   = WndProc ;

wndclass.cbClsExtra    = 0 ;

wndclass.cbWndExtra    = 0 ;

wndclass.hInstance     = hInstance ;

wndclass.hIcon         = LoadIcon (NULL, IDI_APPLICATION) ;

wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW) ;

wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH) ;

wndclass.lpszMenuName  = NULL ;

wndclass.lpszClassName = szAppName ;

// Register the window //

if(!RegisterClass(&wndclass)){

    MessageBox(NULL,"Registering the class failled","Error",MB_OK|MB_ICONERROR);

    exit(0);

}

// CreateWindow //

HWND hwnd=CreateWindow(szAppName,"DDA - Programming Techniques",

            WS_OVERLAPPEDWINDOW,

             CW_USEDEFAULT,

             CW_USEDEFAULT,

             CW_USEDEFAULT,

             CW_USEDEFAULT,

             NULL,

             NULL,

             hInstance,

             NULL);

if(!hwnd){

    MessageBox(NULL,"Window Creation Failed!","Error",MB_OK);

    exit(0);

  }

  // ShowWindow and UpdateWindow //

  ShowWindow(hwnd,iCmdShow);

 UpdateWindow(hwnd);

 // Message Loop //

 MSG msg;

 while(GetMessage(&msg,NULL,0,0)){

    TranslateMessage(&msg);

    DispatchMessage(&msg);

 }

  /* return no error to the operating system */

  return 0;

}

在这个程序中我使用了DDA画线算法。像素绘制任务是通过 setPixel(ROUND(x), ROUND(y)) 函数完成的。 这是 Windows 编程,您可以在这里了解详细信息


1
投票

要在 CodeBlocks 中使用,我发现了这个(您必须添加链接器选项

-lgdi32
):

//Code Blocks: Project Build Options Linker settings Othoer linker options: add -lgdi32

我忘了:你必须把这个放在包括

windows.h
之前:

#define _WIN32_WINNT 0x0500

再次完整的余弦代码。准备编译:

//Code Blocks: Project Build Options Linker settings Othoer linker options: add -lgdi32
#define _WIN32_WINNT 0x0500
#include "windows.h"
#include <iostream>
#include <cmath>
using namespace std;

#define PI 3.14

int main(){
    HWND myconsole = GetConsoleWindow();
    HDC mydc = GetDC(myconsole);
    int pixel =0;
    COLORREF COLOR= RGB(255,255,255);

    //Draw pixels
    for(double i = 0; i < PI * 4; i += 0.05)
    {
        SetPixel(mydc,pixel,(int)(50+25*cos(i)),COLOR);
        pixel+=1;
    }

    ReleaseDC(myconsole, mydc);
    cin.ignore();
    return 0;
}

0
投票

Вот пример кода для отображения картинки pic.bmp размером с 640x400:

#include <windows.h>
HBITMAP LoadBmp(LPCWSTR name) {
    return (HBITMAP)LoadImage(NULL, name, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
}
void DrawBmp(HDC hdc, int x, int y, int width, int height, HBITMAP bmp) {
    BITMAP bitmap;
    HDC hdcMem;
    HGDIOBJ oldBitmap;
    hdcMem = CreateCompatibleDC(hdc);
    oldBitmap = SelectObject(hdcMem, bmp);
    GetObject(bmp, sizeof(bitmap), &bitmap);
    BitBlt(hdc, x, y, width, height, hdcMem, 0, 0, SRCCOPY);
    SelectObject(hdcMem, oldBitmap);
    DeleteDC(hdcMem);
}
int main() {
    HDC console = GetDC(GetConsoleWindow());
    HBITMAP bmp = LoadBmp(L"pic.bmp");  
    while (true) {
        DrawBmp(console, 0, 0, 640, 400, bmp); // Куда рисуем, позиция x, позиция y, ширина картинки, высота картинки
    }
    return 0;
}
© www.soinside.com 2019 - 2024. All rights reserved.