记录一次用 Vue 简单完成小游戏:十滴水 (无动画)

前言

闲来无事,想起以前经常玩的一个小游戏《十滴水》,简单开发游戏逻辑,时间原因没编写动画和不同难度。
基于 Vue 开发,效果如下。
在这里插入图片描述

1.游戏规则

鼠标点击消耗子弹增大水滴,水滴饱和后再加水就会破裂,破裂后会向四方溅射水滴,引起一系列爆炸。
在这里用方块代替水滴,方块内部填满后意味着水滴饱和。
每次水滴爆炸时获得分数,所有水滴破裂即为获胜,进入下一关,奖励若干子弹。
用完子弹未进入下一关,则游戏结束。

2.开发思路

1.地图设计

随机散布水滴在一个矩阵上,每个元素即为水滴 水滴都有自身属性,如 x:行,y:列,level:当前层级。

2.子弹发射事件

每当点击元素时,则消耗一个子弹,并为元素层级累计 1,当层级大于 0 时,则表明该坐标存在一个水滴。

3.水滴状态

当元素的层级达到设定的最大层级,则代表水滴发生爆炸,自身消失(层级归 0),并向四周(上下左右)发射水滴。

4.水滴溅射

水滴溅射时会朝自身周围四个方向发射水滴,如果发射中的水滴经过的元素层级为 0,则表明该元素没水滴,继续朝该方向飞行,直到找到有层级(有水滴)的元素,为之层级+1,如超出边界,则不作处理,并重复上诉条件判断。

5.获胜条件

当所有水滴不存在时(矩阵中所有元素的层级为 0 时),则获胜,进入下一关卡。

3.源码

3.1 Template 部分

<template>
  <div class="st">
    hasBlock:{{ hasBlock }} bullets:{{ bullets }} scores:{{ scores }} level:{{
      gLevel
    }}
    <div v-for="(ytem, y) in martix" :key="y">
      <div
        class="cbutton"
        :class="ytem.class"
        v-for="(xtem, x) in ytem"
        :key="x"
        @click="sendBullet(xtem)"
      >
        <div class="btn_cover" v-for="ltem in xtem.level" :key="ltem"></div>
      </div>
    </div>
  </div>
</template>

3.2 Script 部分

