same.c

来自「minigui PDA系统 可实现手机功能」· C语言 代码 · 共 659 行 · 第 1/2 页

C
659
字号
#include <sys/types.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
#include <dirent.h>

#include <minigui/common.h>
#include <minigui/minigui.h>
#include <minigui/gdi.h>
#include <minigui/window.h>
#include <minigui/control.h>

//菜单键ID定义
#define IDM_NEW         100
#define IDM_EXIT        120
#define IDM_ABOUT        300

#define ID_TIMER        100


//定义方块大小、行列数
#define STONE_SIZE        20
#define STONE_LINES        7
#define STONE_COLS        15




#define _(x) (x)

static RECT rcBoard;
static HWND hwnd_score = HWND_INVALID, hwnd_menu;
static BITMAP stones;
static int tagged_count = 0;
static int ball_timeout_id = -1;
static int old_x = -1, old_y = -1;
static int score;

static int cur_sel_scen = 0;

//方块属性
static struct ball {
    int color;
    int tag;
    int frame;
} field [STONE_COLS][STONE_LINES];

static int nstones;
static int ncolors;
static int sync_stones = 0;

#define mapx(x) (x)
#define mapy(y) (STONE_LINES-1-(y))

//绘制方块布局2
static void draw_ball (HDC hdc, int x, int y)
{
    int bx, by;

    if (field [x][y].color)	{
        by = STONE_SIZE * (field [x][y].color - 1);
        bx = STONE_SIZE * (field [x][y].frame);
        
        FillBoxWithBitmapPart (hdc, x * STONE_SIZE, y * STONE_SIZE, 
                 STONE_SIZE, STONE_SIZE, 0, 0, &stones, bx, by);
    } 
	else{
        SetBrushColor (hdc, PIXEL_black);
        FillBox (hdc, x * STONE_SIZE, y * STONE_SIZE, STONE_SIZE, STONE_SIZE);
    }
}

//绘制方块布局1(布局)
static void paint (HWND hwnd, HDC hdc)
{
    RECT rc;
    int x1, y1, x2, y2, x, y;
    
    GetClientRect (hdc, &rc);
    x1 = rc.left / STONE_SIZE;
    y1 = rc.top / STONE_SIZE;
    x2 = rc.right / STONE_SIZE;
    y2 = rc.bottom / STONE_SIZE;

    for (x = 0; x < STONE_COLS; x++){
        for (y = 0; y < STONE_LINES; y++){
			//调用绘制方块布局2
            draw_ball (hdc, x, y);
        }
    }
}

static void untag_all (HWND hwnd)
{
    int x, y;
    HDC hdc = GetClientDC (hwnd);

    for (x = 0; x < STONE_COLS; x++)
        for (y = 0; y < STONE_LINES; y++){
            field [x][y].tag   = 0;
            if (sync_stones && field [x][y].frame != 0) {
                field [x][y].frame = 0;
                draw_ball (hdc, x, y);
            }
        }

    ReleaseDC (hdc);
}

static int flood_fill (int x, int y, int color)
{
    int c = 0;
    
    if (field [x][y].color != color)
        return c;
    
    if (field [x][y].tag)
        return c;

    c = 1;
    field [x][y].tag = 1;
    
    if (x+1 < STONE_COLS)
        c += flood_fill (x+1, y, color);
    if (x)
        c += flood_fill (x-1, y, color);
    if (y+1 < STONE_LINES)
        c += flood_fill (x, y+1, color);
    if (y)
        c += flood_fill (x, y-1, color);
    return c;
}

static int move_tagged_balls (HDC hdc)
{
    int x, y;
    
    for (x = 0; x < STONE_COLS; x++)
        for (y = 0; y < STONE_LINES; y++){
            if (!field [x][y].tag)
                continue;
            field [x][y].frame = (field [x][y].frame + 1) % nstones;
			draw_ball (hdc, x, y);
        }
    return 1;
}

static void disable_timeout (HWND hwnd)
{
    if (ball_timeout_id != -1){
        KillTimer (hwnd, ball_timeout_id);
        ball_timeout_id = -1;
    }
}

