当前位置: 首页 > 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;不可通过参数循环…...

龙虎榜——20250610

上证指数放量收阴线&#xff0c;个股多数下跌&#xff0c;盘中受消息影响大幅波动。 深证指数放量收阴线形成顶分型&#xff0c;指数短线有调整的需求&#xff0c;大概需要一两天。 2025年6月10日龙虎榜行业方向分析 1. 金融科技 代表标的&#xff1a;御银股份、雄帝科技 驱动…...

反向工程与模型迁移:打造未来商品详情API的可持续创新体系

在电商行业蓬勃发展的当下&#xff0c;商品详情API作为连接电商平台与开发者、商家及用户的关键纽带&#xff0c;其重要性日益凸显。传统商品详情API主要聚焦于商品基本信息&#xff08;如名称、价格、库存等&#xff09;的获取与展示&#xff0c;已难以满足市场对个性化、智能…...

【JavaEE】-- HTTP

1. HTTP是什么&#xff1f; HTTP&#xff08;全称为"超文本传输协议"&#xff09;是一种应用非常广泛的应用层协议&#xff0c;HTTP是基于TCP协议的一种应用层协议。 应用层协议&#xff1a;是计算机网络协议栈中最高层的协议&#xff0c;它定义了运行在不同主机上…...

相机Camera日志实例分析之二:相机Camx【专业模式开启直方图拍照】单帧流程日志详解

【关注我&#xff0c;后续持续新增专题博文&#xff0c;谢谢&#xff01;&#xff01;&#xff01;】 上一篇我们讲了&#xff1a; 这一篇我们开始讲&#xff1a; 目录 一、场景操作步骤 二、日志基础关键字分级如下 三、场景日志如下&#xff1a; 一、场景操作步骤 操作步…...

鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个生活电费的缴纳和查询小程序

一、项目初始化与配置 1. 创建项目 ohpm init harmony/utility-payment-app 2. 配置权限 // module.json5 {"requestPermissions": [{"name": "ohos.permission.INTERNET"},{"name": "ohos.permission.GET_NETWORK_INFO"…...

JVM暂停(Stop-The-World,STW)的原因分类及对应排查方案

JVM暂停(Stop-The-World,STW)的完整原因分类及对应排查方案,结合JVM运行机制和常见故障场景整理而成: 一、GC相关暂停​​ 1. ​​安全点(Safepoint)阻塞​​ ​​现象​​:JVM暂停但无GC日志,日志显示No GCs detected。​​原因​​:JVM等待所有线程进入安全点(如…...

论文笔记——相干体技术在裂缝预测中的应用研究

目录 相关地震知识补充地震数据的认识地震几何属性 相干体算法定义基本原理第一代相干体技术&#xff1a;基于互相关的相干体技术&#xff08;Correlation&#xff09;第二代相干体技术&#xff1a;基于相似的相干体技术&#xff08;Semblance&#xff09;基于多道相似的相干体…...

IP如何挑?2025年海外专线IP如何购买?

你花了时间和预算买了IP&#xff0c;结果IP质量不佳&#xff0c;项目效率低下不说&#xff0c;还可能带来莫名的网络问题&#xff0c;是不是太闹心了&#xff1f;尤其是在面对海外专线IP时&#xff0c;到底怎么才能买到适合自己的呢&#xff1f;所以&#xff0c;挑IP绝对是个技…...

RabbitMQ入门4.1.0版本(基于java、SpringBoot操作)

RabbitMQ 一、RabbitMQ概述 RabbitMQ RabbitMQ最初由LShift和CohesiveFT于2007年开发&#xff0c;后来由Pivotal Software Inc.&#xff08;现为VMware子公司&#xff09;接管。RabbitMQ 是一个开源的消息代理和队列服务器&#xff0c;用 Erlang 语言编写。广泛应用于各种分布…...

Redis:现代应用开发的高效内存数据存储利器

一、Redis的起源与发展 Redis最初由意大利程序员Salvatore Sanfilippo在2009年开发&#xff0c;其初衷是为了满足他自己的一个项目需求&#xff0c;即需要一个高性能的键值存储系统来解决传统数据库在高并发场景下的性能瓶颈。随着项目的开源&#xff0c;Redis凭借其简单易用、…...