📄 compic.cpp
字号:
/* WM_PAINT 消息处理函数 */
void OnPaint(HDC hDC)
{
int i = 0, j = 0;
/* 填充背景和绘制线条 */
SelectObject(h_MemDC, hPen);
SelectObject(h_MemDC, h_CliBm);
apiBitBlt(hDC, 0, 0, rc.right-rc.left,rc.bottom-rc.top);
SelectObject(h_MemDC, h_PicBkGnd);
apiBitBlt(hDC, rc.left, rc.top, ROW*y_cell+4, rc.bottom);
/* 绘制背景各个坐标位图 */
for(i = 0; i < LINE; i ++)
{
for(j = 0; j < ROW; j ++)
{
if(map[i][j].status == 1) continue;
drawPic(hDC, i, j);
}
}
/* 绘制右上角小的全图 */
SelectObject(h_MemDC, h_SmPicBm);
apiBitBlt(hDC, rc.right-261, 2, 260, 210);
}
/* 设置鼠标形状 */
void OnSetCursor()
{
int x = 0, y = 0, dx = 0, dy = 0;
int ret = 0;
if(mcur_x <= 0 || mcur_y <= 0)
{
SetCursor(LoadCursor(NULL, (LPCTSTR)IDC_ARROW));
return;
}
x = (mcur_x - 1)/x_cell;
y = (mcur_y - 2)/y_cell;
if(gameStatus == GMGOING)
{
if(y < 0 || y >= ROW || x < 0 || x >= LINE)
{
SetCursor(LoadCursor(NULL, (LPCTSTR)IDC_ARROW));
return;
}
ret = chkStatus(x, y, &dx, &dy);
if(ret < 0) /* 不可移动 */
{
SetCursor(LoadCursor(hInst, (LPCTSTR)IDC_CURSOR_NO));
return;
}
switch(ret)
{
case UP: /* 可以向上移动 */
SetCursor(LoadCursor(hInst, (LPCTSTR)IDC_CURSOR_UP));
break;
case DOWN: /* 可以向下移动 */
SetCursor(LoadCursor(hInst, (LPCTSTR)IDC_CURSOR_DOWN));
break;
case LEFT: /* 可以向左移动 */
SetCursor(LoadCursor(hInst, (LPCTSTR)IDC_CURSOR_LEFT));
break;
case RIGHT: /* 可以向右移动 */
SetCursor(LoadCursor(hInst, (LPCTSTR)IDC_CURSOR_RIGHT));
break;
}
}
else
SetCursor(LoadCursor(NULL, (LPCTSTR)IDC_ARROW));
}
/* 鼠标点击消息处理 */
int OnMouseClick(HDC hDC)
{
int i = 0, j = 0, ret = 0;
int mx = 0, my = 0, nx = 0, ny = 0, x = 0, y = 0;
RECT rt;
/* 计算鼠标点击的坐标对应的背景坐标 */
mx = (mouse_x - 1)/x_cell;
my = (mouse_y - 2)/y_cell;
/* 检查点击的图片的状态,判断是否该图片块可以移动 */
ret = chkStatus(mx, my, &nx, &ny);
if(ret < 0) return 0;
intSteps ++;
swapPic(&map[mx][my], &map[nx][ny]);
drawPic(hDC, mx, my);
/* 获得重画的矩形区域,使该区域立即生效 */
x = (mx < nx ? mx : nx);
y = (my < ny ? my : ny);
rt.left = y*y_cell + 2;
rt.top = x*x_cell + 1;
rt.right = rt.left + y_cell+4;
rt.bottom = rt.top + x_cell+4;
switch(ret)
{
case UP:
case DOWN:
rt.bottom += x_cell;
break;
case RIGHT:
case LEFT:
rt.right += y_cell;
break;
}
InvalidateRect(hWndMain, &rt, FALSE);
/* 检查游戏是否结束 */
for(i = 0; i < LINE; i ++)
{
for(j = 0; j < ROW; j ++)
{
if(map[i][j].x != map[i][j].px ||
map[i][j].y != map[i][j].py)
{
if(map[i][j].status != 1) return 0;
}
}
}
rt.left = rc.left;
rt.top = rc.top;
rt.bottom = rc.bottom;
rt.right = ROW*y_cell + 2;
gameStatus = GMOVER;
/* 游戏结束显示背景图 */
for(i = 0; i < LINE; i ++)
{
for(j = 0; j < ROW; j ++)
{
map[i][j].status = 1;
}
}
InvalidateRect(hWndMain, &rt, FALSE);
MessageBox(hWndMain, "真棒!恭喜你(^_^)", "游戏结束", MB_OK);
/* 恢复拼图图片显示 */
for(i = 0; i < LINE; i ++)
{
for(j = 0; j < ROW; j ++)
{
map[i][j].status = 0;
}
}
InvalidateRect(hWndMain, &rt, FALSE);
rt.left = rc.right-230;
rt.top = rc.top+285;
rt.bottom = rc.top+345;
rt.right = rc.right;
/* 清除统计信息 */
SelectObject(h_MemDC, h_CliBm);
FillRect(h_MemDC, &rt, hBrush);
InvalidateRect(hWndMain, &rt, FALSE);
return 0;
}
/* 随机生成游戏的初始图片序列 */
int OnNewGame(HDC hDC)
{
int cur_x = 0, cur_y = 0, x= 0, y = 0, dx = 0, dy = 0;
int i = 0, j = 0, dir = 0, ret = 0;
RECT rt;
intSteps = 0;
startT = time(NULL);
/* 恢复背景坐标到初始状态 */
for(i = 0; i <= LINE; i ++)
{
for(j = 0; j <= ROW; j++)
{
map[i][j].x = i;
map[i][j].y = j;
map[i][j].status = 0;
map[i][j].px = i;
map[i][j].py = j;
}
}
cur_x = rand()%LINE;
cur_y = rand()%ROW;
map[cur_x][cur_y].status = 1;
x = cur_x;
y = cur_y;
dir = UP;
for(i = 0; i < 4*LINE*ROW; i ++)
{
switch(dir)
{
case RIGHT:
y ++; break;
case DOWN:
x ++; break;
case LEFT:
y --; break;
case UP:
x --; break;
}
ret = chkStatus(x, y, &dx, &dy);
if(ret < 0)
{
dir = rand()%4;
x = cur_x;
y = cur_y;
continue;
}
swapPic(&map[x][y], &map[dx][dy]);
cur_x = x;
cur_y = y;
dir = rand()%4;
}
/* 绘制背景坐标各个点的位图 */
for(i = 0; i < LINE; i ++)
{
for(j = 0; j < ROW; j ++)
{
if(map[i][j].status == 1) continue;
drawPic(hDC, i, j);
}
}
rt.left = 1;
rt.top = 1;
rt.right = rt.left + ROW*y_cell;
rt.bottom = rt.top + LINE*x_cell;
InvalidateRect(hWndMain, &rt, FALSE);
return 0;
}
/* 交换两个坐标点的位图 */
void swapPic(MAPSTATUS *s, MAPSTATUS *t)
{
MAPSTATUS tMap;
tMap.px = s->px;
tMap.py = s->py;
tMap.status = s->status;
s->px = t->px;
s->py = t->py;
s->status = t->status;
t->px = tMap.px;
t->py = tMap.py;
t->status = tMap.status;
}
/* 检查坐标点(x,y) 的状态,如果成功返回其移动的方向 */
int chkStatus(int x, int y, int *px, int *py)
{
int i = 0, ret = -1;
if(gameStatus != GMGOING) return -1;
if(y < 0 || y >= ROW || x < 0 || x >= LINE) return -1;
if(map[x][y].status == 1) return -1;
for(i = 0; i < 4; i ++)
{
*px = x;
*py = y;
ret = -1;
switch(i)
{
case RIGHT:
(*py) ++; break;
case DOWN:
(*px) ++; break;
case LEFT:
(*py) --; break;
case UP:
(*px) --; break;
}
if(*py < 0 || *py >= ROW || *px < 0 || *px >= LINE) continue;
if(map[*px][*py].status == 1)
{
ret = i;
break;
}
}
return ret;
}
void displayText(int posx, int posy, char *text, int len)
{
RECT rt;
rt.left = posx;
rt.top = posy;
rt.right=rt.left + len + 8;
rt.bottom=rt.top + 20;
SelectObject(h_MemDC, h_CliBm);
FillRect(h_MemDC, &rt, hBushText);
TextOut(h_MemDC, posx+4, posy+2, text, strlen(text));
InvalidateRect(hWndMain, &rt, FALSE);
}
void showInfo()
{
RECT rt;
char tmp[256];
time_t curT = 0;
displayText(rc.right-200, rc.top+250, curtime("%y-%m-%d %h:%i:%s"), 132);
displayText(rc.right-230, rc.top+390, "支持拖其他BMP图片到游戏窗口", 210);
if(gameStatus == GMGOING)
{
memset(tmp, 0x00, sizeof(tmp));
sprintf(tmp, "步数: %08d", intSteps);
displayText(rc.right-230, rc.top+290, tmp, 7*strlen(tmp)+2);
curT = time(NULL);
memset(tmp, 0x00, sizeof(tmp));
sprintf(tmp, "用时: %02d分%02d秒", ((curT-startT)/60)%99, (curT-startT)%60);
displayText(rc.right-230, rc.top+320, tmp, 7*strlen(tmp));
}
if(gameStatus == GMINIT || gameStatus == GMOVER)
{
displayText(rc.right-230, rc.top+360, "请选择游戏开始新游戏", 150);
}
else
{
rt.left = rc.right-230;
rt.top = rc.top+360;
rt.right=rt.left + 230 + 8;
rt.bottom=rt.top + 25;
SelectObject(h_MemDC, h_CliBm);
FillRect(h_MemDC, &rt, hBrush);
InvalidateRect(hWndMain, &rt, FALSE);
displayText(rc.right-230, rc.top+360, "正在游戏中", 75);
}
}
char *curtime(char *fmt)
{
int i = 0;
time_t t;
struct tm *lt = NULL;
static char res[128];
char *p = fmt;
memset(res, 0x00, sizeof(res));
if(!fmt) return res;
t = time(NULL);
lt = (struct tm *)localtime(&t);
while(*p)
{
if(*p != '%')
{
res[i++] = *p; p ++;
continue;
}
switch(*(p+1))
{
case '\0':
res[i++] = *p;
res[i] = '\0';
return res;
case 'y':
sprintf(&res[i], "%04d", lt->tm_year + 1900);
i += 2;
p ++;
break;
case 'm':
sprintf(&res[i], "%02d", lt->tm_mon + 1);
p ++;
break;
case 'd':
sprintf(&res[i], "%02d", lt->tm_mday);
p ++;
break;
case 'h':
sprintf(&res[i], "%02d", lt->tm_hour);
p ++;
break;
case 'i':
sprintf(&res[i], "%02d", lt->tm_min);
p ++;
break;
case 's':
sprintf(&res[i], "%02d", lt->tm_sec);
p ++;
break;
default:
res[i] = *p;
i --;
break;
}
i += 2;
p ++;
}
res[i] = '\0';
return res;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -