パズルインタラクティブミニゲーム(純粋なVUEバージョン)の実装方法を教えてください

晩秋のある日、地下鉄で携帯電話をスワイプして仕事をしていると、Xu Xiaoxiの公式アカウントからプッシュされた記事がモバイル端末でジグソーパズルゲームを紹介しているのを見て、QRコードを特定して終了しました。非常に興味深いです。私は今週末に時間をかけてこの小さなゲームの機能を確認しました。元の作者に聞いたところ、彼はネイティブJSで書かれたバージョンを使用していました。プロジェクトの開発にVUEを使用することを学んでいたので、発芽しました。 VUEでバージョンを修正してみましたが、たまたま学べたので、ゲームの全体的な効果を見て、VUEでバージョンを書き直してプレイすることにしました。興味のある、アイデアのある友達も話し合うことができます。 。

使用されるいくつかの知識ポイントは次のとおりです。

  • シャッフルアルゴリズム

  • CSS3アニメーション切り替え(画像カットスタイルの配置)

  • FileReaderAPIを使用してローカルプレビューファイルを実現する

  • Canvasでポスターを生成する

  • Webpackパッケージ(難易度の異なる切り替えスタイルの問題)

少しずつ週末に2〜3週間かかり、次のページが展開されました。問題はありましたが、コードは比較的ラフでしたが、思い通りの効果が得られました。

一般的な実装のアイデア趣谈前端については、パブリックアカウントの記事を参照し200行のコード(ソースコード付き)でH5ミニゲームを作成する方法を教えてください。ここでは、このゲームVUEに関連する機能を実装しました。また、いくつか追加しました。自分の考え。

相邻元素才可以挪动难度等级選択肢があり、2つの異なるバージョンがリリースされました。もちろん、実装プロセスでいくつかの問題が発生しましたが、私自身のトスの後、基本的に私が望む効果を達成しました。

チャレンジ結果

一般的な実装関数モデルを見てみましょう。

実装:

1.選択した難易度に応じてn * nマトリックスグラフのカット画像を生成します

// 生成n维矩阵
generateMatrix(n, dx, dy) {
  var arr = [],
    index = 0;
  for (var i = 0; i < n; i++) {
    for (var j = 0; j < n; j++) {
      arr.push({ x: j * dx, y: i * dy, index: index });
      index++;
    }
  }
  return arr;
}

2.配列が故障しています(再配置)

    upsetArr(arr) {
      return arr.sort(function() {
        return Math.random() > 0.5 ? -1 : 1;
      });
    }

3.クリックしてハイライトし、対応する位置を切り替えます(現在クリックされており、交換したい)

   // 点击高亮并且切换对应位置 (想办法交换对应索引位置的x,y值即可)
    changePositon(e, item) {
      //点击小图片切换位置方法
      let reg = /active/g;
      this.boxArractivelass = item;
      let pieces = document.querySelectorAll(".piece");
      if (!this.wall) {
        this.wall = 1;
        this.prevEl = e.target;
        for (var i = 0, len = pieces.length; i < len; i++) {
          // 使用replace为了避免元素后期加入其他类名
          pieces[i].className = pieces[i].className.replace(" active", "");
        }
        !reg.test(this.className) && (this.className += " active");
      } else {
        this.wall = 0;
        var prevIndex = +this.prevEl.getAttribute("index"),
          curIndex = +e.target.getAttribute("index");

        // 置换数组
        this.swap(this.pool, prevIndex, curIndex);
        this.prevEl.style.transform =
          "translate(" +
          this.pool[prevIndex].x +
          "vw," +
          this.pool[prevIndex].y +
          "vh" +
          ")";
        e.target.style.transform =
          "translate(" +
          this.pool[curIndex].x +
          "vw," +
          this.pool[curIndex].y +
          "vh" +
          ")";
        // 清除样式
        this.boxArractivelass = -1;

        // 校验是否成功
        if (this.isTestSuccess(this.pool)) {
    
          clearInterval(this.timer);
          this.startDx -= 100;
          this.issuccess = true;
          this.transformX(this.$refs.wrap, this.startDx + "vw");
       
        }
      }
    }

4.交換画像の場所をクリックします

    // 置换数组(对应索引的x,y值进行交换)
    swap(arr, indexA, indexB) {
      // ES6的解耦交换方式: [arr[index], arr[n]] = [arr[n], arr[index]];
      [arr[indexA], arr[indexB]] = [arr[indexB], arr[indexA]];
    },

5.メソッドが成功したかどうかを確認します。

    //对比数组中的每一个值是否与之前的值相等
    isTestSuccess(arr) {
      return arr.every(function(item, i) {
        return item.index === i;
      });
    }

実装の過程で、印象が深いという問題が発生しました。最初のページ简单でレベルを選択し、クリックしてゲームを開始中级し、スタイルの読み込み順序が原因でレベルを再選択すると、表示される简单ページは前のレベルのページのままです。スタイル。

以前のこの問題の理由は、私の側が選択レベルを判断し、次に異なるスタイルのファイルをインポートすることによって引き起こされているためです。

例:判断のアイデアの実現:

if(this.gradeSelected==3) {
    import('../assets/style/default.css');
} else if(this.gradeSelected===4){
    import('../assets/style/middle.css');
} else if(this.gradeSelected===5) {
    import('../assets/style/senior.css');
}
パッケージスタイルの問題

その後、気が変わって、選択したレベルをローカルに保存して、難易度の異なる選択したスタイルファイルを設定するメソッドを作成し、それをヘッドタグに動的に挿入しました。

    // 引入设置和获取本地存储的挑战等级标识
    import localStorage from "./storage"; 
    const skin = {};
    let getSkinStyle = (skin) => {
    if (!skin) {
        return "";
    }
    if (skin === 'three') {
        return `简单等级的样式文件`
    } else if(skin==='four') {
        return `中等等级的样式文件`
    } else if(skin==='five') {
        return `高级等级的样式文件`
    }
    
    let setSkinStyle = (skin) => {
    let styleText = getSkinStyle(skin);
    let oldStyle = document.getElementById("skin");
    const style = document.createElement("style");
    style.id = "skin";
    style.type = "text/css";
    style.innerHTML = styleText;
    oldStyle ? document.head.replaceChild(style, oldStyle) : document.head.appendChild(style);
};
// 设置不同等级图片切割样式
skin[localStorage.getSkin()] && setSkinStyle(skin[localStorage.getSkin()]);
export { skin, setSkinStyle }

この時点で、異なるレベルの選択を切り替えても、選択レベルが画像セグメンテーションインターフェイスのスタイルと矛盾することはなくなります。また、楽しくプレイすることもできます。

もちろん、コードはまだ比較的ラフで、いくつかの問題があります。また、異なるバージョンの携帯電話の互換性はテストされておらず、コードはすべて同じページにあり、適切なコンポーネントの分割などはありません。

上記のゲームは純粋なエンターテインメントです。興味のある友達も歓迎します。質問がある場合は、一緒に話し合うことができます。ソースコードアドレスも私のGithub一番上にあります。みんなで話し合い、一緒に進歩することを歓迎します。

Githubプロジェクトアドレス:https://github.com/pybyongbo/vue-pinpngle

興味のある方は、左下の元のリンクをクリックしてトライアル体験してください。リアクションバージョンのパズルゲームを実装したい場合は、何千人ものネットユーザーとおすすめを共有することもできます〜

おすすめ

転載: blog.csdn.net/KlausLily/article/details/109912828