C++러시아 블록 구현(windows API)
컴 파일 러 는 code:block + MinGW,CB 라 는 IDE 가 정말 강력 하 다 고 생각 합 니 다.너무 좋 습 니 다.아래 코드 를 VC 로 직접 복사 해서 실행 하 는 것 이 잘못 되 지 않 을 것 입 니 다.문 제 는 어떻게 해결 해 야 할 지 모 르 겠 습 니 다.바로 고객 지역 을 업데이트 할 때 창 이 반 짝 거 려 서 어떤 달인 이 저 를 지적 해 줄 수 있 는 지 모 르 겠 습 니 다.windows API 가 쓴 것 도 있 고 windows 프로 그래 밍 에 대해 잘 모 르 니 댓 글 을 많이 남 겨 주세요.본인 에 게 조언 해 주세요.
#include <windows.h>
#include <iostream>
#include <cstdlib>
#include <ctime>
using namespace std;
#define CellWidth 20
#define MAP_WIDTH 12
#define MAP_HEIGHT 18
#define ID_TIMER 1
class map_floor;
class Block;
LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM);
/* Make the class name into a global variable */
char szClassName[ ] = "CodeBlocksWindowsApp";
int WINAPI WinMain (HINSTANCE hThisInstance,
HINSTANCE hPrevInstance,
LPSTR lpszArgument,
int nCmdShow)
{
HWND hwnd; /* This is the handle for our window */
MSG messages; /* Here messages to the application are saved */
WNDCLASSEX wincl; /* Data structure for the windowclass */
/* The Window structure */
wincl.hInstance = hThisInstance;
wincl.lpszClassName = szClassName;
wincl.lpfnWndProc = WindowProcedure; /* This function is called by windows */
wincl.style = CS_DBLCLKS|CS_HREDRAW | CS_VREDRAW; /* Catch double-clicks */
wincl.cbSize = sizeof (WNDCLASSEX);
/* Use default icon and mouse-pointer */
wincl.hIcon = LoadIcon (NULL, IDI_APPLICATION);
wincl.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
wincl.hCursor = LoadCursor (NULL, IDC_ARROW);
wincl.lpszMenuName = NULL; /* No menu */
wincl.cbClsExtra = 0; /* No extra bytes after the window class */
wincl.cbWndExtra = 0; /* structure or the window instance */
/* Use Windows's default colour as the background of the window */
wincl.hbrBackground =(HBRUSH) GetStockObject(WHITE_BRUSH);//COLOR_BACKGROUND;
/* Register the window class, and if it fails quit the program */
if (!RegisterClassEx (&wincl))
return 0;
/* The class is registered, let's create the program*/
hwnd = CreateWindowEx (
0, /* Extended possibilites for variation */
szClassName, /* Classname */
"Code::Blocks Template Windows App", /* Title Text */
WS_OVERLAPPEDWINDOW, /* default window */
CW_USEDEFAULT, /* Windows decides the position */
CW_USEDEFAULT, /* where the window ends up on the screen */
CW_USEDEFAULT, /* The programs width */
CW_USEDEFAULT, /* and height in pixels */
NULL, /* The window is a child-window to desktop */
NULL, /* No menu */
hThisInstance, /* Program Instance handler */
NULL /* No Window Creation data */
);
/* Make the window visible on the screen */
ShowWindow (hwnd, nCmdShow);
/* Run the message loop. It will run until GetMessage() returns 0 */
while (GetMessage (&messages, NULL, 0, 0))
{
/* Translate virtual-key messages into character messages */
TranslateMessage(&messages);
/* Send message to WindowProcedure */
DispatchMessage(&messages);
}
/* The program return-value is 0 - The value that PostQuitMessage() gave */
return messages.wParam;
}
enum{e_LINE,e_CORNER,e_STAIR,e_TANCK,e_TIAN};
const int TOTAL_BLOCK_STYLE = 5;// 4
class Block
{
public:
Block(int x = 100, int y = 100);
Block(const Block & rh)// , ,
{
this->m_style = rh.m_style;
this->m_direct = rh.m_direct;
for(int i = 0 ; i < 4 ; i ++)
this->m_block[i] = rh.m_block[i];
}
Block & operator = (const Block& rh)// = ,
{
this->m_style = rh.m_style;
this->m_direct = rh.m_direct;
for(int i = 0 ; i < 4 ; i ++)
this->m_block[i] = rh.m_block[i];
return *this;
}
~Block(){}
int create_block(int x = 100 , int y = 100);
//
int show_block(HDC hdc,const POINT& GameLeftTop);
// ,
int show_next_block(HDC hdc);
// , , , ,
int rotate();
//
int random_block();
//
int get_block_height(){ return m_block[1].y;}
int move_down(const RECT& GameClient);
int move_left(const RECT& GameClient);
int move_right(const RECT& GameClient);
int move_up(const RECT& GameClient);
int move_to(int x , int y);
//
// int check_block(const map_floor& map, const RECT& GameClent);
int check_block(const map_floor& map, const POINT& LeftTopScrCdnt);
int print_to_map(map_floor& map , const POINT& LeftTopScrCdnt);
private:
int m_style;// ,
int m_direct;// , m_style
POINT m_block[4];// 1 , ,
};
class map_floor
{
public:
map_floor()
{
ZeroMemory(m_block_bar,sizeof(int )*12*18);
}
~map_floor(){}
void show_block_bar(HDC hdc , const POINT& LeftTopScrCdnt)
{
for(int i = 0 ; i < MAP_HEIGHT ; ++ i)
{
for(int j = 0 ; j < MAP_WIDTH ; ++ j)
{
if(m_block_bar[i][j])
{
Rectangle(hdc,LeftTopScrCdnt.x + j*CellWidth , LeftTopScrCdnt.y + i*CellWidth,
LeftTopScrCdnt.x + (j+1)*CellWidth , LeftTopScrCdnt.y + (i+1)*CellWidth);
}
}
}
}
friend class Block;
protected:
private:
int m_block_bar[MAP_HEIGHT][MAP_WIDTH];// , 18*12
};
Block::Block(int x , int y)
{
// ZeroMemory(m_block_bar,sizeof(int )*12*18);
srand( (unsigned)time( NULL ) );// ,
// POINT pt = {100,100};
create_block(x,y);
}
int Block::random_block()
{
m_style = rand()%TOTAL_BLOCK_STYLE;
// m_style = e_CORNER; //
// m_style = e_LINE; //
if(m_style == e_STAIR || m_style == e_TANCK)
m_direct = rand()%4;
else if(m_style == e_LINE)
m_direct = rand()%2;
else if(m_style == e_CORNER)
m_direct = rand()%8;
else if(m_style == e_TIAN)
m_direct = 0;
m_direct = 1;
}
int Block::check_block(const map_floor& map, const POINT& LeftTopScrCdnt)
{
int x , y ; //x , y , (0,0)
for(int i = 0 ; i < 4 ; i ++)
{
x = (m_block[i].x - LeftTopScrCdnt.x)/CellWidth;
y = (m_block[i].y - LeftTopScrCdnt.y)/CellWidth;
if(x < 0 || x >= MAP_WIDTH || y >= MAP_HEIGHT)// y < 0
return 0;
if(y < 0) continue;
if(map.m_block_bar[y][x])
return 0;
}
return 1;
}
int Block::move_down(const RECT& GameClient)// ,
{
int i;
// for (i = 0 ; i < 4 ; i ++ )
// {
// if(m_block[i].y == GameClient.bottom - CellWidth)
// return 0;
// }
for (i = 0; i < 4 ;i ++ )
{
m_block[i].y += CellWidth;
}
return 1;
}
int Block::move_up(const RECT& GameClient)
{
move_to(m_block[1].x,m_block[1].y - CellWidth);
return 1;
}
int Block::move_left(const RECT& GameClient)
{
move_to(m_block[1].x - CellWidth,m_block[1].y);
return 1;
}
int Block::move_right(const RECT& GameClient)
{
move_to(m_block[1].x + CellWidth , m_block[1].y);
return 1;
}
int Block::create_block(int x , int y)
{
m_block[1].x = x;
m_block[1].y = y;
random_block();
rotate();
return 1;
}
int Block::move_to(int x , int y)
{
int Vx = x - m_block[1].x;
int Vy = y - m_block[1].y;
for(int i = 0 ; i < 4 ; i ++)
{
m_block[i].x += Vx;
m_block[i].y += Vy;
}
}
int Block::print_to_map(map_floor& map , const POINT& LeftTopScrCdnt)
{
int x , y;
int i , j;
for(i = 0 ; i < 4 ; i ++ )
{
x = (m_block[i].x - LeftTopScrCdnt.x)/CellWidth;
y = (m_block[i].y - LeftTopScrCdnt.y)/CellWidth;
if(x<0 || x >= MAP_WIDTH || y <0 || y >= MAP_HEIGHT)// , ,
return 0;
map.m_block_bar[y][x] = 1 ;
for(j = 0 ; j < MAP_WIDTH ; j ++)
{
if(map.m_block_bar[y][j] != 1)
break;
}
if(MAP_WIDTH == j)
{
for(j = 0 ; j < MAP_WIDTH ; j ++)
{
map.m_block_bar[y][j] = 5;// 5
}
}
}
int idx;
for(i = 0 ; i < MAP_WIDTH ; i ++)
{
for(idx = j = MAP_HEIGHT - 1 ; j >= 0 ; j --)
{
if(map.m_block_bar[j][i] != 5)
{
map.m_block_bar[idx--][i] = map.m_block_bar[j][i];
}
}
while(idx >= 0)
{
map.m_block_bar[idx--][i] = 0;
}
}
return 1;
}
// , 【 】 ,
// block【4】 , 3 block【1】 ,
// , 7 , , , :
//
//e_LINE , , ,
// m_direct ,
//
//e_TANCK , , m_direct 4
// , , ,
// 。
//
//e_STAIR , ,
// , m_direct , e_STAIR_BACK e_STAIR_FRONT
// , block【0】 block【1】
// , block【2】 block【3】,block【2】 block【1】 ,x block【1】
// ,block【3】.y block【1】 ,
//
//e_CORNER , , e_CORNER_FRONT , e_CORNER_BACK
// , , , block【3】
// m_direct
int Block::rotate()
{
switch (m_style)
{
case e_LINE:
{
switch(m_direct)
{
case 0://
{
for(int i = 0 ; i < 4 ; i ++)
{
m_block[i].x = m_block[1].x;
m_block[i].y = m_block[1].y + (1-i)*CellWidth;
}
m_direct = 1;
}
break;
case 1://
{
for(int i = 0 ; i < 4 ; i ++)
{
m_block[i].y = m_block[1].y;
m_block[i].x = m_block[1].x + (1-i)*CellWidth;
}
m_direct = 0;
}
break;
}
}
break;
// , , ,
//m_direct% == 0
case e_STAIR:
{
int flag;
flag = m_direct < 2 ? 1 : -1;
m_block[0].x = m_block[1].x + flag*CellWidth;
m_block[0].y = m_block[1].y;
m_block[2].x = m_block[1].x;
m_block[3].y = m_block[1].y + CellWidth;
if(m_direct%2 == 0)
{
m_block[2].y = m_block[1].y - CellWidth;
m_block[3].x = m_block[1].x + flag*CellWidth;
m_direct++;
}
else
{
m_block[2].y = m_block[1].y + CellWidth;
m_block[3].x = m_block[1].x - flag*CellWidth;
if(m_direct < 2) m_direct = 0;
else m_direct = 2;
}
}
break;
// , , , ,
// m_direct%4 , ,
// , block【3】 ,
case e_CORNER:
{
switch (m_direct%4)
{
case 0:
{
m_block[0].x = m_block[1].x+CellWidth;
m_block[0].y = m_block[2].y = m_block[1].y;
m_block[2].x = m_block[1].x-CellWidth;
m_block[3].x = m_block[1].x-CellWidth;
if(m_direct>=4) m_block[3].y = m_block[1].y-CellWidth;
else m_block[3].y = m_block[1].y+CellWidth;
m_direct ++;
}
break;
case 1:
{
m_block[0].x = m_block[2].x = m_block[1].x;
m_block[0].y = m_block[1].y+CellWidth;
m_block[2].y = m_block[1].y-CellWidth;
if(m_direct>=4) m_block[3].x = m_block[1].x+CellWidth;
else m_block[3].x = m_block[1].x-CellWidth;
m_block[3].y = m_block[1].y-CellWidth;
m_direct ++;
}
break;
case 2:
{
m_block[0].x = m_block[1].x-CellWidth;
m_block[0].y = m_block[2].y = m_block[1].y;
m_block[2].x = m_block[1].x+CellWidth;
m_block[3].x = m_block[1].x+CellWidth;
if (m_direct>=4) m_block[3].y = m_block[1].y+CellWidth;
else m_block[3].y = m_block[1].y-CellWidth;
m_direct ++;
}
break;
case 3:
{
m_block[0].x = m_block[2].x = m_block[1].x;
m_block[0].y = m_block[1].y-CellWidth;
m_block[2].y = m_block[1].y+CellWidth;
if(m_direct>=4) { m_block[3].x = m_block[1].x-CellWidth; m_direct = 4;}
else { m_block[3].x = m_block[1].x+CellWidth; m_direct = 0;}
m_block[3].y = m_block[1].y+CellWidth;
}
break;
default:
break;
}
}
break;
case e_TANCK:// , ,
{
switch (m_direct%2)
{
case 0:
{
m_block[0].x = m_block[2].x = m_block[1].x;
m_block[0].y = m_block[1].y - CellWidth;
m_block[2].y = m_block[1].y + CellWidth;
int flag = m_direct == 0 ? 1 : -1;
m_block[3].x = m_block[1].x + flag*CellWidth;
m_block[3].y = m_block[1].y;
m_direct++;
}
break;
case 1:
{
m_block[0].y = m_block[2].y = m_block[1].y;
m_block[0].x = m_block[1].x - CellWidth;
m_block[2].x = m_block[1].x + CellWidth;
m_block[3].x = m_block[1].x;
int flag = m_direct == 3 ? -1:1;
m_block[3].y = m_block[1].y + flag*CellWidth;
if(m_direct == 3) m_direct = 0;
else m_direct++;
}
break;
default:
break;
}
}
break;
case e_TIAN:
{
m_block[0].y = m_block[1].y;
m_block[0].x = m_block[1].x + CellWidth;
m_block[2].x = m_block[1].x;
m_block[2].y = m_block[1].y + CellWidth;
m_block[3].x = m_block[1].x + CellWidth;
m_block[3].y = m_block[1].y + CellWidth;
}
break;
default:
break;
}
return 0;
}
int Block::show_block(HDC hdc,const POINT& GameLeftTop)
{
for (int i = 0 ; i < 4 ; i ++ )
{
if(m_block[i].y >= GameLeftTop.y)
Rectangle(hdc,m_block[i].x,m_block[i].y,m_block[i].
x+CellWidth,m_block[i].y+CellWidth);
if(i==0)// ,
{MoveToEx(hdc,m_block[i].x,m_block[i].y,NULL);
LineTo(hdc,m_block[i].x+CellWidth,m_block[i].y+CellWidth);}
}
return 1;
}
int Block::show_next_block(HDC hdc)
{
for (int i = 0 ; i < 4 ; i ++ )
{
Rectangle(hdc,m_block[i].x,m_block[i].y,m_block[i].
x+CellWidth,m_block[i].y+CellWidth);
}
return 1;
}
Block block , next_block , try_block;
map_floor map;int d = 0;
LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
HDC hdc ;
PAINTSTRUCT ps ;
//
static RECT GameClient;
// CellWidth = 20 12 18
const int Width = 240 ,Height = 360;
static POINT LeftTopScrCdnt;//
switch (message)
{
case WM_CREATE:
SetTimer(hwnd,ID_TIMER,500,NULL);
return 0 ;
case WM_SIZE:
GetClientRect(hwnd,&GameClient);
LeftTopScrCdnt.x = (GameClient.right-GameClient.left)/2 - Width/2;
LeftTopScrCdnt.y = GameClient.top + 50;
GameClient.left = LeftTopScrCdnt.x;
GameClient.top = LeftTopScrCdnt.y;
GameClient.right = LeftTopScrCdnt.x + Width;
GameClient.bottom = LeftTopScrCdnt.y + Height;
//
next_block.create_block(GameClient.right+2*CellWidth,(GameClient.bottom+GameClient.top)/2-3*CellWidth);
block.move_to((GameClient.right+GameClient.left)/2,GameClient.top-CellWidth);
break;
case WM_TIMER:
block.move_down(GameClient);
if(!block.check_block(map,LeftTopScrCdnt))// , ,
{
block.move_up(GameClient);
if(!block.check_block(map,LeftTopScrCdnt) ||
block.get_block_height() <= LeftTopScrCdnt.y )//
{
KillTimer(hwnd,ID_TIMER);
d = 4;
}
block.print_to_map(map,LeftTopScrCdnt);
SendMessage(hwnd,WM_KEYDOWN,VK_ESCAPE,0);
}
InvalidateRect(hwnd,NULL,true);
break;
case WM_PAINT:
hdc = BeginPaint (hwnd, &ps) ;
MoveToEx(hdc,LeftTopScrCdnt.x,LeftTopScrCdnt.y,NULL);
Rectangle(hdc,GameClient.left,GameClient.top,GameClient.right,GameClient.bottom);//
SelectObject(hdc,GetStockObject(BLACK_BRUSH));
map.show_block_bar(hdc,LeftTopScrCdnt);
block.show_block(hdc,LeftTopScrCdnt);
next_block.show_next_block(hdc);
EndPaint (hwnd, &ps);
break;
case WM_KEYDOWN:
InvalidateRect(hwnd,NULL,true);
switch (wParam)
{
case VK_SPACE:
{
try_block = block;
try_block.rotate();
if(try_block.check_block(map ,LeftTopScrCdnt))
block = try_block;
break;
}
case VK_LEFT:
{
block.move_left(GameClient);
if(!block.check_block(map ,LeftTopScrCdnt))
block.move_right(GameClient);
}
break;
case VK_RIGHT:
{
block.move_right(GameClient);
if (!block.check_block(map ,LeftTopScrCdnt))
block.move_left(GameClient);
}
break;
case VK_DOWN:
{
// block.move_down(GameClient);
SendMessage(hwnd,WM_TIMER,0,0);
}
break;
case VK_ESCAPE:// ,
{
block = next_block;
next_block.create_block(GameClient.right+2*CellWidth,(GameClient.bottom+GameClient.top)/2-3*CellWidth);
block.move_to((GameClient.right+GameClient.left)/2,GameClient.top-CellWidth);
}
break;
default:
break;
}
break;
case WM_DESTROY:
PostQuitMessage (0) ;
return 0 ;
}
return DefWindowProc (hwnd, message, wParam, lParam) ;
}
이상 이 바로 본 고의 모든 내용 입 니 다.여러분 의 학습 에 도움 이 되 고 저 희 를 많이 응원 해 주 셨 으 면 좋 겠 습 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Visual Studio에서 파일 폴더 구분 (포함 경로 설정)Visual Studio에서 c, cpp, h, hpp 파일을 폴더로 나누고 싶었습니까? 어쩌면 대부분의 사람들이 있다고 생각합니다. 처음에 파일이 만들어지는 장소는 프로젝트 파일 등과 같은 장소에 있기 때문에 파일...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.