c++大作業怎麼用windows API 做個窗口程序?不用MFC或者是QT這些工具。

感謝大家的回答orz

---------分界線------------

其實題主想做得遊戲不複雜,界面也可以醜醜的,大概是做個小的跑酷類的遊戲,感覺還是得具體下手之後有問題再問問比較好,先看看《windows程序設計》這本書好了。

再次感謝orz

--------以下是原來的問題-----------

題主現在是軟工的大一新生,c++大作業,想做一個小遊戲,窗口程序那種的,但是想直接使用windows api 來做(知道會比較難弄orz),題主看過一些windows API的函數,知道怎麼在cmd裡面搞出顏色和填充這些東西,但是不知道,從這到用API直接做出小遊戲還需要學習哪些知識


過時的資料都該扔了。

題主說的是 C++ 吧?好,看這裡:

Learn to Program for Windows in C++ (Windows)

這個是入門的,其中圖形部分直接扔掉了 GDI,直接上的 Direct2D,而且裡面的 C++ 代碼還可以。

然後實戰,學習 M$ 為 Windows 7 寫的一個 Demo:HiLo,應用了各種 Windows 7 的新特性:

Hilo: Developing C++ Applications for Windows 7 (Windows)

Ok。那些什麼用純 C 寫 Win32,GDI 滿天飛的都不要看,沒有任何價值。Windows XP 扔了。

另外囑咐一句,Win32 GUI 會建一個窗口得了,那些 Aji 控制項在我看來都是糟粕,用到再查。相比之下 Windows via C/C++ 5th Edition 的內容更有意義。


《Windows 程序設計》,下本這個書看看,很久很久以前我讀書那會,用的就是這個^_^,照著做挺容易的。windows api幾乎沒人用了,不過看看他的實現原理和消息響應挺有意思的。


一個貌似靠譜的做法:

1. 將《Windows 程序設計》前幾章看一下,掌握:

(1) Windows 的消息機制、消息回調函數;知道如何處理滑鼠、鍵盤、定時器等消息。

(2) 畫筆、畫刷的創建、使用、銷毀;

(3) 點陣圖的使用;更進一步可以了解一下雙緩衝技術、了解一下精靈圖;

2. 《Windows 核心編程》翻到附錄,了解一下 windowsx.h 提供的消息處理宏、轉發宏的使用。windowsx.h 中還提供了形如 SelectPen、DeletePen 這樣的更方便使用的宏。

3. 我記得 @毛星雲 的 CSDN 博客里有好多相關知識。

以前,還看過一本書:Visual C++遊戲編程基礎 (豆瓣),直接用的 Win32 API 編遊戲。

最後,老師讓用 SDL、SFML、GDI+ 嗎?


/******************************************************************
貪食蛇 Preview
此版本貪吃蛇用蛇的方塊是集合用的是數組
蛇移動是以Sleep()阻斷進程實現的
故蛇移動看似較為卡頓,且數組插入數據效率較低,
故操作體驗十分一般
*******************************************************************/
#include&
#include &

#pragma comment(lib,"winmm.lib")

#define LENGTH 40 //遊戲場地的寬
#define WIDTH 10 //組成蛇的的正方形的邊長
#define RANGE 50 //遊戲場地與客戶去之間間隔
#define SNAKE_COLOR RGB(255,0,0) //蛇的顏色
#define BK_COLOR RGB(204,232,207) //窗體背景色
#define NO_SNAKE 0
#define HAS_SNAKE 1
#define STEP 2
#define MAKECOOR(x) (x)*WIDTH //把flags數組的下標映射為坐標

typedef struct
{
int x;
int y;
int flag;
} GRID;//蛇的結構

LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);
void MakePartSnake(int,int,int,GRID *); //為蛇身增加或設置一個方塊
void MoveSnake(HWND); //移動蛇
void MakeFood(GRID *food); //製造隨機方塊
void initializer(); //初始化遊戲
void Manager();

