改訂 GTK+とC言語を使ったパズルゲーム

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
028el
記事: 17
登録日時: 9年前

改訂 GTK+とC言語を使ったパズルゲーム

#1

投稿記事 by 028el » 9年前

数日前に表題の件でお伺いを立てさせていただいた者です。同じ件ですがコードを必要な部分だけに削りました。どなた様かお知恵をお貸しくださいましたら幸いです。
GTK+とC言語を使ったパズルゲーム作成の課題です。3x3等(製作者の任意)に分割したイメージをシャッフルして表示させ、クリックで交換しながら分割前のイメージに戻すというものです。イメージを取り込み表示させるまではできましたが、gdk_pixbuf_new_subpixbuf()を使って分割したイメージを配列に格納して・・・というヒントが与えられているにも関わらず、パズルを作成するにはどうしたらいいのか分かりません。とても難しいです。イメージはなんでも構わないのですが、とりあえず使ったものを添付いたします。

コード:

#include <gtk/gtk.h>
#include <stdlib.h>

#define IMAGE_FILE "thecat.png"


static void
activate (GtkApplication *app,
          gpointer        user_data)
{
	GtkWidget *window;
	GtkWidget *image;
	GtkWidget *box;
	GtkWidget *event;
	GdkPixbuf *pixbuf;
	GError    *error = NULL;
	
	/* load the image from a file */
	pixbuf = gdk_pixbuf_new_from_file (IMAGE_FILE, &error);
	
	/* create a window with title etc. */
	window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
	gtk_window_set_application (GTK_WINDOW (window), GTK_APPLICATION(app));
	gtk_window_set_resizable (GTK_WINDOW (window), FALSE);
	gtk_window_set_position (GTK_WINDOW (window), GTK_WIN_POS_CENTER);
	gtk_window_set_title (GTK_WINDOW (window), "Puzzlegame"); 
	gtk_window_set_default_size (GTK_WINDOW (window), 500, 500);
	
	box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
	
	if (!pixbuf) 
	{
		g_print ("error->core : %d\n", error->code);    
		g_print ("error->message :\n %s\n", error->message);
	} 
	else 
	{
		g_print ("%d x %d, %d\n",
			gdk_pixbuf_get_width (pixbuf),
			gdk_pixbuf_get_height (pixbuf),
			gdk_pixbuf_get_rowstride (pixbuf));

		image = gtk_image_new_from_pixbuf(pixbuf);
		
		gtk_container_add (GTK_CONTAINER (window), box);
		
		event = gtk_event_box_new();
		gtk_box_pack_start (GTK_BOX (box), event, TRUE, TRUE, 10);
		gtk_container_add (GTK_CONTAINER (event), image);
		
		gtk_widget_show_all (window);

		gtk_main ();

	}
}

int
main (int argc, char **argv)
{
	GtkApplication *app;
	int status;
	app = gtk_application_new (NULL, G_APPLICATION_FLAGS_NONE);
	g_signal_connect (app, "activate", G_CALLBACK (activate), NULL);
	status = g_application_run (G_APPLICATION (app), argc, argv);
	g_object_unref (app);

	return status;
}

添付ファイル
thecat.png

f8

Re: 改訂 GTK+とC言語を使ったパズルゲーム

#2

投稿記事 by f8 » 9年前

028el さんが書きました:イメージを取り込み表示させるまではできましたが、gdk_pixbuf_new_subpixbuf()を使って分割したイメージを配列に格納して・・・というヒントが与えられているにも関わらず、パズルを作成するにはどうしたらいいのか分かりません。
GTK+は使ったことないので参考程度にお願いします。
まずは読み込んだイメージを9分割して保持するところまでにしますか。

