#include <Windows.h>
#include <time.h>
#include <iostream>
using namespace std;
HWND hwnd;
#define UUMLINES ((int)(sizeof devcaps/sizeof devcaps[0]))//注意加空格
#define W 12
#define H 20
#define CELL 30
#if(1)
//block_shap ,0--19,1+2+8+4+5
#define BLOCKS_NUM 19
#define BLOCK_SHAPE_O 0
#define BLOCK_SHAPE_I_1 1
#define BLOCK_SHAPE_I_2 2
#define BLOCK_SHAPE_L_0 3
#define BLOCK_SHAPE_L_1 4
#define BLOCK_SHAPE_L_2 5
#define BLOCK_SHAPE_L_3 6
#define BLOCK_SHAPE_L_4 7
#define BLOCK_SHAPE_L_5 8
#define BLOCK_SHAPE_L_6 9
#define BLOCK_SHAPE_L_7 10
#define BLOCK_SHAPE_S_0 11
#define BLOCK_SHAPE_S_1 12
#define BLOCK_SHAPE_S_2 12
#define BLOCK_SHAPE_S_3 14
#define BLOCK_SHAPE_T_0 15
#define BLOCK_SHAPE_T_1 16
#define BLOCK_SHAPE_T_2 17
#define BLOCK_SHAPE_T_3 18
#endif
#define MAP_NONE 0
#define MAP_LAND 1
#define MAP_BLOCK 2
#define MOVE_TIME 200
#define REFRESH_TIME 33
#define CHANGE_TIME 150
#define STATE_DOWN 0
#define STATE_LEFT 1
#define STATE_RIGHT 2
#define STATE_LAND 3
#define STATE_CHANGESHAPE 4
#define SCORE_EACH 5
#define COLOR_BK RGB(255,255,255)
#define COLOR_BLOCK RGB(0,0,0)
class Clock
{
public:
void Init()
{
curtime = GetTickCount();
pretime = curtime;
premovetime = curtime;
curmovetime = curtime;
curchangtime = curtime;
prechangetime = curtime;
}
bool isRefresh()
{
curtime = GetTickCount();
if (curtime - pretime > REFRESH_TIME)
{
pretime = curtime;
return true;
}
else
return false;
}
bool isChangeShape()
{
curchangtime = GetTickCount();
if (curchangtime - prechangetime > CHANGE_TIME)
{
prechangetime = curchangtime;
return true;
}
else
return false;
}
bool isMove()
{
curmovetime = GetTickCount();
if (curmovetime - premovetime > MOVE_TIME)
{
premovetime = curmovetime;
return true;
}
else
return false;
}
private:
clock_t curtime;
clock_t pretime;
clock_t curmovetime;
clock_t premovetime;
clock_t curchangtime;
clock_t prechangetime;
};
void VerCpy(int dest[BLOCKS_NUM][4][4], int source[BLOCKS_NUM][4][4])
{
memcpy(dest, source, 4 * 4 * BLOCKS_NUM*sizeof(int));
}
class Point
{
public:
int x;
int y;
};
class Block
{
private:
int shape_num;//0-18,共19个
int shape_num_width[BLOCKS_NUM];//记录每种状态的宽度
int shape_num_height[BLOCKS_NUM];
int shape_state_size[5];//分别为1,2,8,4,4,共19
int blocks[BLOCKS_NUM][4][4];
Point pos;
enum block_state
{
DOWN,LEFT,RIGHT,LAND,CHANGESHAPE
}blockstate;
public:
void BlockDistribute()
{
pos.x = W / 2;
pos.y = -4;
srand((unsigned int)time(NULL));
shape_num = rand()%BLOCKS_NUM;///0-19
ChangeBlockState(STATE_DOWN);
}
void Init()
{
#if(1)
int temp_blocks[BLOCKS_NUM][4][4]=
{
{
{1,1,0,0},
{1,1,0,0},
{0,0,0,0},
{0,0,0,0}
},//1
{
{ 1, 0, 0, 0 },
{ 1, 0, 0, 0 },
{ 1, 0, 0, 0 },
{ 1, 0, 0, 0 }
},//2
{
{ 1, 1, 1, 1 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 }
},//3
{
{ 1, 0, 0, 0 },
{ 1, 0, 0, 0 },
{ 1, 1, 0, 0 },
{ 0, 0, 0, 0 }
},//4
{
{ 0, 0, 1, 0 },
{ 1, 1, 1, 0 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 }
},//5
{
{ 1, 1, 0, 0 },
{ 0, 1, 0, 0 },
{ 0, 1, 0, 0 },
{ 0, 0, 0, 0 }
},//6
{
{ 1, 1, 1, 0 },
{ 1, 0, 0, 0 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 }
},//7
{
{ 0, 1, 0, 0 },
{ 0, 1, 0, 0 },
{ 1, 1, 0, 0 },
{ 0, 0, 0, 0 }
},//8
{
{ 1, 1, 1, 0 },
{ 0, 0, 1, 0 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 }
},//9
{
{ 1, 1, 0, 0 },
{ 1, 0, 0, 0 },
{ 1, 0, 0, 0 },
{ 0, 0, 0, 0 }
},//10
{
{ 1, 0, 0, 0 },
{ 1, 1, 1, 0 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 }
},//11
{
{ 0, 1, 1, 0 },
{ 1, 1, 0, 0 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 }
},//12
{
{ 1, 0, 0, 0 },
{ 1, 1, 0, 0 },
{ 0, 1, 0, 0 },
{ 0, 0, 0, 0 }
},//13
{
{ 1, 1, 0, 0 },
{ 0, 1, 1, 0 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 }
},//14
{
{ 0, 1, 0, 0 },
{ 1, 1, 0, 0 },
{ 1, 0, 0, 0 },
{ 0, 0, 0, 0 }
},//15
{
{ 0, 1, 0, 0 },
{ 1, 1, 1, 0 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 }
},//16
{
{ 0, 1, 0, 0 },
{ 1, 1, 0, 0 },
{ 0, 1, 0, 0 },
{ 0, 0, 0, 0 }
},//17
{
{ 1, 1, 1, 0 },
{ 0, 1, 0, 0 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 }
},//18
{
{ 1, 0, 0, 0 },
{ 1, 1, 0, 0 },
{ 1, 0, 0, 0 },
{ 0, 0, 0, 0 }
},//19
};
#endif
memcpy(blocks,temp_blocks, 4 * 4 * BLOCKS_NUM*sizeof(int));
int temp_num_width[BLOCKS_NUM] = { 2, 1, 4, 2, 3, 2, 3, 2, 3, 2, 3, 3, 2, 3, 2, 3, 2, 3, 2 };
memcpy(shape_num_width, temp_num_width, BLOCKS_NUM*sizeof(int));
int temp_shape_state_size[5] = { 0, 2, 10, 14, 18 };
memcpy(shape_state_size, temp_shape_state_size, 5 * sizeof(int));
int temp_shape_state_heigth[BLOCKS_NUM] = { 2, 4, 1, 3, 2, 3, 2, 3, 2, 3, 2, 2, 3, 2, 3, 2, 3, 2, 3 };
memcpy(shape_num_height, temp_shape_state_heigth, BLOCKS_NUM*sizeof(int));
pos.x = W / 2;
pos.y = -4;
blockstate = DOWN;
srand((unsigned int)time(NULL));
shape_num = rand() % BLOCKS_NUM ;
}
void ChangeShape()
{
if (shape_num > BLOCK_SHAPE_O)
{
int key;
// int minnum;
for (key = 0; key < 5; key++)
{
if (shape_state_size[key] >= shape_num)
break;
}
if ((++shape_num)>shape_state_size[key])
shape_num = shape_state_size[key - 1] + 1;
}
else
return;
}
int GetNextShapeNum()
{
if (shape_num > BLOCK_SHAPE_O)
{
int key;
// int minnum;
for (key = 0; key < 5; key++)
{
if (shape_state_size[key] >= shape_num)
break;
}
if ((shape_num + 1)>shape_state_size[key])
return shape_state_size[key - 1] + 1;
else
return shape_num + 1;
}
else
return shape_num;
}
void ChangeBlockState(int STATE)
{
switch (STATE)
{
case STATE_DOWN:
blockstate = DOWN;
break;
case STATE_LEFT:
blockstate = LEFT;
break;
case STATE_RIGHT:
blockstate = RIGHT;
break;
case STATE_CHANGESHAPE:
blockstate = CHANGESHAPE;
break;
case STATE_LAND:
blockstate = LAND;
break;
}
}
int GetBlockState()
{
switch (blockstate)
{
case DOWN:
return STATE_DOWN;
break;
case LEFT:
return STATE_LEFT;
break;
case RIGHT:
return STATE_RIGHT;
break;
case LAND:
return STATE_LAND;
break;
case CHANGESHAPE:
return STATE_CHANGESHAPE;
break;
}
return DOWN;
}
int GetShapenum()
{
return shape_num;
}
int GetShapeWidth(int num)
{
return shape_num_width[num];
}
int GetShapeHeigt(int num)
{
return shape_num_height[num];
}
void GetBlockShape(int m[4][4],int number)
{
memcpy(m, blocks[number], 16 * sizeof(int));
}
Point GetPos()
{
return pos;
}
void LeftMove()
{
pos.x--;
/// if (pos.x <= 0)
// pos.x = 0;
}
void RightMove()
{
pos.x++;
// if (pos.x >=W-1)
// pos.x = W-1;
}
void DownMove()
{
pos.y++;
// if (pos.y >= H - 1)
// pos.y = H - 1;
}
};
class GameSystem
{
private:
int map[H][W];
int color[2];//背景,砖块
int score;//line的可次方,linescore = 5
int speed;//特指砖块移动速度,定义为1,即没0.5s移动1格
Block block;
Clock clock;
WCHAR strings[100];
public:
void Init()
{
for (int i = 0; i < H; i++)
{
for (int j = 0; j < W; j++)
{
map[i][j] = MAP_NONE;
}
}
color[0] = 0;
color[1] = 1;
score = 0;
int speed = 1;
clock.Init();
block.Init();
Render();
}
void InsertBlock()
{
int shapenum = block.GetShapenum();
int shape[4][4] = { 0 };
Point pos = block.GetPos();
int hidelen = ((pos.y < 0) ? -pos.y : 0);
if (hidelen == 4)
return;
block.GetBlockShape(shape, shapenum);
for (int i = hidelen; i < 4; i++)
{
for (int j = 0; j < 4; j++)
{
if (shape[i][j])
map[pos.y + i][pos.x + j] = MAP_BLOCK;
}
}
//gai
if (block.GetBlockState() == STATE_LAND)
{
FixMap();
score += Checkline() * 10;
block.BlockDistribute();
}
}
void RefreshMap()
{
for (int i = 0; i < H; i++)
{
for (int j = 0; j < W; j++)
{
if (map[i][j] == MAP_BLOCK)
map[i][j] = MAP_NONE;
}
}
}
void FixMap()
{
//经过判断砖块应该插入地图,成为地图一部分
for (int i = 0; i < H; i++)
{
for (int j = 0; j < W; j++)
{
if (map[i][j] == MAP_BLOCK)
map[i][j] = MAP_LAND;
}
}
}
bool isOkToDo(int state)
{
//准备阶段
Point pos = block.GetPos();
int shape[4][4] = { 0 };
int shapenum = block.GetShapenum();
int shapewidth ;
int shapeheight;
int nextshapenum;
switch (state)//先判断特殊,再一起判断常规--碰撞
{
case STATE_DOWN:
//先判断底部
shapeheight = block.GetShapeHeigt(shapenum);
shapewidth = block.GetShapeHeigt(shapenum);
if (shapeheight + pos.y >= H)
return false;
block.GetBlockShape(shape, shapenum);
pos.y++;//gai
break;
case STATE_LEFT:
//需要修改pos.x,获取当前shape
if (pos.x <= 0)
return false;
else
pos.x--;
shapeheight = block.GetShapeHeigt(shapenum);
shapewidth = block.GetShapeHeigt(shapenum);
block.GetBlockShape(shape, shapenum);
break;
case STATE_RIGHT://与右边墙壁
shapewidth= block.GetShapeWidth(shapenum);
if (pos.x + shapewidth >= W)
return false;
else
pos.x++;
shapeheight = block.GetShapeHeigt(shapenum);
block.GetBlockShape(shape, shapenum);
break;
case STATE_CHANGESHAPE://右,下特殊
//右
nextshapenum = block.GetNextShapeNum();
shapewidth = block.GetShapeWidth(nextshapenum);
shapeheight = block.GetShapeHeigt(nextshapenum);
if (nextshapenum == BLOCK_SHAPE_O)
return false;
if (pos.x + shapewidth >= W)
return false;
//下
else if (pos.y + shapeheight > H)
return false;
else
shapenum = nextshapenum;
block.GetBlockShape(shape,shapenum);
break;
}
//根据地图判断一般情况--砖块碰撞
int hidelen = ((pos.y < 0) ? -pos.y : 0);
if (hidelen == 4)
return true;
block.GetBlockShape(shape, shapenum);
for (int i = hidelen; i < shapeheight; i++)
{
for (int j = 0; j < 4; j++)
{
if (map[pos.y + i][pos.x + j] + shape[i][j] >= 2)
return false;
}
}
return true;
}
int Checkline()
{
int lines = 0;
//经过判断砖块应该插入地图,成为地图一部分
for (int i = H-1; i >=0; i--)
{
int count = 0;
for (int j = 0; j < W; j++)
{
count += map[i][j];
}
if (count == W)
{
lines++;
for (int k = i; k > 0; k--)
{
for (int j = 0; j < W; j++)
{
if (k == 0)
map[k][j] = 0;
else
map[k][j] = map[k - 1][j];
}
}
i++;
}
}
return lines;
}
void Chargeblock()
{
// int temp_block[4][4] = { 0 };
switch (block.GetBlockState())
{
case STATE_DOWN:
if (clock.isMove())
{
if (isOkToDo(STATE_DOWN))
{
block.DownMove();
}
else
block.ChangeBlockState(STATE_LAND);
}
break;
case STATE_LAND:
// FixMap();
//score += Checkline() * 10;
//block.BlockDistribute();
break;
case STATE_LEFT:
//判断是否可以左,可以则左移,否则,不变,状态也要做出相应的改变
if (clock.isMove())
{
if (isOkToDo(STATE_LEFT))
{
block.LeftMove();
}
}
block.ChangeBlockState(STATE_DOWN);
break;
case STATE_RIGHT:
if (clock.isMove())
{
if (isOkToDo(STATE_RIGHT))
{
block.RightMove();
}
}
block.ChangeBlockState(STATE_DOWN);
break;
case STATE_CHANGESHAPE:
if (isOkToDo(STATE_CHANGESHAPE)&&clock.isChangeShape())
{
block.ChangeShape();
}
block.ChangeBlockState(STATE_DOWN);
break;
}
}
void DrawRectangle(int x1, int y1, int x2, int y2, COLORREF c)
{
HDC hdc;
HBRUSH hbrush;
RECT rect;
SetRect(&rect, x1, y1, x2, y2);
hbrush = CreateSolidBrush((COLORREF)c);
hdc = GetDC(hwnd);
FillRect(hdc, &rect, hbrush);
ReleaseDC(hwnd, hdc);
DeleteObject(hbrush);
}
void DrawText(TCHAR* text, int x, int y, COLORREF c)
{
HDC hdc;
hdc = GetDC(hwnd);
SetTextColor(hdc,(COLORREF)c);
SetBkMode(hdc, TRANSPARENT);
TextOut(hdc, x, y, text, lstrlen(text));
ReleaseDC(hwnd, hdc);
}
void Render()
{
for (int i = 0; i < H; i++)
{
for (int j = 0; j < W; j++)
{
int y = i*CELL;
int x = j*CELL;
switch (map[i][j])
{
case MAP_NONE:
DrawRectangle(x, y, x + CELL, y + CELL,RGB(0,0,0));
break;
case MAP_BLOCK:
DrawRectangle(x, y, x + CELL, y + CELL, RGB(255,0,0));
break;
case MAP_LAND:
DrawRectangle(x, y, x + CELL, y + CELL, RGB(255, 0, 0));
break;
}
}
}
wsprintf(strings, TEXT("score:%d"), score);
DrawText(strings, CELL , CELL, RGB(0, 255, 0));
}
void Sendstate(int state)
{
//if ((state!=-1)&&clock.isMove())
if (state!=-1)
block.ChangeBlockState(state);
}
void Gamemain(int state)
{
RefreshMap();
Sendstate(state);
Chargeblock();
InsertBlock();
if (clock.isRefresh())
{
Render();
}
}
};
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE prevInstance, PSTR szCmdLine, int iCmdShow)
{
static TCHAR szAppName[] = TEXT("DevCaps1");
GameSystem game;
MSG msg = { 0 };
WNDCLASS wndclass;
wndclass.style = CS_HREDRAW | CS_VREDRAW;// | CS_OWNDC;
wndclass.lpfnWndProc = WndProc;
wndclass.cbClsExtra = 0;
wndclass.cbWndExtra = 0;
wndclass.hInstance = hInstance;
wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wndclass.hCursor = LoadCursor(NULL, IDC_APPSTARTING);
wndclass.hbrBackground = (HBRUSH)(GetStockObject(WHITE_BRUSH));
wndclass.lpszMenuName = NULL;
wndclass.lpszClassName = szAppName;
if (!RegisterClass(&wndclass))
{
MessageBox(NULL, TEXT("窗口创建需要WINNT"), szAppName, MB_ICONERROR);
return 0;
}
hwnd = CreateWindow(szAppName, TEXT("eluosifangkuai"), WS_DLGFRAME | WS_POPUP,200,20, W*CELL,H*CELL, NULL, NULL, NULL, NULL);
ShowWindow(hwnd, iCmdShow);
UpdateWindow(hwnd);
game.Init();
int state = -1;
while (msg.message != WM_QUIT)
{
if (PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else
{
if (GetAsyncKeyState(VK_UP))
state = STATE_CHANGESHAPE;
if (GetAsyncKeyState(VK_LEFT))
state = STATE_LEFT;
if (GetAsyncKeyState(VK_RIGHT))
state = STATE_RIGHT;
game.Gamemain(state);
state = -1;
}
}
return msg.wParam;
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
static int cxChar, cxCaps, cyChar;
// int status;
// TCHAR szBuffer[10];
HDC hdc;
// int i;
PAINTSTRUCT ps;
// TEXTMETRIC tm;
// RECT rect;
switch (message)
{
case WM_CREATE:
hdc = GetDC(hwnd);
ReleaseDC(hwnd, hdc);
return 0;
case WM_KEYDOWN:
switch (VK_UP)
{
case VK_UP :
SendMessage(hwnd, WM_KEYDOWN, VK_UP, 0);
break;
case VK_DOWN:
SendMessage(hwnd, WM_KEYDOWN, VK_DOWN, 0);
break;
case VK_LEFT:
SendMessage(hwnd, WM_KEYDOWN, VK_LEFT, 0);
break;
case VK_RIGHT:
SendMessage(hwnd, WM_KEYDOWN, VK_RIGHT, 0);
break;
}
case WM_PAINT:
hdc = BeginPaint(hwnd, &ps);
// SelectObject(ps.hdc, GetStockObject(DC_BRUSH));
EndPaint(hwnd, &ps);
return 0;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hwnd, message, wParam, lParam);
}
我的俄罗斯方块,WI32,GDI
最新推荐文章于 2022-04-25 17:14:31 发布