vue3 を使用したジグソーパズルゲームのリファクタリングの例

vue3 を使用したジグソーパズルゲームのリファクタリングの例

序文

プロジェクト内のパズルゲーム(デジタル華容路とも呼ばれる)を再構築するのに 2 日かかりました。使いやすさを考慮して、独立したコンポーネントに抽出されました。効果は次のとおりです。

オンライン体験

ソースコードのアドレスは記事の最後にあります!

主な再建ポイント

オリジナルのジグソーパズル ゲームは、vue2 を使用してオープン ソース コードを通じて変更されました。実際のプロジェクトではすべてうまく機能しますが、次のような問題点が残っています。

  • ソース コードは肥大化しており、公開されている構成項目は、特にプロジェクトの既存のロジックと組み合わせると不十分です。
  • 生成されたゲームには解決できない状況が含まれる場合があります。解決できない状況を回避するには、いくつかの状況を記述し、それらをランダムに生成する必要があります。
  • ソースコードはvue2バージョンであり、vue3をサポートしていません

最終的に、次の詳細に注意しながら、vue3を使用してジグソーパズルゲームを再実装することにしました。

  • コンポーネントは使いやすいほどシンプルです
  • カスタマイズ可能なゲーム難易度
  • 画像モードと配列モードの両方をサポート

実装のアイデア

パズルの絵でもパズルの数字でも、元々シャッフルされていた配列を整列した状態に移動するのが原則です。インターネット上には、デジタル華容を実装するアルゴリズムも多数あります。アルゴリズムが解決する必要がある主な問題は、ランダムかつ解ける配列のセットを生成する方法です。華容配列が解けない可能性はあるのだろうかと疑問に思う人もいるかもしれません。

生成されたゲームが上記のようなものである場合、解決策はありません。原理はルービックキューブで遊ぶのと同じです。通常、どんなにぐちゃぐちゃになっても元に戻すことができます。しかし、いくつかのブロックを取り出して位置を変えると、元に戻せなくなる場合があります。

インターネット上には解決不可能な問題の発生を回避できるアルゴリズムが多数存在しますが、いずれも比較的高度なものです。また、アルゴリズムを読む能力にも限界があるため、最終的には自分のアイデアで実装することにしました。

私のアイデアは実はとてもシンプルです。一文で「逆推論」と要約できます。まずは整列した配列から始めて、それを移動することでランダムに順序を乱します。こうすることで、生成された質問に必ず解答があることが保証されます。同時に、乱れたステップの数に応じてゲームの難易度を制御できます。これはまさに一石二鳥のアイデアです。

ソースコードの実装

データストレージ

まず、データを格納するために 1 次元配列を使用することを検討しました。

let arr = [1,2,3,4,5,6,7,8,0] // 0は空白を表す

しかし、1次元配列ではデータしか記録できず、垂直位置を記録できないため、移動時にロジックがかなり面倒になるという問題があります。このとき、自然に2次元配列の使用を考えます。たとえば、3×3のゲームを生成する必要がある場合、データは次のようになります。

アーレ [
  [1,2,3],
  [4,5,6],
  [7,8,0]
]

このようにして、x 軸と y 軸をシミュレートして、各数字の位置を示すことができます。たとえば、0 の位置は (2,2) で、6 の位置は (1,2) です。6 と 0 の位置を移動したい場合は、それらの座標を入れ替えるだけです。

移動機能

デジタル華龍島の最も重要なインタラクションは、ユーザーがクリックしたブロックを移動することですが、0 に近い配列のみを移動できることに注意してください。次に移動関数を完成させます

 関数move(x, y, moveX, moveY) {
  定数num = state.arr[x][y];
  state.arr[x][y] = state.arr[moveX][moveY];
  state.arr[moveX][moveY] = 数値;
 }

とても簡単ではないでしょうか。実際には、移動する 2 つの数字の添え字を交換するだけです。移動関数を使用すると、上下左右への移動を実現できます。

