ソフトウェア設計及び演習2017

GDK2017::スプライト

スプライト

  • アニメーションで移動する画像
  • 画像は矩形だが、実際に動かしたいスプライトは矩形とは限らない
    • 背景を透明なものとして、ドローアブルに描く必要がある

静止画像の場合(GDK2017::GdkPixbuf

はじめから背景を透明にした画像(GDK2017::透明な画像)を用意して、そのまま描く
GdkPixbuf* gdk_pixbuf_new_from_file (const char *filename, 
                                     GError **error);
int gdk_pixbuf_get_width (const GdkPixbuf *pixbuf);
int gdk_pixbuf_get_height (const GdkPixbuf *pixbuf);
void gdk_cairo_set_source_pixbuf (cairo_t *cr,
                                  const GdkPixbuf *pixbuf,
                                  double pixbuf_x,
                                  double pixbuf_y);
テニスボールをスプライトとして描画
  • my_animation_ball関数
/* ボールの画像からスプライト用ピクスバッファを作成する */
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);
  • draw_sprite関数
/* スプライト用ピクスバッファをドローイングエリアに描く */
/* スプライトをソースの指定された座標にセット */
gdk_cairo_set_source_pixbuf(cr, s_pixbuf, anime->x, anime->y);
cairo_paint(cr);
背景を一色で塗りつぶした画像を用意して、その色を透明と設定して描く
GdkPixbuf* gdk_pixbuf_add_alpha (const GdkPixbuf *pixbuf,
                                 gboolean substitute_color,
                                 guchar r, guchar g, guchar b);

アニメーション画像の場合

はじめからアニメーション画像を用意
GdkPixbufAnimation*
gdk_pixbuf_animation_new_from_file (const char *filename,
                                    GError **error);
GdkPixbufAnimationIter*
gdk_pixbuf_animation_get_iter (GdkPixbufAnimation *animation,
                               const GTimeVal *start_time);
GdkPixbuf*
gdk_pixbuf_animation_iter_get_pixbuf (GdkPixbufAnimationIter *iter);
int gdk_pixbuf_animation_iter_get_delay_time (GdkPixbufAnimationIter *iter);
gboolean
gdk_pixbuf_animation_iter_advance (GdkPixbufAnimationIter *iter,
                                   const GTimeVal *current_time);
int gdk_pixbuf_animation_get_width (GdkPixbufAnimation *animation);
int gdk_pixbuf_animation_get_height (GdkPixbufAnimation *animation);
まわる地球をスプライトとして描画
  • my_animation_earth関数
/* アニメーション画像をスプライトとして読み込む */
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);
  • read_anim関数
/* アニメーション画像をから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);
  • update_sprite関数
/* スプライトの画像を更新する必要があるかチェック */
if(gdk_pixbuf_animation_iter_advance(anime->iter, NULL)) {
  /* 更新の必要があったら */
  /* 新しいスプライトの画像をスプライト用ピクスバッファにコピー */
  anime->s_pixbuf = gdk_pixbuf_animation_iter_get_pixbuf(anime->iter);

  /* ドローイングエリアを更新 */
  draw_animation(anime);
}
バラバラの画像からGdkPixbufSimpleAnimを作成
GdkPixbufSimpleAnim*
gdk_pixbuf_simple_anim_new (gint width,
                            gint height,
                            gfloat rate);
void gdk_pixbuf_simple_anim_add_frame (GdkPixbufSimpleAnim *animation,
                                       GdkPixbuf *pixbuf);
void gdk_pixbuf_simple_anim_set_loop (GdkPixbufSimpleAnim *animation,
                                      gboolean loop);
歩くキャラクターをスプライトとして描画
  • my_animation_chara関数
/* 歩行パターン画像をスプライトとして読み込む */
make_anim(anime);
/* 必要な時間間隔でスプライト更新と再描画 */
anime->s_timeout = g_timeout_add(gdk_pixbuf_animation_iter_get_delay_time(anime->iter),
                                 (GSourceFunc)update_sprite,
                                 (gpointer)anime);
  • make_anim関数
/* 歩行パターン画像から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;
  • update_sprite関数
/* スプライトの画像を更新する必要があるかチェック */
if(gdk_pixbuf_animation_iter_advance(anime->iter, NULL)) {
  /* 更新の必要があったら */
  /* 新しいスプライトの画像をスプライト用ピクスバッファにコピー */
  anime->s_pixbuf = gdk_pixbuf_animation_iter_get_pixbuf(anime->iter);

  /* ドローイングエリアを更新 */
  draw_animation(anime);
}


最終更新日:2017/04/28 15:08:53