改写gtk4-demo的例子程序sliding_puzzle拼图游戏

改写gtk4-demo的例子程序sliding_puzzle拼图游戏

在openSUSE-Leap-15.6-DVD-x86_64中改写gtk4-demo的例子程序sliding_puzzle拼图游戏

一、安装gtk4-demo

应用程序------工具------终端

ruhong@localhost:~> su -

密码:

localhost:~ # zypper install gtk4-devel-4.12.4-150600.1.5.x86_64 gtk4-devel-tools-4.12.4-150600.1.5.x86_64

从普通用户ruhong切换到root用户安装gtk4图形工具包

应用程序------编程------GTK Demo

双击sliding puzzle运行程序使用鼠标点击就可以开始游戏了,单击右上角的齿轮图标------选择图片------单击加号图标,将图片切割成3X3、4X4或者5X5------apply开始游戏,单击左上角是重新开始游戏,当你完成拼图后会自动补上最后缺失的小图片并响一声。

二、改写source.c

应用程序------工具------终端,不用切换到root,保持普通用户即可

ruhong@localhost:~> mkdir sliding_puzzle

ruhong@localhost:~> cd sliding_puzzle

ruhong@localhost:~/sliding_puzzle> touch source.c puzzlepiece.c puzzlepiece.h

ruhong@localhost:~/sliding_puzzle> gedit puzzlepiece.h

ruhong@localhost:~/sliding_puzzle> gedit puzzlepiece.c

使用文本编辑器gedit打开puzzlepiece.h,单击puzzlepiece.h标签卡,复制GTK Demo中puzzlepiece.h的代码内容,保持原样保存,不用修改,对于puzzlepiece.c也是同样操作

ruhong@localhost:~/sliding_puzzle> gedit source.c

使用文本编辑器gedit打开source.c,复制以下提供修改过的内容

c 复制代码
/*
Sliding Puzzle
This demo demonstrates how to use gestures and paintables to create a small sliding puzzle game.
*/

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

/* Include the header for the puzzle piece */
#include "puzzlepiece.h"
/* #include "paintable.h" */


static GtkWidget *window = NULL;
static GtkWidget *frame = NULL;
static GtkWidget *choices = NULL;
static GtkWidget *size_spin = NULL;
static GdkPaintable *puzzle = NULL;
static GdkPaintable *puzzle02 = NULL;
static GdkPaintable *puzzle03 = NULL;

static gboolean solved = TRUE;
static guint width = 3;
static guint height = 3;
static guint pos_x;
static guint pos_y;

static void
ended (GObject *object)
{
	g_object_unref (object);
}

static void
celebrate (gboolean win)
{
	GtkMediaStream *stream;

	if (win)
	stream = gtk_media_file_new_for_filename ("/home/ruhong/sliding_puzzle/complete.oga");
	gtk_media_stream_set_volume (stream, 1.0);
	gtk_media_stream_play (stream);

	g_signal_connect( stream, "notify::ended", G_CALLBACK( ended ), NULL );
}

static gboolean
move_puzzle (GtkWidget *grid,
             int        dx,
             int        dy)
{
  GtkWidget *pos, *next;
  GdkPaintable *piece;
  guint next_x, next_y;

  /* We don't move anything if the puzzle is solved */
  if (solved)
    return FALSE;

  /* Return FALSE if we can't move to where the call
   * wants us to move.
   */
  if ((dx < 0 && pos_x < -dx) ||
      dx + pos_x >= width ||
      (dy < 0 && pos_y < -dy) ||
      dy + pos_y >= height)
    return FALSE;

  /* Compute the new position */
  next_x = pos_x + dx;
  next_y = pos_y + dy;

  /* Get the current and next image */
  pos = gtk_grid_get_child_at (GTK_GRID (grid), pos_x, pos_y);
  next = gtk_grid_get_child_at (GTK_GRID (grid), next_x, next_y);

  /* Move the displayed piece. */
  piece = gtk_picture_get_paintable (GTK_PICTURE (next));
  gtk_picture_set_paintable (GTK_PICTURE (pos), piece);
  gtk_picture_set_paintable (GTK_PICTURE (next), NULL);

  /* Update the current position */
  pos_x = next_x;
  pos_y = next_y;

  /* Return TRUE because we successfully moved the piece */
  return TRUE;
}

