我的第一个win32的小游戏,渲染时出错
正在学习windows游戏编程,自己的第一个小游戏。
我觉得是Draw_Block()函数里CreateSolidBrush()的问题,但是没有找到解决办法。
下面是我的代码:
/*windows GDI下的游戏程序*/
#define WIN32_LEAN_AND_MEAN
#include<windows.h>
#include<stdlib.h>
#include<stdio.h>
#include<math.h>
//窗口类
#define WINDOW_CLASS_NAME "WIN3DCLASSS"
//按键响应
#define KEY_DOWN(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 1 : 0)
//窗口尺寸
#define WINDOW_WIDTH 640
#define WINDOW_HEIGHT 480
#define SCREEN_WIDTH 640
#define SCREEN_HEIGHT 480
//Block设置
#define NUM_BLOCK_ROWS 6
#define NUM_BLOCK_COLUMNS 8
#define BLOCK_WIDTH 64
#define BLOCK_HEIGHT 16
#define BLOCK_ORIGIN_X 8
#define BLOCK_ORIGIN_Y 8
#define BLOCK_X_GAP 80
#define BLOCK_Y_GAP 32
//Paddle设置
#define PADDLE_START_X (SCREEN_WIDTH/2-16)
#define PADDLE_START_Y (SCREEN_HEIGHT-32)
#define PADDLE_WIDTH 32
#define PADDLE_HEIGHT 8
#define PADDLE_COLOR 191
//Ball设置
#define BALL_START_Y (SCREEN_HEIGHT/2)
#define BALL_SIZE 4
int Game_Init(void *parms=NULL); //游戏初始化函数
int Game_Shutdown(void *parms=NULL); //游戏关闭函数
int Game_Main(void *parms=NULL); //游戏处理函数
void Draw_Blocks(void); //Block绘画函数
HWND main_window_handle=NULL; //窗口句柄
HINSTANCE main_instance=NULL; //实例句柄
HDC main_hdc=NULL;
HBRUSH main_brush=NULL;
HBRUSH old_brush=NULL;
int paddle_x=0,paddle_y=0; //Paddle的坐标
int ball_x=0,ball_y=0; //Ball的坐标
int ball_dx=0,ball_dy=0; //Ball的运动向量
int score=0; //分数
int level=1; //等级
int blocks_hit=0; //Block撞击数
char buffer[80]=""; //字符缓存
//Block的颜色数组
UCHAR blocks[NUM_BLOCK_ROWS][NUM_BLOCK_COLUMNS];
LRESULT CALLBACK WindowProc(HWND hwnd,
UINT msg,
WPARAM wparam,
LPARAM lparam)
{
PAINTSTRUCT ps;
switch(msg)
{
case WM_CREATE:
{
return(0);
}break;
case WM_PAINT:
{
main_hdc=BeginPaint(hwnd,&ps);
EndPaint(hwnd,&ps);
return(0);
}break;
case WM_TIMER: //定时器
{
switch(wparam)
{
case 1:
{ //键盘获取Paddle的移动
if(KEY_DOWN(VK_RIGHT))
{
paddle_x+=8;
if(paddle_x>(SCREEN_WIDTH-PADDLE_WIDTH))
paddle_x=SCREEN_WIDTH-PADDLE_WIDTH;
}
else if(KEY_DOWN(VK_LEFT))
{
paddle_x-=8;
if(paddle_x<0)
paddle_x=0;
}
//Ball的移动
ball_x+=ball_dx;
ball_y+=ball_dy;
RECT rect;//矩形结构体
/*渲染屏幕*/ rect.left=1;
rect.top=1;
rect.right=SCREEN_WIDTH-1;
rect.bottom=SCREEN_HEIGHT-1;
main_brush=CreateSolidBrush(200);
SelectObject(main_hdc,main_brush);
FillRect(main_hdc,&rect,main_brush);
Draw_Blocks();//绘制Block
/*绘制Paddle*/ rect.left=paddle_x-8;
rect.top=paddle_y+8;
rect.right=paddle_x+PADDLE_WIDTH-8;
rect.bottom=paddle_y+PADDLE_HEIGHT+8;
main_brush=CreateSolidBrush(0);
SelectObject(main_hdc,main_brush);
FillRect(main_hdc,&rect,main_brush);
rect.left=paddle_x;
rect.top=paddle_y;
rect.right=paddle_x+PADDLE_WIDTH;
rect.bottom=paddle_y+PADDLE_HEIGHT;
main_brush=CreateSolidBrush(PADDLE_COLOR);
SelectObject(main_hdc,main_brush);
FillRect(main_hdc,&rect,main_brush);
/*绘制Ball*/ rect.left=ball_x-2;
rect.top=ball_y+2;
rect.right=ball_x+BALL_SIZE-2;
rect.bottom=ball_y+BALL_SIZE+2;
main_brush=CreateSolidBrush(0);
SelectObject(main_hdc,main_brush);
FillRect(main_hdc,&rect,main_brush);
rect.left=ball_x;
rect.top=ball_y;
rect.right=ball_x+BALL_SIZE;
rect.bottom=ball_y+BALL_SIZE;
main_brush=CreateSolidBrush(255);
SelectObject(main_hdc,main_brush);
FillRect(main_hdc,&rect,main_brush);
/*分数、等级*/ sprintf(buffer,"FREAKOUT Score %d Level %d",score,level);
SetTextColor(main_hdc,0);
SetBkColor(main_hdc,200);
SetBkMode(main_hdc,TRANSPARENT);
TextOut(main_hdc,8,SCREEN_HEIGHT-16,buffer,strlen(buffer));
}
default:break;
}
return(0);
}break;
case WM_DESTROY:
{
PostQuitMessage(0);
return(0);
}break;
default:break;
}
return(DefWindowProc(hwnd,msg,wparam,lparam));
}
int WINAPI WinMain(HINSTANCE hinstance,
HINSTANCE hprevinstance,
LPSTR lpcmdline,
int ncmdshow)
{
/*窗口类、注册、创建*/
ShowCursor(FALSE);
main_window_handle=hwnd;
main_instance=hinstance;
main_hdc=GetDC(main_window_handle);
Game_Init();//游戏初始化
while(1)
{
if(PeekMessage(&msg,NULL,0,0,PM_REMOVE))
{
if(msg.message==WM_QUIT)
break;
TranslateMessage(&msg);
DispatchMessage(&msg);
}
Game_Main();//游戏处理
if(KEY_DOWN(VK_ESCAPE))
break;
}
Game_Shutdown();//游戏关闭
ShowCursor(TRUE);
return(msg.wParam);
}
//初始化Block
void Init_Blocks(void)
{
for(int row=0;row<NUM_BLOCK_ROWS;row++)
for(int col=0;col<NUM_BLOCK_COLUMNS;col++)
blocks[row][col]=row*16+col*3+16;
}
//绘制Block
void Draw_Blocks(void)
{
int x1=BLOCK_ORIGIN_X;
int y1=BLOCK_ORIGIN_Y;
for(int row=0;row<NUM_BLOCK_ROWS;row++)
{
x1=BLOCK_ORIGIN_X;
for(int col=0;col<NUM_BLOCK_COLUMNS;col++)
{
if(blocks[row][col]!=0)
{
RECT rect;
rect.left=x1-4;
rect.top=y1+4;
rect.right=x1+BLOCK_WIDTH-4;
rect.bottom=y1+BLOCK_HEIGHT+4;
main_brush=CreateSolidBrush(0);
SelectObject(main_hdc,main_brush);
FillRect(main_hdc,&rect,main_brush);
rect.left=x1;
rect.top=y1;
rect.right=x1+BLOCK_WIDTH;
rect.bottom=y1+BLOCK_HEIGHT;
main_brush=CreateSolidBrush(blocks[row][col]);
SelectObject(main_hdc,main_brush);
FillRect(main_hdc,&rect,main_brush);
}
x1+=BLOCK_X_GAP;
}
y1+=BLOCK_Y_GAP;
}
}
//游戏初始化
int Game_Init(void *parms)
{
/*屏*/ RECT rect;
/*幕*/ rect.left=1;
/*渲*/ rect.top=1;
/*染*/ rect.right=SCREEN_WIDTH-1;
rect.bottom=SCREEN_HEIGHT-1;
main_brush=CreateSolidBrush(200);
old_brush=(HBRUSH)SelectObject(main_hdc,main_brush);
FillRect(main_hdc,&rect,main_brush);
Init_Blocks(); /*Block*/
blocks_hit=0; /*初始化*/
Draw_Blocks();
paddle_x=PADDLE_START_X; /*Paddle*/
paddle_y=PADDLE_START_Y; /*初始化*/
rect.left=paddle_x-8;
rect.top=paddle_y+8;
rect.right=paddle_x+PADDLE_WIDTH-8;
rect.bottom=paddle_y+PADDLE_HEIGHT+8;
main_brush=CreateSolidBrush(0);
SelectObject(main_hdc,main_brush);
FillRect(main_hdc,&rect,main_brush);
rect.left=paddle_x;
rect.top=paddle_y;
rect.right=paddle_x+PADDLE_WIDTH;
rect.bottom=paddle_y+PADDLE_HEIGHT;
main_brush=CreateSolidBrush(PADDLE_COLOR);
SelectObject(main_hdc,main_brush);
FillRect(main_hdc,&rect,main_brush);
srand(GetTickCount());//随机种子 /*Ball*/
ball_x=8+rand()%(SCREEN_WIDTH-16); /*初始化*/
ball_y=BALL_START_Y;
ball_dx=-4+rand()%(8+1);
ball_dy=6+rand()%2;
rect.left=ball_x-2;
rect.top=ball_y+2;
rect.right=ball_x+BALL_SIZE-2;
rect.bottom=ball_y+BALL_SIZE+2;
main_brush=CreateSolidBrush(0);
SelectObject(main_hdc,main_brush);
FillRect(main_hdc,&rect,main_brush);
rect.left=ball_x;
rect.top=ball_y;
rect.right=ball_x+BALL_SIZE;
rect.bottom=ball_y+BALL_SIZE;
main_brush=CreateSolidBrush(255);
SelectObject(main_hdc,main_brush);
FillRect(main_hdc,&rect,main_brush);
sprintf(buffer,"FREAKOUT Score %d Level %d",score,level); /*分数,等级*/
SetTextColor(main_hdc,0); /*初始化*/
SetBkColor(main_hdc,200);
SetBkMode(main_hdc,TRANSPARENT);
TextOut(main_hdc,8,SCREEN_HEIGHT-16,buffer,strlen(buffer));
SetTimer(main_window_handle,1,50,NULL);
return(1);
}
//游戏关闭函数
int Game_Shutdown(void *parms)
{
SelectObject(main_hdc,old_brush);
DeleteObject(main_brush);
DeleteObject(old_brush);
ReleaseDC(main_window_handle,main_hdc);
PostMessage(main_window_handle,WM_DESTROY,0,0);
return(1);
}
void Process_Ball(void)
{
int x1=BLOCK_ORIGIN_X,
y1=BLOCK_ORIGIN_Y;
int ball_cx=ball_x+(BALL_SIZE/2),
ball_cy=ball_y+(BALL_SIZE/2);
if(ball_y>(SCREEN_HEIGHT/2) && ball_dy>0) /*Paddle与*/
{ /*Block的*/
int x=ball_x+(BALL_SIZE/2), /*碰撞*/
y=ball_y+(BALL_SIZE/2);
if((x>=paddle_x && x<=paddle_x+PADDLE_WIDTH) &&
(y>=paddle_y && y<=paddle_y+PADDLE_HEIGHT))
{
ball_dy=-ball_dy;
ball_y+=ball_dy;
if(KEY_DOWN(VK_RIGHT))
ball_dx-=(rand()%3);
else if(KEY_DOWN(VK_LEFT))
ball_dx+=(rand()%3);
else
ball_dx+=(-1+rand()%3);
if(blocks_hit>=(NUM_BLOCK_ROWS*NUM_BLOCK_COLUMNS))
{
level++;
}
MessageBeep(MB_OK);
return;
}
}
for(int row=0;row<NUM_BLOCK_ROWS;row++) /*Block与*/
{ /*Ball的碰撞*/
x1=BLOCK_ORIGIN_X;
for(int col=0;col<NUM_BLOCK_COLUMNS;col++)
{
if(blocks[row][col]!=0)
{
if((ball_cx>x1) && (ball_cx<x1+BLOCK_WIDTH) &&
(ball_cy>y1) && (ball_cy<y1+BLOCK_HEIGHT))
{
blocks[row][col]=0;
blocks_hit++;
ball_dy=-ball_dy;
ball_dx+=(-1+rand()%3);
MessageBeep(MB_OK);
score+=5*(level+(abs(ball_dx)));
return;
}
}
x1+=BLOCK_X_GAP;
}
y1+=BLOCK_Y_GAP;
}
}
//游戏处理
int Game_Main(void *parms)
{
if(ball_x>(SCREEN_WIDTH-BALL_SIZE) || ball_x<0) /*Ball与*/
{ /*窗体的*/
ball_dx=-ball_dx; /*碰撞*/
ball_x+=ball_dx;
}
if(ball_y<0)
{
ball_dy=-ball_dy;
ball_y+=ball_dy;
}
else if(ball_y>(SCREEN_HEIGHT-BALL_SIZE))
{
ball_dy=-ball_dy;
ball_y+=ball_dy;
score-=100;
}
if(ball_dx>8) ball_dx=8;
else if(ball_dx<-8) ball_dx=-8;
Process_Ball();
return(1);
}