/** animation.c **/ #include #include static struct ballStruct { double x; double y; double xVelocity; double yVelocity; } ball[5]; gint eventDelete(GtkWidget *widget, GdkEvent *event,gpointer data); gint eventDestroy(GtkWidget *widget, GdkEvent *event,gpointer data); gint nextFrame(gpointer data); void newBall(struct ballStruct *b); void nextBall(struct ballStruct *b); gint nextFrame(gpointer data); #define WIDTH 400 #define HEIGHT 300 #define GRAVITY 0.8 #define RADIUS 5 #define DIAMETER (RADIUS * 2) #define INTERVAL 30 int main(int argc,char *argv[]) { int i; GtkWidget *app; GtkWidget *area; gnome_init("animation","1.0",argc,argv); app = gnome_app_new("animation", "Drawing Area Animation"); gtk_container_set_border_width(GTK_CONTAINER(app),20); gtk_signal_connect(GTK_OBJECT(app),"delete_event", GTK_SIGNAL_FUNC(eventDelete),NULL); gtk_signal_connect(GTK_OBJECT(app),"destroy", GTK_SIGNAL_FUNC(eventDestroy),NULL); area = gtk_drawing_area_new(); gtk_widget_set_usize(area,WIDTH,HEIGHT); gnome_app_set_contents(GNOME_APP(app),area); gtk_timeout_add(INTERVAL,nextFrame,area); for(i=0; i<5; i++) newBall(&ball[i]); gtk_widget_show_all(app); gtk_main(); exit(0); } gint nextFrame(gpointer data) { int i; static GdkPixmap *pixmap = NULL; GtkWidget *widget = (GtkWidget *)data; if(pixmap == NULL) { pixmap = gdk_pixmap_new(widget->window, WIDTH,HEIGHT,-1); } gdk_draw_rectangle(pixmap, widget->style->white_gc, TRUE, 0,0, WIDTH,HEIGHT); for(i=0; i<5; i++) { nextBall(&ball[i]); gdk_draw_arc(pixmap, widget->style->black_gc, TRUE, (int)ball[i].x,(int)ball[i].y, DIAMETER,DIAMETER, 0,360*64); } gdk_draw_pixmap(widget->window, widget->style->black_gc, pixmap, 0,0, 0,0, WIDTH,HEIGHT); return(TRUE); } void newBall(struct ballStruct *b) { b->x = (((double)rand()*WIDTH)/RAND_MAX); b->y = (((double)rand()*HEIGHT)/RAND_MAX) - HEIGHT; do { b->xVelocity = (((double)rand()*10)/RAND_MAX) - 5; b->yVelocity = (((double)rand()*10)/RAND_MAX) - 5; } while(fabs(b->xVelocity) < 0.5); } void nextBall(struct ballStruct *b) { if((b->x < -DIAMETER) || (b->x > WIDTH)) { newBall(b); return; } if((b->y + DIAMETER) >= HEIGHT) { if(b->yVelocity > 0) b->yVelocity = -b->yVelocity; b->yVelocity *= 0.9; } else { b->yVelocity += GRAVITY; } b->x += b->xVelocity; b->y += b->yVelocity; } gint eventDelete(GtkWidget *widget, GdkEvent *event,gpointer data) { return(FALSE); } gint eventDestroy(GtkWidget *widget, GdkEvent *event,gpointer data) { gtk_main_quit(); return(0); }