static void
shuffle_puzzle (GtkWidget *grid)
{
  guint i, n_steps;

  /* Do this many random moves */
  n_steps = width * height * 50;

  for (i = 0; i < n_steps; i++)
    {
      /* Get a random number for the direction to move in */
      switch (g_random_int_range (0, 4))
        {
        case 0:
          /* left */
          move_puzzle (grid, -1, 0);
          break;

        case 1:
          /* up */
          move_puzzle (grid, 0, -1);
          break;

        case 2:
          /* right */
          move_puzzle (grid, 1, 0);
          break;

        case 3:
          /* down */
          move_puzzle (grid, 0, 1);
          break;

        default:
          g_assert_not_reached ();
          continue;
        }
    }
}

static gboolean
check_solved (GtkWidget *grid)
{
  GtkWidget *picture;
  GdkPaintable *piece;
  guint x, y;

  /* Nothing to check if the puzzle is already solved */
  if (solved)
    return TRUE;

  /* If the empty cell isn't in the bottom right,
   * the puzzle is obviously not solved */
  if (pos_x != width - 1 ||
      pos_y != height - 1)
    return FALSE;

  /* Check that all pieces are in the right position */
  for (y = 0; y < height; y++)
    {
      for (x = 0; x < width; x++)
        {
          picture = gtk_grid_get_child_at (GTK_GRID (grid), x, y);
          piece = gtk_picture_get_paintable (GTK_PICTURE (picture));

          /* empty cell */
          if (piece == NULL)
            continue;

          if (gtk_puzzle_piece_get_x (GTK_PUZZLE_PIECE (piece)) != x ||
              gtk_puzzle_piece_get_y (GTK_PUZZLE_PIECE (piece)) != y)
            return FALSE;
        }
    }

  /* We solved the puzzle!
   */
  solved = TRUE;

  /* Fill the empty cell to show that we're done.
   */
  picture = gtk_grid_get_child_at (GTK_GRID (grid), 0, 0);
  piece = gtk_picture_get_paintable (GTK_PICTURE (picture));

  piece = gtk_puzzle_piece_new (gtk_puzzle_piece_get_puzzle (GTK_PUZZLE_PIECE (piece)),
                                pos_x, pos_y,
                                width, height);
  picture = gtk_grid_get_child_at (GTK_GRID (grid), pos_x, pos_y);
  gtk_picture_set_paintable (GTK_PICTURE (picture), piece);

  celebrate (TRUE);

  return TRUE;
}

static gboolean
puzzle_key_pressed (GtkWidget *grid,
                    GVariant  *args,
                    gpointer   unused)
{
  int dx, dy;

  g_variant_get (args, "(ii)", &dx, &dy);

  if (!move_puzzle (grid, dx, dy))
    {
      /* Make the error sound and then return TRUE.
       * We handled this key, even though we didn't
       * do anything to the puzzle.
       */
      gtk_widget_error_bell (grid);
      return TRUE;
    }

  check_solved (grid);

  return TRUE;
}

static void
puzzle_button_pressed (GtkGestureClick *gesture,
                       int              n_press,
                       double           x,
                       double           y,
                       GtkWidget       *grid)
{
  GtkWidget *child;
  int l, t, i;
  int pos;

  child = gtk_widget_pick (grid, x, y, GTK_PICK_DEFAULT);

  if (!child)
    {
      gtk_widget_error_bell (grid);
      return;
    }

  gtk_grid_query_child (GTK_GRID (grid), child, &l, &t, NULL, NULL);

  if (l == pos_x && t == pos_y)
    {
      gtk_widget_error_bell (grid);
    }
  else if (l == pos_x)
    {
      pos = pos_y;
      for (i = t; i < pos; i++)
        {
          if (!move_puzzle (grid, 0, -1))
            gtk_widget_error_bell (grid);
        }
      for (i = pos; i < t; i++)
        {
          if (!move_puzzle (grid, 0, 1))
            gtk_widget_error_bell (grid);
        }
    }
  else if (t == pos_y)
    {
      pos = pos_x;
      for (i = l; i < pos; i++)
        {
          if (!move_puzzle (grid, -1, 0))
            gtk_widget_error_bell (grid);
        }
      for (i = pos; i < l; i++)
        {
          if (!move_puzzle (grid, 1, 0))
            gtk_widget_error_bell (grid);
        }
    }
  else
    {
      gtk_widget_error_bell (grid);
    }

  check_solved (grid);
}

