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 + -
显示快捷键?