<script>
export default {
  data() {
    return {
      mapSize: {
        x: 5,
        y: 5
      },// 矩阵大小
      martix: [], // 矩阵数据
      bullets: 0, // 可用子弹数
      levelMax: 5, // 爆炸层级
      scores: 0, // 分数
      hasBlock: 0, // 当前剩余块 为0则胜利进入下一关

      gLevel: 0 // 当前关卡
    };
  },
  mounted() {
    this.__INIT(); // 初始化
  },
  methods: {
    GetRandomNum(Min, Max) {
      const Range = Max - Min;
      const Rand = Math.random();
      return Min + Math.round(Rand * Range);
    },
    __INIT() {
      // 地图大小
      this.gLevel = 0;
      this.scores = 0;
      this.bullets = 15; // 初始子弹数
      this.createMap();
    },
    // 下一关
    __NextMap() {
      this.gLevel++;
      this.bullets += 8; // 每次过关,奖励8个子弹
      this.createMap();
    },
    // 创建地图,初始化数据
    createMap() {
      let hasBlock = 0;
      const m = this.mapSize;
      const martix = [];
      for (let y = 0; y < m.y; y++) {
        for (let x = 0; x < m.x; x++) {
          martix[x] = martix[x] || [];
          martix[x][y] = {
            x,
            y,
            level: this.GetRandomNum(0, 3), // 获取随机层级 随机0-3层
            class: []
          };
          if (martix[x][y].level > 0) {
            // 记录需要消灭的水滴数量
            hasBlock++;
          }
        }
      }
      this.martix = martix;
      this.hasBlock = hasBlock;
    },
    radioActive(tem, direction) {
      let { x, y } = tem;
      // 有方向朝指定方向扩展,没反向四散
      if (direction) {
        // 存在方向 去对应方向查找,直到找到为之加一层级或者找不到结束
        let data = null;
        switch (direction) {
          case "up": {
            while (x >= 0 && !data?.level) {
              x--;
              data = this.martix[x]?.[y];
            }
            data?.level && this.upLevelOnce(data);
            break;
          }
          case "down": {
            while (x < this.martix.length && !data?.level) {
              x++;
              data = this.martix[x]?.[y];
            }
            data?.level && this.upLevelOnce(data);
            break;
          }
          case "left": {
            while (y >= 0 && !data?.level) {
              y--;
              data = this.martix[x]?.[y];
            }
            data?.level && this.upLevelOnce(data);
            break;
          }
          case "right": {
            while (y < this.martix[x].length && !data?.level) {
              y++;
              data = this.martix[x]?.[y];
            }
            data?.level && this.upLevelOnce(data);
            break;
          }
          default: {
          }
        }
      } else {
        // 不存在方向,说明需要四周执行
        this.radioActive(tem, "up");
        this.radioActive(tem, "down");
        this.radioActive(tem, "left");
        this.radioActive(tem, "right");
      }
    },
    // 为某个点升一级
    upLevelOnce(tem) {
      if (!tem) return;
      let { x, y, level } = tem;
      if (level + 1 !== this.levelMax) {
        this.martix[x][y].level++;
        return;
      } else {
        // 达到爆炸层级 当前清零
        this.martix[x][y].level = 0;
        // 需要消灭的水滴减一
        this.hasBlock--;
        // 分数累计
        this.scores++;
        // 如果剩余消灭水滴为0进入下一级
        if (this.hasBlock === 0) {
          //
          this.__NextMap();
          return;
        }
        // TODO: 进行动画播放

        // update other data
        // setTimeout(() => {
        this.radioActive(tem); // 因为爆炸,所以四周发射水滴
        // }, 1000);
      }
    },
    // 指定某个点升一级
    sendBullet(tem) {
      this.bullets--;
      this.upLevelOnce(tem);
      // 爆炸完后没子弹了也没通过当前关,结束
      if (this.bullets === 0) {
        alert("you are die");
        this.__INIT(); // 重新初始化
        return;
      }
    }
  }
};
</script>

3.3 Style 部分

<style>
body {
  background: #242943;
  color: #ffffff;
}
.cbutton {
  width: 120px;
  position: relative;
  display: inline-flex;
  padding: 0;
  box-shadow: inset 0 0 0 2px #ffffff;
  color: #ffffff;
  cursor: pointer;
  height: 3.5em;
}
.btn_cover {
  width: 25%;
  background-color: #fff;
}
</style>
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
【资源说明】 基于Vue开发的猜数字小游戏源码(课程作业).zip基于Vue开发的猜数字小游戏源码(课程作业).zip基于Vue开发的猜数字小游戏源码(课程作业).zip基于Vue开发的猜数字小游戏源码(课程作业).zip基于Vue开发的猜数字小游戏源码(课程作业).zip基于Vue开发的猜数字小游戏源码(课程作业).zip基于Vue开发的猜数字小游戏源码(课程作业).zip基于Vue开发的猜数字小游戏源码(课程作业).zip基于Vue开发的猜数字小游戏源码(课程作业).zip基于Vue开发的猜数字小游戏源码(课程作业).zip基于Vue开发的猜数字小游戏源码(课程作业).zip基于Vue开发的猜数字小游戏源码(课程作业).zip基于Vue开发的猜数字小游戏源码(课程作业).zip基于Vue开发的猜数字小游戏源码(课程作业).zip基于Vue开发的猜数字小游戏源码(课程作业).zip基于Vue开发的猜数字小游戏源码(课程作业).zip基于Vue开发的猜数字小游戏源码(课程作业).zip基于Vue开发的猜数字小游戏源码(课程作业).zip 【备注】 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载使用,也适合小白学习进阶,当然也可作为毕设项目、课程设计、作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可直接用于毕设、课设、作业等。 欢迎下载,沟通交流,互相学习,共同进步!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值