static void
add_move_binding (GtkShortcutController *controller,
                  guint                  keyval,
                  guint                  kp_keyval,
                  int                    dx,
                  int                    dy)
{
  GtkShortcut *shortcut;

  shortcut = gtk_shortcut_new_with_arguments (
                 gtk_alternative_trigger_new (gtk_keyval_trigger_new (keyval, 0),
                                              gtk_keyval_trigger_new (kp_keyval, 0)),
                 gtk_callback_action_new (puzzle_key_pressed, NULL, NULL),
                 "(ii)", dx, dy);
  gtk_shortcut_controller_add_shortcut (controller, shortcut);
}

static void
start_puzzle (GdkPaintable *paintable)
{
  GtkWidget *picture, *grid;
  GtkEventController *controller;
  guint x, y;
  float aspect_ratio;

  /* Create a new grid */
  grid = gtk_grid_new ();
  gtk_widget_set_focusable (grid, TRUE);
  gtk_aspect_frame_set_child (GTK_ASPECT_FRAME (frame), grid);
  aspect_ratio = gdk_paintable_get_intrinsic_aspect_ratio (paintable);
  if (aspect_ratio == 0.0)
    aspect_ratio = 1.0;
  gtk_aspect_frame_set_ratio (GTK_ASPECT_FRAME (frame), aspect_ratio);
  gtk_aspect_frame_set_obey_child (GTK_ASPECT_FRAME (frame), FALSE);

  /* Add shortcuts so people can use the arrow
   * keys to move the puzzle
   */
  controller = gtk_shortcut_controller_new ();
  gtk_shortcut_controller_set_scope (GTK_SHORTCUT_CONTROLLER (controller),
                                     GTK_SHORTCUT_SCOPE_LOCAL);
  add_move_binding (GTK_SHORTCUT_CONTROLLER (controller),
                    GDK_KEY_Left, GDK_KEY_KP_Left,
                    -1, 0);
  add_move_binding (GTK_SHORTCUT_CONTROLLER (controller),
                    GDK_KEY_Right, GDK_KEY_KP_Right,
                    1, 0);
  add_move_binding (GTK_SHORTCUT_CONTROLLER (controller),
                    GDK_KEY_Up, GDK_KEY_KP_Up,
                    0, -1);
  add_move_binding (GTK_SHORTCUT_CONTROLLER (controller),
                    GDK_KEY_Down, GDK_KEY_KP_Down,
                    0, 1);
  gtk_widget_add_controller (GTK_WIDGET (grid), controller);

  controller = GTK_EVENT_CONTROLLER (gtk_gesture_click_new ());
  g_signal_connect (controller, "pressed",
                    G_CALLBACK (puzzle_button_pressed),
                    grid);
  gtk_widget_add_controller (GTK_WIDGET (grid), controller);

  /* Make sure the cells have equal size */
  gtk_grid_set_row_homogeneous (GTK_GRID (grid), TRUE);
  gtk_grid_set_column_homogeneous (GTK_GRID (grid), TRUE);

  /* Reset the variables */
  solved = FALSE;
  pos_x = width - 1;
  pos_y = height - 1;

  /* add a picture for every cell */
  for (y = 0; y < height; y++)
    {
      for (x = 0; x < width; x++)
        {
          GdkPaintable *piece;

          /* Don't paint anything for the lsiding part of the video */
          if (x == pos_x && y == pos_y)
            piece = NULL;
          else
            piece = gtk_puzzle_piece_new (paintable,
                                          x, y,
                                          width, height);
          picture = gtk_picture_new_for_paintable (piece);
          gtk_picture_set_content_fit (GTK_PICTURE (picture), GTK_CONTENT_FIT_FILL);
          gtk_grid_attach (GTK_GRID (grid),
                           picture,
                           x, y,
                           1, 1);
        }
    }

  shuffle_puzzle (grid);
}