static void mark_balls (HWND hwnd, int x, int y)
{
    if (x == old_x && y == old_y)
        return;

    old_x = x;
    old_y = y;

    untag_all (hwnd);
    disable_timeout (hwnd);
    if (!field [x][y].color)
        return;
    
    tagged_count = flood_fill (x, y, field [x][y].color);
    
    if (tagged_count > 1) {
        SetTimer (hwnd, ID_TIMER, 10); 
        ball_timeout_id = ID_TIMER;
    }
}

static void unmark_balls (HWND hWnd)
{
    old_x = -1;
    old_y = -1;
    disable_timeout (hWnd);
    untag_all (hWnd);
}

static void compress_column (int x)
{
    int y, ym;
    
    for (y = STONE_LINES - 1; y >= 0; y--){
        if (!field [mapx(x)][mapy(y)].tag)
            continue;
        for (ym = y; ym < STONE_LINES - 1; ym++)
            field [mapx(x)][mapy(ym)] = field [mapx(x)][mapy(ym+1)];
        field [mapx(x)][mapy(ym)].color = 0;
        field [mapx(x)][mapy(ym)].tag   = 0;
    }
}

static void compress_y (void)
{
    int x;

    for (x = 0; x < STONE_COLS; x++)
        compress_column (x);
}

static void copy_col (int dest, int src)
{
    int y;
    
    for (y = 0; y < STONE_LINES; y++)
        field [mapx(dest)][mapy(y)] = field [mapx(src)][mapy(y)];
}

static void clean_last_col (void)
{
    int y;

    for (y = 0; y < STONE_LINES; y++){
        field [mapx(STONE_COLS-1)][mapy(y)].color = 0;
        field [mapx(STONE_COLS-1)][mapy(y)].tag   = 0;
    }
}

static void compress_x (void)
{
    int x, xm, l;

    for (x = 0; x < STONE_COLS; x++){
        for (l = STONE_COLS; field [mapx(x)][mapy(0)].color == 0 && l; l--){
            for (xm = x; xm < STONE_COLS-1; xm++)
                copy_col (xm, xm+1);
            clean_last_col ();
        } 
    }
}

//输出成绩
static void set_score (int new_score)
{
    char b [40];
    
    score = new_score;
    sprintf (b, "Score: %.5d", score);
    if (hwnd_score != HWND_INVALID)
        SetWindowText (hwnd_score, b);
}


//游戏结束
static void end_of_game (HWND hWnd, char *title)
{
    
    char b [256];

    sprintf (b, "游戏结束\n成绩: %.5d", score);

    MessageBox (hWnd, b, title, MB_OK | MB_ICONINFORMATION | MB_BASEDONPARENT);
}

//游戏结束条件检测
static void check_game_over (HWND hwnd)
{
    int cleared=1;
    int x,y;
    
    for(x = 0; x < STONE_COLS; x++)
        for(y = 0 ; y < STONE_LINES; y++) {
            if (!field [x][y].color)
                continue;
            cleared = 0;
            if(x+1 < STONE_COLS) 
                if(field[x][y].color == field[x+1][y].color)
                    return;
            if(y+1 < STONE_LINES) 
                if(field[x][y].color == field[x][y+1].color)
                    return;
        }
    if (cleared){
        set_score (score+1000);
        end_of_game (hwnd, _("快准很"));
    }
    else
        end_of_game(hwnd, _("快准很"));
}

//相同相减
static void kill_balls (HWND hwnd, int x, int y)
{
    if (!field [x][y].color)
        return;
    
    if (tagged_count < 2)
        return;

    set_score (score + (tagged_count - 2) * (tagged_count - 2));
    compress_y ();
    compress_x ();
    InvalidateRect (hwnd, &rcBoard, FALSE);
    check_game_over (hwnd);
}

static void fill_board (void)
{
    int x, y;

    for (x = 0; x < STONE_COLS; x++)
        for (y = 0; y < STONE_LINES; y++){
            field [x][y].color = 1 + (rand () % ncolors);
            field [x][y].tag   = 0;
            field [x][y].frame = sync_stones ? 0 : (rand () % nstones);
        }
}

//游戏开始
static void new_game (HWND hwnd)
{
    fill_board ();

    set_score (0);

    InvalidateRect (hwnd, &rcBoard, FALSE);

}

static void configure_sync (const char *fname)
{
    if (strstr (fname, "-sync.gif"))
        sync_stones = 1;
    else

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?