样式表文件
不好意思上篇没有贴样式表,先补充上来 /assets/css/style.css
* {
padding: 0;
margin: 0;
box-sizing: border-box;
}
body {
background-color: #fbe9e7;
}
.game-wrapper {
width: 100%;
max-width: 480px;
margin: auto;
padding: 0 6px 6px;
}
.game-wrapper canvas.game-ui {
display: block;
width: 100%;
cursor: pointer;
-webkit-tap-highlight-color: transparent;
}
复制代码
方块类
扫雷游戏界面由很多方块租成,方块应该有自己的坐标(行和列),还有它周围的雷数量,是否被标记(插上红旗),是否已被点开;方块应该有描述如何绘制自己的方法;这包括文本,图标,背景的绘制;最后我们会创建一个通用的绘制方法,实现方块的绘制功能;
class Block {
constructor({ row, col, num = 0 }) {
this.row = row
this.col = col
this.num = num
this.isFlag = false
this.isOpened = false
}
// 绘制文本 雷数量
drawText({ context, size, space }) {
let fontSize = size / 2 + 'px'
let color = ({ 1: '#ff0', 2: '#0f0' })[this.num] || '#f00'
let fw = context.measureText(this.num).width
let tx = this.col * size + (size - space - fw) / 2
let ty = this.row * size + (size - space - fw) / 2
context.save()
context.font = `bold ${fontSize} serif`
context.textBaseline = 'hanging'
context.fillStyle = color
context.fillText(this.num, tx, ty)
context.restore()
}
// 绘制图标 雷和旗帜
drawIcon({ context, size, space, icon }) {
let dw, dh
if (icon.width > icon.height) {
dw = size * .5
dh = dw * (icon.height / icon.width)
} else {
dh = size * .5
dw = dh * (icon.width / icon.height)
}
let dx = this.col * size + space + (size - space - dw) / 2
let dy = this.row * size + space + (size - space - dh) / 2
context.drawImage(icon, dx, dy, dw, dh)
}
// 绘制背景
drawBG({ context, size, space, icon }) {
context.drawImage(
icon, 0, 0, icon.width, icon.height,
this.col * size + space, this.row * size + space, size - space, size - space
)
}
// 通用的绘制方法
draw({ context, size, space = 6 }) {
let params = { context, size, space }
let { blockEnd, bomb, blockFront, flag } = source.icons
if (this.isOpened) {
this.drawBG({ ...params, icon: blockEnd })
if (this.num > 0 && this.num < 9) {
this.drawText(params)
} else if (this.num === 9) {
this.drawIcon({ ...params, icon: bomb })
}
} else {
this.drawBG({ ...params, icon: blockFront })
if (this.isFlag) {
this.drawIcon({ ...params, icon: flag })
}
}
}
}
复制代码
工具对象
把一些方法放到工具对象中,是为了减轻游戏类的重量
const utils = {
// 创建一个画布包裹容器
createWrapper(mountEl) {
mountEl = mountEl || document.body
const wrapper = document.createElement('div')
wrapper.className = 'game-wrapper'
mountEl.appendChild(wrapper)
return wrapper
},
// 创建画布
createCanvas(wrapper) {
const canvas = document.createElement('canvas')
canvas.className = 'game-ui'
wrapper.appendChild(canvas)
return canvas
},
// 获取设备像素比 基于像素比的尺寸是为了让画布适应高分屏
getPixRatio(context) {
var backingStore = context.backingStorePixelRatio ||
context.webkitBackingStorePixelRatio ||
context.mozBackingStorePixelRatio || 1
return (window.devicePixelRatio || 1) / backingStore
},
// 生成初始方块数组
genBlocks(rows, cols) {
const blocks = []
for (let row = 0; row < rows; row++) {
for (let col = 0; col < cols; col++) {
blocks.push(new Block({ row, col }))
}
}
return blocks
},
// 判断是否是函数
isFunc(func) {
return typeof func === 'function'
}
}
复制代码
今天的源码分享到此结束,明天我将分享游戏的核心部分,游戏类和游戏控制类;大家有什么不明白的地方可以评论区提问,谢谢观看;前端小白,初次写文章,写的不好还请见谅;