animate.c

来自「开发linux应用-用gtk+和gdk开发linux图形用户界面应用--的实例」· C语言 代码 · 共 322 行

C
322
字号
/* * Auth: Eric Harlow * File: animate.c * * Linux application development * * Defender game.   */#include <gtk/gtk.h>#include <gdk/gdkkeysyms.h>#include "defender.h"void AddKey (GdkEventKey *event);void RemoveKey (GdkEventKey *event);void HandleKeysPressed ();void StartGame ();void DrawScreen (GdkPixmap *pixmap, GtkWidget *drawing_area);int GetGameHeight ();void LoadImages (GtkWidget *window);/* --- Backing pixmap for drawing area  --- */GdkPixmap *pixmap = NULL;/* * DisplaySprite * * Display the sprite on the drawing_area at the prescribed  * coordinates.  Use a mask so that we do not draw the  * invisible area - it should be transparent. * * drawing_area - where to draw the sprite * sprite - the sprite to draw * x, y - position to draw the sprite. */void DisplaySprite (GtkWidget *drawing_area, typSprite *sprite, int x, int y){    GdkGC *gc;    /* --- Get gc of a the normal style --- */    gc = drawing_area->style->fg_gc[GTK_STATE_NORMAL];    /* --- Set up the clip mask and origin --- */    gdk_gc_set_clip_mask (gc, sprite->mask);    gdk_gc_set_clip_origin (gc, x, y);    /* --- Copy pixmap to the window --- */    gdk_draw_pixmap (pixmap,          drawing_area->style->fg_gc[GTK_STATE_NORMAL],          sprite->pixmap,          0, 0, x, y,          sprite->width, sprite->height);    /* --- Clear the clip mask when done. --- */    gdk_gc_set_clip_mask (gc, NULL);}/* * Repaint * * data - widget to repaint */gint Repaint (gpointer data){    GtkWidget*    drawing_area = (GtkWidget *) data;    GdkRectangle  update_rect;    /* --- Draw the game on the background. --- */    DrawScreen (pixmap, drawing_area);    /* --- Copy background to screen --- */    update_rect.x = 0;    update_rect.y = 0;    update_rect.width = drawing_area->allocation.width;    update_rect.height = drawing_area->allocation.height;    /* --- Copy the background to the foreground --- */    gtk_widget_draw (drawing_area, &update_rect);    return (FALSE);}/*  * configure_event * * Create a new backing pixmap of the appropriate size  * Of course, this is called whenever the window is  * resized.  We have to free up things we allocated. */static gint configure_event (GtkWidget *widget, GdkEventConfigure *event){    /* --- Free background if we created it --- */    if (pixmap) {        gdk_pixmap_unref (pixmap);    }     /* --- Create a new pixmap with new size --- */    pixmap = gdk_pixmap_new (widget->window,                widget->allocation.width,                widget->allocation.height,                -1);    return TRUE;}/* * GotFocus * * Called when the window gets the focus.  This is necessary * because the keys repeat themeselves and block out other  * keys when pressed at the same time.  The only way around * this is to disable that behavior and handle the key "up" * and "down" ourselves.  Of course, this change is global  * across all applications so we should only set it when we * have the focus. */static gint GotFocus (GtkWidget *widget, gpointer data){    gdk_key_repeat_disable ();    return (FALSE);}/* * LostFocus * * See GotFocus.  Since the change is global, we should * restore the repeat so that other applications aren't * messed up. */static gint LostFocus (GtkWidget *widget, gpointer data){    gdk_key_repeat_restore ();    return (FALSE);}/* * KeyPress * * Hey, a keypress.  Add the key to the list of  * keys currently being pressed. */static gint KeyPress (GtkWidget *widget, GdkEventKey *event){    AddKey (event);    return (FALSE);}/* * KeyRelease * * Hey, they let go of a keypress.  Remove the  * key from the list of keys that is currently * being pressed. */static gint KeyRelease (GtkWidget *widget, GdkEventKey *event){    RemoveKey (event);    return (FALSE);}/* * expose_event * * When the window is exposed to the viewer or  * the gdk_widget_draw routine is called, this  * routine is called.  Copies the background pixmap * to the window. */gint expose_event (GtkWidget *widget, GdkEventExpose *event){    /* --- Copy pixmap to the window --- */    gdk_draw_pixmap (widget->window,          widget->style->fg_gc[GTK_WIDGET_STATE (widget)],          pixmap,          event->area.x, event->area.y,          event->area.x, event->area.y,          event->area.width, event->area.height);    return FALSE;}/* * GetPen * * Get a pen using the GdkColor passed in.  The "pen" * (just a GdkGC) is created and returned ready for  * use. */GdkGC *GetPen (GdkColor *c){    GdkGC *gc;    /* --- Create a gc --- */    gc = gdk_gc_new (pixmap);    /* --- Set the forground to the color --- */    gdk_gc_set_foreground (gc, c);    /* --- Return it. --- */    return (gc);}/* * NewColor * * Create and allocate a GdkColor with the color  * specified in the parameter list. */ GdkColor *NewColor (long red, long green, long blue){    /* --- Get the color --- */    GdkColor *c = (GdkColor *) g_malloc (sizeof (GdkColor));    /* --- Fill it in. --- */    c->red = red;    c->green = green;    c->blue = blue;    gdk_color_alloc (gdk_colormap_get_system (), c);    return (c);}/* * quit * * Get out of the application */void quit (){    gtk_exit (0);}/* * main * * Program begins here. */ int main (int argc, char *argv[]){    GtkWidget *window;    GtkWidget *drawing_area;    GtkWidget *vbox;    StartGame ();    gtk_init (&argc, &argv);    window = gtk_window_new (GTK_WINDOW_TOPLEVEL);    vbox = gtk_hbox_new (FALSE, 0);    gtk_container_add (GTK_CONTAINER (window), vbox);    gtk_widget_show (vbox);    gtk_signal_connect (GTK_OBJECT (window), "destroy",                GTK_SIGNAL_FUNC (quit), NULL);    /* --- Create the drawing area  --- */    drawing_area = gtk_drawing_area_new ();    gtk_drawing_area_size (GTK_DRAWING_AREA (drawing_area), 400, GetGameHeight ());    gtk_box_pack_start (GTK_BOX (vbox), drawing_area, TRUE, TRUE, 0);    gtk_widget_show (drawing_area);    gtk_widget_set_events (window, GDK_KEY_RELEASE_MASK);    /* --- Signals used to handle backing pixmap --- */    gtk_signal_connect (GTK_OBJECT (drawing_area), "expose_event",                (GtkSignalFunc) expose_event, NULL);    gtk_signal_connect (GTK_OBJECT (drawing_area), "configure_event",                (GtkSignalFunc) configure_event, NULL);    /* --- Focus signals --- */    gtk_signal_connect (GTK_OBJECT (window), "focus_in_event",                (GtkSignalFunc) GotFocus, NULL);    gtk_signal_connect (GTK_OBJECT (window), "focus_out_event",                (GtkSignalFunc) LostFocus, NULL);    /* --- Key press signals --- */    gtk_signal_connect (GTK_OBJECT (window), "key_press_event",                (GtkSignalFunc) KeyPress, NULL);    gtk_signal_connect (GTK_OBJECT (window), "key_release_event",                (GtkSignalFunc) KeyRelease, NULL);    /* --- Show the window --- */    gtk_widget_show (window);    /* --- Repaint every second --- */    gtk_timeout_add (100, Repaint, drawing_area);    LoadImages (window);    /* --- Call gtk-main loop --- */    gtk_main ();    return 0;}/* * GetWidthHeight * * Get the height and width of the pixmap from the xpm data. */void GetWidthHeight (gchar **xpm, int *width, int *height){		sscanf (xpm [0], "%d %d", width, height);}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?