现在的位置: 首页 > 综合 > 正文

gtk+ 游戏 “大家来找茬“

2012年06月01日 ⁄ 综合 ⁄ 共 14011字 ⁄ 字号 评论关闭

原作地址: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下。

抱歉!评论已关闭.