原作地址:http://oldyu66.blog.ithome.com.tw/post/2074/27597
在我机器上编译出了几个错误提示如图:
运行结果我第一关只能找到4出不同:
****************************************************************************************************************************************
abc.c源码:
/********************************************************/
/* INCLUDE */
/********************************************************/
#include <gtk/gtk.h>
#include <stdio.h>
#include <stdlib.h> /*exit() */
#include <unistd.h> /*usleep() */
/********************************************************/
/* DEFINE */
/********************************************************/
/*picture size: 350X450*/
#define F_IMAGE_X 25
#define R_IMAGE_X 415
#define F_IMAGE_Y 70
#define R_IMAGE_Y 70
#define P_BAR_X 40
#define P_BAR_Y 10
#define FIXED_X 790
#define FIXED_Y 550
#define PIC_AMOUNT 5
/********************************************************/
/* VARIABLE & STRUCT */
/********************************************************/
static GdkPixmap* pixmap_right = NULL;
static GdkPixmap* pixmap_left = NULL;
static GtkWidget *top_window=NULL;
static GtkWidget* drawing_area_left=NULL;
static GtkWidget* drawing_area_right=NULL;
unsigned int faults_find_completed_check=0;
typedef struct fault{ /*單一錯誤所在的範圍*/
unsigned short fault_area_x1;
unsigned short fault_area_x2;
unsigned short fault_area_y1;
unsigned short fault_area_y2;
}FAULT;
/*每張圖有5個錯誤*/
static const FAULT faults_info1[5]={{186,211,226,250},
{181,216,5,43},
{125,151,294,315},
{0,26,137,171},
{312,326,371,386}};
/*
static const FAULT faults_info1[5]={{186,211,226,250},
{181,216,5,43},
{125,151,294,315},
{0,26,137,171},
{312,326,371,386}};
*/
static const FAULT faults_info2[5]={{117,143,341,348},
{40,54,275,302},
{170,196,302,315},
{262,336,108,113},
{329,349,364,378}};
static const FAULT faults_info3[5]={{155,195,0,12},
{57,92,332,347},
{266,294,11,34},
{248,318,170,224},
{158,190,154,184}};
static const FAULT faults_info4[5]={{0,23,135,170},
{215,226,184,203},
{321,349,277,285},
{171,237,415,450},
{182,190,231,251}};
static const FAULT faults_info5[5]={{159,165,232,238},
{270,278,237,247},
{65,121,423,434},
{230,239,41,95},
{324,344,20,37}};
typedef struct pic_pair_info{
gchar* original_pic_name;
gchar* faulty_pic_name;
FAULT* fult_array;
}PIC_PAIR_INFO;
PIC_PAIR_INFO* current_pic_pair=NULL;
gint current_pic_index=0;
static const PIC_PAIR_INFO pic_pair_array[PIC_AMOUNT]={
{ (gchar*)"1.jpg", (gchar*)"1_fault.jpg",(FAULT*)faults_info1},
{ (gchar*)"2.jpg", (gchar*)"2_fault.jpg",(FAULT*)faults_info2},
{ (gchar*)"3.jpg", (gchar*)"3_fault.jpg",(FAULT*)faults_info3},
{ (gchar*)"4.jpg", (gchar*)"4_fault.jpg",(FAULT*)faults_info4},
{ (gchar*)"5.jpg", (gchar*)"5_fault.jpg",(FAULT*)faults_info5}
};
/********************************************************/
/* EXTERN FUNCTION */
/********************************************************/
/*empty*/
/********************************************************/
/* LOCAL FUNCTION */
/********************************************************/
static gboolean on_configure( GtkWidget *, GdkEventConfigure *);
static gboolean on_expose( GtkWidget *, GdkEventExpose * );
static void on_button_press( GtkWidget *, GdkEvent *, gpointer );
static gboolean progress_timeout(GtkWidget *);
static void gameover(gboolean ,gpointer );
static void ResetPic(gpointer);
/********************************************************/
/* FUNCTION */
/********************************************************/
int main( int argc, char *argv[])
{
GtkWidget *image_right;
GtkWidget *image_left;
GtkWidget *frame_left;
GtkWidget *frame_right;
GtkWidget *probar;
GtkWidget *vbox;
GtkWidget *hbox;
gtk_init(&argc, &argv);
current_pic_pair=(PIC_PAIR_INFO *)pic_pair_array;
/*window*/
top_window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_position(GTK_WINDOW(top_window), GTK_WIN_POS_CENTER);
gtk_window_set_default_size(GTK_WINDOW(top_window), 1000 ,1000);
gtk_window_set_title(GTK_WINDOW(top_window), "Finding faults");
gtk_window_set_resizable(GTK_WINDOW(top_window), FALSE);
gtk_container_set_border_width(GTK_CONTAINER(top_window), 2);
/*vbox*/
vbox = gtk_vbox_new (FALSE, 5);
gtk_container_set_border_width (GTK_CONTAINER (vbox), 8);
/*progress bar*/
probar = gtk_progress_bar_new ();
gtk_box_pack_start (GTK_BOX (vbox), probar, FALSE, FALSE, 0);
gtk_widget_show (probar);
/*hbox*/
hbox = gtk_hbox_new (FALSE, 5);
gtk_container_set_border_width (GTK_CONTAINER (hbox), 8);
/*frame*/
frame_left = gtk_frame_new(NULL);
gtk_frame_set_shadow_type(GTK_FRAME(frame_left),GTK_SHADOW_ETCHED_IN);
frame_right = gtk_frame_new(NULL);
gtk_frame_set_shadow_type(GTK_FRAME(frame_right),GTK_SHADOW_ETCHED_IN);
/*drawing area*/
drawing_area_left= gtk_drawing_area_new();
gtk_drawing_area_size( GTK_DRAWING_AREA(drawing_area_left), 350, 450);
gtk_widget_add_events(drawing_area_left, GDK_BUTTON_PRESS_MASK);
drawing_area_right= gtk_drawing_area_new();
gtk_drawing_area_size( GTK_DRAWING_AREA(drawing_area_right), 350, 450);
gtk_widget_add_events(drawing_area_right, GDK_BUTTON_PRESS_MASK);
/*layout*/
gtk_container_add(GTK_CONTAINER(frame_left),drawing_area_left);
gtk_container_add(GTK_CONTAINER(frame_right),drawing_area_right);
gtk_box_pack_start (GTK_BOX (hbox), frame_left, FALSE, FALSE, 0);
gtk_box_pack_start (GTK_BOX (hbox), frame_right, FALSE, FALSE, 0);
gtk_widget_show (hbox);
gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
gtk_container_add (GTK_CONTAINER (top_window), vbox);
/*signal*/
g_signal_connect_swapped(G_OBJECT(top_window), "destroy",
G_CALLBACK(gtk_main_quit), G_OBJECT(top_window));
gtk_signal_connect (GTK_OBJECT(top_window),"configure_event",
(GtkSignalFunc) on_configure, NULL);
gtk_signal_connect (GTK_OBJECT (top_window), "expose_event",
(GtkSignalFunc) on_expose, NULL);
gtk_signal_connect (GTK_OBJECT(top_window),"button_press_event",
(GtkSignalFunc) on_button_press, (gpointer) probar);
/*timer*/
g_timeout_add(1000, (GSourceFunc) progress_timeout, (gpointer) probar);
/*show all*/
gtk_widget_show_all(top_window);
gtk_main();
return 0;
}
/******************************************************************************************/
static gboolean on_configure( GtkWidget *widget, GdkEventConfigure *event)
{
/*g_print("configure/n");*/
/*configure event會在我們改變窗口大小時產生,包括窗口創建時*/
/*若緩衝區是NULL則建立新的Pixmap*/
/*right*/
if (! pixmap_right){
pixmap_right=gdk_pixmap_create_from_xpm(widget->window,NULL,NULL,
pic_pair_array[0].faulty_pic_name);
}
/*left*/
if (! pixmap_left){
pixmap_left=gdk_pixmap_create_from_xpm(widget->window,NULL,NULL,
pic_pair_array[0].original_pic_name);
}
return TRUE;
}
static gboolean on_expose( GtkWidget *widget, GdkEventExpose *event )
{
/*g_print("expose/n");*/
/*將緩衝區pixmap貼到GtkDrawingArea 的 window 成員上*/
/*right*/
gdk_draw_pixmap(drawing_area_right->window,
drawing_area_right->style->fg_gc[GTK_WIDGET_STATE (drawing_area_right)],
pixmap_right,0, 0,0, 0, -1, -1);
/*將緩衝區pixmap貼到GtkDrawingArea 的 window 成員上*/
/*left*/
gdk_draw_pixmap(drawing_area_left->window,
drawing_area_left->style->fg_gc[GTK_WIDGET_STATE (drawing_area_left)],
pixmap_left,0, 0,0, 0, -1, -1);
return FALSE;
}
static void on_button_press( GtkWidget *widget, GdkEvent *event, gpointer pbar)
{
gchar i;
unsigned int shift_bit=0x000001;
/*g_print("button_press_event (%d, %d)/n",(gint) event->button.x, (gint) event->button.y);*/
/*fault area check:比對button press的座標是否在錯誤的範圍內,若是,則做畫圈的動作*/
for(i=0;i<5;i++){
if(((gint) event->button.x>(current_pic_pair->fult_array[i].fault_area_x1))&&
((gint) event->button.x<(current_pic_pair->fult_array[i].fault_area_x2))&&
((gint) event->button.y>(current_pic_pair->fult_array[i].fault_area_y1))&&
((gint) event->button.y<(current_pic_pair->fult_array[i].fault_area_y2)))
{
/*right*/
gdk_gc_set_line_attributes(drawing_area_right->style->black_gc,3,
GDK_LINE_SOLID,GDK_CAP_NOT_LAST,GDK_JOIN_MITER);
gdk_draw_arc(pixmap_right,drawing_area_right->style->black_gc,FALSE,
current_pic_pair->fult_array[i].fault_area_x1,current_pic_pair->fult_array[i].fault_area_y1,
(current_pic_pair->fult_array[i].fault_area_x2-current_pic_pair->fult_array[i].fault_area_x1),
(current_pic_pair->fult_array[i].fault_area_y2-current_pic_pair->fult_array[i].fault_area_y1),0,360*64);
gdk_draw_pixmap(drawing_area_right->window,
drawing_area_right->style->fg_gc[GTK_WIDGET_STATE (drawing_area_right)],
pixmap_right,0, 0,0, 0, -1, -1);
/*left*/
gdk_gc_set_line_attributes(drawing_area_left->style->black_gc,3,
GDK_LINE_SOLID,GDK_CAP_NOT_LAST,GDK_JOIN_MITER);
gdk_draw_arc(pixmap_left,drawing_area_left->style->black_gc,FALSE,
current_pic_pair->fult_array[i].fault_area_x1,current_pic_pair->fult_array[i].fault_area_y1,
(current_pic_pair->fult_array[i].fault_area_x2-current_pic_pair->fult_array[i].fault_area_x1),
(current_pic_pair->fult_array[i].fault_area_y2-current_pic_pair->fult_array[i].fault_area_y1),0,360*64);
gdk_draw_pixmap(drawing_area_left->window,
drawing_area_left->style->fg_gc[GTK_WIDGET_STATE (drawing_area_left)],
pixmap_left,0, 0,0, 0, -1, -1);
/*檢查5個錯誤是否找齊,若找齊 faults_find_completed_check=31*/
shift_bit=shift_bit<<i;
faults_find_completed_check|=shift_bit;
}
}
if(faults_find_completed_check==31){
/*g_print("faults find completed!!/n");*/
usleep(900000);
current_pic_index++;
if(current_pic_index==PIC_AMOUNT){ /*player win!*/
gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (pbar), 0);
gameover(TRUE,pbar);
}
else
ResetPic(pbar);
}
}
static void ResetPic(gpointer pbar)
{
current_pic_pair=(PIC_PAIR_INFO *)&pic_pair_array[current_pic_index];
/*right*/
pixmap_right=gdk_pixmap_create_from_xpm(drawing_area_right->window,
NULL,NULL,current_pic_pair->faulty_pic_name);
gdk_draw_pixmap(drawing_area_right->window,
drawing_area_right->style->fg_gc[GTK_WIDGET_STATE (drawing_area_right)],
pixmap_right,0, 0,0, 0, -1, -1);
/*left*/
pixmap_left=gdk_pixmap_create_from_xpm(drawing_area_left->window,
NULL,NULL,current_pic_pair->original_pic_name);
gdk_draw_pixmap(drawing_area_left->window,
drawing_area_left->style->fg_gc[GTK_WIDGET_STATE (drawing_area_left)],
pixmap_left,0, 0,0, 0, -1, -1);
/*restart the progress*/
gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (pbar), 0);
faults_find_completed_check=0;
}
static gboolean progress_timeout(GtkWidget *pbar)
{
/*0.5sec 50times*/
gdouble new_val;
/*GtkWidget probar = pbar;*/
/* Calculate the value of the progress bar using the
* value range set in the adjustment object */
if(current_pic_index!=PIC_AMOUNT){
new_val = gtk_progress_bar_get_fraction (GTK_PROGRESS_BAR (pbar)) + 0.02;
/* Set the new value */
gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (pbar), new_val);
if (new_val > 1.0){
gameover(FALSE,pbar);
new_val = 0.0;
}
}
return TRUE;
}
static void gameover(gboolean won,gpointer pbar)
{
GtkWidget *dialog;
gchar msg[50];
gchar response;
if(won==TRUE){
g_snprintf(msg, 50, "You won! Restart again?");
}else{
g_snprintf(msg, 50, "Time's up! Retry again?.");
}
dialog=gtk_message_dialog_new(GTK_WINDOW(top_window),GTK_DIALOG_DESTROY_WITH_PARENT,
GTK_MESSAGE_INFO,GTK_BUTTONS_YES_NO, msg);
response=gtk_dialog_run(GTK_DIALOG(dialog));
if(response==GTK_RESPONSE_YES){
current_pic_index=0;
ResetPic(pbar);
}
else
exit (0);
gtk_widget_destroy(dialog);
}
Makefile源码:
#以#开头表示是注释行,以Tab键开头表示命令行,'/'表示之后一行合并到前一行,其后不能有任何字符
CC=gcc
PROG_NAME=abc
INCS=
SRCS= /
abc.c
#从 xx.c 文件得到 xx.o 文件
OBJS=${SRCS:.c=.o}
#编译 GTK 程序时要用到的库
LIBS=libglade-2.0
#---- 用户修改区域 结束
# -O2
CFLAGS=`pkg-config --cflags ${LIBS}` -g -Wall
LDFLAGS=`pkg-config --libs ${LIBS}` -g -Wall
all: ${PROG_NAME}
${PROG_NAME}:${OBJS}
${CC} -o ${PROG_NAME} ${OBJS} ${LDFLAGS} -export-dynamic
#注意:上边”${CC}" 的前边有一个 TAB 键,而不是空格
#如果有头文件进行修改,则自动编译源文件
${OBJS}:${INCS}
.c.o:
${CC} -c $< ${CFLAGS}
clean:
rm -f *.o
${PROG_NAME}
rebuild: clean all
原图:
1.jpg
1_fault.jpg
2.jpg
2_fault.jpg
3.jpg
3_fault.jpg
4.jpg
4_fault.jpg
5.jpg
5_fault.jpg
****************************************************************************************************************************************
注意:
1;Makefile复制时可能会把Tab键误改,如果这样请在make出错时改正。
2:原图请放在abc.c和Makefile同一目录abc下。