#include <windows.h>
#include "stdafx.h"
#include "math.h"
#include <stdio.h>
#include <conio.h>
#include <time.h>
#define MAX 4
#define Blockn 7
LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;
INT_PTR CALLBACK About(HWND, UINT, WPARAM, LPARAM);
int GameArea[11][23];
int NextArea[MAX][MAX];
int TimeElapsed = 0,TimeElapsed2; //1是陣列用計時器 2是 pixel值用計時器
//int block[MAX][MAX];
//int i = 3,j = 2; //GameArea陣列座標引述
int blockx = 103,blocky = 111; // x和y的 pixel值 下降時處理用
int bottonline[] = {747,747,747,747,747,747,747,747,747,747,747}; //每一行的底界
int H = 23,W = 11; //畫面長寬, 方塊數目
bool bExit = false; //是否持續遊戲
int level=0, score=0; //關卡, 積分
int ox=13, oy=57; //畫面左上原點
int B, N; //當前&下一個 方塊的編號
int X, Y, dir=0; //方塊位置, 所處方位(0~3)
int delay_time = 1000; //延遲時間
int block[Blockn][4] = //方塊樣式
{{0x6220,0x1700,0x2230,0x0740}, // L
{0x6440,0x0e20,0x44c0,0x8e00}, // _|
{0x04e0,0x0464,0x00e4,0x04c4}, // T
{0x4620,0x6c00,0x4620,0x6c00}, // z
{0x2640,0xc600,0x2640,0xc600}, // 反z
{0x0f00,0x4444,0x0f00,0x4444}, // |
{0x0660,0x0660,0x0660,0x0660}}; // 田
LOGBRUSH background;
static TCHAR szAppName [] = TEXT ("Bricks") ;
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
PSTR szCmdLine, int iCmdShow)
{
HWND hwnd ;
MSG msg ;
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_ARROW) ;
//wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH) ;
wndclass.lpszMenuName = NULL ;
wndclass.lpszClassName = szAppName ;
background.lbStyle = BS_PATTERN;
background.lbHatch = (long) LoadImage(NULL,TEXT("background1.bmp"), IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
wndclass.hbrBackground = CreateBrushIndirect(&background);
if (!RegisterClass (&wndclass))
{
MessageBox (NULL, TEXT ("This program requires Windows NT!"),
szAppName, MB_ICONERROR) ;
return 0 ;
}
hwnd = CreateWindow ( szAppName,
TEXT ("TETRIS (?)"),
WS_OVERLAPPED | WS_SYSMENU,
CW_USEDEFAULT,
0,
520,
850,
NULL,
NULL,
hInstance, NULL) ;
ShowWindow (hwnd, iCmdShow) ;
UpdateWindow (hwnd) ;
while (GetMessage (&msg, NULL, 0, 0))
{
TranslateMessage (&msg) ;
DispatchMessage (&msg) ;
}
return msg.wParam ;
}
void drawline(HDC hdc, IN HWND hWnd,
OUT LPPAINTSTRUCT lpPaint)
{
CHAR str[] = "N E X T";
CHAR str2[] = "I T E M";
CHAR str3[] = "S C O R E ";
WCHAR wsz[64];
swprintf(wsz, L"%S", str3);
LPCWSTR p3 = wsz;
TextOut(hdc,10,10,p3,strlen(str3));
swprintf(wsz, L"%S", str);
LPCWSTR p = wsz;
TextOut(hdc,412,35,p,strlen(str));
swprintf(wsz, L"%S", str2);
LPCWSTR p2 = wsz;
TextOut(hdc,397,445,p2,strlen(str2));
//Rectangle(hdc,10,54,346,750); //主視窗範圍
//Rectangle(hdc,12,56,344,748);
Rectangle(hdc,10,54,346,56);
Rectangle(hdc,344,54,346,748);
Rectangle(hdc,12,748,346,750);
Rectangle(hdc,10,56,12,750);
Rectangle(hdc,374,54,500,176); //下一個方塊範圍
Rectangle(hdc,376,56,498,174);
Rectangle(hdc,374,466,470,562); //道具範圍
Rectangle(hdc,376,468,468,560);
Rectangle(hdc,374,562,470,656);
Rectangle(hdc,376,564,468,654);
Rectangle(hdc,374,656,470,750);
Rectangle(hdc,376,658,468,748);
}
bool bMove_block (int bx, int by, int d) //傳入新位置與旋轉方向
{ //檢驗方塊能否變動
for (int p = 0x8000, x, y=0; y<4; y++){
for (x=0; x<4; x++, p>>=1) {
if ((block[B][d]&p) && GameArea[X][Y]){
return false;
}
}
}
return true;
}
void try_move_block (int x, int y, int d) { //嘗試移動
if (!bMove_block (x,y,d)) return;
int colortemp = GameArea[X][Y];
GameArea[x][y] = 0;
X = x;
Y = y;
dir = d;
GameArea[x][y] = colortemp;
}
int remove_lines(){
return 0;
}
LRESULT CALLBACK WndProc ( HWND hwnd, UINT message, WPARAM wParam,LPARAM lParam)
{
int wmId,wmEvent;
PAINTSTRUCT ps ;
char tmp[60];
LPCWSTR p;
HDC hdc;
HINSTANCE hInstance;
RECT r,tmpr;
static HBITMAP hBitmap, hBitmap2, hBitmapBlock0,hBitmapBlock1,hBitmapBlock2,hBitmapBlock3,hBitmapBlock4;
static int cxClient, cyClient, cxSource, cySource ;
static int cxClient2, cyClient2, cxSource2, cySource2 ;
BITMAP bitmap, bitmap2;
HDC hdcMem ;
int gameover = 0,Ncolor,Bcolor;
int n;
switch (message)
{
case WM_CREATE:
SetTimer(hwnd,1,delay_time,NULL);
srand (time(0));
hInstance = ((LPCREATESTRUCT) lParam)->hInstance ;
hBitmap = LoadBitmap (hInstance, TEXT ("Bricks1")) ;
hBitmapBlock0 = LoadBitmap (hInstance, TEXT ("Block0")) ;
hBitmapBlock1 = LoadBitmap (hInstance, TEXT ("Block1")) ;
hBitmapBlock2 = LoadBitmap (hInstance, TEXT ("Block2")) ;
hBitmapBlock3 = LoadBitmap (hInstance, TEXT ("Block3")) ;
hBitmapBlock4 = LoadBitmap (hInstance, TEXT ("Block4")) ;
B = rand() % Blockn;
N = rand() % Blockn;
X = W/2-1;
Y = 0;
ZeroMemory(GameArea,sizeof(GameArea));
ZeroMemory(NextArea,sizeof(NextArea));
GameArea[3][2] = 1;
//int x2, y2,
//Ncolor = rand()%7;
Ncolor = 1;
for (int y2=0,p2 = 0x8000; y2<4; y2++){
for (int x2=0; x2<4; x2++, p2>>=1) {
if (block[N][0] & p2) {
NextArea[x2][y2] = Ncolor;
}
}
}
InvalidateRect(hwnd,NULL,TRUE);
return 0 ;
case WM_KEYDOWN:
switch(wParam){
case VK_UP:
try_move_block (X,Y,(dir+1)&3);
break;
case VK_DOWN:
/*GameArea[i][j] = 0;
j = j+1;
GameArea[i][j] = 1;*/
try_move_block (X,Y+1,dir);
break;
case VK_LEFT:
/*GameArea[i][j] = 0;
i = i - 1;
GameArea[i][j] = 1;*/
try_move_block (X-1,Y,dir);
break;
case VK_RIGHT:
/*GameArea[i][j] = 0;
i= i+1;
GameArea[i][j] = 1;*/
try_move_block (X+1,Y,dir);
break;
}
break;
/*case WM_SIZE:
cxClient = LOWORD (lParam) ;
cyClient = HIWORD (lParam) ;
return 0 ;*/
case WM_PAINT:
hdc = BeginPaint (hwnd, &ps) ;
hdcMem = CreateCompatibleDC (hdc) ;
drawline(hdc, hwnd, &ps);
WCHAR ww2[640]; //記數器測試用
sprintf(tmp,"%d",TimeElapsed);
swprintf(ww2, L"%S", tmp);
p = ww2;
TextOut(hdc,200,30,p,strlen(tmp));
WCHAR ww[640];
sprintf(tmp,"%d",blocky);
swprintf(ww, L"%S", tmp);
p = ww;
TextOut(hdc,200,10,p,strlen(tmp));
/*GetObject (hBitmap, sizeof (BITMAP), &bitmap) ;
cxSource2 = bitmap.bmWidth ;
cySource2 = bitmap.bmHeight ;
SelectObject (hdcMem, hBitmap) ;
BitBlt (hdc, 12, 56, 332, 692, hdcMem, 50, 200, SRCCOPY) ;*/
for (int y=0; y<H; y++){
for (int x=0; x<W; x++){
switch(GameArea[x][y]){
case 0:
TextOut(hdc,18+(x*30),62+(y*30),(LPCTSTR)"0",1);
break;
case 1:
GetObject(hBitmapBlock0,sizeof(BITMAP),&bitmap);
SelectObject(hdcMem,hBitmapBlock0);
BitBlt(hdc,ox+(30*x),oy+(30*y),bitmap.bmWidth,bitmap.bmHeight,hdcMem,0,0,SRCCOPY);
break;
case 2:
break;
case 3:
break;
case 4:
break;
case 5:
break;
case 6:
break;
case 7:
break;
}
}
}
for (int yy=0; yy<MAX; yy++){
for (int xx=0; xx<MAX; xx++){
switch(NextArea[xx][yy]){
case 0:
TextOut(hdc,18+(xx*30),62+(yy*30),(LPCTSTR)"0",1);
break;
case 1:
/*GetObject(hBitmapBlock0,sizeof(BITMAP),&bitmap);
SelectObject(hdcMem,hBitmapBlock0);*/
BitBlt(hdc,377+(30*xx),57+(30*yy),bitmap.bmWidth,bitmap.bmHeight,hdcMem,0,0,SRCCOPY);
break;
case 2:
break;
case 3:
break;
case 4:
break;
case 5:
break;
case 6:
break;
case 7:
break;
}
}
}
DeleteDC (hdcMem) ;
/*if(TimeElapsed!=0){
GetObject(hBitmapBlock2,sizeof(BITMAP),&bitmap);
SelectObject(hdcMem,hBitmapBlock2);
BitBlt(hdc,blockx,blocky,bitmap.bmWidth,bitmap.bmHeight,hdcMem,0,0,SRCCOPY);
}*/
EndPaint (hwnd, &ps) ;
return 0 ;
case WM_TIMER:
r.left = 200;
r.right = r.left+strlen(tmp);
r.top = 10;
r.bottom = r.top+40;
tmpr.left = 12;
tmpr.right = 344;
tmpr.top = 56;
tmpr.bottom = 748;
InvalidateRect(hwnd,&r,TRUE);
Bcolor = Ncolor;
/*if(TimeElapsed%5==0){
GameArea[i][j] = 0;
j = j+1;
GameArea[i][j] = 1;
}*/
if (bMove_block (X,Y+1,dir)) {
try_move_block (X,Y+1,dir);
TimeElapsed++;
return 0;
}
if (Y==0) {
gameover = 1;
}
for (int p = 0x8000, x, y=0; y<4; y++){
for (x=0; x<4; x++, p>>=1) {
if (block[B][dir] & p) {
GameArea[X][Y] = Bcolor;
}
}
}
n = remove_lines();
TimeElapsed++;
//InvalidateRect(hwnd,&tmpr,TRUE);
InvalidateRect(hwnd,NULL,TRUE);
if(gameover==1){
switch (MessageBox(hwnd,TEXT("G A M E O V E R"),TEXT("回合結束"),MB_ICONINFORMATION|MB_YESNO))
{
case IDYES:
SendMessage(hwnd,WM_CREATE,0,0);
break;
case IDNO:
PostQuitMessage(0);
break;
}
}
break;
case WM_DESTROY:
DeleteObject(&background);
DeleteObject (hBitmap) ;
PostQuitMessage (0) ;
return 0 ;
}
return DefWindowProc (hwnd, message, wParam, lParam) ;
}
INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
UNREFERENCED_PARAMETER(lParam);
switch (message)
{
case WM_INITDIALOG:
return (INT_PTR)TRUE;
case WM_COMMAND:
if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
{
EndDialog(hDlg, LOWORD(wParam));
return (INT_PTR)TRUE;
}
break;
}
return (INT_PTR)FALSE;
}