TCHAR szAppName[] = TEXT("Gluttony Snake");
int flags[LENGTH][LENGTH]; //遊戲區域所有方塊的狀態標記
RECT playground; //遊戲場地
GRID *snake = NULL; //蛇所在位置數組
GRID *food = NULL; //食物對象
static int MAX_LENGTH = 0;//默認蛇分配的最大長度(可變的)
int snake_len = 0;
int direct = 0;
int WINAPI WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
PSTR szCmdLine,
int iCmdShow)
{
MSG msg;
HWND hwnd;
WNDCLASS wndclass;
while(TRUE)
{
wndclass.cbClsExtra = 0;
wndclass.cbWndExtra = 0;
wndclass.hbrBackground=CreateSolidBrush(RGB(203,202,201));
wndclass.hIcon = LoadIcon(NULL,IDI_APPLICATION);
wndclass.hCursor = LoadCursor(NULL,IDC_ARROW);
wndclass.hInstance = hInstance;
wndclass.lpfnWndProc = WndProc;
wndclass.lpszMenuName = NULL;
wndclass.lpszClassName = szAppName;
wndclass.style = CS_VREDRAW | CS_HREDRAW;

if(!RegisterClass(wndclass))
{
MessageBox(NULL,TEXT("Register class failed!! Retry??"),szAppName,0);
return 0;
}
break;
}
hwnd = CreateWindow(szAppName,
TEXT("Gluttony Snake Preview V1.0.1"),
WS_OVERLAPPEDWINDOW ^ WS_THICKFRAME ^ WS_MINIMIZEBOX ^ WS_MAXIMIZEBOX,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
NULL,NULL,
hInstance,
NULL);

ShowWindow(hwnd,SW_NORMAL);
UpdateWindow(hwnd);
while(TRUE)
{
if(PeekMessage(msg,NULL,0,0,PM_REMOVE))
{
if(msg.message == WM_QUIT)
break;
TranslateMessage(msg);
DispatchMessage(msg);
}
else
{
MoveSnake(hwnd);
}
}
return msg.wParam;
}
LRESULT CALLBACK WndProc(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam)
{
HDC hdc;
PAINTSTRUCT ps;
HBRUSH hBrush;
switch(message)
{
case WM_DESTROY:
PostQuitMessage(0);
return 0;

case WM_CREATE:
//PlaySound(TEXT("HG.wav"),NULL ,SND_ASYNC | SND_LOOP);//播放遊戲音樂;
initializer();
MoveWindow(hwnd,RANGE * 2,RANGE * 2,WIDTH * LENGTH + RANGE * 3,WIDTH * LENGTH + RANGE * 3,TRUE);
return 0;
case WM_KEYDOWN:
switch(wParam)
{
case VK_LEFT:
if(direct != VK_RIGHT)
direct = VK_LEFT;
break;
case VK_RIGHT:
if(direct != VK_LEFT)
direct = VK_RIGHT;
break;
case VK_UP:
if(direct != VK_DOWN)
direct = VK_UP;
break;
case VK_DOWN:
if(direct != VK_UP)
direct = VK_DOWN;
break;
default:
break;
}
return 0;

case WM_PAINT:
for(int i = 0; i != snake_len; ++i)
{
flags[(snake + i)-&>x][(snake + i)-&>y] = (snake + i)-&>flag;
}
hdc = BeginPaint(hwnd,ps);
SetViewportOrgEx(hdc,RANGE/2,RANGE,NULL);
hBrush = CreateSolidBrush(BK_COLOR);
SelectObject(hdc,hBrush);
Rectangle(hdc,playground.left,playground.top,playground.right,playground.bottom);
DeleteObject(hBrush);
hBrush = CreateSolidBrush(SNAKE_COLOR);
SelectObject(hdc,hBrush);
for(int i = 0; i != LENGTH;++i)
{
for(int j = 0; j != LENGTH;++j)
{
if(flags[i][j] == HAS_SNAKE)
{
Rectangle(hdc,MAKECOOR(i),MAKECOOR(j),MAKECOOR(i+1),MAKECOOR(j+1));
}
}
}
DeleteObject(hBrush);
EndPaint(hwnd,ps);
}
return DefWindowProc(hwnd,message,wParam,lParam);
}
//////////////////////////初始化遊戲各個參數////////////////////////////////////////////////////////////
void initializer()
{
if(snake != NULL)
free(snake);
if(food != NULL)
free(food);
snake_len = 3; //蛇的初始長度為3
direct = VK_RIGHT; //蛇的初始方向為向右
MAX_LENGTH = 100; //蛇默認最初分配最大長度為20
food = (GRID *)calloc(1,sizeof(GRID));//分配儲存food的內存
snake = (GRID *)calloc(MAX_LENGTH,sizeof(GRID));//分配儲存蛇的內存
/*************初始化遊戲場地*******************/
playground.left = 0;
playground.top = 0;
playground.right = WIDTH * LENGTH;
playground.bottom = WIDTH * LENGTH;
/**************初始化遊戲場地********************/

for(int i = 0 ;i &< LENGTH;++i) { for(int j = 0; j &< LENGTH;++j) { flags[i][j] = NO_SNAKE; } } for(int i = 0; i != snake_len;++i) { MakePartSnake(LENGTH / 2 + 2 - i,LENGTH / 2,HAS_SNAKE,(snake + i)); }///初始化蛇 MakeFood(food);///產生food } void MakePartSnake(int x,int y,int flag,GRID * snake) { snake-&>x = x;
snake-&>y = y;
snake-&>flag = flag;
}
////////////////////////////////////////////////////////////////////////////////