図を貼りたかったけどやり方不明。(^_^;

コード:

┌───┬───┬───┐
│id=0  │id=1  │id=2  │
│      │      │      │
├───┼───┼───┤
│id=3  │id=4  │id=5  │
│      │      │      │
├───┼───┼───┤
│id=6  │id=7  │id=8  │
│      │      │      │
└───┴───┴───┘

読み込んだイメージを9分割してそれぞれのピースにidを付けます。

データを保持するための構造体を以下のような感じで。

typedef struct {
  int id;
  GdkPixbuf* pixbuf;
} PUZZLE_PIECE;

PUZZLE_PIECE pieces[9];

gdk_pixbuf_new_subpixbuf()ですが、プロトタイプによるとこんな感じで画像の一部を切出せそうなんですが…。

コード:

//プロトタイプ
//GdkPixbuf*  gdk_pixbuf_new_subpixbuf ( GdkPixbuf* pixbuf, gint src_x, gint src_y, gint width,  gint height );

//使用例
GdkPixbuf* piece = gdk_pixbuf_new_subpixbuf ( pixbuf, 1, 1, 200, 100 );

028el
記事: 17
登録日時: 9年前

Re: 改訂 GTK+とC言語を使ったパズルゲーム

#3

投稿記事 by 028el » 9年前

f8さま

返信ありがとうございます。
絶望的な気分でしたがまたやる気が出ました。
ご教示いただいた点を参考にさせていただき、もう少し頑張ってみます。

028el
記事: 17
登録日時: 9年前

Re: 改訂 GTK+とC言語を使ったパズルゲーム

#4

投稿記事 by 028el » 9年前

たびたび失礼します。
未だに同じ課題で四苦八苦しております。
2x2に分割した画像データを2次元配列に格納して表示させるまでなんとかこぎつけました。
少しうれしいのでご報告いたします。(低レベルですみません・・・)
次のステップで、パネルをシャッフルしてパズルに仕立て上げなければなりませんが、実際のところどのように書いていいのか分かりません。
再びどなた様かお知恵をお貸しくださいましたらありがたいです。

コード:


#include <gtk/gtk.h>
#include <stdlib.h>

#define IMAGE_FILE "thecat.png"

//globals
GtkWidget *panel1, *panel2, *panel3, *panel4;

static void
activate (GtkApplication *app,
          gpointer        user_data)
{
	GtkWidget *window;
	GtkWidget *grid;
	GdkPixbuf *pixbuf;
	GdkPixbuf *images[2][2];
	GError    *error = NULL;
	
	/* load the image from a file */
	pixbuf = gdk_pixbuf_new_from_file (IMAGE_FILE, &error);
	
	/* create divided images from original pixbuf */
	images[0][0] = gdk_pixbuf_new_subpixbuf(pixbuf,0,0,150,150);
	images[0][1] = gdk_pixbuf_new_subpixbuf(pixbuf,150,0,150,150);
	images[1][0] = gdk_pixbuf_new_subpixbuf(pixbuf,0,150,150,150);
	images[1][1] = gdk_pixbuf_new_subpixbuf(pixbuf,150,150,150,150); 
	
	/* create a window with title etc. */
	window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
	gtk_window_set_application (GTK_WINDOW (window), GTK_APPLICATION(app));
	gtk_window_set_resizable (GTK_WINDOW (window), FALSE);
	gtk_window_set_position (GTK_WINDOW (window), GTK_WIN_POS_CENTER);
	gtk_window_set_default_icon_from_file("thecat.png", NULL);
	gtk_window_set_title (GTK_WINDOW (window), "Puzzlegame"); 
	gtk_window_set_default_size (GTK_WINDOW (window), 400, 400);
	
	/* create a grid to be used as layout container */
	grid = gtk_grid_new();
	gtk_container_add (GTK_CONTAINER (window), grid);
	
	panel1 = gtk_image_new_from_pixbuf(images[0][0]);
	gtk_grid_attach(GTK_GRID(grid),panel1, 0,0,1,1);
	panel2 = gtk_image_new_from_pixbuf(images[0][1]);
	gtk_grid_attach(GTK_GRID(grid),panel2, 1,0,1,1);
	panel3 = gtk_image_new_from_pixbuf(images[1][0]);
	gtk_grid_attach(GTK_GRID(grid),panel3, 0,1,1,1);
	panel4 = gtk_image_new_from_pixbuf(images[1][1]);
	gtk_grid_attach(GTK_GRID(grid),panel4, 1,1,1,1);
			
	gtk_widget_show_all (window);

	gtk_main ();

}

int
main (int argc, char **argv)
{
	GtkApplication *app;
	int status;
	app = gtk_application_new (NULL, G_APPLICATION_FLAGS_NONE);
	g_signal_connect (app, "activate", G_CALLBACK (activate), NULL);
	status = g_application_run (G_APPLICATION (app), argc, argv);
	g_object_unref (app);

	return status;
}

添付ファイル
thecat.png
thecat.png (170.03 KiB) 閲覧数: 3128 回

f8

Re: 改訂 GTK+とC言語を使ったパズルゲーム

#5

投稿記事 by f8 » 9年前

028el さんが書きました: 次のステップで、パネルをシャッフルしてパズルに仕立て上げなければなりませんが、実際のところどのように書いていいのか分かりません。
ざっくりですが。(^_^;

コード:

1.最初に完成形を表示
┌─┬─┬─┐
│ 1│ 2│ 3│
├─┼─┼─┤
│ 4│ 5│ 6│
├─┼─┼─┤
│ 7│ 8│ 9│
└─┴─┴─┘

2.「ゲーム開始」で9番のピースを抜いて1~8番のピースをシャッフルして表示
┌─┬─┬─┐
│ 4│ 3│ 8│
├─┼─┼─┤
│ 7│ 6│ 1│
├─┼─┼─┤
│ 2│ 5│  │
└─┴─┴─┘
  この状態で移動可能なピースは1番と5番
  例えば1番のピースを移動すると
┌─┬─┬─┐
│ 4│ 3│ 8│
├─┼─┼─┤
│ 7│ 6│  │
├─┼─┼─┤
│ 2│ 5│ 1│
└─┴─┴─┘
  この状態で移動可能なピースは1,6,8番

3.ピースの移動を繰り返しパズルを完成させる
  (以下の状態になったら完成、つまりピースを移動するごとに完成状態か判定する)
┌─┬─┬─┐
│ 1│ 2│ 3│
├─┼─┼─┤
│ 4│ 5│ 6│
├─┼─┼─┤
│ 7│ 8│  │
└─┴─┴─┘

4.最初に抜いておいた9番のピースを表示(「おめでとう」的なメッセージも表示)して終了
┌─┬─┬─┐
│ 1│ 2│ 3│
├─┼─┼─┤
│ 4│ 5│ 6│
├─┼─┼─┤
│ 7│ 8│ 9│
└─┴─┴─┘
で、これを実装するためにデータ構造やらを考える必要があるわけです。
どういう風にデータを持っていればシャッフルしたり完成の判定ができるかなーと。

メニューが選択された、マウスがクリックされた等のイベントハンドラについても学習されていると思いますのでそれらを駆使して実装します。

028el
記事: 17
登録日時: 9年前

Re: 改訂 GTK+とC言語を使ったパズルゲーム

#6

投稿記事 by 028el » 9年前

f8 さま

返信ありがとうございます。
道のりはまだまだ遠そうですが、
ご教示いただいた点を再び参考にさせていただきます。
一人でやっているのはなかなか辛いので、
このようにアドヴァイスいただけるととてもありがたいです。

閉鎖

“C言語何でも質問掲示板” へ戻る