vue制作3*3拼图

自从上次发布了vue制作抓娃娃机经验之后,好多朋友来私信我让我多分享一些小游戏的经验。(看来友友们对这种小游戏还是挺感兴趣哦捂脸笑
好了,回归正题。今天给大家带来一个比较简单的小游戏——拼图。想必大家平时或多或少都玩过拼图游戏吧,我记得小时候经常偷偷用我爸爸的手机玩上面的拼图小游戏,简单的有2×2,3×3甚至有4×4、5×5等等复杂的难关。作为玩者我们是在研究如何过关,而对于我们程序猿来说,我们是不是应该研究研究这些游戏怎么做出来的呢。今天它来啦~~
老样子,先看效果图。

gif1.gif

首先介绍规则:3×3的方格中,有一处是空白,点击空白周围的卡片,使其移动,直至拼成最终效果图(页面下方有成品图,这里录gif的时候没带上)。
第一步,上样式:

      <div class="game">
        <ul class="puzzle-wrap">
          <li
            v-for="(puzzle, index) in puzzles"
            :key="puzzle.id"
            :class="{'puzzle': true, 'puzzle-empty': !puzzle}"
            @click="move(puzzle,index)"
          >
            <img :src="puzzle.url" alt="error" width="100%" height="100%" />
          </li>
        </ul>
      </div>
.game {
      width: 560px;
      height: 560px;
      margin-top: 30px;
      background-image: url("./../assets/img/bgsmall.png");
      background-size: 100%;
      .puzzle-wrap {
        background-image: url("./../assets/img/dot1.png");
        width: 560px;
        height: 560px;
        overflow: hidden;
        background-size: 100%;
        list-style: none;
        padding: 19px 20px 0 21px;
        border-radius: 40px;
        animation: puzzle-wrap infinite 0.6s;
        .puzzle {
          float: left;
          width: 173px;
          height: 173px;
          font-size: 20px;
          background: #f90;
          text-align: center;
          line-height: 100px;
          border: 1px solid #ccc;
          box-shadow: 1px 1px 4px;
          text-shadow: 1px 1px 1px #b9b4b4;
          cursor: pointer;
          img {
            height: 100%;
            width: 100%;
          }
          &.puzzle-empty {
            background: #ccc;
            box-shadow: inset 2px 2px 18px;
          }
        }
      }
      @keyframes puzzle-wrap {    // 此动画是用来装饰游戏边框的动画(可忽略)
        form {
          background-image: url("./../assets/img/dot1.png");
        }
        to {
          background-image: url("./../assets/img/dot2.png");
        }
      }
    }

样式没什么问题,咱来看如何实现点击拼图。
首先准备好卡片资源,并随机设置生成卡片序列

data() {
    return {
        puzzles: [    // 可以在data中向这样引入,也可单独写个js文件来引入,看自己习惯。(其中有一张空白图片,并将其多设置一个参数,如:empty。用来后面判断是否拼图成功)
        {
          id: 0,
          url: require("./../assets/img/pintu/pintu_01.png")
        },
        {
          id: 1,
          url: require("./../assets/img/pintu/pintu_02.png")
        },
        {
          id: 2,
          url: require("./../assets/img/pintu/pintu_03.png")
        },
        {
          id: 3,
          url: require("./../assets/img/pintu/pintu_04.png")
        },
        {
          id: 4,
          url: require("./../assets/img/pintu/pintu_05.png")
        },
        {
          id: 5,
          url: require("./../assets/img/pintu/pintu_06.png")
        },
        {
          id: 6,
          url: require("./../assets/img/pintu/pintu_07.png")
        },
        {
          id: 7,
          url: require("./../assets/img/pintu/pintu_08.png")
        },
        {
          empty: true,
          id: 8,
          url: require("./../assets/img/pintu/pintu_09.jpg")
        }
      ],
    };
 },
mounted() {
    this.randomRender();
  },
methods: {
 // 随机生成方块序列
    randomRender() {
      let puzzles = this.puzzles,
        results = [];                     // 用拿到的卡片数据随机排序生成新的数组赋值,
      results = puzzles.sort(() => {
        return Math.random() > 0.5 ? -1 : 1;
      });
      this.puzzles = results;
    },
}

这样卡片的随机排序就生成好了,在页面初始mouted去调用以及拼图成功或失败之后再次调用来初始数据。
接下来就是点击卡片让其移动并判断是否达到最终效果图。

// 点击方块
    move(puzzle, index) {
        let puzzles = this.puzzles;
        // 获取点击位置及其上下左右的值
        let curNum = puzzles[index],
          leftNum = puzzles[index - 1],
          rightNum = puzzles[index + 1],
          topNum = puzzles[index - 3],
          bottomNum = puzzles[index + 3];

        let emptyObj = {
          empty: true,
          id: 8,
          url: require("./../assets/img/pintu/pintu_09.jpg")
        };

        // 和为空的位置交换数值
        if (leftNum && leftNum.empty && index % 3) {
          this.$set(puzzles, index - 1, curNum);
          this.$set(puzzles, index, emptyObj);
        } else if (rightNum && rightNum.empty && 2 !== index % 3) {
          this.$set(puzzles, index + 1, curNum);
          this.$set(puzzles, index, emptyObj);
        } else if (topNum && topNum.empty) {
          this.$set(puzzles, index - 3, curNum);
          this.$set(puzzles, index, emptyObj);
        } else if (bottomNum && bottomNum.empty) {
          this.$set(puzzles, index + 3, curNum);
          this.$set(puzzles, index, emptyObj);
        }
        this.$nextTick(() => {
          this.passChecked();
        });
    },
  passChecked() {
      const puzzles = this.puzzles;
      if (puzzles[8]["empty"]) {
        const isPass = puzzles.every((x, y) => x.id === y);  该方法的用法
        if (isPass) {
            console.log('成功啦~~');
          // return true;
        }
      }
      return false;
    },

当每次点击卡片时,获取该卡片的位置以及其上下左右四张卡片的值。然后定义空卡片的值,判断空卡片在点击卡片的方位,然后进行交换数值替换位置。
接下来用刚开始定义空卡片的empty值去判断当前数组的最后一张卡片该值是否存在,若存在再使用every()依次去判断当前数组每个数据的id是否等于对应的索引值。若返回为true则证明拼图成功。

这样再看游戏是不是觉得很简单呢,玩着自己制作的小游戏是不是有点小成就感呢~~
有不懂的或者我的讲解哪里存在问题的可以在下方评论交流哦O(∩_∩)O

进来的朋友点点赞点点关注哦~以后会分享更多的小游戏制作经验哦 (●ˇ∀ˇ●)

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,293评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,604评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,958评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,729评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,719评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,630评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,000评论 3 397
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,665评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,909评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,646评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,726评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,400评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,986评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,959评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,197评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,996评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,481评论 2 342

推荐阅读更多精彩内容

  • 2015.03.05 从小就馋,如今依旧。吃,是我最喜欢的话题,可说的东西太多了,从哪儿开始呢?零嘴儿吧。 小时候...
    花田闲人阅读 560评论 7 0
  • 感谢论坛的主办方和策划者,把这次论坛的学习时间安排的如此紧凑,从早上八点到晚上九点,紧锣密鼓。我这个来自乡...
    09ccbb214d2f阅读 174评论 0 0
  • 静态效果 动态效果 这里请注意SpriteSheetPainter的参数是一个数组 里面表示每个精灵图的坐标代码如下
    infi_阅读 1,458评论 0 1
  • Redis(Remote Dictionary Service) --- 远程字典服务Redis的五种数据结构:...
    人间六月_阅读 393评论 0 0