Win32俄罗斯方块

来源:互联网 发布:笔记本触摸屏锁定软件 编辑:程序博客网 时间:2024/06/14 04:28

elsHead.h

#pragma once#ifndef DEF_ELS_HEAD#define DEF_ELS_HEAD#define DEF_TIMER1 1234#define WIDTH 700       #define HEIGHT 655#include <time.h>#include <windows.h>void onPaint(HDC hdc);void onCreat();// 显示方块void paintSqare(HDC hdc);// 产生随机块int createRandSqare();// 随机块贴近背景void copySqareToBack();// 按键void onReturn(HWND hwnd);void onTimer(HWND hwnd);void onUp(HWND hwnd);void onLeft(HWND hwnd);void onRight(HWND hwnd);// 方块移动void sqareDown();void sqareLeft();void sqareRight();// 方块停在最底下int canSqareDown();// 把1变成2void change();// 方块停止下落int sqareStop();// 方块左右移动int canSqareRight();int canSqareLeft();// 方块停止左右移动int sqareLeftStop();int sqareRightStop();// 消除完整行void destroyOneLine();// 方块变形void sqareChange();#endif

elsHead.cpp

#include "elsHead.h"// 背景数组char g_arrBackGround[20][16] = { 0 };char g_arrSqare[2][4] = { 0 };char g_;int g_row = 0;int g_list = 0;int g_sqareID;void onPaint(HDC hdc) {    // 兼容性DC    HDC comdc = CreateCompatibleDC(hdc);    // 创建一张纸    HBITMAP hBitmap = CreateCompatibleBitmap(hdc, WIDTH, HEIGHT);    // 关联起来    SelectObject(comdc, hBitmap);    paintSqare(comdc);    // 传递    BitBlt(hdc, // 目标DC        5,      // 起始x        5,      // 起始y        480,  // 目标区域x        600,  // 目标区域y        comdc,  // 源DC        0, 0, SRCCOPY);    // 释放DC    DeleteObject(hBitmap);    DeleteDC(comdc);}void onCreat(){    srand((unsigned int)time(NULL));    createRandSqare();    copySqareToBack();}// 显示方块void paintSqare(HDC comdc){    int i = 0;    int j = 0;    // 遍历    for (i = 0;i < 20;i++)     {        for (j = 0;j < 16;j++)        {            // 如果是1或2 画出方块            if(g_arrBackGround[i][j] == 1 || g_arrBackGround[i][j] == 2)                Rectangle(comdc, 30 * j , 30 * i, 30 + 30 * j, 30 + 30 * i);        }    }}// 产生随机块int createRandSqare(){    int n;    n = rand() % 7 + 1;    g_sqareID = n;    // 方块类型    switch (n)    {        // 正方形    case 1:        g_arrSqare[0][0] = 1;g_arrSqare[0][1] = 1;g_arrSqare[0][2] = 0;g_arrSqare[0][3] = 0;        g_arrSqare[1][0] = 1;g_arrSqare[1][1] = 1;g_arrSqare[1][2] = 0;g_arrSqare[1][3] = 0;        break;        // 一条的    case 2:         g_arrSqare[0][0] = 1;g_arrSqare[0][1] = 1;g_arrSqare[0][2] = 1;g_arrSqare[0][3] = 1;        g_arrSqare[1][0] = 0;g_arrSqare[1][1] = 0;g_arrSqare[1][2] = 0;g_arrSqare[1][3] = 0;        g_row = 0;        g_list = 6;        break;        // 上面两个下面两个,上边靠左    case 3:        g_arrSqare[0][0] = 1;g_arrSqare[0][1] = 1;g_arrSqare[0][2] = 0;g_arrSqare[0][3] = 0;        g_arrSqare[1][0] = 0;g_arrSqare[1][1] = 1;g_arrSqare[1][2] = 1;g_arrSqare[1][3] = 0;        g_row = 0;        g_list = 6;        break;        // 上面倒着的    case 4:        g_arrSqare[0][0] = 0;g_arrSqare[0][1] = 1;g_arrSqare[0][2] = 1;g_arrSqare[0][3] = 0;        g_arrSqare[1][0] = 1;g_arrSqare[1][1] = 1;g_arrSqare[1][2] = 0;g_arrSqare[1][3] = 0;        g_row = 0;        g_list = 6;        break;        // 七型,右边高    case 5:        g_arrSqare[0][0] = 0;g_arrSqare[0][1] = 0;g_arrSqare[0][2] = 1;g_arrSqare[0][3] = 0;        g_arrSqare[1][0] = 1;g_arrSqare[1][1] = 1;g_arrSqare[1][2] = 1;g_arrSqare[1][3] = 0;        g_row = 0;        g_list = 6;        break;        // 七型,左边高    case 6:        g_arrSqare[0][0] = 1;g_arrSqare[0][1] = 0;g_arrSqare[0][2] = 0;g_arrSqare[0][3] = 0;        g_arrSqare[1][0] = 1;g_arrSqare[1][1] = 1;g_arrSqare[1][2] = 1;g_arrSqare[1][3] = 0;        g_row = 0;        g_list = 6;        break;        // 山形    case 7:        g_arrSqare[0][0] = 0;g_arrSqare[0][1] = 1;g_arrSqare[0][2] = 0;g_arrSqare[0][3] = 0;        g_arrSqare[1][0] = 1;g_arrSqare[1][1] = 1;g_arrSqare[1][2] = 1;g_arrSqare[1][3] = 0;        g_row = 0;        g_list = 6;        break;    }    return 0;}// 随机块贴近背景void copySqareToBack(){    int i, j;    i = 0;    j = 0;    for ( i = 0; i < 2; i++)    {        for (j = 0; j < 4; j++)        {            g_arrBackGround[i][j + 6] = g_arrSqare[i][j];        }    }}// 按键消息void onReturn(HWND hwnd){    // 打开定时器    SetTimer(hwnd, DEF_TIMER1, 1000, NULL);}void onRight(HWND hwnd){    // 满足条件右移    if (canSqareRight() == 1 && sqareRightStop() == 1 )    {        // 获取当前窗口的句柄,记得释放        HDC hdc = GetDC(hwnd);        sqareRight();        g_list++;        // 显示方块,并且兼容性DC        onPaint(hdc);        // 释放        ReleaseDC(hwnd, hdc);    }}void onLeft(HWND hwnd){    // 满足条件左移    if (canSqareLeft() == 1 && sqareLeftStop() == 1)    {        // 获取当前窗口的句柄,记得释放        HDC hdc = GetDC(hwnd);        sqareLeft();        g_list--;        // 显示方块,并且兼容性DC        onPaint(hdc);        // 释放        ReleaseDC(hwnd, hdc);    }}void onDown(HWND hwnd){    onTimer(hwnd);}void onUp(HWND hwnd){    HDC hdc = GetDC(hwnd);    if (g_sqareID >= 2 && g_sqareID <= 7)    {        sqareChange();    }    onPaint(hdc);    ReleaseDC(hwnd, hdc);}// 定时器响应函数void onTimer(HWND hwnd){    // 获取当前窗口的句柄,记得释放    HDC hdc = GetDC(hwnd);    if (canSqareDown() == 1 && sqareStop() == 1)    {        sqareDown();        g_row++;    }    else    {        // 把底层的 1 变成 2,这样可以继续判断        change();        // 消除        destroyOneLine();        // 新的产生随机块        createRandSqare();        // 复制到新的背景上        copySqareToBack();    }    // 显示方块,并且兼容性DC    onPaint(hdc);    // 释放    ReleaseDC(hwnd, hdc);}// 方块移动void sqareDown(){    int i, j;    for (i = 19;i >= 0;i--)    {        for (j = 0;j < 16;j++)        {            if (g_arrBackGround[i][j] == 1)            {                g_arrBackGround[i + 1][j] = 1;                g_arrBackGround[i][j] = 0;            }        }    }}void sqareLeft(){    int i, j;    for (i = 0;i < 20;i++)    {        for (j = 0;j < 16;j++)        {            if (g_arrBackGround[i][j] == 1)            {                g_arrBackGround[i][j-1] = 1;                g_arrBackGround[i][j] = 0;            }        }    }}void sqareRight(){    int i, j;    for (i = 0;i < 20;i++)    {        for (j = 15;j >= 0;j--)        {            if (g_arrBackGround[i][j] == 1)            {                g_arrBackGround[i][j + 1] = 1;                g_arrBackGround[i][j] = 0;            }        }    }}// 方块是否到边界停住int canSqareDown(){    int i;    for (i = 0;i < 16;i++)    {        if (g_arrBackGround[19][i] == 1)        {            return 0;        }    }    return 1;}int canSqareLeft(){    int i;    for (i = 0;i < 20;i++)    {        if (g_arrBackGround[i][0] == 1)            return 0;    }    return 1;}int canSqareRight(){    int i;    for (i = 0;i < 20;i++)    {        if (g_arrBackGround[i][15] == 1)            return 0;    }    return 1;}// 把1变成2void change(){    int i, j;    for (i = 0;i < 20;i++)    {        for (j = 0;j < 16;j++)        {            if (g_arrBackGround[i][j] == 1)            {                g_arrBackGround[i][j] = 2;            }        }    }}// 方块遇到新方块停止下落int sqareStop(){    int i, j;    for (i = 19;i >= 0;i--)    {        for (j = 0;j < 16;j++)        {            if (g_arrBackGround[i][j] == 1)            {                if (g_arrBackGround[i + 1][j] == 2)                {                    return 0;                }            }        }    }    return 1;}int sqareLeftStop(){    int i, j;    for (i = 19;i >= 0;i--)    {        for (j = 0;j < 16;j++)        {            if (g_arrBackGround[i][j] == 1)            {                if (g_arrBackGround[i][j - 1] == 2)                {                    return 0;                }            }        }    }    return 1;}int sqareRightStop(){    int i, j;    for (i = 0;i < 20;i++)    {        for (j = 15;j >= 0;j--)        {            if (g_arrBackGround[i][j] == 1)            {                if (g_arrBackGround[i][j + 1] == 2)                {                    return 0;                }            }        }    }    return 1;}// 消除一行void destroyOneLine(){    int i,j;    int sum = 0;    int temp = 0;    for (i = 19;i >= 0;i--)    {        for (j = 0;j < 16;j++)        {            sum += g_arrBackGround[i][j];        }        if (sum == 32)        {            for (temp = i - 1;temp>=0;temp--)                for (j = 0;j < 16;j++)                {                    g_arrBackGround[temp + 1][j] = g_arrBackGround[temp][j];                }        }        sum = 0;    }}void sqareChange(){    int i, j;    char nArrSqare[3][3] = { 0 };    // 把方块复制出来    for (i = 0;i < 3;i++)    {        for (j = 0;j < 3;j++)        {            nArrSqare[i][j] = g_arrBackGround[g_row + i][g_list + j];        }    }    // 变形后复制回去    for (i = 0;i < 3;i++)    {        for (j = 0;j < 3;j++)        {            g_arrBackGround[g_row + i][g_list + j] = nArrSqare[2-j][i];        }    }}

