作者在 2011-01-18 14:56:25 发布以下内容
终于自己写了个俄罗斯方块。。
代码还没来的及整理,比较乱。。。
图形的数据结构:每一组表示一类(代码中为shape_num)图形的四种变形(代码中为shape_direction).数字表示第几个方块是图形的组成块。
#ifndef block_h
#define block_h
int shape[7][4][4]=
{
{
{0,1,5,9},
{2,4,5,6},
{0,4,8,9},
{0,1,2,4}
},
{
{0,1,4,8},
{0,1,2,6},
{1,5,8,9},
{0,4,5,6}
},
{
{0,1,5,6},
{1,4,5,8},
{0,1,5,6},
{1,4,5,8}
},
{
{1,2,4,5},
{0,4,5,9},
{1,2,4,5},
{0,4,5,9}
},
{
{1,4,5,6},
{0,4,5,8},
{0,1,2,5},
{1,4,5,9}
},
{
{0,1,4,5},
{0,1,4,5},
{0,1,4,5},
{0,1,4,5}
},
{
{0,1,2,3},
{0,4,8,12},
{0,1,2,3},
{0,4,8,12}
}
};
#endif
#ifndef function_h
#define function_h
LRESULT CALLBACK WndProc(HWND hwnd,UINT mesage,WPARAM wParam, LPARAM lParam);
void Draw_shape(HWND hwnd,int shape_num,int shape_direction,POINT position,COLORREF color);
void Draw_block(HWND hwnd,POINT block,COLORREF color);
void Init_map();
void New_shape(HWND hwnd);
void Down_shape(HWND hwnd);
void Right_shape(HWND hwnd);
void Left_shape(HWND hwnd);
void Change_direction(HWND hwnd);
bool Downable();
bool Rightable();
bool Leftable();
bool Changeable();
void Update_map();
int Full_row();
void Clean_full_row(HWND hwnd,int row);
void Pause();
void Draw_edge(HWND hwnd);
void Pre_to_cur(HWND hwnd);
bool Over();
void Show_over(HWND hwnd);
void Init_frame(HWND hwnd);
void Show_score(HWND hwnd);
void Show_level(HWND hwnd);
void Change_level(HWND hwnd);
void Show_preview(HWND hwnd);
#endif
主程序:
#define function_h
LRESULT CALLBACK WndProc(HWND hwnd,UINT mesage,WPARAM wParam, LPARAM lParam);
void Draw_shape(HWND hwnd,int shape_num,int shape_direction,POINT position,COLORREF color);
void Draw_block(HWND hwnd,POINT block,COLORREF color);
void Init_map();
void New_shape(HWND hwnd);
void Down_shape(HWND hwnd);
void Right_shape(HWND hwnd);
void Left_shape(HWND hwnd);
void Change_direction(HWND hwnd);
bool Downable();
bool Rightable();
bool Leftable();
bool Changeable();
void Update_map();
int Full_row();
void Clean_full_row(HWND hwnd,int row);
void Pause();
void Draw_edge(HWND hwnd);
void Pre_to_cur(HWND hwnd);
bool Over();
void Show_over(HWND hwnd);
void Init_frame(HWND hwnd);
void Show_score(HWND hwnd);
void Show_level(HWND hwnd);
void Change_level(HWND hwnd);
void Show_preview(HWND hwnd);
#endif
# include<windows.h>
# include<time.h>
# include"block.h"
# include"function.h"
int block_size = 15;//小方块边长
POINT cur_pos = {8,1};//图形当前坐标
int cur_shape_num = 0;//图形当前号码
int cur_shape_direction = 0;//图形当前方向 方向表示同种图形内部的变形变化
int pre_shape_num = 0;
int pre_shape_direction = 0;
#define X_max 20//画图区域宽度
#define Y_max 30//画图区域高度
int map[Y_max][X_max];//画图区域坐标系
COLORREF shape_color = RGB(0,200,200);//图形颜色
COLORREF bg_color = RGB(150,20,20);//背景颜色
COLORREF edge_color = RGB(0,100,100);
int score = 0;
int level = 1;
int WINAPI WinMain(HINSTANCE hInstance,
HINSTANCE hPreInstance,
PSTR szCmdLine,
int iCmdShow)
{
const int caption_height=GetSystemMetrics(SM_CYCAPTION);//标题栏高度
const int frame_height=GetSystemMetrics(SM_CYFRAME);//窗口边框高度
const int frame_width=GetSystemMetrics(SM_CXFRAME);//窗口侧边栏宽度
static TCHAR classname[]=TEXT("classname");
MSG msg;
HWND hwnd;
WNDCLASS wc;
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon(NULL,IDI_APPLICATION);
wc.hCursor = LoadCursor(NULL,IDC_ARROW);
wc.hbrBackground = CreateSolidBrush(bg_color); ;
wc.lpszMenuName = NULL;
wc.lpszClassName = classname;
if(!RegisterClass(&wc))
{
MessageBox(NULL,TEXT("需要windowsNT"),TEXT("出错啦!"),MB_OK|MB_ICONERROR);
return 0;
}
hwnd = CreateWindow(
classname,
TEXT("俄罗斯方块_林语"),
WS_SYSMENU,
500,
200,
(frame_width*2)+((X_max+5)*block_size),//+5用于显示预览,得分,等级
(frame_height*2)+(caption_height)+(Y_max*block_size),
NULL,
NULL,
hInstance,
NULL);
ShowWindow(hwnd,iCmdShow);
// UpdateWindow(hwnd);
while(GetMessage(&msg,NULL,0,0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
LRESULT CALLBACK WndProc(HWND hwnd,UINT message,WPARAM wParam, LPARAM lParam)
{
switch(message)
{
case WM_CREATE:
Init_map();
break;
case WM_PAINT:
Init_frame(hwnd);
New_shape(hwnd);
Pre_to_cur(hwnd);
Draw_shape(hwnd,cur_shape_num,cur_shape_direction,cur_pos,shape_color);
SetTimer(hwnd,1,1000/level,NULL);
break;
case WM_TIMER:
Down_shape(hwnd);
break;
case WM_KEYDOWN:
switch(wParam)
{
case VK_UP:
Change_direction(hwnd);
break;
case VK_DOWN:
Down_shape(hwnd);
break;
case VK_LEFT:
Left_shape(hwnd);
break;
case VK_RIGHT:
Right_shape(hwnd);
break;
case VK_SPACE:
Pause();
break;
}
break;
case WM_CLOSE:
KillTimer(hwnd,1);
PostQuitMessage(0);
break;
}
return DefWindowProc(hwnd,message,wParam,lParam);;
}
//*******************************************************************************************************************
void Draw_shape(HWND hwnd,int shape_num,int shape_direction,POINT position,COLORREF color)//图形号、方向以及左上角坐标、颜色
{//画图形
POINT block;
for(int i=0;i<4;++i)
{
block.x = position.x + shape[shape_num][shape_direction][i] % 4;
block.y = position.y + shape[shape_num][shape_direction][i] / 4;
Draw_block(hwnd,block,color);
}
}
void Draw_block(HWND hwnd,POINT block,COLORREF color)//小方块左上角坐标及颜色
{//画小方块
RECT rc;
SetRect(&rc,
block.x * block_size + 1, //作+1 、-1的调整是为了使得方块之间有间隙
block.y * block_size + 1,
(block.x + 1) * block_size - 1,
(block.y + 1) * block_size - 1);
HDC hdc = GetDC(hwnd);
HBRUSH brush = (HBRUSH)CreateSolidBrush(color);
FillRect(hdc,&rc,brush);
DeleteObject(brush);
ReleaseDC(hwnd,hdc);
}
void Init_map()
{//构造一个开口朝上的半包围结构作为边界
for(int i = 0;i < Y_max;i++)
{
for(int j = 0;j < X_max;j++)
{
map[i][j] = 0;
}
}
//将边界初始化为1表明此处不可被覆盖
for(i = 0;i < Y_max;i++)
{
map[i][0] = 1;
map[i][X_max-1] = 1;
}
for(i = 0;i < X_max;i++)
{
map[Y_max-1][i] = 1;
}
}
void Init_frame(HWND hwnd)
{//初始化界面,画出方框和信息
Draw_edge(hwnd);
HDC hdc = GetDC(hwnd);
HPEN hpen = CreatePen(PS_SOLID,2,shape_color);
SelectObject(hdc,hpen);
TCHAR prev[] = "预览:";//preview
TextOut(hdc,X_max*block_size,block_size,prev,strlen(prev));
TCHAR sco[] = "得分:";//score
TextOut(hdc,X_max*block_size,10*block_size,sco,strlen(sco));
Show_score(hwnd);
TCHAR lev[] = "等级:";//level
TextOut(hdc,X_max*block_size,20*block_size,lev,strlen(lev));
Show_level(hwnd);
DeleteObject(hpen);
ReleaseDC(hwnd,hdc);
}
void New_shape(HWND hwnd)
{//随机生成预览图形并显示
srand((unsigned)time(NULL));
pre_shape_num = rand() % 7;
pre_shape_direction = 0;
Show_preview(hwnd);
}
void Pre_to_cur(HWND hwnd)
{//将预览图形变为将要出现的图形,并生成新的预览图形
cur_shape_num = pre_shape_num;
cur_shape_direction = pre_shape_direction;
cur_pos.x = 8;
cur_pos.y = 1;
New_shape(hwnd);
}
void Down_shape(HWND hwnd)
{//处理图形下移
if(!Downable())
{//如果不可以下移、
Update_map();//在坐标系中记录
if(Over())//判断是否结束
{
KillTimer(hwnd,1);
Show_over(hwnd);
return;
}
int row;
while(row = Full_row())//是否有满行
{
Clean_full_row(hwnd,row);
}
Pre_to_cur(hwnd);//产生新的图形
Draw_shape(hwnd,cur_shape_num,cur_shape_direction,cur_pos,shape_color);
return;
}
Draw_shape(hwnd,cur_shape_num,cur_shape_direction,cur_pos,bg_color);//消除原来的痕迹
cur_pos.y += 1;//图形的纵坐标+1
Draw_shape(hwnd,cur_shape_num,cur_shape_direction,cur_pos,shape_color);//画出下降后的图形
}
void Right_shape(HWND hwnd)
{//处理右移
if(!Rightable())
{
return;
}
Draw_shape(hwnd,cur_shape_num,cur_shape_direction,cur_pos,bg_color);
cur_pos.x += 1;
Draw_shape(hwnd,cur_shape_num,cur_shape_direction,cur_pos,shape_color);
}
void Left_shape(HWND hwnd)
{//处理左移
if(!Leftable())
{
return;
}
Draw_shape(hwnd,cur_shape_num,cur_shape_direction,cur_pos,bg_color);
cur_pos.x -= 1;
Draw_shape(hwnd,cur_shape_num,cur_shape_direction,cur_pos,shape_color);
}
void Change_direction(HWND hwnd)
{//变形处理
if(!Changeable())
{
return;
}
Draw_shape(hwnd,cur_shape_num,cur_shape_direction,cur_pos,bg_color);
cur_shape_direction += 1;
cur_shape_direction %= 4;
Draw_shape(hwnd,cur_shape_num,cur_shape_direction,cur_pos,shape_color);
}
bool Downable()
{//判断是否可以向下
POINT down_pos,block_pos;
down_pos.x = cur_pos.x;
down_pos.y = cur_pos.y + 1;
for(int i = 0;i < 4;i++)
{//分别检查图形中的4个小块是否会与下方重叠
block_pos.x = down_pos.x + shape[cur_shape_num][cur_shape_direction][i] % 4;
block_pos.y = down_pos.y + shape[cur_shape_num][cur_shape_direction][i] / 4;
if(map[block_pos.y][block_pos.x] == 1)
{
return false;
}
}
return true;
}
bool Rightable()
{//判断是否可以向右
POINT down_pos,block_pos;
down_pos.x = cur_pos.x + 1;
down_pos.y = cur_pos.y;
for(int i = 0;i < 4;i++)
{//分别检查图形中的4个小块是否会与右方重叠
block_pos.x = down_pos.x + shape[cur_shape_num][cur_shape_direction][i] % 4;
block_pos.y = down_pos.y + shape[cur_shape_num][cur_shape_direction][i] / 4;
if(map[block_pos.y][block_pos.x] == 1)
{
return false;
}
}
return true;
}
bool Leftable()
{//判断是否可以向左
POINT down_pos,block_pos;
down_pos.x = cur_pos.x - 1;
down_pos.y = cur_pos.y;
for(int i = 0;i < 4;i++)
{//分别检查图形中的4个小块是否会与左方重叠
block_pos.x = down_pos.x + shape[cur_shape_num][cur_shape_direction][i] % 4;
block_pos.y = down_pos.y + shape[cur_shape_num][cur_shape_direction][i] / 4;
if(map[block_pos.y][block_pos.x] == 1)
{
return false;
}
}
return true;
}
bool Changeable()
{//判断是否可以变形
int direction = (cur_shape_direction + 1) % 4;
POINT block_pos;
for(int i = 0;i < 4;i++)
{//分别检查图形中的4个小块是否会与周围重叠
block_pos.x = cur_pos.x + shape[cur_shape_num][direction][i] % 4;
block_pos.y = cur_pos.y + shape[cur_shape_num][direction][i] / 4;
if(map[block_pos.y][block_pos.x] == 1)
{
return false;
}
}
return true;
}
void Update_map()
{//当图形落到底时更新坐标系
POINT postion;
for(int i = 0;i < 4;i++)
{//将当前图形所在的坐标标记为1
postion.x = cur_pos.x + shape[cur_shape_num][cur_shape_direction][i] % 4;
postion.y = cur_pos.y + shape[cur_shape_num][cur_shape_direction][i] / 4;
map[postion.y][postion.x] = 1;
}
}
int Full_row()
{//判断是否有满行,有则返回行的坐标,没有返回0
for(int i = Y_max - 2;i > 0;i--)
{
for(int j = 0;j< X_max;j++)
{
if(map[i][j]==0)
break;
}
if(j==X_max)
{
return i;
}
}
return 0;
}
void Clean_full_row(HWND hwnd,int row)
{//清楚满行
for(int j = 1;j < X_max - 1;j++)
{
map[row][j] = 0;
}
POINT block;
block.y = row;
for(int i = row - 1;i > 0;i--)
{//满行以上的所有行下移
for(j = 1;j <X_max-1;j++)
{
if(map[i][j]==1)
{
map[i + 1][j] = map[i][j];
map[i][j] = 0;
}
}
}
for(i = Y_max - 2;i > 0;i--)
{//把更新过的坐标系重新画出来
for(j = 1;j < X_max-1;j++)
{
block.x = j;
block.y = i;
COLORREF color = bg_color;
if(map[i][j]==1)
color = shape_color;
Draw_block(hwnd,block,color);
}
}
score += 10;//加分并显示
Show_score(hwnd);
if(score >= level*100)
{//判断是否修改等级
Change_level(hwnd);
}
}
void Change_level(HWND hwnd)
{//修改等级
level++;
Show_level(hwnd);
//修改速度
KillTimer(hwnd,1);
SetTimer(hwnd,1,1000/level,NULL);
}
void Pause()
{//未实现
}
void Draw_edge(HWND hwnd)
{//画出边界
HDC hdc;
hdc = GetDC(hwnd);
HPEN hpen = CreatePen(PS_SOLID,1,edge_color);
SelectObject(hdc,hpen);
for(int i = 1;i < Y_max;i++)
{
MoveToEx(hdc,block_size-1,i*block_size-1,NULL);
LineTo(hdc,(X_max-1)*block_size,i*block_size-1);
}
for(i = 0;i < X_max;i++)
{
MoveToEx(hdc,i*block_size-1,block_size-1,NULL);
LineTo(hdc,i*block_size-1,(Y_max-1)*block_size-1);
}
ReleaseDC(hwnd,hdc);
}
void Show_preview(HWND hwnd)
{//显示预览图形
POINT postion;
postion.x = X_max + 1;
postion.y = 3;
Draw_shape(hwnd,cur_shape_num,0,postion,bg_color);
Draw_shape(hwnd,pre_shape_num,pre_shape_direction,postion,shape_color);
}
void Show_score(HWND hwnd)
{//显示得分
HDC hdc = GetDC(hwnd);
TCHAR sc[5];
itoa(score,sc,10);
TextOut(hdc,(X_max+2)*block_size,13*block_size,sc,strlen(sc));
ReleaseDC(hwnd,hdc);
}
void Show_level(HWND hwnd)
{//显示等级
HDC hdc = GetDC(hwnd);
TCHAR lev[2];
itoa(level,lev,10);
TextOut(hdc,(X_max+2)*block_size,23*block_size,lev,strlen(lev));
ReleaseDC(hwnd,hdc);
}
bool Over()
{//判断游戏是否结束
for(int i = 1;i < X_max - 1;i++)
{
if(map[1][i]==1)
return true;
}
return false;
}
void Show_over(HWND hwnd)
{//这个功能还没完全写好
RECT rc;
SetRect(&rc,0,0,(X_max+5)*block_size,Y_max*block_size);
HDC hdc = GetDC(hwnd);
HBRUSH hbrush = CreateSolidBrush((bg_color));
FillRect(hdc,&rc,hbrush);
MessageBox(hwnd,TEXT("GameOver"),TEXT("GameOver"));
ReleaseDC(hwnd,hdc);
DeleteObject(hbrush);
}
# include<time.h>
# include"block.h"
# include"function.h"
int block_size = 15;//小方块边长
POINT cur_pos = {8,1};//图形当前坐标
int cur_shape_num = 0;//图形当前号码
int cur_shape_direction = 0;//图形当前方向 方向表示同种图形内部的变形变化
int pre_shape_num = 0;
int pre_shape_direction = 0;
#define X_max 20//画图区域宽度
#define Y_max 30//画图区域高度
int map[Y_max][X_max];//画图区域坐标系
COLORREF shape_color = RGB(0,200,200);//图形颜色
COLORREF bg_color = RGB(150,20,20);//背景颜色
COLORREF edge_color = RGB(0,100,100);
int score = 0;
int level = 1;
int WINAPI WinMain(HINSTANCE hInstance,
HINSTANCE hPreInstance,
PSTR szCmdLine,
int iCmdShow)
{
const int caption_height=GetSystemMetrics(SM_CYCAPTION);//标题栏高度
const int frame_height=GetSystemMetrics(SM_CYFRAME);//窗口边框高度
const int frame_width=GetSystemMetrics(SM_CXFRAME);//窗口侧边栏宽度
static TCHAR classname[]=TEXT("classname");
MSG msg;
HWND hwnd;
WNDCLASS wc;
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon(NULL,IDI_APPLICATION);
wc.hCursor = LoadCursor(NULL,IDC_ARROW);
wc.hbrBackground = CreateSolidBrush(bg_color); ;
wc.lpszMenuName = NULL;
wc.lpszClassName = classname;
if(!RegisterClass(&wc))
{
MessageBox(NULL,TEXT("需要windowsNT"),TEXT("出错啦!"),MB_OK|MB_ICONERROR);
return 0;
}
hwnd = CreateWindow(
classname,
TEXT("俄罗斯方块_林语"),
WS_SYSMENU,
500,
200,
(frame_width*2)+((X_max+5)*block_size),//+5用于显示预览,得分,等级
(frame_height*2)+(caption_height)+(Y_max*block_size),
NULL,
NULL,
hInstance,
NULL);
ShowWindow(hwnd,iCmdShow);
// UpdateWindow(hwnd);
while(GetMessage(&msg,NULL,0,0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
LRESULT CALLBACK WndProc(HWND hwnd,UINT message,WPARAM wParam, LPARAM lParam)
{
switch(message)
{
case WM_CREATE:
Init_map();
break;
case WM_PAINT:
Init_frame(hwnd);
New_shape(hwnd);
Pre_to_cur(hwnd);
Draw_shape(hwnd,cur_shape_num,cur_shape_direction,cur_pos,shape_color);
SetTimer(hwnd,1,1000/level,NULL);
break;
case WM_TIMER:
Down_shape(hwnd);
break;
case WM_KEYDOWN:
switch(wParam)
{
case VK_UP:
Change_direction(hwnd);
break;
case VK_DOWN:
Down_shape(hwnd);
break;
case VK_LEFT:
Left_shape(hwnd);
break;
case VK_RIGHT:
Right_shape(hwnd);
break;
case VK_SPACE:
Pause();
break;
}
break;
case WM_CLOSE:
KillTimer(hwnd,1);
PostQuitMessage(0);
break;
}
return DefWindowProc(hwnd,message,wParam,lParam);;
}
//*******************************************************************************************************************
void Draw_shape(HWND hwnd,int shape_num,int shape_direction,POINT position,COLORREF color)//图形号、方向以及左上角坐标、颜色
{//画图形
POINT block;
for(int i=0;i<4;++i)
{
block.x = position.x + shape[shape_num][shape_direction][i] % 4;
block.y = position.y + shape[shape_num][shape_direction][i] / 4;
Draw_block(hwnd,block,color);
}
}
void Draw_block(HWND hwnd,POINT block,COLORREF color)//小方块左上角坐标及颜色
{//画小方块
RECT rc;
SetRect(&rc,
block.x * block_size + 1, //作+1 、-1的调整是为了使得方块之间有间隙
block.y * block_size + 1,
(block.x + 1) * block_size - 1,
(block.y + 1) * block_size - 1);
HDC hdc = GetDC(hwnd);
HBRUSH brush = (HBRUSH)CreateSolidBrush(color);
FillRect(hdc,&rc,brush);
DeleteObject(brush);
ReleaseDC(hwnd,hdc);
}
void Init_map()
{//构造一个开口朝上的半包围结构作为边界
for(int i = 0;i < Y_max;i++)
{
for(int j = 0;j < X_max;j++)
{
map[i][j] = 0;
}
}
//将边界初始化为1表明此处不可被覆盖
for(i = 0;i < Y_max;i++)
{
map[i][0] = 1;
map[i][X_max-1] = 1;
}
for(i = 0;i < X_max;i++)
{
map[Y_max-1][i] = 1;
}
}
void Init_frame(HWND hwnd)
{//初始化界面,画出方框和信息
Draw_edge(hwnd);
HDC hdc = GetDC(hwnd);
HPEN hpen = CreatePen(PS_SOLID,2,shape_color);
SelectObject(hdc,hpen);
TCHAR prev[] = "预览:";//preview
TextOut(hdc,X_max*block_size,block_size,prev,strlen(prev));
TCHAR sco[] = "得分:";//score
TextOut(hdc,X_max*block_size,10*block_size,sco,strlen(sco));
Show_score(hwnd);
TCHAR lev[] = "等级:";//level
TextOut(hdc,X_max*block_size,20*block_size,lev,strlen(lev));
Show_level(hwnd);
DeleteObject(hpen);
ReleaseDC(hwnd,hdc);
}
void New_shape(HWND hwnd)
{//随机生成预览图形并显示
srand((unsigned)time(NULL));
pre_shape_num = rand() % 7;
pre_shape_direction = 0;
Show_preview(hwnd);
}
void Pre_to_cur(HWND hwnd)
{//将预览图形变为将要出现的图形,并生成新的预览图形
cur_shape_num = pre_shape_num;
cur_shape_direction = pre_shape_direction;
cur_pos.x = 8;
cur_pos.y = 1;
New_shape(hwnd);
}
void Down_shape(HWND hwnd)
{//处理图形下移
if(!Downable())
{//如果不可以下移、
Update_map();//在坐标系中记录
if(Over())//判断是否结束
{
KillTimer(hwnd,1);
Show_over(hwnd);
return;
}
int row;
while(row = Full_row())//是否有满行
{
Clean_full_row(hwnd,row);
}
Pre_to_cur(hwnd);//产生新的图形
Draw_shape(hwnd,cur_shape_num,cur_shape_direction,cur_pos,shape_color);
return;
}
Draw_shape(hwnd,cur_shape_num,cur_shape_direction,cur_pos,bg_color);//消除原来的痕迹
cur_pos.y += 1;//图形的纵坐标+1
Draw_shape(hwnd,cur_shape_num,cur_shape_direction,cur_pos,shape_color);//画出下降后的图形
}
void Right_shape(HWND hwnd)
{//处理右移
if(!Rightable())
{
return;
}
Draw_shape(hwnd,cur_shape_num,cur_shape_direction,cur_pos,bg_color);
cur_pos.x += 1;
Draw_shape(hwnd,cur_shape_num,cur_shape_direction,cur_pos,shape_color);
}
void Left_shape(HWND hwnd)
{//处理左移
if(!Leftable())
{
return;
}
Draw_shape(hwnd,cur_shape_num,cur_shape_direction,cur_pos,bg_color);
cur_pos.x -= 1;
Draw_shape(hwnd,cur_shape_num,cur_shape_direction,cur_pos,shape_color);
}
void Change_direction(HWND hwnd)
{//变形处理
if(!Changeable())
{
return;
}
Draw_shape(hwnd,cur_shape_num,cur_shape_direction,cur_pos,bg_color);
cur_shape_direction += 1;
cur_shape_direction %= 4;
Draw_shape(hwnd,cur_shape_num,cur_shape_direction,cur_pos,shape_color);
}
bool Downable()
{//判断是否可以向下
POINT down_pos,block_pos;
down_pos.x = cur_pos.x;
down_pos.y = cur_pos.y + 1;
for(int i = 0;i < 4;i++)
{//分别检查图形中的4个小块是否会与下方重叠
block_pos.x = down_pos.x + shape[cur_shape_num][cur_shape_direction][i] % 4;
block_pos.y = down_pos.y + shape[cur_shape_num][cur_shape_direction][i] / 4;
if(map[block_pos.y][block_pos.x] == 1)
{
return false;
}
}
return true;
}
bool Rightable()
{//判断是否可以向右
POINT down_pos,block_pos;
down_pos.x = cur_pos.x + 1;
down_pos.y = cur_pos.y;
for(int i = 0;i < 4;i++)
{//分别检查图形中的4个小块是否会与右方重叠
block_pos.x = down_pos.x + shape[cur_shape_num][cur_shape_direction][i] % 4;
block_pos.y = down_pos.y + shape[cur_shape_num][cur_shape_direction][i] / 4;
if(map[block_pos.y][block_pos.x] == 1)
{
return false;
}
}
return true;
}
bool Leftable()
{//判断是否可以向左
POINT down_pos,block_pos;
down_pos.x = cur_pos.x - 1;
down_pos.y = cur_pos.y;
for(int i = 0;i < 4;i++)
{//分别检查图形中的4个小块是否会与左方重叠
block_pos.x = down_pos.x + shape[cur_shape_num][cur_shape_direction][i] % 4;
block_pos.y = down_pos.y + shape[cur_shape_num][cur_shape_direction][i] / 4;
if(map[block_pos.y][block_pos.x] == 1)
{
return false;
}
}
return true;
}
bool Changeable()
{//判断是否可以变形
int direction = (cur_shape_direction + 1) % 4;
POINT block_pos;
for(int i = 0;i < 4;i++)
{//分别检查图形中的4个小块是否会与周围重叠
block_pos.x = cur_pos.x + shape[cur_shape_num][direction][i] % 4;
block_pos.y = cur_pos.y + shape[cur_shape_num][direction][i] / 4;
if(map[block_pos.y][block_pos.x] == 1)
{
return false;
}
}
return true;
}
void Update_map()
{//当图形落到底时更新坐标系
POINT postion;
for(int i = 0;i < 4;i++)
{//将当前图形所在的坐标标记为1
postion.x = cur_pos.x + shape[cur_shape_num][cur_shape_direction][i] % 4;
postion.y = cur_pos.y + shape[cur_shape_num][cur_shape_direction][i] / 4;
map[postion.y][postion.x] = 1;
}
}
int Full_row()
{//判断是否有满行,有则返回行的坐标,没有返回0
for(int i = Y_max - 2;i > 0;i--)
{
for(int j = 0;j< X_max;j++)
{
if(map[i][j]==0)
break;
}
if(j==X_max)
{
return i;
}
}
return 0;
}
void Clean_full_row(HWND hwnd,int row)
{//清楚满行
for(int j = 1;j < X_max - 1;j++)
{
map[row][j] = 0;
}
POINT block;
block.y = row;
for(int i = row - 1;i > 0;i--)
{//满行以上的所有行下移
for(j = 1;j <X_max-1;j++)
{
if(map[i][j]==1)
{
map[i + 1][j] = map[i][j];
map[i][j] = 0;
}
}
}
for(i = Y_max - 2;i > 0;i--)
{//把更新过的坐标系重新画出来
for(j = 1;j < X_max-1;j++)
{
block.x = j;
block.y = i;
COLORREF color = bg_color;
if(map[i][j]==1)
color = shape_color;
Draw_block(hwnd,block,color);
}
}
score += 10;//加分并显示
Show_score(hwnd);
if(score >= level*100)
{//判断是否修改等级
Change_level(hwnd);
}
}
void Change_level(HWND hwnd)
{//修改等级
level++;
Show_level(hwnd);
//修改速度
KillTimer(hwnd,1);
SetTimer(hwnd,1,1000/level,NULL);
}
void Pause()
{//未实现
}
void Draw_edge(HWND hwnd)
{//画出边界
HDC hdc;
hdc = GetDC(hwnd);
HPEN hpen = CreatePen(PS_SOLID,1,edge_color);
SelectObject(hdc,hpen);
for(int i = 1;i < Y_max;i++)
{
MoveToEx(hdc,block_size-1,i*block_size-1,NULL);
LineTo(hdc,(X_max-1)*block_size,i*block_size-1);
}
for(i = 0;i < X_max;i++)
{
MoveToEx(hdc,i*block_size-1,block_size-1,NULL);
LineTo(hdc,i*block_size-1,(Y_max-1)*block_size-1);
}
ReleaseDC(hwnd,hdc);
}
void Show_preview(HWND hwnd)
{//显示预览图形
POINT postion;
postion.x = X_max + 1;
postion.y = 3;
Draw_shape(hwnd,cur_shape_num,0,postion,bg_color);
Draw_shape(hwnd,pre_shape_num,pre_shape_direction,postion,shape_color);
}
void Show_score(HWND hwnd)
{//显示得分
HDC hdc = GetDC(hwnd);
TCHAR sc[5];
itoa(score,sc,10);
TextOut(hdc,(X_max+2)*block_size,13*block_size,sc,strlen(sc));
ReleaseDC(hwnd,hdc);
}
void Show_level(HWND hwnd)
{//显示等级
HDC hdc = GetDC(hwnd);
TCHAR lev[2];
itoa(level,lev,10);
TextOut(hdc,(X_max+2)*block_size,23*block_size,lev,strlen(lev));
ReleaseDC(hwnd,hdc);
}
bool Over()
{//判断游戏是否结束
for(int i = 1;i < X_max - 1;i++)
{
if(map[1][i]==1)
return true;
}
return false;
}
void Show_over(HWND hwnd)
{//这个功能还没完全写好
RECT rc;
SetRect(&rc,0,0,(X_max+5)*block_size,Y_max*block_size);
HDC hdc = GetDC(hwnd);
HBRUSH hbrush = CreateSolidBrush((bg_color));
FillRect(hdc,&rc,hbrush);
MessageBox(hwnd,TEXT("GameOver"),TEXT("GameOver"));
ReleaseDC(hwnd,hdc);
DeleteObject(hbrush);
}