基于Vue3实现数字华容道游戏的示例代码

目录
  • 前言
  • 环境
  • 思路
  • 实现
    • GameCnt
    • GameTool
    • GamePass
    • GameTip
    • Menu
  • 最后

前言

恰逢春之四月,天气忽热忽凉,遇游戏大赛,以笨拙之技,书一篇小文。

游戏规则:存在n*n的格子,需要将它们按数字顺序或图片顺序一一还原即可。

环境

主要环境:

vue3 version:3.2.4

vite version:2.5.0

vue-router version:4.0.14

注:这个游戏的路由使用的是自动路由插件

主要插件:

windicss version:3.5.1

预览地址

代码地址

运行如图:

思路

  • 搭建环境,下载依赖
  • 运行项目
  • 利用windicss主体兼容pc和移动端

姑且认为小于1024的是平板或者手机 lg(1024px)

App.vue

<div class="relative w-full h-full lg:(w-750px h-800px)">
    <route-view
</div>

主体Game.vue设置4个主体组件:GameTool.vue游戏工具栏(返回、开始和步数统计)、GameCnt.vue游戏主体、Tip.vue开局提示、GamePass.vue游戏通过

实现

GameCnt

布局

  • 先画出3*3的格子,这里有多种方法,笔者这里采取最简单的动态grid布局实现,后来因为css动画选取的是transform则不用gird布局了
  • 宽高获取,这里要获取,原因是使用了transform位移动画,则需要平移距离和宽高了
  • 设置lazyShow,让第一次渲染不会有transform动画
  • 隐藏最后一个,利用数组对象value值+css实现
  • 添加其他css(windicss不好实现的css)
// 定义行个数
const rowLen = 3
// 定义cnt宽高和item的宽高
const cntWidth = ref(0)
const cntHeight = ref(0)
const itemWidth = ref(0)
const itemHeight = ref(0)

// 定义数组
const lists = ref([])

lists.value = new Array(rowLen.value * rowLen.value).fill(1).map((item, index) => ({
    key: index, // 存储原序号
    value: item, // 1 代表不是空位
    moveIndex: index
  }))

// 设置最后一个为-1
  lists.value[lists.value.length - 1]['value'] = 0

//获取dom和渲染
onMounted(() => {
   // 获取cnt宽高和item的宽高
  getCntWidth()
  // 让第一次渲染不会有transform动画
  lazyShow.value = false
})
<div v-show="!lazyShow" v-for="(item, index ) in lists" class="box rounded-md  overflow-hidden absolute"
      :class="[item.value ? 'origin' : 'opacity-0']" @click="boxClick(item)" :style="{
        transform: `translate(${(item.moveIndex % rowLen) * (1 / rowLen) * cntWidth}px, ${parseInt(item.moveIndex / rowLen) * (1 / rowLen) * cntHeight}px) `, width: itemWidth + 'px', height: itemHeight + 'px'
      }">
    <p class="absolute z-10 text-light-100 left-1/2 top-1/2" :class="hasImg ? 'opacity-60' : ''"
        :style="{ 'font-size': (180 / rowLen) + 'px' }">{{ item.key + 1 }}</p>
</div>

点击元素的交换

核心代码:

// 是否在一行
  const isInline = parseInt(index / rowLen.value) === parseInt(emptyIndex / rowLen.value)

 // 在一行是否相邻
  Math.abs(emptyIndex - index) === 1

  // 不在一行是否是上下关系
  Math.abs(index - emptyIndex) === rowLen.value

点击元素上下左右的交换

先判断是否在一行,再判断是否相邻即可。

  • 先判断是否在一行
  • 在一行是否相邻或不在一行是否是上下关系
  • 看情况调用changeIndex
// 是否在一行
  if (isInline) {
    // 一行则判断是否左右相邻
    console.log('相差:' + (index - emptyIndex))
    // 是否相邻
    if (Math.abs(emptyIndex - index) === 1) {
      // 改变对应moveIndex
      changeIndex()
    } else {
      console.log('不相邻')
      return
    }
  } else {
    //  不是则判断是否上下相邻
    console.log('相差:' + (index - emptyIndex))
    // 是否上或者下
    if (Math.abs(index - emptyIndex) === rowLen.value) {
      // 改变对应moveIndex
      changeIndex()
    } else {
      console.log('不相邻')
      return
    }
  }

  // 声明改变的数组moveIndex的方法
  const changeIndex = () => {
    // 步数改变
    emit('stepChange');
    // 改变对应数组里的moveIndex 注意不是 index和 moveIndex
    ([lists.value[item.key].moveIndex, lists.value[emptyItem.key].moveIndex] = [emptyIndex, index]);
  }