static void
reshuffle (void)
{
  GtkWidget *grid;

  if (solved)
    {
      start_puzzle (puzzle);
      grid = gtk_aspect_frame_get_child (GTK_ASPECT_FRAME (frame));
    }
  else
    {
      grid = gtk_aspect_frame_get_child (GTK_ASPECT_FRAME (frame));
      shuffle_puzzle (grid);
    }
  gtk_widget_grab_focus (grid);
}

static void
reconfigure (void)
{
  GtkWidget *popover;
  GtkWidget *grid;
  GtkWidget *child;
  GtkWidget *image;
  GList *selected;

  width = height = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (size_spin));

  selected = gtk_flow_box_get_selected_children (GTK_FLOW_BOX (choices));
  if (selected == NULL)
    child = gtk_widget_get_first_child (choices);
  else
    {
      child = selected->data;
      g_list_free (selected);
    }

  image = gtk_flow_box_child_get_child (GTK_FLOW_BOX_CHILD (child));
  puzzle = gtk_image_get_paintable (GTK_IMAGE (image));

  start_puzzle (puzzle);
  popover = gtk_widget_get_ancestor (size_spin, GTK_TYPE_POPOVER);
  gtk_popover_popdown (GTK_POPOVER (popover));
  grid = gtk_aspect_frame_get_child (GTK_ASPECT_FRAME (frame));
  gtk_widget_grab_focus (grid);
}

static void
add_choice (GtkWidget    *container,
            GdkPaintable *paintable)
{
  GtkWidget *icon;

  icon = gtk_image_new_from_paintable (paintable);
  gtk_image_set_icon_size (GTK_IMAGE (icon), GTK_ICON_SIZE_LARGE);

  gtk_flow_box_insert (GTK_FLOW_BOX (container), icon, -1);
}

static void
widget_destroyed (gpointer data,
                  GObject *widget)
{
  if (data)
    *(gpointer *) data = NULL;
}
   
