在使用 Code::Blocks v10.05 的 C++ 中,如何在控制台屏幕上绘制单个像素?这很容易吗,还是只画一个矩形会更容易?怎样给它上色?
抱歉,我无法从 SOF、HF 甚至 cplusplus.com 获取任何代码来工作。这是屏幕上的《超级马里奥世界》人物。我认为该游戏是16位的,并且适用于SNES系统。 C::B 说我需要 C::B 的 SDK。它说“afxwin.h”不存在。可以下载吗?
这就是我想做的:
这取决于您的操作系统。我想你是在 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等
windows.h
提供了SetPixel()
函数来打印窗口指定位置的像素。函数的一般形式为
SetPixel(HDC hdc, int x, int y, COLORREF& color);
其中,x和y是要显示的像素的坐标,color是像素的颜色。
重要:要使用 Code::blocks IDE 打印机器中的像素,请在链接器设置中添加链接库
libgdi32.a
(通常位于 MinGW\lib
内部)。
控制台是一种文本设备,因此通常您不会写入单个像素。您可以创建一种特殊字体并选择它作为控制台的字体,但它将是单色的。有一些库可以简化控制台 UI 的编写(例如 Curses),但我相信除了显示精灵之外,您还可以考虑更多类似游戏的功能。
如果您想编写游戏,我建议您查看一些图形/游戏框架/库,例如SDL
我在 code::blocks 中使用 windows.h 绘制了直线。我无法详细解释它,但我可以为您提供代码和程序来在 code::blocks 中编译它。
现在编译这个程序
#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 编程,您可以在这里了解详细信息
要在 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;
}
Вот пример кода для отображения картинки 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;
}