// 上に移動する function moveTop(x, y) {
  x <= 0 の場合は -1 を返します。
  // 位置の交換を開始します const okx = x - 1;
  移動(x, y, okx, y);
  戻る {
   x: わかりました、
   はい、
  };
 }
 //下へ移動 function moveDown(x, y) {
  (x >= レベル - 1) の場合は -1 を返します。
  定数okx = x + 1;
  移動(x, y, okx, y);
  戻る {
   x: わかりました、
   はい、
  };
 }
 // 左に移動する function moveLeft(x, y) {
  y <= 0 の場合は -1 を返します。
  定数 oky = y - 1;
  移動(x, y, x, ok);
  戻る {
   ×、
   y: わかったよ
  };
 }

 // 右に移動する function moveRight(x, y) {
  y >= レベル - 1 の場合は -1 を返します。
  定数 oky = y + 1;
  移動(x, y, x, ok);
  戻る {
   ×、
   y: わかったよ
  };
 }

次に、以下に示すように、移動方向を決定するメソッドを実装します。

 関数 shouldMove(x, y) {
  // 移動先を決定します const { emptyX, emptyY } = seekEmpty();
  (x === emptyX && y !== emptyY && Math.abs(y - emptyY) === 1) の場合 {
   // 水平線上で左または右に移動する可能性があることを示します if (y > emptyY) {
    左へ移動(x, y);
   } それ以外 {
    右へ移動(x, y);
   }
  }
  (y === emptyY && x !== emptyX && Math.abs(x - emptyX) === 1)の場合{
   // 上下に移動する必要があることを示します if (x > emptyX) {
    上へ移動(x, y);
   } それ以外 {
    下へ移動します(x, y);
   }
  }
 }

if の判断は、クリックしたブロックが空白ブロックであるか、空白ブロックに隣接していない場合は何もしないことを意味します。

ゲームボードを生成する

実際には、上、下、左、右のシフト関数をランダムに呼び出して配列を混乱させるのです。

 // ランダムにシャッフルする function moveInit(diffic) {
  状態.arr = createArr(レベル);
  const num = diffic ? diffic: state.diffec;
  const fns = [上へ移動、下へ移動、左へ移動、右へ移動];
  インデックスを null にします。
  fn にします。
  (i = 0; i < num; i++ とします) {
   インデックス = Math.floor(Math.random() * fns.length);
   // コンソールを移動します(インデックス);
   fn = fns[インデックス](開始X、開始Y);
   (fn!=-1)の場合{
    定数 { x, y } = fn;
    開始X = x;
    開始Y = y;
   }
  }
 }

ほんの数個の関数でコアロジックが完成します。ゲームの完了判定や、空きブロックの位置の検索、2次元配列の作成など、まだ紹介していない関数がいくつかあります。ソースコードは自分で読んでみてください。

vue3 によるリファクタリング

上記のロジックはvue3とは関係ないように思えますが、最も重要な点を見落としています。つまり、配列を変更すると、ビューも変更されます。これはレスポンシブではありませんか?vue3を使用すると、ゲームに関するすべてのロジックをjsにまとめることができ、コードの結合が大幅に削減されます。

const { arr、shouldMove、moveInit } = useCreateGame(
 ゲームデータレベル、
 ゲームデータ難易度、
 ゲーム終了コールバック
);

疑問に思う方もいるかもしれません。ロジックをすべて抽出するのが普通ではないでしょうか?vue2 を使用する場合、抽出は不可能でしょうか?
ただし、配列はレスポンシブである必要があることを忘れないでください。ロジックを個別に抽出した場合、js ファイル内の配列を変更しても、レスポンシブになりますか?

しかし、vue3のcomposition-apiを使用すると、jsファイルでレスポンシブ変数を宣言することができ、コンポーネントで使用してもレスポンシブになります。

デフォルト関数 useCreateGame() をエクスポートします。
// レスポンシブ変数を宣言します...
 定数状態 = リアクティブ({
  編曲: [],
 });
...
 戻る {
 ...toRefs(状態)
 ...
 }
 }
const { arr、shouldMove、moveInit } = useCreateGame(
 ゲームデータレベル、
 ゲームデータ.難易度、
 ゲーム終了コールバック
);
// 現時点では、arr はまだ応答します

これがcomposition-apiの威力です。composition-apiを使用すると、ロジックコードを任意に組み立てることができます。

vue2では、レスポンシブ変数を維持したい場合、コードの結合度が増すvuexのような状態マネージャを使用する必要がありますか?

vite2について

現在、vite は vite2 バージョンに到達しており、公式バージョンはまだ急速に更新されています。vite2 で作成されたプロジェクトは、デフォルトで新しいセットアップ機能を使用できます。たとえば、次のように記述できます。

<テンプレート>
 <div>
  {{ 名前 }}
 </div>
</テンプレート>

