消消乐的进化之路

本次作业使用easyX图形库。

 

version 1.0.1 (an ugly one)

基本实现消消乐的下落,消除的功能。

下个版本需改进的:1. 防止下落过程中消除。

         2. 导入游戏初始菜单,尽量实现菜单中的各种功能。

         3.显示得分。

#include <stdio.h>
#include <graphics.h>
#include <conio.h>
#include <Windows.h>
#pragma warning (disable:4996)
#define Height 480
#define Width 640

char canvas[14][10];
bool removed[14][10] = { 0 };
static RECT red[3]; 
int scores = 0;


int fall()
{
    for (int i = 0;i<14;i++)
        for (int j = 0; j < 10; j++)
            if (removed[i][j] == 1)
            {
                removed[i][j] = 0;
                for(j; j > 0; j--)
                    canvas[i][j] = canvas[i][j - 1];
                canvas[i][0] = rand() % (6) + 65;
                scores++;
            }
    return scores;
}
void remove(char canvas[14][10])
{ 
    static int length = 1;
    for (int j = 0; j <= 9; j++)
    {
        length = 1;
        for (int i = 0; i < 13; i++)
        {
            if (canvas[i][j] == canvas[i + 1][j])
                length++;
            else
                length = 1;
            if (length == 3)
                removed[i][j] = removed[i + 1][j] = removed[i - 1][j] = 1;
            if (length > 3)
                removed[i + 1][j] = 1;
        }
    }
    for (int i = 0; i <= 13; i++)
    {
        length = 1;
        for (int j = 0; j < 13; j++)
        {
            if (canvas[i][j] == canvas[i][j + 1])
                length++;
            else
                length = 1;
            if (length == 3)
                removed[i][j] = removed[i][j + 1] = removed[i][j - 1] = 1;
            if (length > 3)
                removed[i][j + 1] = 1;
        }
    }
    
}
void swap(RECT red[])
{
    int temp;
    temp = canvas[(red[1].left + 1) / 40 - 1][(red[1].top + 1) / 40 - 1];
    canvas[(red[1].left + 1) / 40 - 1][(red[1].top + 1) / 40 - 1] = canvas[(red[2].left + 1) / 40 - 1][(red[2].top + 1) / 40 - 1];
    canvas[(red[2].left + 1) / 40 - 1][(red[2].top + 1) / 40 - 1] = temp;
}
void startup()
{
    initgraph(Width, Height + 120);
    setcolor(WHITE);
    setfillcolor(BLACK);
    setbkcolor(BLACK);
    for (int i = 1; i <= 14; i++)
        for (int j = 1; j <= 10; j++)
            canvas[i - 1][j - 1] = rand() % (6) + 65;
    remove(canvas);
}