static void
activate (GtkApplication *app,
          gpointer        user_data)
{
      GtkWidget *header;
      GtkWidget *restart;
      GtkWidget *tweak;
      GtkWidget *popover;
      GtkWidget *tweaks;
      GtkWidget *apply;
      GtkWidget *label;
      GtkWidget *sw;
/*       GtkMediaStream *media;		*/
      
      window = gtk_application_window_new (app);
      gtk_window_set_title (GTK_WINDOW (window), "Sliding Puzzle");
      gtk_window_set_default_size (GTK_WINDOW (window), 800, 600);
      g_object_weak_ref (G_OBJECT (window), widget_destroyed, &window);

      header = gtk_header_bar_new ();
      gtk_window_set_titlebar (GTK_WINDOW (window), header);

      restart = gtk_button_new_from_icon_name ("view-refresh-symbolic");
      g_signal_connect (restart, "clicked", G_CALLBACK (reshuffle), NULL);
      gtk_header_bar_pack_start (GTK_HEADER_BAR (header), restart);

      popover = gtk_popover_new ();
      tweak = gtk_menu_button_new ();
      gtk_menu_button_set_popover (GTK_MENU_BUTTON (tweak), popover);
      gtk_menu_button_set_icon_name (GTK_MENU_BUTTON (tweak), "emblem-system-symbolic");
      gtk_header_bar_pack_end (GTK_HEADER_BAR (header), tweak);
           
      tweaks = gtk_grid_new ();
      gtk_popover_set_child (GTK_POPOVER (popover), tweaks);
      gtk_grid_set_row_spacing (GTK_GRID (tweaks), 10);
      gtk_grid_set_column_spacing (GTK_GRID (tweaks), 10);
      gtk_widget_set_margin_start (tweaks, 10);
      gtk_widget_set_margin_end (tweaks, 10);
      gtk_widget_set_margin_top (tweaks, 10);
      gtk_widget_set_margin_bottom (tweaks, 10);
      
      choices = gtk_flow_box_new ();
      gtk_widget_add_css_class (choices, "view");
      puzzle = GDK_PAINTABLE (gdk_texture_new_from_filename ("/home/ruhong/sliding_puzzle/picture01.jpg", NULL));
      add_choice (choices, puzzle);
      puzzle02 = GDK_PAINTABLE (gdk_texture_new_from_filename ("/home/ruhong/sliding_puzzle/picture02.jpg", NULL));
      add_choice (choices, puzzle02);
      puzzle03 = GDK_PAINTABLE (gdk_texture_new_from_filename ("/home/ruhong/sliding_puzzle/picture03.jpg", NULL));
      add_choice (choices, puzzle03);
/*
      add_choice (choices, nuclear_animation_new (TRUE));
      media = gtk_media_file_new_for_resource ("/images/gtk-logo.webm");
      gtk_media_stream_set_loop (media, TRUE);
      gtk_media_stream_set_muted (media, TRUE);
      gtk_media_stream_play (media);
      add_choice (choices, GDK_PAINTABLE (media));
*/
 
      sw = gtk_scrolled_window_new ();
      gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (sw), choices);
      gtk_grid_attach (GTK_GRID (tweaks), sw, 0, 0, 2, 1);

      label = gtk_label_new ("Size");
      gtk_label_set_xalign (GTK_LABEL (label), 0.0);
      gtk_grid_attach (GTK_GRID (tweaks), label, 0, 1, 1, 1);
      
      size_spin = gtk_spin_button_new_with_range (2, 10, 1);
      gtk_spin_button_set_value (GTK_SPIN_BUTTON (size_spin), width);
      gtk_grid_attach (GTK_GRID (tweaks), size_spin, 1, 1, 1, 1);

      apply = gtk_button_new_with_label ("Apply");
      gtk_widget_set_halign (apply, GTK_ALIGN_END);
      gtk_grid_attach (GTK_GRID (tweaks), apply, 1, 2, 1, 1);
      g_signal_connect (apply, "clicked", G_CALLBACK (reconfigure), NULL);

      frame = gtk_aspect_frame_new (0.5, 0.5, (float) gdk_paintable_get_intrinsic_aspect_ratio (puzzle), FALSE);
      gtk_window_set_child (GTK_WINDOW (window), frame);

      gtk_widget_set_visible (window, TRUE);

      start_puzzle (puzzle);
}

int
main (int    argc,
      char **argv)
{
  GtkApplication *app;
  int status;

  app = gtk_application_new ("org.gtk.example", G_APPLICATION_DEFAULT_FLAGS);
  g_signal_connect (app, "activate", G_CALLBACK (activate), NULL);
  status = g_application_run (G_APPLICATION (app), argc, argv);
  g_object_unref (app);

  return status;
}

将声音文件complete.oga和三张图片picture01.jpg改为为绝对路径

stream = gtk_media_file_new_for_filename ("/home/ruhong/sliding_puzzle/complete.oga");

puzzle = GDK_PAINTABLE (gdk_texture_new_from_filename ("/home/ruhong/sliding_puzzle/picture01.jpg", NULL));

puzzle02 = GDK_PAINTABLE (gdk_texture_new_from_filename ("/home/ruhong/sliding_puzzle/picture02.jpg", NULL));

puzzle03 = GDK_PAINTABLE (gdk_texture_new_from_filename ("/home/ruhong/sliding_puzzle/picture03.jpg", NULL));

三、使用原作者的素材图片和声音文件

这个拼图游戏是来自于

https://github.com/aeldemery/gtk4_sliding_puzzle

单击code------复制git地址------回到自己的家目录------git克隆整个项目文件

ruhong@localhost:~/sliding_puzzle> cd /home/ruhong

ruhong@localhost:/home/ruhong> git clone https://github.com/aeldemery/gtk4_sliding_puzzle.git

正克隆到 'gtk4_sliding_puzzle'...

remote: Enumerating objects: 50, done.