<スクリプトの設定>
"vue" から { ref } をインポートします。
const name = ref('"公衆番号は止まりません"');
</スクリプト>

これは次のように書くのと同じである。

<テンプレート>
 <div>
  {{ 名前 }}
 </div>
</テンプレート>
<スクリプト>
"vue" から { ref } をインポートします。
エクスポートデフォルト{
 設定() {
  const name = ref("公衆番号は止まりません");
  戻る {
   名前、
  };
 },
};
</スクリプト>

見た目はかなりシンプルになり、Vue はセットアップ版でいくつかの API を公開しています。興味があれば、公式サイトに行って確認してみてください。個人的にはかなり良いと感じています。新しい構文はまだ実験段階であるため、このコード リファクタリングでは使用されませんでした。

ソースコードアドレス

ソースコードアドレス: デジタル華龍島パズルゲームへようこそ😍

やっと

あなたは興味があるかもしれません:

vue-routerの考え方に基づいて🕓 vue-routerのシンプルなバージョンを実装する
マルチページアプリケーションのWebpackパッケージングに基づくフロントエンドエンジニアリングについて考える

vue3 を使用したジグソーパズルゲームの再構築の実装例については、これで終了です。より関連性の高い vue3 再構築パズルコンテンツについては、123WORDPRESS.COM の過去の記事を検索するか、以下の関連記事を引き続き閲覧してください。今後とも 123WORDPRESS.COM をよろしくお願いいたします。

以下もご興味があるかもしれません:
  • vue3 でブロック崩しゲームを開発する方法をステップバイステップで教えます

<<:  MySQL 5.7.17 圧縮バージョンのインストールノート

>>:  Linux の crw、brw、lrw などのファイル属性は何ですか?

推薦する

ffmpeg 中国語パラメータの詳細な説明

FFMPEG 3.4.1 バージョンパラメータの詳細使用方法: ffmpeg [オプション] [[入...

Vue の共通 A​​PI と高度な API の概要

目次次のチェックミックスイン$強制更新設定、削除フィルター指令その他の単純な共通プロパティとメソッド...

MySQLの不合理なMaxIdleConnsにより接続が短くなる

1 背景最近、Shimo Document のオンライン ビジネスでパフォーマンスの問題が発生しまし...

初心者がソースコードからMySQLのデッドロック問題を理解する

夜遅くまで何度も困難なシングルステップデバッグを行った後、ようやく理想的なブレークポイントを見つけま...

MySQL explain クエリ命令情報の取得原理と例

explain はクエリ実行プラン情報を取得するために使用されます。 1. 文法次のように、sele...

Linux における SUID、SGID、SBIT の素晴らしい使い方の詳細な説明

序文Linux のファイル権限管理はとにかく素晴らしいです。SUID、SGID、SBIT の機能を確...

Dockerとiptablesとブリッジモードのネットワーク分離と通信操作の実装

Docker は、ブリッジ、ホスト、オーバーレイなどの複数のネットワークを提供します。同じ Dock...

ffmpeg 中国語パラメータの説明と使用例

1. ffmpeg がビデオ ファイルをプッシュする場合、オーディオとビデオのエンコード形式は H2...

vue+element で動的スキニングを実装するためのサンプルコード

プロジェクトのテーマがすべての人の美的感覚を満足できないこともあります。このとき、スキン変更機能は非...

Linux のファイル圧縮とパッケージ化の概要

1. 圧縮と包装の概要一般的な圧縮ファイルウィンドウズ .rar .zip .7z Linux .z...

JavaScript Alert関数の実行順序の詳細な説明

目次質問分析する解決するAlert() 関数を置き換えるsetTimeOut関数まとめ質問数日前、J...

React Nativeプロジェクトフレームワークの構築経験

React Native は、2015 年 4 月に Facebook によってオープンソース化され...

URL 書き換えモジュール 2.1 URL 書き換えモジュールのルール記述

目次前提条件テストページの設定書き換えルールの作成命名規則モードの定義アクションの定義設定ファイル内...

Web デザイナーにはどのような知識体系が必要ですか?

製品設計者は、複雑で大規模な製造システムと多様な市場に直面しているため、知識体系には幅広さと深さの両...

MySQLは1つのテーブルからデータをクエリし、それを別のテーブルに挿入する実装方法

MySQLは1つのテーブルからデータをクエリし、それを別のテーブルに挿入する実装方法ウェブサイト開発...