一、效果展示
文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-848352.html
二、代碼
<template>
<view class="page">
<view class="top">
<view class="score">
得分:{{total}}
</view>
<view class="time">
用時(shí):{{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()">
結(jié)束
</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'
// 游戲狀態(tài)
const gameStatus = ref<boolean>(false);
// 顯示的數(shù)組
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>();
// 用時(shí)
const allTime = ref(0)
const timer1 = ref()
// 游戲開始
const gameStart = () => {
total.value = 0;
allTime.value = 0
gameStatus.value = true;
gameBoard.value = numInit()
timer1.value = setInterval(() => {
allTime.value = allTime.value + 1;
}, 1000)
}
// 游戲結(jié)束
const gameOver = () => {
gameStatus.value = false;
clearInterval(timer1.value)
timer1.value = null;
newArr.value = Array.from({ length: 2 }, () => Array(2).fill(null));
}
// 獲取隨機(jī)數(shù)的函數(shù)
const getRandomlet = (min, max) => {
min = Math.ceil(min);
max = Math.floor(max);
return Math.floor(Math.random() * (max - min + 1)) + min;
}
// 隨機(jī)初始化數(shù)值
const numInit = () => {
const array = Array.from({ length: 4 }, () => Array(4).fill(0));
const positions = [];
// 生成一個(gè)包含所有可能位置的數(shù)組
for (let i = 0; i < 4; i++) {
for (let j = 0; j < 4; j++) {
positions.push({ x: i, y: j });
}
}
// 隨機(jī)選擇6個(gè)位置
const selectedPositions = [];
for (let i = 0; i < 6; i++) {
const randomIndex = getRandomlet(0, positions.length - 1);
selectedPositions.push(positions[randomIndex]);
positions.splice(randomIndex, 1); // 從數(shù)組中移除已選位置,避免重復(fù)選擇
}
// 設(shè)置前4個(gè)位置為2
for (let i = 0; i < 4; i++) {
const position = selectedPositions[i];
array[position.x][position.y] = 2;
}
// 對(duì)于剩下的2個(gè)位置,隨機(jī)設(shè)置為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;
}
// 旋轉(zhuǎn)數(shù)組
const rotate90Clockwise = (matrix) => {
const n = matrix.length;
let rotatedMatrix = Array.from({ length: n }, () => []);
// 順時(shí)針旋轉(zhuǎ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;
}
// 累計(jì)與填入
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++) {
// 找到第一個(gè)不為0
if (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;
}
// 移動(dòng)到第一個(gè)0
if (copiedArray[i][p] == 0) {
copiedArray[i][p] = copiedArray[i][j];
copiedArray[i][j] = 0;
}
}
}
}
}
total.value = total.value + defen
return copiedArray;
}
// 添加新數(shù)字
const addRandomNumbersToZeros = (arr) => {
let matrix = JSON.parse(JSON.stringify(arr));
// 存儲(chǔ)所有值為0的元素的坐標(biāo)
let zeroIndices = [];
// 遍歷二維數(shù)組,找到值為0的元素的坐標(biāo)
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]);
}
}
}
// 如果沒(méi)有0,則無(wú)法添加數(shù)字
if (zeroIndices.length < 2) {
gameOver()
return;
}
// 從所有0的坐標(biāo)中隨機(jī)選擇兩個(gè)
let randomIndices = zeroIndices.sort(() => 0.5 - Math.random()).slice(0, 2);
// 為這兩個(gè)坐標(biāo)對(duì)應(yīng)的元素添加隨機(jī)數(shù)字
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;
}
// 移動(dòng)
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>
三、體驗(yàn)地址
微信小程序搜索《靜遠(yuǎn)的工具箱》:偶數(shù)求和那個(gè)功能文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-848352.html
到了這里,關(guān)于vue3+uniapp在微信小程序?qū)崿F(xiàn)一個(gè)2048小游戲的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!