remote: Counting objects: 100% (50/50), done.

remote: Compressing objects: 100% (34/34), done.

remote: Total 50 (delta 20), reused 46 (delta 16), pack-reused 0 (from 0)

接收对象中: 100% (50/50), 992.13 KiB | 737.00 KiB/s, 完成.

处理 delta 中: 100% (20/20), 完成.

ruhong@localhost:~> cd gtk4_sliding_puzzle/

ruhong@localhost:~/gtk4_sliding_puzzle> ls

data LICENSE meson.build README.md Screenshot 1.png src

ruhong@localhost:~/gtk4_sliding_puzzle> cd data/

ruhong@localhost:~/gtk4_sliding_puzzle/data> ls

distribution-linux.jpg linuxadminhero.jpg penguine.jpg

github.aeldemery.gtk4_sliding_puzzle.gresource.xml linux-penguin-3d-model.jpg portland-rose.jpg

进入文件夹gtk4_sliding_puzzle/data复制三张图片到/home/ruhong/sliding_puzzle/,并依次改名为picture01.jpg,这个过程可以使用鼠标操作,不用全靠命令行操作

ruhong@localhost:~/gtk4_sliding_puzzle/data> cp portland-rose.jpg distribution-linux.jpg penguine.jpg /home/ruhong/sliding_puzzle/

ruhong@localhost:~/gtk4_sliding_puzzle/data> cd /home/ruhong/sliding_puzzle/

ruhong@localhost:~/sliding_puzzle> ls

distribution-linux.jpg penguine.jpg portland-rose.jpg puzzlepiece.c puzzlepiece.h source.c

ruhong@localhost:~/sliding_puzzle> mv portland-rose.jpg picture01.jpg

ruhong@localhost:~/sliding_puzzle> mv distribution-linux.jpg picture02.jpg

ruhong@localhost:~/sliding_puzzle> mv penguine.jpg picture03.jpg

ruhong@localhost:~/sliding_puzzle> ls

picture01.jpg picture02.jpg picture03.jpg puzzlepiece.c puzzlepiece.h source.c

搜索本机系统中所有oga格式的声音文件,找到complete.oga和复制到/home/ruhong/sliding_puzzle中

ruhong@localhost:~/sliding_puzzle> locate .oga

/home/ruhong/sliding_puzzle/complete.oga

/usr/share/novnc/app/sounds/bell.oga

/usr/share/sounds/freedesktop/stereo/alarm-clock-elapsed.oga

...

/usr/share/sounds/freedesktop/stereo/complete.oga

...

ruhong@localhost:~/sliding_puzzle> cp /usr/share/sounds/freedesktop/stereo/complete.oga /home/ruhong/sliding_puzzle/

四、编译与测试

要用到编译C语言的gcc,先查看系统上是否已经安装,没有就要切换root安装

ruhong@localhost:~/sliding_puzzle> su -

密码:

localhost:~ # zypper install gcc

Loading repository data...

Reading installed packages...

'gcc' is already installed.

No update candidate for 'gcc-7-3.9.1.x86_64'. The highest available version is already installed.

Nothing to do.

ruhong@localhost:~/sliding_puzzle> gcc --version

gcc (SUSE Linux) 7.5.0

Copyright © 2017 Free Software Foundation, Inc.

This is free software; see the source for copying conditions. There is NO

warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

ruhong@localhost:~/sliding_puzzle> pkg-config --list-all |grep gtk4

vte-2.91-gtk4 vte - VTE widget for GTK+ 4.0

gtk4-wayland GTK - GTK Graphical UI Library

gtk4-broadway GTK - GTK Graphical UI Library

gtk4-unix-print GTK - GTK Unix print support

gtk4-x11 GTK - GTK Graphical UI Library

gtk4 GTK - GTK Graphical UI Library

bash 复制代码
ruhong@localhost:~/sliding_puzzle> gcc -g -Wall `pkg-config --cflags gtk4` puzzlepiece.c source.c `pkg-config --libs gtk4` -o source

没有报错就会在当前目录产生source,输入./source运行一下,英文句号右斜杠