判断游戏通过

这个地方很简单,主要判断数组对象每一个是否原序号key是否都相等于移动后的moveIndex

// 是否都成功
  const getIsAllOk = () => {
    //
    return lists.value.some(item => item.moveIndex !== item.key)
  }
  // // 判断是否都成功了
  const flag = getIsAllOk()
  console.log(flag)
  if (!flag) {
    // alert('成功')
    gamePass()
  }

注:这个gamePass需要在defineEmits里注册

打乱数组

这个地方很有点麻烦,存在无解的情况,暂时没想到更好的实现方法,这里使用的是排序打乱

// 打乱数据
const mixData = () => {
  const arr = new Array(rowLen.value * rowLen.value).fill(0).map((item, index) => index)
  // console.log(arr)
  arr.sort(() => {
    return Math.random() > 0.5 ? -1 : 1
  })
  arr.forEach((item, index) => {
    lists.value[index].moveIndex = item
  })

  // 如果直接是成功的则重新来一次排序
  const flag = getIsAllOk()
  if (!flag) {
    // alert('成功')
    mixData()
  }
}

注:有想法可以沟通下,一起提升!

动态格子和宽高

const params = route.query
// 定义行个数
rowLen.value = +params.num || 3;

// 重新获取item宽高
cnt.value && getCntWidth()

图片华容道

图片使用定位。然后超出截取即可展示出效果

<img v-if="hasImg" class="absolute" :src="Default" alt=""
        :style="{ width: cntWidth + 'px', maxWidth: cntWidth + 'px', height: cntHeight + 'px', left: -(item.key % rowLen) * (1 / rowLen) * cntWidth + 'px', top: -parseInt(item.key / rowLen) * (1 / rowLen) * cntHeight + 'px' }">

 // 是否渲染图片
  hasImg.value = params.hasImg === '1' ? true : false;

GameTool

左侧是返回按钮,右侧是重新开始按钮,中间是移动步数

移动步数后中间会调整为移动多少次

注:图标从iconfont找的

GamePass

  • 先布局全屏遮罩
  • 设置中间div样式
  • 设置通过成功提示和步数提示即可

GameTip

这个组件就是开局的提示组件

Menu

这个组件就是菜单页 设置了两种入口

最后

GameCnt 可以写一些测试代码,方便测试下通关后的情况

GameCnt 的块级效果优化过,否则只有颜色,不太好看

GamePass 还有优化空间,例如图片通过可以有不同效果啊等等

整体难度不高,可以练习下vue3,以及游戏思维