void show(RECT red[3])
{
    for (int i = 1; i <= 14; i++)
        for (int j = 1; j <= 10; j++)
        {
            RECT r = { i * 40 - 1,j * 40 - 1,(i + 1) * 40 - 1, (j + 1) * 40 - 1 };
            for (int i = 0;i<3;i++)
                if ((r.right == red[i].right) && (r.left == red[i].left) && (r.top == red[i].top) && (r.bottom == red[i].bottom))
                {
                        setbkcolor(RED);
                        setfillcolor(RED);
                }
            fillrectangle(i * 40, j * 40, (i + 1) * 40, (j + 1) * 40);
            if (removed[i][j] == 1)
                canvas[i][j] = 32;
            drawtext(canvas[i-1][j-1], &r, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
            setfillcolor(BLACK);
            setbkcolor(BLACK);
        }
    RECT scores = { 0,510,639,570 };
    TCHAR s[3];
    _stprintf(s, _T("%d"), scores);
    drawtext(s, &scores, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
    TCHAR c[] = _T("click L botton to select and R botton to swap.");
    outtextxy(170, 460, c);
}

void updateWithInput()
{
    MOUSEMSG m;
    m = GetMouseMsg();
    for (int i = 1; i <= 14; i++)
        for (int j = 1; j <= 10; j++)
            if ((m.x > i * 40 - 1) && (m.x < (i + 1) * 40 - 1) && (m.y > j * 40 - 1) && (m.y < (j + 1) * 40 - 1))
            {
                red[0] = { i * 40 - 1,j * 40 - 1,(i + 1) * 40 - 1, (j + 1) * 40 - 1 };
                static int times = 0;
                if (m.uMsg == WM_LBUTTONDOWN)
                {
                    times++;
                    if (times > 3)
                    {
                        printf("???");///
                        continue;

                    }
                    else
                        red[times] = { i * 40 - 1,j * 40 - 1,(i + 1) * 40 - 1, (j + 1) * 40 - 1 };
                }
                if (m.uMsg == WM_RBUTTONDOWN)
                {
                    swap(red);
                    red[20] = red[3] = { 0,0,0,0 };
                }
            }
}


void updateWithoutInput()
{
    remove(canvas);
    
    static int speed = 0;
        if (speed < 10)
            speed++;
        if (speed == 9)
        {
            speed = 0;
            fall();
            scores += fall();
        }
}

int main()
{
    startup();
    while (1)
    {
        BeginBatchDraw();
        updateWithoutInput();
        updateWithInput();
        show(red);
        FlushBatchDraw();
    }
    return 0;
}

 

 

emmm, 期末大作业其实也交上去好久了, 但因为期末(其实是懒)就一直没在更新。

这份作业的总结PPT就不放在这里了, 有感兴趣的同学可以私信。

还是存在各种各样的bug, 下次更好, 下次一定!

 

以下是最终版本:

#include <graphics.h>
#include <stdio.h>
#include <Windows.h>
#include <stdbool.h>
#include <time.h>
#include <conio.h>
#include <math.h>
#include <string.h>
#include <mmsystem.h>
#pragma comment (lib, "winmm.lib")
#pragma warning (disable:4996)

#define Height 480
#define Width 640

int shape = 2, size=2;
bool removePause = 0;
bool fallPause = 0;
bool fall_over = 1;
bool renewTheGame = 0;//为了节省内存,尽量使游戏呈线性,不让函数互相无限调用。
bool backToMenu = 0;
bool backToWindows = 0;
int canvas[10][10];
bool removed[10][10];
int init_mx, init_my, des_mx, des_my;
int move_mx, move_my;    
bool swapFlag = 0;
bool selected[10][10];
int i0;//方形原点
time_t t;
int scores = 0;
DWORD start, end;
DWORD start_bonus, end_bonus;
float usedtime;
float d_i1, d_j1, d_i2, d_j2;
int status;
bool music = 1;
bool opr = 0;

void settings(void);
void startup() {  
    initgraph(Width, Height);
    setcolor(WHITE);
}

void swap() {
    int temp;
    if (shape == 1) {
        temp = canvas[(init_mx - i0) / 50][(init_my - i0) / 50];
        canvas[(init_mx - i0) / 50][(init_my - i0) / 50] = canvas[(move_mx - i0) / 50][(move_my - i0) / 50];
        canvas[(move_mx - i0) / 50][(move_my - i0) / 50] = temp;
    }
    else if (shape == 2) {
        temp = canvas[(int)(d_i2 / sqrt(20 * 20 + 25 * 25))][(int)(d_j2 / sqrt(20 * 20 + 25 * 25))] = 1;
        canvas[(int)(d_i2 / sqrt(20 * 20 + 25 * 25))][(int)(d_j2 / sqrt(20 * 20 + 25 * 25))] = canvas[(int)(d_i1 / sqrt(20 * 20 + 25 * 25))][(int)(d_j1 / sqrt(20 * 20 + 25 * 25))];
        canvas[(int)(d_i1 / sqrt(20 * 20 + 25 * 25))][(int)(d_j1 / sqrt(20 * 20 + 25 * 25))] = temp;

    }
    memset(selected, 0, sizeof(selected));
    swapFlag = 0;
}//to be continued

void initmap() {//initialize a new map.
    cleardevice();

    memset(canvas, 0, sizeof(canvas));
    memset(removed, 0, sizeof(removed));
    memset(selected, 0, sizeof(selected));

    i0 = 240 - 50 * (size + 1);


    srand((unsigned)time(&t));
    for (int i = 0; i < size * 2 + 2; i++) {
        for (int j = 0; j < size * 2 + 2; j++) {
            canvas[i][j] = rand() % 6;
        }
    }

static int length = 1;
for (int j = 0; j < size * 2 + 2; j++)
{
    length = 1;
    for (int i = 0; i < size * 2 + 1; i++)
    {
        if (canvas[i][j] == canvas[i + 1][j])
            length++;
        else
            length = 1;
        if (length == 3) {
            canvas[i + 1][j]++;
            if (canvas[i + 1][j] == 6)canvas[i + 1][j] = 0;
        }
    }
}
for (int i = 0; i < size * 2 + 2; i++)
{
    length = 1;
    for (int j = 0; j < size * 2 + 1; j++)
    {
        if (canvas[i][j] == canvas[i][j + 1])
            length++;
        else
            length = 1;
        if (length == 3) {
            canvas[i][j + 1]++;
            if (canvas[i][j + 1] == 6)canvas[i][j + 1] = 0;
            if (canvas[i][j + 1] == canvas[i - 1][j + 1]) {
                canvas[i][j + 1]++;
                if (canvas[i][j + 1] == 6)canvas[i][j + 1] = 0;
            }
        }
    }
}

}

void opreations(int l,int t, int r, int b, int size) {
    
    RECT opreation = { l+10,t+10,r-10,b-10 };
    settextstyle(size, 0, _T("Consolas"));
    BeginBatchDraw();

    fillrectangle(l, t, r, b);
    drawtext(_T("Opreations:\n\n1.click l_button \nonce to select\n2.if select, click\n l_button to put \nand click r_button\n to cancel\n3.strike ESC to \nreturn"), &opreation, DT_LEFT | DT_VCENTER);

    FlushBatchDraw();
    settextstyle(24, 0, _T("Consolas"));
}

void showSave() {
    RECT file_1{ 185,130,459,189 };
    RECT file_2{ 185,210,459,269 };
    RECT file_3{ 185,290,459,349 };
    
    fillrectangle(140, 100, 499, 379);
    fillrectangle(180, 130, 459, 189);
    fillrectangle(180, 210, 459, 269);
    fillrectangle(180, 290, 459, 349);

    setfillcolor(WHITE);
    fillrectangle(465, 145, 494, 174);
    fillrectangle(465, 225, 494, 254);
    fillrectangle(465, 305, 494, 334);
    setfillcolor(BLACK);

    setlinestyle(PS_SOLID | PS_ENDCAP_FLAT, 3);
    setcolor(BLACK);
    for (int i = 0; i < 3; i++) {
        line(472, 152 + 80 * i, 488, 168 + 80 * i);
        line(488, 152 + 80 * i, 472, 168 + 80 * i);
    }
    setlinestyle(PS_SOLID | PS_ENDCAP_FLAT, 1);
    setcolor(WHITE);

    drawtext(_T("FILE 1"), &file_1, DT_LEFT | DT_VCENTER | DT_SINGLELINE);
    drawtext(_T("FILE 2"), &file_2, DT_LEFT | DT_VCENTER | DT_SINGLELINE);
    drawtext(_T("FILE 3"), &file_3, DT_LEFT | DT_VCENTER | DT_SINGLELINE);

    settextstyle(15, 0, _T("Consolas"));
    FILE* fp_save1 = fopen("save1.txt", "r");
    if (fgetc(fp_save1) == EOF) drawtext(_T("empty"), &file_1, DT_RIGHT | DT_VCENTER | DT_SINGLELINE);
    else {
        char s[100];
        fgets(s, 100, fp_save1);
        drawtext(s, &file_1, DT_RIGHT | DT_VCENTER | DT_SINGLELINE);
    }
    fclose(fp_save1);

    FILE* fp_save2 = fopen("save2.txt", "r");
    if (fgetc(fp_save2) == EOF) drawtext(_T("empty"), &file_2, DT_RIGHT | DT_VCENTER | DT_SINGLELINE);
    else {
        char s[100];
        fgets(s, 100, fp_save2);
        drawtext(s, &file_2, DT_RIGHT | DT_VCENTER | DT_SINGLELINE);
    }
    fclose(fp_save2);

    FILE* fp_save3 = fopen("save3.txt", "r");
    if (fgetc(fp_save3) == EOF) drawtext(_T("empty"), &file_3, DT_RIGHT | DT_VCENTER | DT_SINGLELINE);
    else {
        char s[100];
        fgets(s, 100, fp_save3);
        drawtext(s, &file_3, DT_RIGHT | DT_VCENTER | DT_SINGLELINE);
    }
    fclose(fp_save3);
    settextstyle(24, 0, _T("Consolas"));
}

void save() {
    setfillcolor(BLACK);
    while (1) {
        BeginBatchDraw();

        showSave();

        FlushBatchDraw();
        EndBatchDraw();

        MOUSEMSG m;
        if (MouseHit()) {
            m = GetMouseMsg();
            if (m.uMsg == WM_LBUTTONDOWN && m.x <= 419 && m.x >= 220) {
                FILE* fp_save = NULL;
                if (m.y >= 130 && m.y <= 189) fp_save = fopen("save1.txt", "w");
                if (m.y >= 210 && m.y <= 269) fp_save = fopen("save2.txt", "w");
                if (m.y >= 290 && m.y <= 349) fp_save = fopen("save3.txt", "w");
                time_t curtime;
                time(&curtime);
                fputs(ctime(&curtime), fp_save);
                for (int i = 0; i < (size + 1) * 2; i++) {
                    for (int j = 0; j < (size + 1) * 2; j++) {
                        fprintf(fp_save, "%d\n", canvas[i][j]);
                    }
                }
                fprintf(fp_save, "%d %d %d %f\n", shape, size, scores, usedtime);
                fclose(fp_save);
            }
            465, 145, 494, 174;
            if (m.uMsg == WM_LBUTTONDOWN && m.x <= 494 && m.x >= 465) {
                FILE* fp_save = NULL;
                if (m.y >= 145 && m.y <= 174) fp_save = fopen("save1.txt", "w");
                if (m.y >= 225 && m.y <= 254) fp_save = fopen("save2.txt", "w");
                if (m.y >= 305 && m.y <= 334) fp_save = fopen("save3.txt", "w");
            }
        }

        char input;
        if (kbhit()) {
            input = getch();
            if (input == 27) break;
        }

    }
}

void pause() {
    PlaySound(NULL,NULL, NULL);
    start_bonus = GetTickCount();
    
    setfillcolor(BLACK);
    RECT resume = { 160,105,319,194 };
    RECT renew = { 310,105,489,194 };
    RECT savaGame = { 160,195,319,284 };
    RECT setting = { 320,195,479,284 };
    RECT backtoMain = { 160,285,319,374 };
    RECT backtoWindows = { 320,285,479,374 };
    MOUSEMSG m;
    char input;

    while (1) {
        fillrectangle(140, 100, 499, 379);
        drawtext(_T("RESUME"), &resume, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
        if(status == 1) drawtext(_T("RENEW"), &renew, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
        else if (status == 2) drawtext(_T("REOPEN THE FILE"), &renew, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
        drawtext(_T("SAVE"), &savaGame, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
        drawtext(_T("SETTINGS"), &setting, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
        drawtext(_T("BACK TO MENU"), &backtoMain, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
        drawtext(_T("BACK TO WINDOWS"), &backtoWindows, DT_CENTER | DT_VCENTER | DT_SINGLELINE);

        if (MouseHit) {
            m = GetMouseMsg();
            if (m.uMsg == WM_LBUTTONDOWN) {
                if (m.x >= 160 && m.x <= 319 && m.y >= 105 && m.y <= 194) {
                    cleardevice();
                    break;
                }
                else if (m.x >= 320 && m.x <= 479 && m.y >= 105 && m.y <= 194) {
                    renewTheGame = 1;
                    break;
                }
                else if (m.x >= 320 && m.x <= 479 && m.y >= 195 && m.y <= 284) {
                    cleardevice();
                    settings();
                    break;
                }
                else if (m.x >= 160 && m.x <= 319 && m.y >= 195 && m.y <= 284) {
                    save();
                }
                else if (m.x >= 160 && m.x <= 319 && m.y >= 285 && m.y <= 374) {
                    backToMenu = 1;
                    break;
                }
                else if (m.x >= 320 && m.x <= 479 && m.y >= 285 && m.y <= 374) {
                    backToWindows = 1;
                    break;
                }
            }
            
        }

        if (kbhit()) {
            input = getch();
            if (input == 27) {
                break;
            }
        }
    }
    cleardevice();
    PlaySound(TEXT("Audiomachine - Above and Beyond.wav"), NULL, SND_FILENAME | SND_ASYNC);
    end_bonus = GetTickCount();
}

void show_shape1and2() {
    BeginBatchDraw();

    char s[3];
    sprintf(s, "%d", scores);
    outtextxy(490, 270, s);
    char str1[] = "SCORE: ";
    outtextxy(490, 240, str1);

    char usedTime[100000];
    sprintf(usedTime, "%.2f", usedtime);
    char timeused[] = "USED TIME:";
    outtextxy(490, 300, timeused);
    outtextxy(490, 330, usedTime);

    setfillcolor(BLACK);
    if (opr) opreations(485, 5, 634, 200, 15);

    COLORREF selectedPiece = NULL, toswap = NULL;
    int selectedFlag = 0, toswapFlag = 0;
    for (int i = 0; i < size * 2 + 2; i++) {
        for (int j = 0; j < size * 2 + 2; j++) {
            if (canvas[i][j] == 0)setfillcolor(WHITE);
            else if (canvas[i][j] == 1)setfillcolor(YELLOW);
            else if (canvas[i][j] == 2)setfillcolor(RED);
            else if (canvas[i][j] == 3)setfillcolor(BLUE);
            else if (canvas[i][j] == 4)setfillcolor(GREEN);
            else setfillcolor(MAGENTA);

            if (swapFlag) {
                if (shape == 1 && i == (move_mx - i0) / 50 && j == (move_my - i0) / 50) {
                    toswap = getfillcolor();
                    toswapFlag = 1;
                }

                if (shape == 2) {
                    float d_j = fabs(move_my - 240 + 0.8 * i0 - 0.8 * move_mx) / sqrt(1.64);
                    float d_i = fabs(move_my - 240 - 0.8 * i0 + 0.8 * move_mx) / sqrt(1.64);
                    if (i == (int)(d_i / sqrt(20 * 20 + 25 * 25)) && j == (int)(d_j / sqrt(20 * 20 + 25 * 25))) {
                        toswap = getfillcolor();
                        toswapFlag = 1;
                    }
                }

                if (selected[i][j] == 1) {
                    selectedFlag = 1;
                    selectedPiece = getfillcolor();
                }
            }
            
            if (removed[i][j] == 1) setfillcolor(BLACK);

            if (shape == 1) {
                if (i == (move_mx - i0) / 50 && j == (move_my - i0) / 50 && swapFlag)setfillcolor(BLACK);
                fillrectangle(240 - (size + 1) * 50 - 1 + i * 50, 240 - (size + 1) * 50 - 1 + j * 50, 240 - (size + 1) * 50 - 1 + (i + 1) * 50, 240 - (size + 1) * 50 - 1 + (j + 1) * 50);
            }
            else if (shape == 2) {
                float d_j = fabs(move_my - 240 + 0.8 * i0 - 0.8 * move_mx) / sqrt(1.64);
                float d_i = fabs(move_my - 240 - 0.8 * i0 + 0.8 * move_mx) / sqrt(1.64);
                if (i == (int)(d_i / sqrt(20 * 20 + 25 * 25)) && j == (int)(d_j / sqrt(20 * 20 + 25 * 25)) && swapFlag) setfillcolor(BLACK);
                int add_x = 25 * (i + j) - 1, add_y = 20 * (i - j) - 1;
                POINT pts[] = { {i0 + add_x,240 + add_y},{i0 + 25 + add_x,240 - 20 + add_y},{i0 + 50 + add_x,240 + add_y} ,{i0 + 25 + add_x,240 + 20 + add_y} };
                fillpolygon(pts, 4);
            }
        }
    }
    
    if (swapFlag) {
        if (toswapFlag) {
            for (int i = 0; i < size * 2 + 2; i++) {
                for (int j = 0; j < size * 2 + 2; j++) {
                    if (selected[i][j] == 1) {
                        setfillcolor(toswap);
                        
                        if (shape == 1) {
                            if (i == (move_mx - i0) / 50 && j == (move_my - i0) / 50)setfillcolor(BLACK);
                            fillrectangle(240 - (size + 1) * 50 - 1 + i * 50, 240 - (size + 1) * 50 - 1 + j * 50, 240 - (size + 1) * 50 - 1 + (i + 1) * 50, 240 - (size + 1) * 50 - 1 + (j + 1) * 50);
                        }
                        if (shape == 2) {
                            float d_j = fabs(move_my - 240 + 0.8 * i0 - 0.8 * move_mx) / sqrt(1.64);
                            float d_i = fabs(move_my - 240 - 0.8 * i0 + 0.8 * move_mx) / sqrt(1.64);
                            if (i == (int)(d_i / sqrt(20 * 20 + 25 * 25)) && j == (int)(d_j / sqrt(20 * 20 + 25 * 25))) setfillcolor(BLACK);
                            int add_x = 25 * (i + j) - 1, add_y = 20 * (i - j) - 1;
                            POINT pts[] = { {i0 + add_x,240 + add_y},{i0 + 25 + add_x,240 - 20 + add_y},{i0 + 50 + add_x,240 + add_y} ,{i0 + 25 + add_x,240 + 20 + add_y} };
                            fillpolygon(pts, 4);
                        }
                    }
                        
                }
            }
        }

        if (selectedFlag) {
            setfillcolor(selectedPiece);
            if(shape==1) fillrectangle(move_mx - 24, move_my - 24, move_mx + 24, move_my + 24);
            if (shape == 2) {
                POINT pts[] = { {move_mx - 24,move_my},{move_mx,move_my - 19},{move_mx + 24,move_my},{move_mx,move_my + 19} };
                fillpolygon(pts, 4);
            }
        }

        toswapFlag = selectedFlag = 0;
    }

    if (removePause) {
        Sleep(1500);
        removePause = 0;
    }
    if (fallPause) {
        if (shape == 1) Sleep(300);
        else if (shape == 2) Sleep(1000);
        fallPause = 0;
    }

    FlushBatchDraw();
    EndBatchDraw();
}

void function(float a, float b, float c, float d,int*x,int*y) {
    *x = (int)(-b - d) / (a + c);
    *y = (int)(a * (*x) + b);
}

void updateWithInput_shape1and2() {
    char input;
    if (kbhit()) {
        input = getch();
        if (input == 27) {
            pause(); 
        }
    }

    MOUSEMSG m;
    if (MouseHit()) {
        m = GetMouseMsg();
    
        int mid_x, mid_y;
        float d_j = 0, d_i = 0;
        
        if (m.uMsg == WM_LBUTTONDOWN && swapFlag == 0) {
            init_mx = m.x;
            init_my = m.y;
            memset(selected, 0, sizeof(selected));
            if (shape == 1) selected[(init_mx - i0) / 50][(init_my - i0) / 50] = 1;
            if (shape == 2) {
                d_j = fabs(init_my - 240 + 0.8 * i0 - 0.8 * init_mx) / sqrt(1.64);
                d_i = fabs(init_my - 240 - 0.8 * i0 + 0.8 * init_mx) / sqrt(1.64);
                selected[(int)(d_i / sqrt(20 * 20 + 25 * 25))][(int)(d_j / sqrt(20 * 20 + 25 * 25))] = 1;
            }
            swapFlag = 1;
        }
        if (swapFlag == 1) {
            move_mx = m.x;
            move_my = m.y;
            
            d_j1 = fabs(init_my - 240 + 0.8 * i0 - 0.8 * init_mx) / sqrt(1.64);
            d_i1 = fabs(init_my - 240 - 0.8 * i0 + 0.8 * init_mx) / sqrt(1.64);
            d_j2 = fabs(move_my - 240 + 0.8 * i0 - 0.8 * move_mx) / sqrt(1.64);
            d_i2 = fabs(move_my - 240 - 0.8 * i0 + 0.8 * move_mx) / sqrt(1.64);

            if (shape == 1) {
                mid_x = i0 + (2 * ((init_mx - i0) / 50) + 1) * 25;//控制边界
                mid_y = i0 + (2 * ((init_my - i0) / 50) + 1) * 25;
                if (move_mx - mid_x >= 50) move_mx = mid_x + 49;//限定在矩形内
                if (mid_x - move_mx >= 50) move_mx = mid_x - 51;
                if (move_my - mid_y >= 50) move_my = mid_y + 49;
                if (mid_y - move_my >= 50) move_my = mid_y - 51;
                if (move_mx >= i0 + 100 * (size + 1) - 26)move_mx = i0 + 100 * (size + 1) - 26;//限定在地图内
                else if (move_mx <= i0 + 24) move_mx = i0 + 24;
                if (move_my >= i0 + 100 * (size + 1) - 26)move_my = i0 + 100 * (size + 1) - 26;
                else if (move_my <= i0 + 24) move_my = i0 + 24;
            }

            /*if (shape == 2) {
                mid_x = i0 + 25 + 25 * ((int)(d_i / sqrt(20 * 20 + 25 * 25)) + (int)(d_j / sqrt(20 * 20 + 25 * 25)));
                mid_y = 239 + 20 * ((int)(d_i / sqrt(20 * 20 + 25 * 25)) - (int)(d_j / sqrt(20 * 20 + 25 * 25)));
                int* x = &mid_x, * y = &mid_y;

                if (abs(5 * (move_mx - mid_x)) + abs(4 * (move_my - mid_y)) >= 100) {
                    canvas[(int)(d_i / sqrt(20 * 20 + 25 * 25))][(int)(d_j / sqrt(20 * 20 + 25 * 25))] = 1;
                }
            }*/
        }

        if (m.uMsg == WM_LBUTTONDOWN && swapFlag == 1 && shape == 1 && ((init_mx - i0) / 50 != (move_mx - i0) / 50 || (init_my - i0) / 50 != (move_my - i0) / 50)) {
            swap();
        }
        if (m.uMsg == WM_LBUTTONDOWN && swapFlag == 1 && shape == 2 && ((int)(d_i1 / sqrt(20 * 20 + 25 * 25)) != (int)(d_i2 / sqrt(20 * 20 + 25 * 25)) || (int)(d_j2 / sqrt(20 * 20 + 25 * 25)) != (int)(d_j1 / sqrt(20 * 20 + 25 * 25))) ){
            swap();
        }

        if (m.uMsg == WM_RBUTTONDOWN) {
            memset(selected, 0, sizeof(selected));
            swapFlag = 0;
        }

    }

}

void remove_shape1and2() {
    static int length = 1;
    bool flag = 0;
    for (int j = 0; j < size * 2 + 2; j++)
    {
        length = 1;
        for (int i = 0; i < size * 2 + 1; i++)
        {
            if (canvas[i][j] == canvas[i + 1][j])
                length++;
            else
                length = 1;
            if (length == 3) {
                flag = 1;
                removed[i][j] = removed[i + 1][j] = removed[i - 1][j] = 1;
            }
            if (length > 3)
                removed[i + 1][j] = 1;
        }
    }
    for (int i = 0; i < size * 2 + 2; i++)
    {
        length = 1;
        for (int j = 0; j < size * 2 + 1; j++)
        {
            if (canvas[i][j] == canvas[i][j + 1])
                length++;
            else
                length = 1;
            if (length == 3) {
                flag = 1;
                removed[i][j] = removed[i][j + 1] = removed[i][j - 1] = 1;
            }
            if (length > 3)
                removed[i][j + 1] = 1;
        }
    }

    removePause = flag;
}

void fall_shape1and2() {
    bool flag = 0; 
    if (shape == 1) {
        for (int i = 0; i < size * 2 + 2; i++)
            for (int j = 0; j < size * 2 + 2; j++)
                if (removed[i][j] == 1) {
                    removed[i][j] = 0;
                    scores++;
                    for (j; j > 0; j--)
                        canvas[i][j] = canvas[i][j - 1];
                    canvas[i][0] = rand() % 6;
                    flag = 1;
                    break;
                }
    }
    else if (shape == 2) {
        for (int i = 0; i < size * 2 + 2; i++)
            for (int j = 0; j < size * 2 + 2; j++)
                if (removed[i][j] == 1) {
                    removed[i][j] = 0;
                    scores++;
                    for (j; j > 0; j--)
                        canvas[i][j] = canvas[i][j - 1];
                    canvas[i][0] = rand() % 6;
                    flag = 1;
                }
    }
    fallPause = flag;
}

void updateWithoutInput_shape1and2() {
    fall_shape1and2();
    if (!fallPause) remove_shape1and2();
    
    end = GetTickCount();
    usedtime = (float)(end - start)/1000 - (float)(end_bonus - start_bonus)/1000;
}

void newGame() {
    status = 1;
    if (shape == 1 || shape == 2) {
        initmap();
        start = GetTickCount();
        while (1) {
            show_shape1and2();
            updateWithInput_shape1and2();
            updateWithoutInput_shape1and2();
            if (renewTheGame) {
                renewTheGame = 0;
                break;
            }
            if (backToMenu || backToWindows)break;
        }
    }
}

void settings() {
    RECT mapShape = { 108,80,235,179 };
    RECT mapShape_ = { 310,80,576,179 };
    RECT mapSize = { 108,180,235,279 };
    RECT mapSize_ = { 310,180,576,279 };
    RECT sound = { 0,280,159,379 };
    RECT opre = { 320,280,479,379 };
    char input;
    MOUSEMSG m;
    POINT pts_l_1[] = { {300,130},{310,150},{310,110} };
    POINT pts_r_1[] = { {576,130},{566,150},{566,110} };
    POINT pts_l_2[] = { {300,230},{310,250},{310,210} };
    POINT pts_r_2[] = { {576,230},{566,250},{566,210} };
    
    POINT soundon[] = { {200,320},{259,320},{219,339},{200,339} };
    POINT soundoff[] = { {260,320},{279,320},{279,339},{219,339} };
    POINT opreationson[] = { {520,320},{579,320},{539,339},{520,339} };
    POINT opreationsoff[] = { {580,320},{599,320},{599,339},{529,339} };

    i0 = 240 - 50 * (size + 1);
    while (1) {
        BeginBatchDraw();
        
        cleardevice();
        drawtext(_T("MAP SHAPE: "), &mapShape, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
        drawtext(_T("MAP SIZE: "), &mapSize, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
        setfillcolor(WHITE);
        fillpolygon(pts_l_1, 3);
        fillpolygon(pts_r_1, 3);
        fillpolygon(pts_l_2, 3);
        fillpolygon(pts_r_2, 3);
        if (size == 2) {
            settextstyle(24, 0, _T("Consolas"));
            drawtext(_T("MEDIUM"), &mapSize_, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
        }
        else if (size == 1) {
            settextstyle(20, 0, _T("Consolas"));
            drawtext(_T("SMALL"), &mapSize_, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
        }
        else {
            settextstyle(30, 0, _T("Consolas"));
            drawtext(_T("LARGE"), &mapSize_, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
        }
        settextstyle(24, 0, _T("Consolas"));

        if (shape == 2) drawtext(_T("DIAMOND"), &mapShape_, DT_CENTER | DT_VCENTER | DT_SINGLELINE);

        else if (shape == 1) drawtext(_T("SQUARE"), &mapShape_, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
        
        else drawtext(_T("TOBEDONE"), &mapShape_, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
        
        drawtext(_T("SOUND: "), &sound, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
        setfillcolor(WHITE);
        if (music) fillpolygon(soundon, 4);
        else fillpolygon(soundoff, 4);
        setfillcolor(BLACK);
        if(music)fillpolygon(soundoff, 4);
        else fillpolygon(soundon, 4);

        drawtext(_T("OPREATIONS: "), &opre, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
        setfillcolor(WHITE);
        if (opr) fillpolygon(opreationson, 4);
        else fillpolygon(opreationsoff,4);
        setfillcolor(BLACK);
        if (opr)fillpolygon(opreationsoff, 4);
        else fillpolygon(opreationson, 4);

        FlushBatchDraw();
        EndBatchDraw();

        if (kbhit()) {
            input = getch();
            if (input == 27) {
                break;
            }
        }

        if (MouseHit()) {
            m = GetMouseMsg();
            
            if (m.uMsg == WM_LBUTTONDOWN) {
                if (m.x <= 310 && m.x >= 300 && m.y >= 210 && m.y <= 250) {
                    size--;
                    if (size == 0)size = 3;
                }
                else if (m.x <= 576 && m.x >= 566 && m.y >= 210 && m.y <= 250) {
                    size++;
                    if (size == 4) size = 1;
                }
                else if (m.x <= 310 && m.x >= 300 && m.y >= 110 && m.y <= 150) {
                    shape--;
                    if (shape == 0)shape = 3;
                }
                else if (m.x <= 576 && m.x >= 566 && m.y >= 110 && m.y <= 150) {
                    shape++;
                    if (shape == 4)shape = 1;
                }

                else if (m.x >= 200 && m.x <= 279 && m.y >= 320 && m.y <= 339) {
                    if (music == 1) {
                        PlaySound(NULL, NULL, NULL);
                        music = 0;
                    }
                    else {
                        PlaySound(TEXT("Audiomachine - Above and Beyond.wav"), NULL, SND_FILENAME | SND_ASYNC);
                        music = 1;
                    }
                }
                else if (m.x >= 520 && m.x <= 599 && m.y >= 320 && m.y <= 339) {
                    if (opr == 1) opr = 0;
                    else opr = 1;
                }
            }
        }
    }
}

void loadmap(int n) {
    cleardevice();

    memset(canvas, 0, sizeof(canvas));
    memset(removed, 0, sizeof(removed));
    memset(selected, 0, sizeof(selected));

    i0 = 240 - 50 * (size + 1);

    FILE* fp = NULL;
    if (n == 1) fp = fopen("save1.txt", "r");
    else if (n == 2) fp = fopen("save2.txt", "r");
    else if (n == 3) fp = fopen("save3.txt", "r");
    char time[100];
    fgets(time, 100, fp);
    for (int i = 0; i < (size + 1) * 2; i++) {
        for (int j = 0; j < (size + 1) * 2; j++) {
            fscanf(fp, "%d", &canvas[i][j]);
        }
    }
    fscanf(fp, "%d %d %d %f", &shape, &size, &scores, &usedtime);
    fclose(fp);
}

void loadGames(int n) {
    status = 2;
    if (shape == 1 || shape == 2) {
        loadmap(n);
        while (1) {
            show_shape1and2();
            updateWithInput_shape1and2();
            updateWithoutInput_shape1and2();
            if (renewTheGame == 1) {
                renewTheGame = 0;
                break;
            }
            if (backToMenu || backToWindows)break;
        }
    }
}

void continueGames() {
    setfillcolor(BLACK);
    RECT warning = { 140, 100, 499, 379 };
    while (1) {
        BeginBatchDraw();

        showSave();

        FlushBatchDraw();
        EndBatchDraw();

        MOUSEMSG m;//loadGames
        if (MouseHit()) {
            m = GetMouseMsg();
            if (m.uMsg == WM_LBUTTONDOWN && m.x <= 419 && m.x >= 220) {
                FILE* fp_save = NULL;
                int n;
                if (m.y >= 130 && m.y <= 189) {
                    fp_save = fopen("save1.txt", "r");
                    n = 1;
                }
                if (m.y >= 210 && m.y <= 269) {
                    fp_save = fopen("save2.txt", "r");
                    n = 2;
                }
                if (m.y >= 290 && m.y <= 349) {
                    fp_save = fopen("save2.txt", "r");
                    n = 3;
                }
                if (fgetc(fp_save) == EOF) {
                    drawtext(_T("YOU CANNOT LOAD AN EMPTY FILE."), &warning, DT_LEFT | DT_VCENTER | DT_SINGLELINE);
                    Sleep(2000);
                }
                else {
                    while (1) {
                        loadGames(n);//类似newGame
                        if (backToMenu || backToWindows) break;
                    }
                }
                fclose(fp_save);
            }
            if (backToMenu || backToWindows)break;

            if (m.uMsg == WM_LBUTTONDOWN && m.x <= 494 && m.x >= 465) {
                FILE* fp_save = NULL;
                if (m.y >= 145 && m.y <= 174) fp_save = fopen("save1.txt", "w");
                if (m.y >= 225 && m.y <= 254) fp_save = fopen("save2.txt", "w");
                if (m.y >= 305 && m.y <= 334) fp_save = fopen("save3.txt", "w");
            }
        }

        char input;
        if (kbhit()) {
            input = getch();
            if (input == 27) break;
        }

    }
}

void mainMenu() {
    PlaySound(TEXT("Audiomachine - Above and Beyond.wav"), NULL, SND_FILENAME | SND_ASYNC);
    
    settextcolor(WHITE);
    RECT newGameStart = { 256,180,383,239 };
    RECT continueGame = { 256,240,383,299 };
    RECT setting = { 256,300,383,359 };
    RECT exitGame = { 256,360,383,419 };
    RECT opreation = { 560,20,619,79 };
    RECT title = { 0,0,639,179 };
    
    music = 1;

    while (1) {

        BeginBatchDraw();

        cleardevice();
        settextstyle(60, 0, _T("Script"),0,0,600,0,0,0);
        drawtext(_T("Rockem Blocks!"), &title, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
        settextstyle(24, 0, _T("Consolas"),0,0,0,0,0,0);
        drawtext(_T("NEW GAME"), &newGameStart, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
        drawtext(_T("CONTINUE"), &continueGame, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
        drawtext(_T("SETTINGS"), &setting, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
        drawtext(_T("EXIT"), &exitGame, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
        drawtext(_T("?"), &opreation, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
        rectangle(565, 25, 614, 74);
        rectangle(505, 25, 554, 74);
        setfillcolor(WHITE);
        fillrectangle(517, 42, 522, 56);
        POINT pts[] = { {522,42},{542,35},{542,63},{522,56} };
        setfillcolor(BLACK);
        fillpolygon(pts, 4);
        if (music == 0) {
            setlinestyle(PS_SOLID | PS_ENDCAP_FLAT, 3);
            line(505, 25, 554, 74);
            setlinestyle(PS_SOLID | PS_ENDCAP_FLAT, 1);
        }
        
        

        FlushBatchDraw();
        EndBatchDraw();

        MOUSEMSG m;
        m = GetMouseMsg();
        if (m.uMsg == WM_LBUTTONDOWN) {
            cleardevice();
            
            if (m.x <= 384 && m.x >= 256) {
                if (m.y >= 180 && m.y <= 239) {
                    while (1) {
                        newGame();
                        if (backToMenu) {
                            backToMenu = 0;
                            break;
                        }
                        if (backToWindows)exit(0);
                    }
                }
                else if (m.y >= 240 && m.y <= 299) {
                    continueGames();
                    if (backToMenu) {
                        backToMenu = 0;
                        break;
                    }
                    if (backToWindows)exit(0);
                }
                else if (m.y >= 300 && m.y <= 359) {
                    settings();
                }
                else if (m.y >= 360 && m.y <= 419) {
                    break;
                }
            }
            
            if (m.x >= 565 && m.y >= 25 && m.x <= 614 && m.y <= 74) {
                while (1) {
                    opreations(0, 0, 639, 479, 20);

                    char input;
                    if (kbhit()) {
                        input = getch();
                        if (input == 27) break;
                    }
                }
            }
            
            if (m.x >= 505 && m.y >= 25 && m.x <= 554 && m.y <= 74) {
                if (music == 1) {
                    PlaySound(NULL, NULL, NULL);
                    music = 0;
                }
                else {
                    PlaySound(TEXT("Audiomachine - Above and Beyond.wav"), NULL, SND_FILENAME | SND_ASYNC);
                    music = 1;
                }
            }
        }
    }
}

int main() {
    startup();
    mainMenu();
    return 0;
}
posted on 2020-12-15 14:23  porest  阅读(175)  评论(0编辑  收藏  举报