ruhong@localhost:~/sliding_puzzle> ./source

单击右上角的齿轮图标------单击减号图标,将图片切割成2X2,完成拼图后是否有响一声

五、使用数字图片

使用手机打开淘宝网,输入关键字"数字华容道",下载3X3、4X4、5X5的图片,用数据线将手机与电脑连接,将三个图片复制到电脑中,使用图片编辑软件gimp截取数字部分内容,例如截取好4X4的图片改名为picture02.jpg替换原来的picture02.jpg,看一下实际效果,因为淘宝的图片像素很少,在电脑中会显示空白的

右击4X4的原图片------打开方式------单击gimp------打开

工具------选择工具------矩形选择------选择数字部分

编辑------复制

文件------第二个新建------从剪贴板

文件------保存------名称输入picture02.jpg------保存------带我到导出对话框------选择目录为/home/ruhong/sliding_puzzle/------替换------导出

ruhong@localhost:~/sliding_puzzle> ./source

运行一下,看一下实际效果

也可以直接在图片上画上数字,例如在picture03.jpg画上16个数字,右击picture03.jpg------------打开方式------单击gimp------打开------图像带有嵌入的色彩配置文件------保持

图像------图像属性------大小(像素)是2048X2048------用手机计算2048/4=512

图像------配置网格------间距水平,单击向上三角图标,将数值增加为512------确定

视图------显示网格

工具------文字------双击前景色选择红色------大小改为450------单击第一个小格------输入数字1------单击移动工具十字架图标------将数字移到小格的中间

单击文字工具A字母图标------单击第二个小格------输入数字2------单击移动工具十字架图标------将数字移到小格的中间

如此类推完成9个数字,将大小改为350,完成10到16的数字

文件------保存------名称输入picture03.jpg------保存------带我到导出对话框------选择目录为/home/ruhong/sliding_puzzle/------替换------导出

ruhong@localhost:~/sliding_puzzle> ./source

运行一下,看一下实际效果

六、制作桌面文件sliding_puzzle.desktop和桌面图标sliding64x64.png

右击picture02.jpg------打开方式------gimp------打开

图像------缩放图像------单击解锁固定比例------宽度和高度都输入64------缩放

文件------另存为------保存文件夹为/home/ruhong/sliding_puzzle/------名称为sliding64x64.png------保存------带我到导出对话框------导出

ruhong@localhost:~/sliding_puzzle> cp /usr/share/applications/org.gnome.Chess.desktop sliding_puzzle.desktop

复制国际象棋游戏的桌面文件org.gnome.Chess.desktop并改名为sliding_puzzle.desktop

ruhong@localhost:~/sliding_puzzle> gedit sliding_puzzle.desktop

使用文本编辑器gedit打开修改成以下内容

Desktop Entry

Name[zh_CN]=滑板拼图

Name=Sliding

GenericName[zh_CN]=滑板拼图游戏

GenericName=Sliding Game

Comment[zh_CN]=经典的单人滑板拼图益智游戏

Comment=The classic single-player skateboard puzzle game

Keywords[zh_CN]=game;strategy;游戏;策略;棋;

Keywords=game;strategy;

Version=1.0

Exec=/home/ruhong/sliding_puzzle/source %U

Terminal=false

Type=Application

Categories=GNOME;GTK;Game;BoardGame;

StartupNotify=true

Icon=/home/ruhong/sliding_puzzle/sliding64x64.png

MimeType=application/x-chess-pgn;

DBusActivatable=true

X-Purism-FormFactor=Workstation;Mobile;

ruhong@localhost:~/sliding_puzzle> cp sliding_puzzle.desktop ~/桌面/

ruhong@localhost:~/sliding_puzzle> ll ~/桌面/

总用量 76

-rwxr-xr-x 1 ruhong users 9777 2月 17 21:06 firefox.desktop

-rwxr-xr-x 1 ruhong users 13826 2月 17 21:06 org.gnome.gedit.desktop

-rwxr-xr-x 1 ruhong users 14991 2月 17 21:06 org.gnome.Nautilus.desktop

