📄 slider.c
字号:
/* 原作: Simon Wood <simon@mungewell.uklinux.net>
* 修改:徐睿
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#define MWINCLUDECOLORS
#include "nano-X.h"
/* 拼图的尺寸设定 */
#define WIDTH_IN_TILES 4
#define HEIGHT_IN_TILES 4
#define MAX_TILES (WIDTH_IN_TILES * HEIGHT_IN_TILES)
static int value[WIDTH_IN_TILES][HEIGHT_IN_TILES];
static int calc_width, calc_height;
static int tile_width = 40;
static int tile_height = 40;
static void * image_addr;
static int using_image = 1;
static GR_WINDOW_ID image; /* 位图的存储区 */
static GR_WINDOW_ID master; /* 整个窗口的ID */
static GR_WINDOW_ID buttons; /* 按钮的ID */
static GR_WINDOW_ID tiles; /* 拼图区域的ID */
static GR_GC_ID gc1; /* 文字显示的图形上下文 */
static void HandleEvents();
static void RefreshWindow();
static void RandomiseTiles();
static void MoveTile();
static void DrawTile();
char bmpname[16]="slidebmp.bmp";
int
main(int argc,char **argv)
{
if (GrOpen() < 0) {
fprintf(stderr, "cannot open graphics\n");
exit(1);
}
gc1 = GrNewGC();
/* 计算位图需要的内存大小.... */
image_addr = malloc(4 * (WIDTH_IN_TILES * tile_width) *
(HEIGHT_IN_TILES * tile_height) );
image = GrNewPixmap((WIDTH_IN_TILES * tile_width),
(HEIGHT_IN_TILES * tile_height), image_addr);
GrDrawImageFromFile(image, gc1, 0, 0,
GR_IMAGE_MAX_SIZE, GR_IMAGE_MAX_SIZE, bmpname, 0);
/* calculate size of tile area */
calc_width = 10 + (WIDTH_IN_TILES * tile_width);
calc_height = 15 + 35 + (HEIGHT_IN_TILES * tile_height);
master = GrNewWindow(GR_ROOT_WINDOW_ID, 0, 0, calc_width, calc_height, 1, RED, WHITE);
buttons = GrNewWindow((GR_WINDOW_ID) master, 5, 5, (calc_width - 5), 35, 1, RED, RED);
tiles = GrNewWindow((GR_WINDOW_ID) master, (calc_width/2) - (WIDTH_IN_TILES * tile_width /2),
45 + ((calc_height - 50)/2) - (HEIGHT_IN_TILES * tile_height /2),
(WIDTH_IN_TILES * tile_width), (HEIGHT_IN_TILES * tile_height), 1, RED, RED);
GrMapWindow(master);
GrMapWindow(buttons);
GrMapWindow(tiles);
GrSelectEvents(master, GR_EVENT_MASK_EXPOSURE|GR_EVENT_MASK_CLOSE_REQ|
GR_EVENT_MASK_KEY_DOWN);
GrSelectEvents(buttons, GR_EVENT_MASK_BUTTON_DOWN);
GrSelectEvents(tiles, GR_EVENT_MASK_BUTTON_DOWN);
srandom((int) getpid());
RandomiseTiles();
RefreshWindow();
while (GR_TRUE) {
GR_EVENT event;
GrGetNextEvent(&event);
HandleEvents(&event);
}
}
/*
* 消息处理函数
*/
void
HandleEvents(GR_EVENT *ep)
{
int hole_x_pos, hole_y_pos;
int tempx, tempy;
switch (ep->type) {
case GR_EVENT_TYPE_BUTTON_DOWN:
if (ep->button.wid == buttons) {
if (ep->button.x < (calc_width/2)) {
/* 按下了Again按钮 */
RandomiseTiles();
RefreshWindow();
} else {
/* 按下了Quit按钮 */
GrClose();
if (using_image)
free(image_addr);
exit(0);
}
}
if (ep->button.wid == tiles) {
/* 想要移动鼠标点击的按钮 */
MoveTile( (int)(ep->button.x / tile_width),
(int)(ep->button.y / tile_height) );
}
break;
case GR_EVENT_TYPE_KEY_DOWN:
if (ep->keystroke.wid == master) {
hole_x_pos = 0;
hole_y_pos = 0;
/* 查找空区 */
for (tempx = 0; tempx < WIDTH_IN_TILES; tempx++)
for (tempy = 0; tempy < HEIGHT_IN_TILES; tempy++)
if (value[tempx][tempy] == MAX_TILES) {
hole_x_pos = tempx;
hole_y_pos = tempy;
}
switch (ep->keystroke.ch) {
case 'q':
case 'Q':
case MWKEY_CANCEL:
GrClose();
if (using_image)
free(image_addr);
exit(0);
case 'r':
case 'R':
RandomiseTiles();
RefreshWindow();
break;
case MWKEY_DOWN:
if (hole_y_pos != 0) {
MoveTile(hole_x_pos, hole_y_pos - 1);
}
break;
case MWKEY_UP:
if (hole_y_pos != (HEIGHT_IN_TILES-1) ) {
MoveTile(hole_x_pos, hole_y_pos + 1);
}
break;
case MWKEY_RIGHT:
if (hole_x_pos != 0) {
MoveTile(hole_x_pos - 1, hole_y_pos);
}
break;
case MWKEY_LEFT:
if (hole_x_pos != (WIDTH_IN_TILES-1) ) {
MoveTile(hole_x_pos + 1, hole_y_pos);
}
break;
}
}
break;
case GR_EVENT_TYPE_EXPOSURE:
RefreshWindow();
break;
case GR_EVENT_TYPE_CLOSE_REQ:
GrClose();
exit(0);
}
}
void
RefreshWindow()
{
int xpos, ypos;
GrSetGCForeground(gc1, WHITE);
GrSetGCBackground(gc1, RED);
/* 绘制按钮 */
GrRect(buttons, gc1, 0, 0, (calc_width - 12)/2, 34);
GrRect(buttons, gc1, (calc_width - 8)/2, 0, (calc_width - 12)/2, 34);
GrText(buttons, gc1, 5, 22, "Again", 5, 0);
GrText(buttons, gc1, (calc_width / 2) + 5, 22, "Quit", 4, 0);
/* 绘制拼图 */
for (ypos=0; ypos< HEIGHT_IN_TILES; ypos++){
for (xpos=0; xpos< WIDTH_IN_TILES; xpos++){
DrawTile(xpos, ypos);
}
}
}
void
RandomiseTiles()
{
int count, xpos, ypos;
/* 将图片对应的4*4的区域编号*/
for (ypos=0; ypos< HEIGHT_IN_TILES; ypos++){
for (xpos=0; xpos< WIDTH_IN_TILES; xpos++){
value[xpos][ypos] = 1 + xpos + (WIDTH_IN_TILES * ypos);
}
}
/* 空区的位置 */
xpos = WIDTH_IN_TILES - 1;
ypos = HEIGHT_IN_TILES - 1;
/* 使用随机数将拼图随意移动 */
for (count=0; count< MAX_TILES * 1000; count++){
switch(random() % 4) {
case 0:
if (ypos < HEIGHT_IN_TILES - 1) {
value[xpos][ypos] = value[xpos][ypos+1];
ypos++;
value[xpos][ypos] = MAX_TILES;
}
break;
case 1:
if (xpos > 0) {
value[xpos][ypos] = value[xpos - 1][ypos];
xpos--;
value[xpos][ypos] = MAX_TILES;
}
break;
case 2:
if (ypos > 0) {
value[xpos][ypos] = value[xpos][ypos - 1];
ypos--;
value[xpos][ypos] = MAX_TILES;
}
break;
case 3:
if (xpos < WIDTH_IN_TILES - 1) {
value[xpos][ypos] = value[xpos + 1][ypos];
xpos++;
value[xpos][ypos] = MAX_TILES;
}
break;
}
}
}
void
MoveTile(int xpos, int ypos)
{
/* 看看能向哪个方向移动 */
if (ypos > 0 && value[xpos][ypos - 1] == MAX_TILES) {
value[xpos][ypos - 1] = value[xpos][ypos];
value[xpos][ypos] = MAX_TILES;
DrawTile(xpos, ypos - 1);
DrawTile(xpos, ypos);
}
if (xpos < (WIDTH_IN_TILES - 1) && value[xpos + 1][ypos] == MAX_TILES) {
value[xpos + 1][ypos] = value[xpos][ypos];
value[xpos][ypos] = MAX_TILES;
DrawTile(xpos + 1, ypos);
DrawTile(xpos, ypos);
}
if (ypos < (HEIGHT_IN_TILES - 1) && value[xpos][ypos + 1] == MAX_TILES) {
value[xpos][ypos + 1] = value[xpos][ypos];
value[xpos][ypos] = MAX_TILES;
DrawTile(xpos, ypos + 1);
DrawTile(xpos, ypos);
}
if (xpos > 0 && value[xpos - 1][ypos] == MAX_TILES) {
value[xpos - 1][ypos] = value[xpos][ypos];
value[xpos][ypos] = MAX_TILES;
DrawTile(xpos - 1, ypos);
DrawTile(xpos, ypos);
}
/* 查看是否完成 */
if (value[WIDTH_IN_TILES - 1][HEIGHT_IN_TILES - 1] == MAX_TILES) {
int winner = 0;
for (ypos=0; ypos< HEIGHT_IN_TILES; ypos++){
for (xpos=0; xpos< WIDTH_IN_TILES; xpos++){
if (value[xpos][ypos] == winner + 1)
winner++;
else
winner=0;
}
}
if (winner == MAX_TILES) {
/* 完成了拼图 */
int loop = MAX_TILES;
for(loop=0; loop < MAX_TILES; loop++) {
for(winner=0; winner < (MAX_TILES - loop) ; winner++) {
xpos = winner % WIDTH_IN_TILES;
ypos = (int)(winner/WIDTH_IN_TILES);
value[xpos][ypos] = loop + winner + 1;
DrawTile(winner % WIDTH_IN_TILES, (int)(winner/WIDTH_IN_TILES));
}
GrFlush();
for(winner=0; winner < 10000000 ; winner++);
/* 延时 */
}
/* 输出完成信息 */
GrSetGCForeground(gc1, WHITE);
GrSetGCBackground(gc1, RED);
GrText(tiles, gc1, ((WIDTH_IN_TILES * tile_width)/2) - 40, (HEIGHT_IN_TILES * tile_height)/2, "Well Done!!", -1, 0);
}
}
}
void
DrawTile(int xpos, int ypos)
{
char text[]="00";
/* 清理屏幕 */
GrSetGCForeground(gc1, RED);
GrFillRect(tiles, gc1, (xpos* tile_width), (ypos*tile_height), tile_width,
tile_height);
if (value[xpos][ypos] != MAX_TILES ) {
/* 重绘屏图的边框 */
GrSetGCForeground(gc1, WHITE);
GrSetGCBackground(gc1, RED);
GrRect(tiles, gc1, (xpos*tile_width), (ypos*tile_height), tile_width,
tile_height);
/* 拷贝并且显示图形的切片 */
GrCopyArea(tiles, gc1, 1 + (xpos*tile_width), 1 + (ypos*tile_height),
tile_width - 2, tile_height - 2, image,
1 + (((value[xpos][ypos] - 1) % WIDTH_IN_TILES) * tile_width),
1 + (((int)(value[xpos][ypos] - 1) / WIDTH_IN_TILES) * tile_height), 0);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -