ページ 11

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

Posted: 2016年6月23日(木) 17:16
by 028el
お世話になります。
現在C言語とGTK+を使ったパズルゲームの作成の課題に取り組んでいます。gdk_pixbuf_new_from_file()で取り込んだイメージをgdk_pixbuf_new_subpixbuf()で3x3等に分割して(何分割するかは作成者の任意です)シャッフルし、クリックで交換することによってイメージをもとに戻すというもので、完成した際には”you won the game!”と表示させます。
画像とメニューバーを表示させる部分まではなんとか作りましたが(メニューバーに関してはまだ問題ありです)、それよりも、肝心のパズルの部分ができません。お手上げです。
どうかお知恵をお貸しくださいませんでしょうか?
コードは下の通りです。少し長いです。すみません。ヘッダーファイルは追記します。

コード:

#include <gtk/gtk.h>
#include <stdlib.h>
#include "classicmenu.h"
#include "menucallbacks.h"

#define IMAGE_FILE "thecat.png"

// map actions to callbacks
const GActionEntry app_entries[] = {
	{ "restart", restart_callback, NULL, NULL, NULL },
	{ "change level", change_callback, NULL, NULL, NULL },
	{ "high score", score_callback, NULL, NULL, NULL },
	{ "quit", quit_callback, NULL, NULL, NULL },
	{ "help", help_callback, NULL, NULL, NULL }
};

static void
construct_menu (GtkApplication *app, GtkWidget *box, gpointer user_data);

static void
construct_menu (GtkApplication *app, GtkWidget *box, gpointer user_data)
{
	GtkWidget *menubar;
	GMenu *menu, *gamemenu, *helpmenu;

	widgets *a = (widgets *) user_data;

	// define keyboard accelerators
	const gchar *restart_accels[2] = { "<Ctrl>R", NULL };
	const gchar *change_accels[2] = { "<Ctrl>C", NULL };
	const gchar *quit_accels[2] = { "<Ctrl>Q", NULL };
	const gchar *help_accels[2] = { "F1", NULL };

	/* map app entries to actions using the global structure */
	g_action_map_add_action_entries (G_ACTION_MAP (app), app_entries,
					 G_N_ELEMENTS (app_entries), (gpointer) a);

	/* create the menu */
	menu = g_menu_new();
	
	/* create the game menu */
	gamemenu = g_menu_new();
	g_menu_append (gamemenu, "_Restart", "app.restart");
	g_menu_append (gamemenu, "_Change level", "app.change");
	g_menu_append (gamemenu, "_High score ...", "app.score");
	g_menu_append (gamemenu, "_Quit", "app.quit");
	g_menu_append_submenu (menu, "_Game", G_MENU_MODEL (gamemenu));
	g_object_unref (gamemenu);
	
	/* create the Help menu */
	helpmenu = g_menu_new();
	g_menu_append (helpmenu, "Help", "app.help");
	g_menu_append_submenu (menu, "_Help", G_MENU_MODEL (helpmenu));
	g_object_unref (helpmenu);
	
	/* create a menu bar and add the above menus */
	menubar = gtk_menu_bar_new_from_model (G_MENU_MODEL (menu));
	gtk_box_pack_start (GTK_BOX (box), menubar, FALSE, FALSE, 0);

	/* connect keyboard accelerators */
	gtk_application_set_accels_for_action (GTK_APPLICATION (app),
					       "app.restart", restart_accels);
	gtk_application_set_accels_for_action (GTK_APPLICATION (app),
					       "app.change", change_accels);
	gtk_application_set_accels_for_action (GTK_APPLICATION (app),
					       "app.quit", quit_accels);
	gtk_application_set_accels_for_action (GTK_APPLICATION (app),
					       "app.help", help_accels);
}


static void
activate (GtkApplication *app,
          gpointer        user_data)
{
	GtkWidget *window;
	GtkWidget *image;
	GtkWidget *box;
	GtkWidget *event;
	widgets *a = (widgets *) user_data;
	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);
		construct_menu (app, GTK_WIDGET (box), (gpointer) a);
		
		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;
}

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

Posted: 2016年6月23日(木) 17:27
by 028el
追記
ヘッダーファイルです。

menucallbacks.h

コード:

#ifndef _menucallbacks_
#define _menucallbacks_

#include <gtk/gtk.h>
//#include <gdk/gdkkeysyms.h>

void message_dialog (GSimpleAction *action, GVariant *parameter, gpointer user_data)
	{
	const gchar *name;
	GtkWidget *dialog;
	widgets *a = (widgets *) user_data;

	name = g_action_get_name (G_ACTION (action));
	dialog = gtk_message_dialog_new (GTK_WINDOW (a->window),
					 GTK_DIALOG_DESTROY_WITH_PARENT,
					 GTK_MESSAGE_INFO,
					 GTK_BUTTONS_CLOSE,
					 "Action %s was selected!",
					 name);
	g_signal_connect (dialog, "response",
			  G_CALLBACK (gtk_widget_destroy), NULL);
	gtk_widget_show (dialog);
	}

void quit_callback (GSimpleAction *action, GVariant *parameter, gpointer user_data)
	{
	widgets *a = (widgets *) user_data;
	message_dialog (action, NULL, (gpointer) a);
	g_print ("quit was clicked .../n");
	}
	
void restart_callback (GSimpleAction *action, GVariant *parameter, gpointer user_data)
	{
	widgets *a = (widgets *) user_data;
	message_dialog (action, NULL, (gpointer) a);
	g_print ("Restart was clicked .../n");
	}
	
void change_callback (GSimpleAction *action, GVariant *parameter, gpointer user_data)
	{
	widgets *a = (widgets *) user_data;
	message_dialog (action, NULL, (gpointer) a);
	g_print ("Change the level was clicked .../n");
	}
	
void score_callback (GSimpleAction *action, GVariant *parameter, gpointer user_data)
	{
	widgets *a = (widgets *) user_data;
	message_dialog (action, NULL, (gpointer) a);
	g_print ("HighScore was clicked .../n");
	}
	
void help_callback (GSimpleAction *action, GVariant *parameter, gpointer user_data)
	{
	widgets *a = (widgets *) user_data;
	message_dialog (action, NULL, (gpointer) a);
	g_print ("Help was clicked .../n");
	}

#endif

classicmenu.h

コード:

#ifndef _classicmenu_
#define _classicmenu_

#include <gtk/gtk.h>
//#include <gdk/gdkkeysys.h>

typedef struct {
			GtkApplication *app;
			GtkWidget *window;
			} widgets;
			
#endif