一样 先上图
源码附上
可优化的地方还有很多,懒得写了 有兴趣可以帮忙改改
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="row-UA-Compatible" content="IE=edge" />
<meta
name="viewport"
content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no, target-densitydpi=device-dpi"
/>
<title>Document</title>
<style>
* {
margin: 0;
padding: 0;
}
body {
padding: 10px;
}
.container {
max-width: 600px;
width: 90vw;
margin: auto;
margin-top: 10px;
font-size: 0;
}
.container span {
display: inline-block;
max-width: 60px;
max-height: 60px;
width: 9vw;
height: 9vw;
background: #a3a3a3;
border: 2px solid #fefbf3;
box-sizing: border-box;
position: relative;
}
.container span.plan {
background-color: #4dac4d;
}
.container span.plan-head {
background-color: #e04444;
}
.container span::after {
content: '';
display: block;
width: 100%;
height: 100%;
position: absolute;
left: 0;
top: 0;
z-index: 999;
background-color: #79b4b7;
}
.container span.nomask::after {
content: none;
}
button {
font-size: 14px;
color: #000;
background-color: rgb(187, 245, 237);
outline: unset;
border: 1px solid #ccc;
padding: 6px 15px;
border-radius: 4px;
margin-bottom: 10px;
}
</style>
</head>
<body>
<header>
<h2 style="text-align: center; line-height: 50px;">炸飞机</h2>
<h4 style="text-align: center; line-height: 20px;">
<button onclick="init()">重新开始</button><br />
<span
>您已发射<span id="shotedNum">0</span>颗导弹,累计击毁<span
id="successShotNum"
>0</span
>架飞机</span
><br />
<span style="color: rgb(209, 209, 209); font-size: 12px;"
>tips:灰色表示空,绿色表示机身,红色表示机头,命中机头则飞机被击落。</span
>
</h4>
</header>
<div class="container" onclick="handleClick()"></div>
<!-- 可以再手机浏览器调试代码 可以排错,一般用于排查手机端兼容性问题 -->
<!-- <script src="https://unpkg.com/vconsole@latest/dist/vconsole.min.js"></script>
<script>
var vConsole = new window.VConsole()
</script> -->
<script>
let shoted = 0
const setShoted = num => {
shoted = num !== undefined ? num : shoted + 1
document.getElementById('shotedNum').innerText = shoted
}
let successShot = 0
const setSuccessShot = num => {
successShot = num !== undefined ? num : successShot + 1
document.getElementById('successShotNum').innerText = successShot
}
// 生成[m,n]的随机数
const rangeRandom = (m, n) => {
const mun = ~~(Math.random() * (n - m + 1) + m)
return mun
}
// 不同朝向的飞机所对应的机头的横纵坐标的范围
const planeHeadRangeMap = {
top: {
row: [0, 6],
col: [2, 7]
},
left: {
row: [2, 7],
col: [0, 6]
},
bottom: {
row: [3, 9],
col: [2, 7]
},
right: {
row: [2, 7],
col: [3, 9]
}
}
const handleClick = () => {
var e = e || window.event
if (
e.target.nodeName !== 'SPAN' ||
e.target.classList.contains('nomask')
) {
return
}
setShoted()
e.target.classList.add('nomask')
// 如果击中飞机头部
const { row, col } = e.target.dataset
if (map[~~row][~~col] === 2) {
setSuccessShot()
if (successShot === 3) {
confirm('恭喜你 所有日本鬼子的飞机都被炸碎了,再来一局吧') && init()
}
}
}
let map
let pointList = []
const addClass = (row, col) => {
const rowEl = document.querySelectorAll('p')[row]
const spanEl = rowEl.children[col].classList.add('plan')
}
const canGeneratePlan = (row, col, direction) => {
switch (direction) {
case 'top':
pointList = [
[row, col],
[row + 1, col - 2],
[row + 1, col - 1],
[row + 1, col],
[row + 1, col + 1],
[row + 1, col + 2],
[row + 2, col],
[row + 3, col - 1],
[row + 3, col],
[row + 3, col + 1]
]
break
case 'left':
pointList = [
[row, col],
[row - 2, col + 1],
[row - 1, col + 1],
[row, col + 1],
[row + 1, col + 1],
[row + 2, col + 1],
[row, col + 2],
[row - 1, col + 3],
[row, col + 3],
[row + 1, col + 3]
]
break
case 'bottom':
pointList = [
[row, col],
[row - 1, col - 2],
[row - 1, col - 1],
[row - 1, col],
[row - 1, col + 1],
[row - 1, col + 2],
[row - 2, col],
[row - 3, col - 1],
[row - 3, col],
[row - 3, col + 1]
]
break
case 'right':
pointList = [
[row, col],
[row - 2, col - 1],
[row - 1, col - 1],
[row, col - 1],
[row + 1, col - 1],
[row + 2, col - 1],
[row, col - 2],
[row - 1, col - 3],
[row, col - 3],
[row + 1, col - 3]
]
break
}
const isbeizhan = pointList.find(i => {
let rowNum = i[0]
let colNum = i[1]
return map[rowNum][colNum] !== 0
})
return !isbeizhan
}
const drawPlan = (row, col) => {
map[row][col] = 2
const rowEl = document.querySelectorAll('p')[row]
const spanEl = rowEl.children[col].classList.add('plan-head')
pointList.map(i => {
const row = i[0]
const col = i[1]
map[row][col] = map[row][col] ? map[row][col] : 1
addClass(row, col)
})
}
let planNum = 0
const generatPlan = num => {
while (planNum < num) {
// 随机飞机方向
const directionList = ['top', 'bottom', 'left', 'right']
const direction = directionList[~~(Math.random() * 4)]
// 获取机头的坐标范围
const { row: rowRange, col: colRange } = planeHeadRangeMap[direction]
// 随机生成机头位置
const row = rangeRandom(...rowRange)
const col = rangeRandom(...colRange)
// 如果放置飞机的位置没有被占用,则生成飞机
if (canGeneratePlan(row, col, direction)) {
drawPlan(row, col)
planNum++
}
}
}
const initExcel = () => {
// 生成 span 标签表示 10 * 10 的格子
const frag = document.createDocumentFragment()
for (let i = 0; i < 10; i++) {
const p = document.createElement('p')
for (let j = 0; j < 10; j++) {
const span = document.createElement('span')
span.setAttribute('data-row', i)
span.setAttribute('data-col', j)
p.appendChild(span)
}
frag.appendChild(p)
}
document.querySelector('.container').innerHTML = ''
document.querySelector('.container').appendChild(frag)
}
const initMap = () => {
// 生成 10 * 10 的二位数字 值都为0
map = JSON.parse(JSON.stringify(Array.from(new Array(10).fill(new Array(10).fill(0)))))
}
const init = () => {
setShoted(0)
setSuccessShot(0)
planNum = 0
initExcel()
initMap()
generatPlan(3)
}
init()
</script>
</body>
</html>