-rwxr-xr-x 1 ruhong users 15693 2月 17 21:06 org.gnome.Terminal.desktop

-r-xr-xr-x 1 ruhong users 850 2月 17 21:06 org.opensuse.opensuse_welcome.desktop

-rw-r--r-- 1 ruhong users 917 2月 17 22:48 sliding_puzzle.desktop

-rwxr-xr-x 1 ruhong root 446 1月 15 21:10 wps-office-prometheus.desktop

-rwxr-xr-x 1 ruhong users 1247 2月 17 21:06 wps-office-wps.desktop

ruhong@localhost:~/sliding_puzzle> chmod a+x ~/桌面/sliding_puzzle.desktop

将sliding_puzzle.desktop复制到/home/ruhong/桌面和添加执行权限

设置opensuse15.6显示桌面图标

应用程序------工具------终端

ruhong@localhost:~> su -

密码:

localhost:~ # zypper install nemo

...

The following 20 NEW packages are going to be installed:

libnemo-extension1 libxapp1 libxklavier16 nemo nemo-extension-fileroller nemo-extension-seahorse

...

(19/20) Installing: nemo-extension-share-6.0.0-bp156.1.2.x86_64 ...[done]

(20/20) Installing: nemo-extension-fileroller-6.0.0-bp156.1.2.x86_64 ...[done]

localhost:~ # exit

logout

ruhong@localhost:~>

ruhong@localhost:~> vim ~/.config/autostart/nemo-autostart-with-gnome.desktop

新建文本文件/home/ruhong/.config/autostart/nemo-autostart-with-gnome.desktop并加入以下内容

Desktop Entry

Type=Application

Name=Nemo

Comment=Start Nemo desktop at log in

Exec=nemo-desktop

OnlyShowIn=GNOME;

AutostartCondition=GSettings org.nemo.desktop show-desktop-icons

X-GNOME-AutoRestart=true

NoDisplay=true

ruhong@localhost:~> gsettings set org.nemo.desktop use-desktop-grid false

ruhong@localhost:~> nemo.desktop &

到此桌面已经显示sliding_puzzle游戏程序图标,双击就可以开始游戏了,也可以复制其它常用程序desktop文件的到桌面也会显示出来的,双击就可以使用了

ruhong@localhost:~> cd /usr/share/applications/

ruhong@localhost:/usr/share/applications> ls ~/.config/autostart/

firefox.desktop org.gnome.Nautilus.desktop wps-office-wps.desktop

nemo-autostart-with-gnome.desktop org.gnome.Terminal.desktop

org.gnome.gedit.desktop org.opensuse.opensuse_welcome.desktop

ruhong@localhost:/usr/share/applications> cp firefox.desktop org.gnome.Nautilus.desktop org.gnome.Terminal.desktop org.gnome.gedit.desktop wps-office-wps.desktop /home/ruhong/桌面/

ruhong@localhost:/usr/share/applications> chmod a+x /home/ruhong/桌面/*

ruhong@localhost:/usr/share/applications> cd

七、结语

最后上网搜索数字华容道,就有许多视频讲解如何还原的方法和技巧了。阅读作者aeldemery的gtk4_sliding_puzzle原代码就好像阅读报纸上的文章很容易明白的,它是使用vala语言写的,gtk4-demo提供的原代码是C语言写的,而改写source.c的过程很主要还得要参考vala所写原代码的分析过程,尝试修改PuzzleBoard.vala,但是编译不成功,我也没有学过vala语言,只能修改source.c能编译通过,希望有人看过我这篇文章后能够修改PuzzleBoard.vala并编译成功。

相关推荐
翻滚吧键盘10 个月前
opensuse Tumbleweed虚拟机上安装
desktop·opensuse
-风中叮铃-2 年前
SUSE linux 15的网络管理
linux·运维·suse·opensuse
sukida1002 年前
视频编辑软件pitivi基本功之将三个相关视频合并成一个视频
音视频·opensuse·pitivi
Mongnewer2 年前
Ubuntu22.04 gnome-builder gnome C 应用程序习练笔记(一)
cambalache·gnome-builder·gtk4·gnome-builder c