!!! スプライト * アニメーションで移動する画像 * 画像は矩形だが、実際に動かしたいスプライトは矩形とは限らない ** 背景を透明なものとして、ドローアブルに描く必要がある !! 静止画像の場合([[GDK2013::GdkPixbuf]]) ! はじめから背景を透明にした画像([[GDK2013::透明な画像]])を用意して、そのまま描く 8< GdkPixbuf* gdk_pixbuf_new_from_file (const char *filename, GError **error); >8 *[gdk_pixbuf_new_from_file|https://developer.gnome.org/gdk-pixbuf/2.26/gdk-pixbuf-File-Loading.html#gdk-pixbuf-new-from-file] ** 入門GTK+ 3版pdf:66(77)ページ 8< int gdk_pixbuf_get_width (const GdkPixbuf *pixbuf); >8 *[gdk_pixbuf_get_width|https://developer.gnome.org/gdk-pixbuf/2.26/gdk-pixbuf-The-GdkPixbuf-Structure.html#gdk-pixbuf-get-width] ** 入門GTK+ 3版pdf:68(80)ページ 8< int gdk_pixbuf_get_height (const GdkPixbuf *pixbuf); >8 *[gdk_pixbuf_get_height|https://developer.gnome.org/gdk-pixbuf/2.26/gdk-pixbuf-The-GdkPixbuf-Structure.html#gdk-pixbuf-get-height] ** 入門GTK+ 3版pdf:68(80)ページ 8< void gdk_cairo_set_source_pixbuf (cairo_t *cr, const GdkPixbuf *pixbuf, double pixbuf_x, double pixbuf_y); >8 * [gdk_cairo_set_source_pixbuf|https://developer.gnome.org/gdk2/2.24/gdk2-Cairo-Interaction.html#gdk-cairo-set-source-pixbuf] ** 入門GTK+ 3版pdf:99(111)ページ ! テニスボールをスプライトとして描画 * my_animation_ball関数 8< /* ボールの画像からスプライト用ピクスバッファを作成する */ anime->s_pixbuf = gdk_pixbuf_new_from_file("tennis.png", NULL); /* スプライトの幅と高さを得る */ anime->s_width = gdk_pixbuf_get_width(anime->s_pixbuf); anime->s_height = gdk_pixbuf_get_height(anime->s_pixbuf); >8 * draw_sprite関数 8< /* スプライト用ピクスバッファをドローイングエリアに描く */ /* スプライトをソースの指定された座標にセット */ gdk_cairo_set_source_pixbuf(cr, s_pixbuf, anime->x, anime->y); cairo_paint(cr); >8 ! 背景を一色で塗りつぶした画像を用意して、その色を透明と設定して描く 8< GdkPixbuf* gdk_pixbuf_add_alpha (const GdkPixbuf *pixbuf, gboolean substitute_color, guchar r, guchar g, guchar b); >8 *[gdk_pixbuf_add_alpha|https://developer.gnome.org/gdk-pixbuf/2.26/gdk-pixbuf-Utilities.html#gdk-pixbuf-add-alpha] !! アニメーション画像の場合 ! はじめからアニメーション画像を用意 8< GdkPixbufAnimation* gdk_pixbuf_animation_new_from_file (const char *filename, GError **error); >8 *[gdk_pixbuf_animation_new_from_file|https://developer.gnome.org/gdk-pixbuf/2.26/gdk-pixbuf-Animations.html#gdk-pixbuf-animation-new-from-file] 8< GdkPixbufAnimationIter* gdk_pixbuf_animation_get_iter (GdkPixbufAnimation *animation, const GTimeVal *start_time); >8 *[gdk_pixbuf_animation_get_iter|https://developer.gnome.org/gdk-pixbuf/2.26/gdk-pixbuf-Animations.html#gdk-pixbuf-animation-get-iter] 8< GdkPixbuf* gdk_pixbuf_animation_iter_get_pixbuf (GdkPixbufAnimationIter *iter); >8 *[gdk_pixbuf_animation_iter_get_pixbuf|https://developer.gnome.org/gdk-pixbuf/2.26/gdk-pixbuf-Animations.html#gdk-pixbuf-animation-iter-get-pixbuf] 8< int gdk_pixbuf_animation_iter_get_delay_time (GdkPixbufAnimationIter *iter); >8 *[gdk_pixbuf_animation_iter_get_delay_time|https://developer.gnome.org/gdk-pixbuf/2.26/gdk-pixbuf-Animations.html#gdk-pixbuf-animation-iter-get-delay-time] 8< gboolean gdk_pixbuf_animation_iter_advance (GdkPixbufAnimationIter *iter, const GTimeVal *current_time); >8 *[gdk_pixbuf_animation_iter_advance|https://developer.gnome.org/gdk-pixbuf/2.26/gdk-pixbuf-Animations.html#gdk-pixbuf-animation-iter-advance] 8< int gdk_pixbuf_animation_get_width (GdkPixbufAnimation *animation); >8 *[gdk_pixbuf_animation_get_width|https://developer.gnome.org/gdk-pixbuf/2.26/gdk-pixbuf-Animations.html#gdk-pixbuf-animation-get-width] 8< int gdk_pixbuf_animation_get_height (GdkPixbufAnimation *animation); >8 *[gdk_pixbuf_animation_get_height|https://developer.gnome.org/gdk-pixbuf/2.26/gdk-pixbuf-Animations.html#gdk-pixbuf-animation-get-height] ! まわる地球をスプライトとして描画 * my_animation_earth関数 8< /* アニメーション画像をスプライトとして読み込む */ read_anim(anime, "earth.gif"); /* 必要な時間間隔でスプライト更新と再描画 */ anime->s_timeout = g_timeout_add(gdk_pixbuf_animation_iter_get_delay_time(anime->iter), (GSourceFunc)update_sprite, (gpointer)anime); >8 * read_anim関数 8< /* アニメーション画像をからPixbufAnimationを作成 */ anim = gdk_pixbuf_animation_new_from_file(filename, NULL); /* PixbufAnimationからイテレータ(ポインタみたいなもの)を作成 */ anime->iter = iter = gdk_pixbuf_animation_get_iter(anim, NULL); /* アニメーション画像の一枚目をスプライト用ピクスバッファにコピー */ anime->s_pixbuf = gdk_pixbuf_animation_iter_get_pixbuf(iter); >8 * update_sprite関数 8< /* スプライトの画像を更新する必要があるかチェック */ if(gdk_pixbuf_animation_iter_advance(anime->iter, NULL)) { /* 更新の必要があったら */ /* 新しいスプライトの画像をスプライト用ピクスバッファにコピー */ anime->s_pixbuf = gdk_pixbuf_animation_iter_get_pixbuf(anime->iter); /* ドローイングエリアを更新 */ draw_animation(anime); } >8 ! バラバラの画像からGdkPixbufSimpleAnimを作成 8< GdkPixbufSimpleAnim* gdk_pixbuf_simple_anim_new (gint width, gint height, gfloat rate); >8 *[gdk_pixbuf_simple_anim_new|https://developer.gnome.org/gdk-pixbuf/2.26/gdk-pixbuf-Animations.html#gdk-pixbuf-simple-anim-new] 8< void gdk_pixbuf_simple_anim_add_frame (GdkPixbufSimpleAnim *animation, GdkPixbuf *pixbuf); >8 *[gdk_pixbuf_simple_anim_add_frame|https://developer.gnome.org/gdk-pixbuf/2.26/gdk-pixbuf-Animations.html#gdk-pixbuf-simple-anim-add-frame] ! 歩くキャラクターをスプライトとして描画 * my_animation_chara関数 8< /* 歩行パターン画像をスプライトとして読み込む */ make_anim(anime); /* 必要な時間間隔でスプライト更新と再描画 */ anime->s_timeout = g_timeout_add(gdk_pixbuf_animation_iter_get_delay_time(anime->iter), (GSourceFunc)update_sprite, (gpointer)anime); >8 * make_anim関数 8< /* 歩行パターン画像からPixbufAnimationを作成 */ /* 歩行パターン画像を読み込む */ pixbuf = gdk_pixbuf_new_from_file_at_scale("majo.png", CHARA_SIZE * 3, -1, TRUE, NULL); /* 空のPixbufSimpleAnimを作成(秒あたり4コマに設定) */ simple_anim = gdk_pixbuf_simple_anim_new(CHARA_SIZE, CHARA_SIZE, 4.0); /* 作成したPixbufSimpleAnimはループ */ gdk_pixbuf_simple_anim_set_loop(simple_anim, TRUE); /* 横に3パターン縦に4パターン並んでいるので切り分けるが 横の2パターン目は2度使う&回転するように縦の読み込み順を変えている */ for(j = 0; j < 4; j++) { for(i = 0; i < 4; i++) { /* 空のPixbufを作成(1パターン分) */ w_pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE, 8, CHARA_SIZE, CHARA_SIZE); /* 画像の端から順に作成したPixbufにコピー */ gdk_pixbuf_copy_area(pixbuf, x[i] * CHARA_SIZE, y[j] * CHARA_SIZE, CHARA_SIZE, CHARA_SIZE, w_pixbuf, 0, 0); /* PixbufをPixbufSimpleAnimに追加(アニメーションに追加) */ gdk_pixbuf_simple_anim_add_frame(simple_anim, w_pixbuf); /* 使い終わったPixbufを破棄 */ g_object_unref(w_pixbuf); } } /* 使い終わったPixbufを破棄 */ g_object_unref(pixbuf); /* PixbufSimpleAnimをPixbufAnimationに変換 */ anim = (GdkPixbufAnimation *)simple_anim; >8 * update_sprite関数 8< /* スプライトの画像を更新する必要があるかチェック */ if(gdk_pixbuf_animation_iter_advance(anime->iter, NULL)) { /* 更新の必要があったら */ /* 新しいスプライトの画像をスプライト用ピクスバッファにコピー */ anime->s_pixbuf = gdk_pixbuf_animation_iter_get_pixbuf(anime->iter); /* ドローイングエリアを更新 */ draw_animation(anime); } >8