Previous: 準備
Up: Xウィンドウ実習
第9回 応用編 アニメーションを作る
Previous Page: 準備
Next Page: Xウィンドウ概論
第10回 ウィンドウ + ネットワーク = X
先生が用意したビットマップデータを元にして
アニメーションのプログラムを作ります。
ここでは7枚のピクスマップを生成し、
マウスの左ボタンがクリックされた時に
アニメーションを呼び出します。
プログラムの最後にあるのが、時間間隔をコントロールするための
関数 timer() です。
(ソース・ファイル名は、pao.c としてください。)
pao .c
#include<stdio.h> #include<sys/time.h> #include<X11/Xlib.h> #include "anime0" #include "anime1" #include "anime2" #include "anime3" #include "anime4" #include "anime5" #include "anime6" #define PIX_NUM 7 /* ピクスマップの枚数 */ #define REPEAT 5 /* 動作の繰り返し回数 */void timer( int ); /* タイマーの関数の宣言 */
main() { Display *dsp; Window win; Pixmap pix[PIX_NUM]; GC gc; XEvent eve; static char *win_name = "PaoPao"; int i, j;
dsp = XOpenDisplay( NULL );
win = XCreateSimpleWindow( dsp, DefaultRootWindow(dsp), 0, 0, 100, 100, 2, BlackPixel(dsp,0), WhitePixel(dsp,0) ); pix[0] = XCreatePixmapFromBitmapData( dsp, win, anime0_bits, anime0_width, anime0_height, BlackPixel(dsp,0), WhitePixel(dsp,0), 8 ); pix[1] = XCreatePixmapFromBitmapData( dsp, win, anime1_bits, anime1_width, anime1_height, BlackPixel(dsp,0), WhitePixel(dsp,0), 8 ); pix[2] = XCreatePixmapFromBitmapData( dsp, win, anime2_bits, anime2_width, anime2_height, BlackPixel(dsp,0), WhitePixel(dsp,0), 8 ); pix[3] = XCreatePixmapFromBitmapData( dsp, win, anime3_bits, anime3_width, anime3_height, BlackPixel(dsp,0), WhitePixel(dsp,0), 8 ); pix[4] = XCreatePixmapFromBitmapData( dsp, win, anime4_bits, anime4_width, anime4_height, BlackPixel(dsp,0), WhitePixel(dsp,0), 8 ); pix[5] = XCreatePixmapFromBitmapData( dsp, win, anime5_bits, anime5_width, anime5_height, BlackPixel(dsp,0), WhitePixel(dsp,0), 8 ); pix[6] = XCreatePixmapFromBitmapData( dsp, win, anime6_bits, anime6_width, anime6_height, BlackPixel(dsp,0), WhitePixel(dsp,0), 8 );
gc = XCreateGC( dsp, win, NULL, NULL );
XStoreName( dsp, win, win_name );
XSelectInput( dsp, win, ButtonPressMask | ExposureMask );
XMapWindow( dsp, win ); XFlush( dsp );
while( True ) { XNextEvent( dsp, &eve ); switch( eve.type ) { case ButtonPress : switch( eve.xbutton.button ) { case 1: for( j=0 ; j<REPEAT ; j++ ) /* 同じ動作を繰り返す */ for( i=0 ; i<PIX_NUM ; i++ ) /* 一コマずつ絵を描く */ { XCopyArea( dsp, pix[i], win, gc, 0, 0, anime0_width, anime0_height, 16, 25 ); XFlush( dsp ); timer( 150000 ); /* 一時停止(0.15秒間) */ } break; case 3: XCloseDisplay( dsp ); /* 右ボタンが押されたら終了 */ exit(0); default: break; } break; case Expose : /* プログラム起動時に一コマ目の絵を表示する */ XCopyArea( dsp, pix[0], win, gc, 0, 0, anime0_width, anime0_height, 16, 25 ); XFlush( dsp ); break; default: break; } } }
/* タイマーの関数の本体 停止時間はマイクロ秒単位 */
void timer( int interval ) { struct timeval old_time, new_time; /* 時刻を記憶する構造体 */
gettimeofday( &old_time, NULL ); /* 時刻を調べるシステムコール */ while( True ) { gettimeofday( &new_time, NULL ); /* 時刻を調べるシステムコール */ if( new_time.tv_sec > old_time.tv_sec ) new_time.tv_usec += 1000000; if( new_time.tv_usec - old_time.tv_usec > interval ) return ; /* 指定された時間が過ぎていたら戻る */ } }
プログラムができたら、コンパイルして実行してみましょう。