当前位置: 首页 > news >正文

vue3+uniapp在微信小程序实现一个2048小游戏

一、效果展示

二、代码

<template><view class="page"><view class="top"><view class="score">得分:{{total}}</view><view class="time">用时:{{allTime}}s</view></view><view class="center"><view class="mainBox"><view class="row" v-for="(row, rowIndex) in gameBoard" :key="rowIndex"><view class="cell" v-for="(cell, cellIndex) in row" :key="cellIndex"><!-- 	<view :class="cell!==0?'cellBox':''"> --><view:class="cellIndex==newArr[0][1]&&rowIndex==newArr[0][0]||cellIndex==newArr[1][1]&&rowIndex==newArr[1][0]?'newBox':cell!==0?'cellBox':''"><view class="colorBox":style="{backgroundColor:cell==2?'#ff3a3a':cell==4?'#ff9b29':cell==8?'#ebff31':cell==16?'#34ff31':cell==32?'#369083':cell==64?'#2e3cff':cell==128?'#c12fff':cell==256?'#ff77ed':cell==512?'#ffe9fe':cell==1024?'#fffcd4':cell==2048?'#04010b':''}"><text v-show=" cell!==0&&cell!==1">{{ cell }}</text></view></view></view></view></view></view><view class="bottom"><view class="kaishi" v-show="gameStatus==false"><view class="flexBox"> <button @click="gameStart()"> 游戏开始</button></view></view><view class="jinxing" v-show="gameStatus==true"><view class="flexBox"><view class="gameOver"><view class="gameOverButton" @click="gameOver()">结束</view></view><view class="contorl"><view class="shang" @click="shang()"></view><view class="xia" @click="xia()"></view><view class="zuo" @click="zuo()"></view><view class="you" @click="you()"></view></view></view></view></view></view>
</template><script lang="ts" setup>import { ref } from 'vue'// 游戏状态const gameStatus = ref<boolean>(false);// 显示的数组let gameBoard = ref<number[][]>(Array.from({ length: 4 }, () => Array(4).fill(0)));// 新增的俩let newArr = ref<number[][]>(Array.from({ length: 2 }, () => Array(2).fill(null)))// 得分const total = ref<number>();// 用时const allTime = ref(0)const timer1 = ref()// 游戏开始const gameStart = () => {total.value = 0;allTime.value = 0gameStatus.value = true;gameBoard.value = numInit()timer1.value = setInterval(() => {allTime.value = allTime.value + 1;}, 1000)}// 游戏结束const gameOver = () => {gameStatus.value = false;clearInterval(timer1.value)timer1.value = null;newArr.value = Array.from({ length: 2 }, () => Array(2).fill(null));}// 获取随机数的函数const getRandomlet = (min, max) => {min = Math.ceil(min);max = Math.floor(max);return Math.floor(Math.random() * (max - min + 1)) + min;}// 随机初始化数值const numInit = () => {const array = Array.from({ length: 4 }, () => Array(4).fill(0));const positions = [];// 生成一个包含所有可能位置的数组  for (let i = 0; i < 4; i++) {for (let j = 0; j < 4; j++) {positions.push({ x: i, y: j });}}// 随机选择6个位置  const selectedPositions = [];for (let i = 0; i < 6; i++) {const randomIndex = getRandomlet(0, positions.length - 1);selectedPositions.push(positions[randomIndex]);positions.splice(randomIndex, 1); // 从数组中移除已选位置,避免重复选择  }// 设置前4个位置为2  for (let i = 0; i < 4; i++) {const position = selectedPositions[i];array[position.x][position.y] = 2;}// 对于剩下的2个位置,随机设置为4或8  for (let i = 4; i < 6; i++) {const position = selectedPositions[i];const randomValue = getRandomlet(1, 2) === 1 ? 4 : 8;array[position.x][position.y] = randomValue;}return array;}// 旋转数组const rotate90Clockwise = (matrix) => {const n = matrix.length;let rotatedMatrix = Array.from({ length: n }, () => []);// 顺时针旋转90度for (let i = 0; i < n; i++) {for (let j = 0; j < n; j++) {rotatedMatrix[j][n - i - 1] = matrix[i][j];}}return rotatedMatrix;}// 累计与填入const addNum = (arr) => {let copiedArray = JSON.parse(JSON.stringify(arr));let defen = 0;for (let i = 0; i < copiedArray.length; i++) {for (let j = 0; j < copiedArray[i].length; j++) {// 找到第一个不为0if (copiedArray[i][j] !== 0) {for (let p = 0; p < j; p++) {if (copiedArray[i][p] == copiedArray[i][j]) {copiedArray[i][p] = copiedArray[i][j] + copiedArray[i][p];defen = defen + copiedArray[i][p] / 2;copiedArray[i][j] = 0;}// 移动到第一个0if (copiedArray[i][p] == 0) {copiedArray[i][p] = copiedArray[i][j];copiedArray[i][j] = 0;}}}}}total.value = total.value + defenreturn copiedArray;}// 添加新数字const addRandomNumbersToZeros = (arr) => {let matrix = JSON.parse(JSON.stringify(arr));// 存储所有值为0的元素的坐标  let zeroIndices = [];// 遍历二维数组,找到值为0的元素的坐标  for (let i = 0; i < matrix.length; i++) {for (let j = 0; j < matrix[i].length; j++) {if (matrix[i][j] === 0) {zeroIndices.push([i, j]);}}}// 如果没有0,则无法添加数字  if (zeroIndices.length < 2) {gameOver()return;}// 从所有0的坐标中随机选择两个  let randomIndices = zeroIndices.sort(() => 0.5 - Math.random()).slice(0, 2);// 为这两个坐标对应的元素添加随机数字  let randomNumbers = [2, 4, 8];for (let index of randomIndices) {let [row, col] = index;let randomNumber = randomNumbers[Math.floor(Math.random() * randomNumbers.length)];matrix[row][col] = randomNumber;}newArr.value = randomIndices;return matrix;}// 移动const moveAndMerge = (dir) => {if (dir == 'shang') {gameBoard.value = addNum(gameBoard.value)}else if (dir == 'zuo') {let newArr = JSON.parse(JSON.stringify(gameBoard.value));newArr = rotate90Clockwise(addNum(rotate90Clockwise(rotate90Clockwise(rotate90Clockwise(newArr)))))gameBoard.value = newArr} else if (dir == 'you') {let newArr = JSON.parse(JSON.stringify(gameBoard.value));newArr = rotate90Clockwise(rotate90Clockwise(rotate90Clockwise(addNum(rotate90Clockwise(newArr)))))gameBoard.value = newArr} else if (dir == 'xia') {let newArr = JSON.parse(JSON.stringify(gameBoard.value));newArr = rotate90Clockwise(rotate90Clockwise(addNum(rotate90Clockwise(rotate90Clockwise(newArr)))))gameBoard.value = newArr}gameBoard.value = addRandomNumbersToZeros(gameBoard.value)}// 操作const shang = () => {moveAndMerge('shang')}const xia = () => {moveAndMerge('xia')}const zuo = () => {moveAndMerge('zuo')}const you = () => {moveAndMerge('you')}
</script><style lang="scss" scoped>.page {width: 100vw;overflow: hidden;height: 100vh;background-color: #c6ffe6;display: flex;flex-direction: column;font-family: cuteFont;.top {width: 80%;height: 20vw;display: flex;align-items: center;margin-left: 10%;font-size: 2rem;.score {flex: 1;}.time {flex: 1;}}.center {width: 100vw;height: 100vw;.mainBox {width: 80%;margin: 10% 10%;height: 80%;border-radius: 15px;display: flex;.row {flex: 1;display: flex;flex-direction: column;}.cell {flex: 1;border: 1px solid #ff80c2;background-color: #b5f2ff;display: flex;justify-content: center;align-items: center;color: #ffffff;font-size: 2rem;.newBox {width: 90%;height: 90%;background-color: #9d6fff;border-radius: 15px;display: flex;justify-content: center;align-items: center;animation: newBox 0.5s;}.cellBox {width: 90%;height: 90%;background-color: #9d6fff;border-radius: 15px;}.colorBox {width: 100%;border-radius: 15px;height: 100%;display: flex;justify-content: center;align-items: center;}}}}.bottom {flex: 1;position: relative;.kaishi {width: 100%;height: 100%;background-color: #86ff61;position: absolute;.flexBox {width: inherit;height: inherit;display: flex;justify-content: center;align-items: center;}}.jinxing {width: 100%;height: 100%;position: absolute;.flexBox {width: inherit;height: inherit;display: flex;flex-direction: row;.contorl {flex: 1;.shang {width: 40px;height: 40%;position: absolute;left: 50%;background-color: #ff0777;clip-path: polygon(0% 50%, 50% 0%, 100% 50%, 80% 50%, 80% 100%, 20% 100%, 20% 50%);}.shang:hover {border: 1px solid #3d37ff;}.xia {width: 40px;height: 40%;position: absolute;top: 50%;left: 50%;background-color: #ff0777;clip-path: polygon(20% 0%, 80% 0%, 80% 50%, 100% 50%, 50% 100%, 0% 50%, 20% 50%);}.xia:hover {border: 1px solid #3d37ff;}.zuo {width: 120px;height: 40px;position: absolute;top: calc(50% - 30px);left: calc(50% - 120px);background-color: #ff0777;clip-path: polygon(0% 50%, 50% 0%, 50% 20%, 100% 20%, 100% 80%, 50% 80%, 50% 100%);}.zuo:hover {border: 1px solid #3d37ff;}.you {width: 120px;height: 40px;position: absolute;top: calc(50% - 30px);left: calc(50% + 40px);background-color: #ff0777;clip-path: polygon(0% 20%, 50% 20%, 50% 0%, 100% 50%, 50% 100%, 50% 80%, 0% 80%);}.you:hover {border: 1px solid #3d37ff;}}.gameOver {.gameOverButton {width: 50px;height: 100%;font-size: 2rem;display: flex;justify-content: center;align-items: center;background-color: #fff;border-radius: 0 15px 0 0;border: 1px solid #a860ff;}}}}}}@keyframes newBox {0% {width: 0%;height: 0%;}100% {width: 90%;height: 90%;}}
</style>

三、体验地址

微信小程序搜索《静远的工具箱》:偶数求和那个功能

相关文章:

vue3+uniapp在微信小程序实现一个2048小游戏

一、效果展示 二、代码 <template><view class"page"><view class"top"><view class"score">得分:{{total}}</view><view class"time">用时:{{allTime}}s</view></view><view cl…...

常见的浏览器跨域解决方法

1. 前端方法&#xff1a;JSONP&#xff08;仅适用于GET请求&#xff09; JSONP&#xff08;JSON with Padding&#xff09;是一种利用<script>标签的src属性不受同源策略限制的特性来实现跨域数据请求的方法。JSONP通过在前端动态创建<script>标签&#xff0c;并将…...

飞桨模型转ONNX模型教程

文章目录 飞桨模型转ONNX模型教程1. ONNX简介2. Paddle2ONNX安装3. 获取Paddle2ONNX模型库4. 飞桨转ONNX教程4.1 飞桨训练模型导出为ONNX模型4.2 飞桨部署模型转为ONNX模型4.3 验证ONNX模型4.4 使用ONNX模型进行推理 5. 注意事项 飞桨模型转ONNX模型教程 1. ONNX简介 ONNX是一…...

vue使用swiper(轮播图)-真实项目使用

一、安装 我直接安装的vue-awesome-swiper": "^3.1.3"指定版本 npm install vue-awesome-swiper3.1.3 swiper --save二、vue页面使用&#xff0c;写了一个小demo <template><div class"vue-swiper"><h1>{{ msg }}</h1><…...

C++ 创建并初始化对象

创建并初始化C对象 当我们创建一个C对象时&#xff0c;它需要占用一些内存&#xff0c;即使我们写一个完全为空的类&#xff0c;类中没有成员&#xff0c;什么也没有&#xff0c;它至少也要占用一个字节的内存。但是我们类中有很多成员&#xff0c;它们需要存储在某地方&#…...

大数据可视化python01

import pandas as pd import matplotlib.pyplot as plt# 设置中文改写字体 plt.rcParams[font.sans-serif] [SimHei]# 读取数据 data pd.read_csv(C:/Users/wzf/Desktop/读取数据进行数据可视化练习/实训作业练习/瓜果类单位面积产量.csv ,encoding utf-8)#输出 print(data)…...

Java底层自学大纲_分布式篇

分布式专题_自学大纲所属类别学习主题建议课时&#xff08;h&#xff09;A 分布式锁001 Zookeeper实现分布式锁l-常规实现方式2.5A 分布式锁002 Zookeeper实现分布式锁II-续命&超时&羊群效应问题解决方案2.5A 分布式锁003 Zookeeper实现分布式锁III-基于Curator框架实现…...

Thread多线程(创建,方法,安全,通信,线程池,并发,并行,线程的生命周期)【全详解】

目录 1.多线程概述 2.多线程的创建 3.Thread的常用方法 4.线程安全 5.线程同步 6.线程通信 7.线程池 8.其它细节知识&#xff1a;并发、并行 9.其它细节知识&#xff1a;线程的生命周期 1.多线程概述 线程是什么&#xff1f; 线程(Thread)是一个程序内部的一条执行…...

自定义View中的ListView和ScrollView嵌套的问题

当我们在使用到ScrollView和ListView的时候可能会出现显示不全的问题。那我们可以进行以下分析 ScrollView在测量子布局的时候会用UNSPECIFIED。通过源码观察&#xff0c; 在ScrollView的onMeasure方法中 Overrideprotected void onMeasure(int widthMeasureSpec, int heightMe…...

支持向量机 SVM | 线性可分:硬间隔模型公式推导

目录 一. SVM的优越性二. SVM算法推导小节概念 在开始讲述SVM算法之前&#xff0c;我们先来看一段定义&#xff1a; 支持向量机(Support VecorMachine, SVM)本身是一个二元分类算法&#xff0c;支持线性分类和非线性分类的分类应用&#xff0c;同时通过OvR或者OvO的方式可以应用…...

【Unity实战】UGUI和Z轴排序那点事儿

如果读者是从Unity 4.x时代过来的&#xff0c;可能都用过NGUI这个插件&#xff08;后来也是土匪成了正规军&#xff09;&#xff0c;NGUI一大特点是可以靠transform位移的Z值进行遮挡排序&#xff0c;然而这个事情在UGUI成了难题&#xff08;Sorting Layer、Inspector顺序等因素…...

Vue/React 前端高频面试

说一说vue钩子函数 钩子函数是Vue实例创建和销毁过程中自动执行的函数。按照组件生命周期的过程分为&#xff1a;挂载阶段 -> 更新阶段 -> 销毁阶段。 每个阶段对应的钩子函数分别为&#xff1a;挂载阶段&#xff08;beforeCreate&#xff0c;created&#xff0c;befor…...

[技巧]Arcgis之图斑四至范围批量计算

ArcGIS图层&#xff08;点、线、面三类图形&#xff09;四至范围计算 例外一篇介绍&#xff1a;[技巧]Arcgis之图斑四至点批量计算 说明&#xff1a;如下图画出来的框&#xff08;范围标记不是很准&#xff09; &#xff0c;图斑的x最大和x最小&#xff0c;y最大&#xff0c;…...

C/C++工程师面试题(STL篇)

STL 中有哪些常见的容器 STL 中容器分为顺序容器、关联式容器、容器适配器三种类型&#xff0c;三种类型容器特性分别如下&#xff1a; 1. 顺序容器 容器并非排序的&#xff0c;元素的插入位置同元素的值无关&#xff0c;包含 vector、deque、list vector&#xff1a;动态数组…...

Effective Programming 学习笔记

1 基本语句 1.1 断言 在南溪看来&#xff0c;断言可以用来有效地确定编程中当前代码运行的前置条件&#xff0c;尤其是以下情况&#xff1a; 第三方工具库对输入数据的依赖&#xff0c;例如&#xff1a;minitouch库对Android版本的要求...

【MGR】MySQL Group Replication 背景

目录 17.1 Group Replication Background 17.1.1 Replication Technologies 17.1.1.1 Primary-Secondary Replication 17.1.1.2 Group Replication 17.1.2 Group Replication Use Cases 17.1.2.1 Examples of Use Case Scenarios 17.1.3 Group Replication Details 17.1…...

300分钟吃透分布式缓存-17讲:如何理解、选择并使用Redis的核心数据类型?

Redis 数据类型 首先&#xff0c;来看一下 Redis 的核心数据类型。Redis 有 8 种核心数据类型&#xff0c;分别是 &#xff1a; & string 字符串类型&#xff1b; & list 列表类型&#xff1b; & set 集合类型&#xff1b; & sorted set 有序集合类型&…...

思科网络设备监控

思科是 IT 行业的先驱之一&#xff0c;提供从交换机到刀片服务器的各种设备&#xff0c;以满足中小企业和企业的各种 IT 管理需求。管理充满思科的 IT 车间涉及许多管理挑战&#xff0c;例如监控可用性和性能、管理配置更改、存档防火墙日志、排除带宽问题等等&#xff0c;这需…...

深入剖析k8s-控制器思想

引言 本文是《深入剖析Kubernetes》学习笔记——《深入剖析Kubernetes》 正文 控制器都遵循K8s的项目中一个通用的编排模式——控制循环 for {实际状态 : 获取集群中对象X的实际状态期望状态 : 获取集群中对象X的期望状态if 实际状态 期望状态 {// do nothing} else {执行…...

go并发模式之----使用时顺序模式

常见模式之二&#xff1a;使用时顺序模式 定义 顾名思义&#xff0c;起初goroutine不管是怎么个先后顺序&#xff0c;等到要使用的时候&#xff0c;需要按照一定的顺序来&#xff0c;也被称为未来使用模式 使用场景 每个goroutine函数都比较独立&#xff0c;不可通过参数循环…...

Linux 文件类型,目录与路径,文件与目录管理

文件类型 后面的字符表示文件类型标志 普通文件&#xff1a;-&#xff08;纯文本文件&#xff0c;二进制文件&#xff0c;数据格式文件&#xff09; 如文本文件、图片、程序文件等。 目录文件&#xff1a;d&#xff08;directory&#xff09; 用来存放其他文件或子目录。 设备…...

DockerHub与私有镜像仓库在容器化中的应用与管理

哈喽&#xff0c;大家好&#xff0c;我是左手python&#xff01; Docker Hub的应用与管理 Docker Hub的基本概念与使用方法 Docker Hub是Docker官方提供的一个公共镜像仓库&#xff0c;用户可以在其中找到各种操作系统、软件和应用的镜像。开发者可以通过Docker Hub轻松获取所…...

云启出海,智联未来|阿里云网络「企业出海」系列客户沙龙上海站圆满落地

借阿里云中企出海大会的东风&#xff0c;以**「云启出海&#xff0c;智联未来&#xff5c;打造安全可靠的出海云网络引擎」为主题的阿里云企业出海客户沙龙云网络&安全专场于5.28日下午在上海顺利举办&#xff0c;现场吸引了来自携程、小红书、米哈游、哔哩哔哩、波克城市、…...

Redis相关知识总结(缓存雪崩,缓存穿透,缓存击穿,Redis实现分布式锁,如何保持数据库和缓存一致)

文章目录 1.什么是Redis&#xff1f;2.为什么要使用redis作为mysql的缓存&#xff1f;3.什么是缓存雪崩、缓存穿透、缓存击穿&#xff1f;3.1缓存雪崩3.1.1 大量缓存同时过期3.1.2 Redis宕机 3.2 缓存击穿3.3 缓存穿透3.4 总结 4. 数据库和缓存如何保持一致性5. Redis实现分布式…...

学习STC51单片机31(芯片为STC89C52RCRC)OLED显示屏1

每日一言 生活的美好&#xff0c;总是藏在那些你咬牙坚持的日子里。 硬件&#xff1a;OLED 以后要用到OLED的时候找到这个文件 OLED的设备地址 SSD1306"SSD" 是品牌缩写&#xff0c;"1306" 是产品编号。 驱动 OLED 屏幕的 IIC 总线数据传输格式 示意图 …...

Neo4j 集群管理:原理、技术与最佳实践深度解析

Neo4j 的集群技术是其企业级高可用性、可扩展性和容错能力的核心。通过深入分析官方文档,本文将系统阐述其集群管理的核心原理、关键技术、实用技巧和行业最佳实践。 Neo4j 的 Causal Clustering 架构提供了一个强大而灵活的基石,用于构建高可用、可扩展且一致的图数据库服务…...

论文浅尝 | 基于判别指令微调生成式大语言模型的知识图谱补全方法(ISWC2024)

笔记整理&#xff1a;刘治强&#xff0c;浙江大学硕士生&#xff0c;研究方向为知识图谱表示学习&#xff0c;大语言模型 论文链接&#xff1a;http://arxiv.org/abs/2407.16127 发表会议&#xff1a;ISWC 2024 1. 动机 传统的知识图谱补全&#xff08;KGC&#xff09;模型通过…...

Linux C语言网络编程详细入门教程:如何一步步实现TCP服务端与客户端通信

文章目录 Linux C语言网络编程详细入门教程&#xff1a;如何一步步实现TCP服务端与客户端通信前言一、网络通信基础概念二、服务端与客户端的完整流程图解三、每一步的详细讲解和代码示例1. 创建Socket&#xff08;服务端和客户端都要&#xff09;2. 绑定本地地址和端口&#x…...

Yolov8 目标检测蒸馏学习记录

yolov8系列模型蒸馏基本流程&#xff0c;代码下载&#xff1a;这里本人提交了一个demo:djdll/Yolov8_Distillation: Yolov8轻量化_蒸馏代码实现 在轻量化模型设计中&#xff0c;**知识蒸馏&#xff08;Knowledge Distillation&#xff09;**被广泛应用&#xff0c;作为提升模型…...

处理vxe-table 表尾数据是单独一个接口,表格tableData数据更新后,需要点击两下,表尾才是正确的

修改bug思路&#xff1a; 分别把 tabledata 和 表尾相关数据 console.log() 发现 更新数据先后顺序不对 settimeout延迟查询表格接口 ——测试可行 升级↑&#xff1a;async await 等接口返回后再开始下一个接口查询 ________________________________________________________…...