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 ; /* 指定された時間が過ぎていたら戻る */ } }


プログラムができたら、コンパイルして実行してみましょう。

maruyama@wakhok.ac.jp
1995年02月01日 (水) 00時21分18秒 JST