到此这篇关于基于Vue3实现数字华容道游戏的示例代码的文章就介绍到这了,更多相关Vue数字华容道内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • VUE+Canvas实现财神爷接元宝小游戏

    之前的canvas小游戏系列欢迎大家戳: <VUE实现一个Flappy Bird~~~> <猜单词游戏> <VUE+Canvas 实现桌面弹球消砖块小游戏> <VUE+Canvas实现雷霆战机打字类小游戏> 如标题,这个游戏大家也玩过,随处可见,左右方向键控制财神移动,接住从天而降的金元宝等,时间一到,则游戏结束.先来看一下效果: 相比于之前的雷霆战机要打出四处飞的子弹,这次元素的运动轨迹就很单一了,垂直方向的珠宝和水平移动的财神爷,类似于之前的代码,这里就

  • 手把手教你用vue3开发一个打砖块小游戏

    前言 用vue3写了几个实例,感觉Vue3的composition Api设计得还是很不错,改变了一下习惯,但写多两个就好了. 这次写一个也是儿时很觉得很好玩的游戏-打砖块, 无聊的时候玩一下也觉得挺好玩,游戏性也挺高.这次我直接用vite+vue3打包尝试一下,vite也是开箱即用,特点是也是可以清除死代码,按需打包,所以打包速度也是非常快的.没用过的同学可以尝试用用. 游戏效果 游戏需求 创建一个场景 创建一个球,创建一堆被打击方块 创建一个可以移动方块并可控制左右移动 当球碰撞左右上边界及

  • vue实现打地鼠小游戏

    本文实例为大家分享了vue实现打地鼠小游戏的具体代码,供大家参考,具体内容如下 效果图如下: 代码如下: <template> <div class="game"> <h2>打地鼠游戏</h2> <div class="wraper"> <div class="item" v-for="n in TOTAL" :key="n"> <

  • VUE实现一个Flappy Bird游戏的示例代码

    Flappy Bird是一个非常简单的小游戏,在app上大家都玩过.这里就用VUE来实现一个简单的PC版Flappy Bird,娱乐一下~~~~~ 要实现这个游戏,首先来分析一下游戏界面里哪几块东西需要动起来: 1.第一当然就是上下移动的小鸟: 2.横向移动的背景图,让小鸟看起来在横向飞行: 3.从画面右端进入的一排排管道. 这样很明确了,我们让上面3块内容按照规律运动起来,然后再加上规则边界判断和计分,就可以得到一个完整的游戏.所以就一块块来解决. 先来定义一些常量和变量: let rafId

  • 利用Vue.js制作一个拼图华容道小游戏

    目录 游戏介绍 核心思路 核心代码 html games 类 生成随机图片数量 移动图片 键盘事件 拼图完成 结语 游戏介绍 先看看界面 这是一个拼图游戏,可以自选难度和自选闯关图片 游戏开始后根据不同难度,生成与所选主图 对应的 不同张数的 随机顺序的小图,然后只要把乱序的小图片还原成完整的图片就闯关成功 游戏区域有一个空白位置,可以用鼠标点击空白位相邻的图片完成替换,也就是移动,也可以用键盘上下左右操作 游戏好玩,可不要贪杯哦,学习也不能落下,不管什么游戏都一样 这个虽然用到的技术很一般很简

  • Vue+TailWindcss实现一个简单的闯关小游戏

    目录 游戏介绍 实现技术 本游特色 技术实现 初始化页面 小方块设置 主角移动 自动索敌 敌人移动 胜利与失败 编辑关卡 移入移出变色 点击设置 保存关卡 游戏介绍 这是一款2d益智闯关游戏,玩家须躲避敌人与陷阱到达终点 拥有多个关卡 可进行关卡的自定义并留存数据 实现技术 vue tailwindcss 本游特色 自定义关卡 敌人自动索敌 低技术力 you win! 技术实现 初始化页面 创建一个json文件,用来存放初始关卡的变量(只有一关...) 为方块设定大小,初始化变量speed设置为

  • 基于Vue3实现数字华容道游戏的示例代码

    目录 前言 环境 思路 实现 GameCnt GameTool GamePass GameTip Menu 最后 前言 恰逢春之四月,天气忽热忽凉,遇游戏大赛,以笨拙之技,书一篇小文. 游戏规则:存在n*n的格子,需要将它们按数字顺序或图片顺序一一还原即可. 环境 主要环境: vue3 version:3.2.4 vite version:2.5.0 vue-router version:4.0.14 注:这个游戏的路由使用的是自动路由插件 主要插件: windicss version:3.5.

  • C语言实现猜数字小游戏的示例代码

    目录 一.猜数字小游戏的要求 二.猜数字小游戏实现的过程 2.1项目创建 2.2头文件内容 2.3源文件内容 三.猜数字小游戏调试结果如下 四.基于猜数字小游戏的总结 五.完整代码 一.猜数字小游戏的要求 猜数字小游戏是我们小时候喜欢我们一个经典小游戏,在本文中,猜数字小游戏主要的功能如下所示 1.登入猜数字小游戏系统,显示小时欢迎界面. 2.用户猜的数字有系统随机在1-20之间生成. 3.用户可以有5次机会猜这个随机生成的数字. 4.若用户猜大了,则系统会显示猜大了,并提示还有多少猜数字的机会

  • 基于Python实现24点游戏的示例代码

    目录 1.前言 2.思路 3.代码 1.前言 24数大家之前玩过没有? 规则:一副扑克牌抽走大王,小王,K,Q,J(有的规则里面会抽走10,本文一律不抽走),之后在牌堆里随机抽取四张牌,将这四张牌加减乘除得到24. 如果再高级一点,还会有根号.阶乘.幂之类的算法,别问为啥不能幂运算,问就是懒,自己看思路自己实现去(bushi. 知识点:随机数,列表,嵌套判断,循环,死循环,都是新手接触的东西. 由于不能进行像根号,阶乘高级的运算,改版之后完全可以了. 话不多说,上思路 2.思路 1.随机生成四个

  • 基于JS实现Flappy Bird游戏的示例代码

    前言 Flappy Bird 是一款无尽的游戏,玩家可以控制一只鸟.玩家必须保护小鸟免于与管道等障碍物相撞.每次小鸟通过管道时,分数都会增加一.当小鸟与管道碰撞或因重力而坠落时,游戏结束.以下部分描述了构建此游戏必须采取的步骤. 游戏可以通过这个链接进入 完整源码地址 实现代码 HTML 部分:在此部分中,创建和加载游戏的元素.选择背景.鸟类.障碍和得分元素的图像.接下来,我们创建并链接 style.css 和 index.js 文件. <!DOCTYPE html> <html>

  • 基于C语言实现迷宫游戏的示例代码

    目录 C语言迷宫游戏 定义地图 打印地图方法一 打印地图方法二 定义起点和终点位置 实现读取按键 实现小球下向下移动一步 总结小球移动规律 实现重新打印地图 实现连续移动 实现小球下向上下左右移动 实现小球走到终点就胜利 C语言迷宫游戏 这篇文章是给学完并学懂了C语言的分支(选择和循环)结构和二维数组的朋友看的. 要做一个游戏或者程序先要想好有那些要求,以下是我认为一个迷宫必带的要求: 迷宫要先打印出来(要设置墙.空气.小球的起点),是墙就不能,是空气就可以走. 每次输入'w'.'a'.'s'.

  • 基于JS实现蜘蛛侠动作游戏的示例代码

    目录 代码结构 代码展示 HTML JS 项目运行 游戏截图 整个游戏源码是由html.js. css.图片等代码完成的,无后端数据保存功能. 代码结构 js文件夹是游戏事件控制文件 vapp文件夹是游戏图片文件 icon.png 是网页游戏图标 index.html 是游戏主页 代码展示 HTML index.html代码如下: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http:/

  • 基于JS实现飞机大战游戏的示例代码

    目录 演示 技术栈 源码 定义敌方战机 定义我方战机 碰撞检测 演示 技术栈 今天没有什么特别要讲的,要不我们提前介绍下次要做的技术吧.你不说话就是同意了.我们开始了. 下图是正则表达式的一些总结大家可以先看看哦 (function() { /** * 1. JavaScript使用正则式的函数 */ const str = "abchelloasdasdhelloasd"; // 1. 查找 console.log(str.search("h")); // 3 /

  • 基于Python实现成语填空游戏的示例代码

    目录 前言 一.环境准备 二.代码展示 三.效果展示 前言 成语填空想必大家都是十分熟悉的了,特别是有在上小学的家长肯定都有十分深刻的印象. 在我们的认知里看图猜成语不就是一些小儿科的东西吗? 当然了你也别小看了成语调控小游戏,有的时候知识储备不够,你还真的不一定猜得出来是什么?更重要的是有的时候给你这个提示你都看不懂,那你就拿他没办法.——小学语文必备 成语是小学语文非常重要的一个知识点,几乎是逢考必有,作为基础,自然是需要长期的积累,并且需要积累到一定的数量,有了一定的量才能够产生质变,对于

  • C#实现数字华容道游戏

    本文实例为大家分享了C#实现数字华容道游戏的具体代码,供大家参考,具体内容如下 代码如下: using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windo

  • 基于C#的winform实现数字华容道游戏

    数字华容道游戏类似于拼图游戏,只需将数字1~15按顺序排好即可.该游戏逻辑比较简单,易于编程实现. 游戏界面如图: 编程准备: 所需控件:label 用于显示时间, 一个重新开始的button,一个panel容器来存放数字块(按钮),再加一个timer来计时及判断游戏是否结束. 主要代码: variables类: class variables     {         public static int[] a = new int[16] { 1, 2, 3, 4, 5, 6, 7, 8,

随机推荐