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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12378642/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 16:13:48  来源:igfitidea点击:

C++ Pixels In Console Window

c++consolecodeblockspixels

提问by hCon

In C++ using Code::Blocks v10.05, how do I draw a single pixel on the console screen? Is this easy at all, or would it be easier to just draw a rectangle? How do I color it? I'm sorry, but I just can't get any code from SOF, HF, or even cplusplus.com to work. This is for a Super Mario World figure on the screen. The game I think is 16-bit, and is for the SNES system. C::B says I need SDK for C::B. It says "afxwin.h" doesn't exist. Download maybe? This is what I'm trying to make:

在 C++ 中使用 Code::Blocks v10.05,如何在控制台屏幕上绘制单个像素?这很简单,还是只画一个矩形更容易?我如何给它上色?抱歉,我无法从 SOF、HF 甚至 cplusplus.com 获取任何代码来工作。这是屏幕上的超级马里奥世界人物。我认为这款游戏是 16 位的,适用于 SNES 系统。C::B 说我需要 C::B 的 SDK。它说“afxwin.h”不存在。可以下载吗?这就是我想要做的:

Image I'm trying to create

我正在尝试创建的图像

回答by FacundoGFlores

It depends on your OS. I suppose you are programming in a Windows platform, therefore you can use SetPixelbut you have to use "windows.h" to get a console handle, so here an example for drawing the cos() function:

这取决于您的操作系统。我想你是在 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;
}

You can also use some others libraries like: conio.h allegro.h sdl, etc.

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

回答by dan04

If you're willing to have the image look blocky, you could take advantage of the block characters from the console code page.

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

  • = '\xDB' = U+2588 FULL BLOCK
  • = '\xDC' = U+2584 LOWER HALF BLOCK
  • ?= '\xDF' = U+2580 UPPER HALF BLOCK
  • and space
  • = '\xDB' = U+2588 全块
  • = '\xDC' = U+2584 下半块
  • ?= '\xDF' = U+2580 上半块
  • 和空间

By using the half-blocks in combination with colored text, you can turn an 80×25 console window into an 80×50 16-color display. (This was the approach used by the QBasic version of Nibbles.)

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

Then, you just need to convert your image to the 16-color palette and a reasonably small size.

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

Mario in 8 lines and 10 columns of "text"

马里奥8行10列“文字”

回答by dan04

windows.hprovides a function SetPixel()to print a pixel at specified location of a window. The general form of the function is

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

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

where, x and y are coordinates of pixel to be display and color is the color of pixel.

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

Important: to print the pixel in your machine with Code::blocks IDE, add a link library libgdi32.a(it is usually inside MinGW\lib) in linker setting.

重要提示:要使用 Code::blocks IDE 在您的机器中打印像素,请在链接器设置中添加一个链接库libgdi32.a(通常在里面MinGW\lib)。

回答by Dinesh Subedi

I have drawn the straight line using windows.h in code::blocks. I can't explain it in details, but I can provide you a code and procedure to compile it in code::blocks.

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

  1. go to setting menu and select compiler and debugger.
  2. Click on linker tab and add a link library libgdi32.a which is at C:\Program Files\CodeBlocks\MinGW\lib directory.
  1. 转到设置菜单并选择编译器和调试器。
  2. 单击链接器选项卡并添加位于 C:\Program Files\CodeBlocks\MinGW\lib 目录的链接库 libgdi32.a。

Now compile this program

现在编译这个程序

#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;

}

In this program I have used DDA line drawing algorithm. Pixel drawing tasks is done by setPixel(ROUND(x), ROUND(y)) function. This is windows programing which you can learn details here

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

回答by Zdeslav Vojkovic

Console is a text device, so in general you don't write to individual pixels. You can create a special font and select it as a font for console, but it will be monochromatic. There are libraries which simplify writing console UI (e.g. Curses), but I believe that you also have more gamelike functionality in mind besides just showing a sprite.

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

if you want to write a game, I suggest taking a look at some of the graphics/game frameworks/libs, e.g. SDL

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

回答by tripijb tripijb

To use in CodeBlocks I found this (you have to add a linker option -lgdi32): //Code Blocks: Project Build Options Linker settings Othoer linker options: add -lgdi32

为了在 CodeBlocks 中使用,我发现了这个(你必须添加一个链接器选项 -lgdi32)://Code Blocks: Project Build Options Linker settings Othoer linker options: add -lgdi32

I forgot: You have to put this before including windows.h :#define _WIN32_WINNT 0x0500

我忘记了:你必须在包含 windows.h 之前放这个:#define _WIN32_WINNT 0x0500

The whole cosine code again. Ready to compile

再次整个余弦代码。准备编译

//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;
}