游戏逻辑
与羊了个羊逻辑一致,不再赘述
游戏实现
- 盛放元素的容器box,临时存储的容器temp,多余元素的容器source与source1,结果元素result
<div id="box"></div>
<div id="temp"></div>
<div id="source"></div>
<div id="source1"></div>
<div class="result">
<div>游戏结束,别灰心,你能行的!</div>
<div class="restart">重新开始</div>
</div>
- 样式基于定位和flex布局
<style>
* {
margin: 0;
padding: 0;
list-style: none;
box-sizing: border-box;
}
html,
body {
width: 100%;
height: 100%;
overflow: auto;
background-image: url('https://pic.qy566.com/snake/bg.jpeg');
background-size: cover;
}
#box{
width: 600px;
height: 600px;
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
margin: auto;
}
#temp{
width: 840px;
height: 120px;
position: absolute;
left: 0;
right: 0;
margin: auto;
bottom: 0;
background-image: url('https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fup.92sucai.com%2Fimage%2F20180626%2F1529979993472449.jpg&refer=http%3A%2F%2Fup.92sucai.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1665795593&t=0c74935a1fa75d5861903e8249c15bbb');
background-size: contain;
border-radius: 16px;
display: flex;
}
.item{
width: 120px;
height: 120px;
border-radius: 16px;
background-size: contain;
background-position: center;
background-repeat: no-repeat;
border: 1px solid #333;
cursor: pointer;
}
.shadow{
box-shadow: 0 0 50px 10px #333 inset;
}
#source{
width: 260px;
height: 120px;
position: absolute;
top: 0;
left: 0;
}
#source1{
width: 260px;
height: 120px;
position: absolute;
top: 0;
right: 0;
}
.result{
width: 200px;
height: 120px;
border: 4px dashed cyan;
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
margin: auto;
background-color: #fff;
padding: 10px;
display: flex;
flex-direction: column;
justify-content: space-around;
align-items: center;
display: none;
}
.restart{
width: 120px;
height: 40px;
line-height: 40px;
border: 1px solid #333;
text-align: center;
cursor: pointer;
margin: auto;
}
</style>
生成元素的逻辑
- 首先会有一个维护好的图片的数组imgSrc
- 生成12*14的随机乱序待消除元素
// 随机乱序
function randomArr (array) {
const arr = [].concat(array)
for (let i = arr.length - 1; i >= 0; i--) {
const inx = Math.floor(Math.random() * i + 1)
const next = arr[inx]
arr[inx] = arr[i]
arr[i] = next
}
return arr
}
// 生成 12*14个待消除元素
for (let i =0;i<12;i++) {
imgSrc.map((v,m)=>{
console.log(m)
source.push({src: v, inx: m})
})
}
- 分为5层,进行排列,其中层数从5至0递减,然后内部双层循环进行5*层数递减页面布局,元素依次由
source.slice(0)
来得到,维护图片索引inx
for(let k =5;k>0;k--) {
for (let i=0;i<5;i++) {
for (let j=0;j<k;j++) {
let div = $('<div>')
div.addClass('item')
div.addClass(`${i}-${j}-${k}`)
div.attr('x', i)
div.attr('y', j)
div.attr('z', k)
div.css('position', 'absolute')
let img = source.splice(0,1)
div.css('left', 120*j-Math.random()*10*k+'px')
div.css('top', 120*i-Math.random()*10*k+'px')
div.attr('inx', img[0].inx)
div.css('backgroundImage', `url(${img[0].src})`)
....
}
}
}
- 判断是否被覆盖,被覆盖时添加shadow类
$('.item').each((i,v) => {
let x = $(v).attr('x')
let y = $(v).attr('y')
let z = $(v).attr('z')
let ele = $(`.${x}-${y}-${z-1}`)
let ele1 = $(`.${x+1}-${y+1}-${z-1}`)
if (ele.length || ele1.length) {
$(v).addClass('shadow')
}
})
- 添加点击事件,通过detach方式向temp中转移
- 判断是否包含shadow类
- 判断是否存在,维护temp对象
- 删除后更新shadow覆盖状态
- 判断是否大于7触发结束条件
div.click(function () {
if(!$(this).hasClass('shadow')) {
if (temp[$(this).attr('inx')]) {
temp[$(this).attr('inx')] += 1
} else {
temp[$(this).attr('inx')] = 1
}
let e = $(this).detach()
e.css('position', 'unset')
$('#temp').append(e)
$('.item').each((i,v) => {
$(v).removeClass('shadow')
let x = $(v).attr('x')
let y = $(v).attr('y')
let z = $(v).attr('z')
let ele = $(`.${x}-${y}-${z-1}`)
let ele1 = $(`.${x+1}-${y+1}-${z-1}`)
if (ele.length || ele1.length) {
$(v).addClass('shadow')
}
})
if (temp[$(this).attr('inx')]===3) {
$(`#temp div[inx=${$(this).attr('inx')}]`).remove()
temp[$(this).attr('inx')] = 0
}
let num = 0
for (let i in temp) {
num+=temp[i]
}
if (num>=7) {
$('.item').off('click')
$('.result').fadeIn()
}
}
})
- 将剩余的待消除元素均分至source和source1
let len = Math.ceil(source.length /2)
source.forEach((v,i) => {
let div = $('<div>')
div.addClass('item')
div.attr('inx', v.inx)
div.css('backgroundImage', `url(${v.src})`)
div.css('position', 'absolute')
div.css('top', 0)
if (i>len) {
div.css('right', `${5*(i-len)}px`)
$('#source1').append(div)
} else {
div.css('left', `${5*i}px`)
$('#source').append(div)
}
...
-
同样添加点击事件处理
-
初始化处理清空容器的相关逻辑
$('#box').empty()
$('#temp').empty()
$('#source').empty()
$('#source1').empty()
$('.result').fadeOut()