uni app 写的 小游戏,文字拼图?文字拼写?不知道叫啥
从下方的偏旁部首中选在1--3个组成上面文章中的文字,完成的文字标红
不喜勿喷
《满江红》 其中用到了两个文件 strdata.json parameters.json 这两个文件太大 放到资源中了
资源文件
<template>
<view class="wenzi_page_main">
<view class="wenzi_main_view">
<view v-for="(item,index) in words" :key="index">
<text :style="{color:item.color}">{{item.name}}</text>
</view>
</view>
<view class="bushou_main_view">
<view class="mall">
<view v-for="(item,index) in ppbslist" :key="index" class="item" :class="item.disabled ? 'disabled' :''"
@click="move(item,index)" :id="item.id" :style="{
width: size+'rpx',
height: size+'rpx',
left: item.left + 'rpx',
top: item.top + 'rpx'
}">
<image :style="{
width: (size-6)+'rpx',
height: (size-6)+'rpx',
borderRadius: '8rpx',
backgroundColor: '#fff',
border: '2rpx solid #71a419',
borderBottom: '10rpx solid #71a419'
}" :src="item.src"></image>
</view>
</view>
</view>
<view class="yixuan_main_view">
<view v-for="(item,index) in select" :key="index">
<image :src="item.src" class="item_image">
</image>
</view>
</view>
<view class="add_button_view">
<text class="add_button" @click="spick_click"> 满江红</text>
<text class="add_button" @click="spick_click"> 开始</text>
</view>
</view>
</template>
<script>
import strdata from './strdata.json'
import parameters from './parameters.json'
// 以下功能库请按需使用
export default {
data() {
return {
allppbslist: [],
ppbslist: [],
words: [],
strword: '怒发冲冠,凭阑处、潇潇雨歇。抬望眼,仰天长啸,壮怀激烈。三十功名尘与土,八千里路云和月。莫等闲、白了少年头,空悲切。靖康耻,犹未雪。臣子恨,何时灭。驾长车,踏破贺兰山缺。壮志饥餐胡虏肉,笑谈渴饮匈奴血。待从头、收拾旧山河,朝天阙。',
select: [],
isover: false,
layerCount: 5, //绘制4层
//行
rows: 7,
//列
cols: 7,
//卡片大小
size: 70,
canMove: true
}
},
onLoad() {
},
onShow() {
},
onReady() {
},
methods: {
move(item, index) {
if (this.isover || item.disabled || item.click) {
return
}
item.left = 800
item.top = 10000
item.id = item.id + '-move'
item.click = true
this.select.push(JSON.parse(JSON.stringify(item)))
this.pipei()
},
getppbs: function(str, id) {
let strdatas = strdata[str]
var word = {
isbj: false,
id: id,
name: str,
childcodes: [],
color: "#666"
}
if (strdatas) {
var valuearr = strdatas[strdatas.length - 1]
for (let j = 0; j < valuearr.length; j++) {
word.childcodes.push(this.convertTextToUnicode(valuearr[j]))
}
} else {
word.childcodes.push(this.convertTextToUnicode(str))
}
this.words.push(word)
},
convertTextToUnicode: function(text) {
return ("" + text).charCodeAt(0).toString(16).toUpperCase().toLowerCase();
},
init: function() {
var ppbslist = JSON.parse(JSON.stringify(this.allppbslist))
this.ppbslist = this.convertToArray5x7x7(ppbslist)
this.checkDisabled()
},
convertToArray5x7x7: function(flatArray) {
const cellHtml = []
//整理
//第一步画表格
//先绘制 最上面一层 然后 从顶层到底层绘制 进行行和列的 数据循环
for (let ly = this.layerCount - 1; ly >= 0; ly--) {
for (let i = 0; i < this.rows; i++) {
for (let j = 0; j < this.cols; j++) {
let pyStep = (ly + 1) % 2 === 0 ? this.size / 2 : 0 //给偏移量和不给偏移量 实现错开的效果
//进行 图层的渲染 id 是必要的 这个定义了 第几层ly 第几行 i 第几列j 可以判断这个卡片有没有被盖住
//最终 我们会以绝对定位的方式 进行 布局
//整个随机数
let item = (flatArray.pop()) //取完随机数 然后用pop 随用 随删 直到没有为止
item && cellHtml.push({
ly: ly,
i: i,
j: j,
left: this.size * j + pyStep,
top: this.size * i + pyStep,
id: 'm' + ly + '-' + i + '-' + j,
name: item.name,
src: item.image,
code: item.code,
isMove: false
})
}
}
}
console.log(cellHtml.length)
return cellHtml.reverse()
},
checkDisabled() {
this.ppbslist.forEach((v, index) => {
const arr = v.id.substring(1).split('-').map(v => Number(v))
const isPy = (arr[0] + 1) % 2 === 0
for (let i = arr[0] + 1; i <= this.layerCount - 1; i++) {
const isPyB = (i + 1) % 2 === 0
if (isPy === isPyB) {
let el = this.ppbslist.find(item => {
return item.id === 'm' + i + '-' + arr[1] + '-' + arr[2]
})
if (el) {
v.disabled = true
break;
}
} else if (isPy && !isPyB) {
[
`${i}-${arr[1]}-${arr[2]}`,
`${i}-${arr[1]}-${arr[2] + 1}`,
`${i}-${arr[1] + 1}-${arr[2]}`,
`${i}-${arr[1] + 1}-${arr[2] + 1}`
].every(k => {
let el = this.ppbslist.find(item => {
return item.id === 'm' + k
})
return !el
})
if (![
`${i}-${arr[1]}-${arr[2]}`,
`${i}-${arr[1]}-${arr[2] + 1}`,
`${i}-${arr[1] + 1}-${arr[2]}`,
`${i}-${arr[1] + 1}-${arr[2] + 1}`
].every(k => {
let el = this.ppbslist.find(item => {
return item.id === 'm' + k
})
return !el
})) {
v.disabled = true
break;
} else {
v.disabled = false
}
} else if (!isPy && isPyB) {
if (![
`${i}-${arr[1]}-${arr[2]}`,
`${i}-${arr[1]}-${arr[2] - 1}`,
`${i}-${arr[1] - 1}-${arr[2]}`,
`${i}-${arr[1] - 1}-${arr[2] - 1}`
].every(k => {
let el = this.ppbslist.find(item => {
return item.id === 'm' + k
})
return !el
})) {
v.disabled = true
break;
} else {
v.disabled = false
}
}
}
})
},
//将数组打乱
shuffle: function(array) {
if (!Array.isArray(array)) {
return array;
}
for (var i = array.length - 1; i > 0; i--) {
var j = Math.floor(Math.random() * (i + 1));
[array[i], array[j]] = [array[j], array[i]]
}
return array;
},
spick_click: function() {
this.isover = false
this.allppbslist = this.shuffle(JSON.parse(JSON.stringify(parameters)))
this.words = []
this.select = []
for (let i = 0; i < this.strword.length; i++) {
this.getppbs(this.strword[i], i)
}
this.init()
},
pipei: function() {
// 将arrayC中的code提取到一个Set中,以便快速查找
let setC = new Set(this.select.map(item => item.code));
for (let i = 0; i < this.words.length; i++) {
if (!this.words[i].isbj) {
let allChildCodesMatched = this.words[i].childcodes.every(code => setC.has(code));
if (allChildCodesMatched) {
this.words[i].color = "#f00"; // 如果全部匹配,将父元素的color设置为红色
this.words[i].isbj = true
for (let j = 0; j < this.words[i].childcodes.length; j++) {
for (let z = 0; z < this.select.length; z++) {
if (this.words[i].childcodes[j] == this.select[z].code) {
this.select.splice(z, 1)
if (this.select.length != 6) {
this.isover = false
}
break
}
}
}
this.checkDisabled()
return
}
}
}
if (this.select.length == 6) {
this.isover = true
uni.showToast({
title: "结束",
icon: "none"
})
} else {
this.checkDisabled()
}
},
}
}
</script>
<style>
.wenzi_page_main {
background-color: #efefef;
width: 100vw;
height: 100vh;
}
.wenzi_main_view {
margin-top: 26rpx;
display: flex;
flex-wrap: wrap;
flex-direction: row;
background: #fff;
min-height: 32px;
padding: 32rpx 32rpx 32rpx 32rpx;
}
.yixuan_main_view {
width: 100%;
margin-top: 26rpx;
display: flex;
flex-wrap: wrap;
flex-direction: row;
background-color: #efefef;
min-height: 40px;
padding: 32rpx 32rpx 32rpx 32rpx;
}
.item_image {
width: 30px;
height: 30px;
border: 1rpx solid #efefef;
margin: 2rpx;
}
.start_tv {
width: 100vw;
height: 80rpx;
background-color: #fff;
display: flex;
justify-content: center;
align-items: center;
position: fixed;
bottom: 0;
}
.bushou_main_view {
display: block;
height: 450rpx;
width: 100vw;
justify-content: center;
align-items: center;
position: relative;
margin-top: 26rpx;
margin-left: 100rpx;
flex-wrap: wrap;
flex-direction: row;
background-color: #efefef;
min-height: 32px;
padding: 32rpx 32rpx 32rpx 32rpx;
}
.main {
position: relative;
}
.item {
position: absolute;
color: #fff;
display: flex;
justify-content: center;
align-items: center;
border-radius: 10rpx;
transition: left .3s, top .3s;
}
/* 如果被压在底下的颜色 应该是一种灰色 */
.item:after {
content: '';
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
transition: background-color .3s;
}
/* 这个是为了 当配够 有disabled 属性的时候 就会透明掉 */
.disabled:after {
background-color: rgba(0, 0, 0, 0.7);
}
.add_button_view {
display: flex;
z-index: 4;
/*row 横向 column 列表 */
flex-direction: row;
justify-content: center;
align-items: center;
text-align: center;
height: 140rpx;
width: 100vw;
background: #fff;
border-top: solid 1rpx #efefef;
position: fixed;
bottom: 0;
}
.add_button {
flex: 1;
height: 88rpx;
border: solid 2rpx #07a5a6;
color: #fff;
background: #07a5a6;
font-size: 32rpx;
border-radius: 10rpx;
align-items: center;
justify-content: center;
display: flex;
margin-left: 16rpx;
margin-right: 16rpx;
}
.not_add_button {
background: #effcfb;
flex: 1;
height: 88rpx;
border: solid 2rpx #07a5a6;
color: #07a5a6;
font-size: 32rpx;
border-radius: 10rpx;
align-items: center;
justify-content: center;
display: flex;
margin-left: 16rpx;
margin-right: 16rpx;
}
</style>