main.c

#include "elsHead.h"LRESULT CALLBACK WndProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam);void onPaint(HDC hdc);/*  主程序*/int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {    WNDCLASSEX wc; /* A properties struct of our window */    HWND hwnd; /* A 'HANDLE', hence the H, or a pointer to our window */    MSG msg; /* A temporary location for all messages */             /* zero out the struct and set the stuff we want to modify */    memset(&wc, 0, sizeof(wc));    wc.cbSize = sizeof(WNDCLASSEX);    wc.lpfnWndProc = WndProc; /* This is where we will send messages to */    wc.hInstance = hInstance;    wc.hCursor = LoadCursor(NULL, IDC_HAND);  //系统光标    wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 2);    wc.lpszClassName = "WindowClass";    wc.hIcon = LoadIcon(NULL, IDI_INFORMATION); /* Load a standard icon */    wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION); /* use the name "A" to use the project icon */    if (!RegisterClassEx(&wc)) {        MessageBox(NULL, "Window Registration Failed!", "Error!", MB_ICONEXCLAMATION | MB_OK);        return 0;    }    hwnd = CreateWindowEx(WS_EX_CLIENTEDGE, "WindowClass", "Tetris", WS_VISIBLE | WS_OVERLAPPEDWINDOW,        60, /* x */        60, /* y */        WIDTH, /* width */        HEIGHT, /* height */        NULL, NULL, hInstance, NULL);    if (hwnd == NULL) {        MessageBox(NULL, "Window Creation Failed!", "Error!", MB_ICONEXCLAMATION | MB_OK);        return 0;    }    /*    This is the heart of our program where all input is processed and    sent to WndProc. Note that GetMessage blocks code flow until it receives something, so    this loop will not produce unreasonably high CPU usage */    while (GetMessage(&msg, NULL, 0, 0) > 0) { /* If no error is received...*/        TranslateMessage(&msg); /* Translate key codes to chars if present */        DispatchMessage(&msg); /* Send it to WndProc */    }    return msg.wParam;}/* 回调函数 */LRESULT CALLBACK WndProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam) {    switch (Message) {        PAINTSTRUCT p;        HDC hdc;    // 窗口创建初期只产生一次,一般做数据初始化的工作     case WM_CREATE:        //GetLastError();        onCreat();        break;    // 窗口产生变化,必须更新时,由这个消息通知程序     case WM_PAINT:        /* getDC,窗口可操作区域的标识 */        hdc = BeginPaint(hwnd, &p);        onPaint(hdc);        /* 关闭DC */        EndPaint(hwnd, &p);        //GetLastError();        break;    // 键盘信息    case WM_KEYDOWN:        switch (wParam)        {        case VK_RETURN:            onReturn(hwnd);            break;        case VK_RIGHT:            onRight(hwnd);            break;        case VK_LEFT:            onLeft(hwnd);            break;        case VK_UP:            onUp(hwnd);            break;        case VK_DOWN:            onDown(hwnd);            break;        }        // 定时器消息    case WM_TIMER:        onTimer(hwnd);        break;    case WM_DESTROY: {        PostQuitMessage(0);        break;    }    /* All other messages (a lot of them) are processed using default procedures */    default:        return DefWindowProc(hwnd, Message, wParam, lParam);    }    return 0;}
0 0