//////////////////控制蛇的移動///////////////////////
void MoveSnake(HWND hwnd)
{
Manager();
flags[(snake + snake_len - 1)-&>x][(snake + snake_len - 1)-&>y] = NO_SNAKE;//把蛇的尾部去除(表現為蛇移動一格)

for(int i = snake_len - 1; i &> 0;--i)
{
(snake+i)-&>x = (snake + i -1)-&>x;
(snake+i)-&>y = (snake + i -1)-&>y;
}
if(direct == VK_LEFT)
{
snake-&>x -= 1;
}
if(direct == VK_RIGHT)
{
snake-&>x += 1;
}
if(direct == VK_UP)
{
snake-&>y -= 1;
}
if(direct == VK_DOWN)
{
snake-&>y += 1;
}
InvalidateRect(hwnd,NULL,FALSE);
Sleep(200);
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

//////////////////////////////////通過隨機生成food
void MakeFood(GRID *food)
{
srand((unsigned) time(NULL));
food-&>x = rand() % LENGTH;
food-&>y = rand() % LENGTH;
food-&>flag = HAS_SNAKE;
flags[food-&>x][food-&>y] = food-&>flag;
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

//////////////////////////////////遊戲規則的映射及內存的處理///////////////////////////////////////////////////
void Manager()
{
if(snake_len &>= MAX_LENGTH - 2)
{
MAX_LENGTH += STEP;
snake = (GRID *)realloc(snake,MAX_LENGTH * sizeof(GRID));
}//若蛇的長度數組snake將超過所分配的內存就再次擴充分配

if(snake-&>x &< 0 || snake-&>x &>= LENGTH || snake-&>y &< 0 || snake-&>y &>= LENGTH)
{
MessageBox(NULL,TEXT("Game Over!!"),szAppName,0);
initializer();
return;
}///判斷蛇是否碰到邊界

for(int i = 4;i &< snake_len;++i) { if(snake-&>x == (snake + i)-&>x snake-&>y == (snake + i)-&>y)
{
MessageBox(NULL,TEXT("Game Over!!"),szAppName,0);
initializer();
return;
}
}////判斷蛇是否碰到自身

if(food-&>x == snake-&>x food-&>y == snake-&>y)
{
MakePartSnake(
(snake + snake_len - 1)-&>x
,(snake + snake_len - 1)-&>y
,HAS_SNAKE
,snake + snake_len
);
++snake_len;
MakeFood(food);
}///判斷蛇是否吃到food
}
////////////////////////////////////////////////////////////////////////////////

win32 API的貪食蛇遊戲~~可直接在VS下編譯運行


百度搜索:

win32窗口繪製源碼

ctrl+c ctrl+v

編譯


現在學這些有點過時,不過如果你是想探究傳統WindowsAPI,我還是挺你的,我上大學的時候也干過這事兒。

你要了解傳統WindowsAPI的界面,萬物皆是Windows,所有Windows都是消息驅動,要會處理Windows消息

然後就好辦了,看MSDN文檔就行,微軟有一個好,就是文檔全,用法舉例搜搜到處都是。

首先是,Windows傳統控制項:Windows Controls (Windows)

然後是傳統圖形處理:Legacy Graphics (Windows)


盡量用windows原生api寫東西,不要用各種第三方庫,包括微軟自己的第三方庫。找個tinyC++做編譯器,就是只包含了最底限windows窗口所需要lib的編譯器。等你把一個遊戲做出來,再回頭看那些庫,你會發現那些庫不過是對windows api的各種封裝。如果你用那些庫,遊戲就算做出來,你也沒學到多少東西。

這個過程中,google,msdn和stackoverflow應該是你的最大幫手。

windows api相較於其他庫介面是比較複雜難搞的,這也正是各種庫封裝他們的原因,但它為什麼這樣設計,來龍去脈是怎樣的,思辨和得出結論,這才是這個過程中價值最大的事情。


一直用winapi + 對話框 來寫win下的東西 簡單,順手而且界面原生

遊戲的話就算了


別折磨自己 直接cocos或者unity 這種低級輪子浪費自己生命


可以先看一下EasyX或者SDL的例子。不過做遊戲,應該先考慮圖形學的問題,圖元繪製,字體,紋理,光照,雙緩衝等等,諸如此類。至於是GDI,GDI+,OpenGL,D3D,D2D,MFC,WX還是QT,要看需求。


跟我一起玩Win32開發(2):完整的開發流程


聽這個問題,題主是就讀於華南地區某985和尚理工科學校?

說說我當年的大作業,完全用cmd做的,橫版過關的一個遊戲

主要用符號代替元素,比如一個字母代替玩家,一個等號代表可以踩的地板之類的。一個畫面是nxm的二維數組,然後用個timer刷新顯示。

當時我的老師特別喜歡這種用基礎知識做出來的東西,ta說ta完全沒想到會有人這麼做,所以還得了個優秀大作業獎

而且說實話,這麼做了之後對邏輯有很大幫助呢

希望能給你作個參考方向


同大一,剛做完大作業,界面遊戲w

英文還行的話我建議SDL2

教程:

http://Lazyfoo.net

僅僅為了做出一個界面遊戲的話大概前十課加上Renderer部分就夠~學習成本個人認為還好。

我小組合作的渣作:

https://github.com/LunziQwQ/Tic-Tac-Toe_Extend-bySDL


講道理

大作業這個東西

上網問

是不是有點

那啥了


照著教材寫了半天終於寫出來了,然後一看,我靠!怎麼畫面怎麼閃啊,然後查資料知道了雙緩衝,然後終於不閃了,但是發現自己定時器做的動畫不自然啊。然後就發現了DX.....


又看了遍問題,題主是想在控制台窗口做這個。

有一系列博客叫做?Windows控制台編程?,題主可以看看。好像還有個叫「控制台高級編程」的源代碼包,是微軟官方九幾年發布的,值得研究研究,裡面是關於控制台API每個函數的例子(包括配合著使用,支持滑鼠鍵盤操作)。

MSDN搜「console functions」也會對你有所幫助。我也喜歡控制台程序,小。


windows程序設計好像是c語言,c++實踐之路可以翻一下。名字不一定對,哄孩子睡覺中,純回憶。


如果真要用winapi寫的話,推薦看windows遊戲編程大師技巧,對於寫一個遊戲涉及的winapi知識基本都講到了,還講了一些基礎的direct。以前看過,雖然現在都不這麼寫遊戲了,不過講的確實不錯。


Windows via C/C++,也就是 《Windows 核心編程》。翻到附錄


win32


推薦閱讀:

如何評價noip2016初賽題?
如何練習編程的手速?
開發一款手游的工作量是怎樣的?
親戚找你做網站你是明碼標價還是送人情免費做?
程序員創立了一家公司當上了CEO之後,還會去寫代碼編程嗎?

TAG:程序員 | 遊戲開發 | 編程 | CC | VisualC |