- 一丶准备素材
- 二丶实现思路
- 三丶使用js代码实现canvas的图片渲染绘制
- 四丶完整代码
准备素材
在网上找到了部分象棋的素材与背景,做为素材使用
实现思路
象棋棋盘中的棋子车、马、象、士、将、炮、卒表示,分别用r、n、b、a、k、c、p表示
棋盘初始化棋盘为:"rnbakabnr/9/1c5c1/p1p1p1p1p/9/9/P1P1P1P1P/1C5C1/9/RNBAKABNR"
代码实现
我们需要两个类 第一个为棋盘数据:chess,第二个为canvas的渲染类,canvas
chess:
我们需要"rnbakabnr/9/1c5c1/p1p1p1p1p/9/9/P1P1P1P1P/1C5C1/9/RNBAKABNR"
转换为棋盘的二维数据
然后吧整个棋盘的数据初始化为对象数组,并且初始化棋盘的图片素材
canvas:
需要初始化canvas的宽高,并且初始化棋盘的图片素材,并且初始化棋盘的渲染
完整代码
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<canvas id="canvas"></canvas>
<script src="./index.js"></script>
</body>
</html>
index.js
class Chess {
constructor() {
// 棋盘初始化字符串
this.board_str = "rnbakabnr/9/1c5c1/p1p1p1p1p/9/9/P1P1P1P1P/1C5C1/9/RNBAKABNR"
// 棋盘数据
this.board = []
//
this.flip = false
// 当前选中的棋子
this.select_chess = null
// 当前选中棋子的可移动位置
this.steps = []
// 初始化棋盘
this.init_board()
}
init_board() {
this.board = []// 棋盘数据初始化
const board = this.board_str.split('/')// 棋盘数据转换
board.forEach(v => {
v = v.split("")
v.forEach(r => {
if (/[0-9]/.test(r)) {
// 棋盘初始化中空白的位置
for (let i = 0; i < r; i++) {
this.board.push({ code: null, xy: {} })
}
} else {
// 有棋子的位置
this.board.push({ code: r, xy: {} })
}
})
})
// 棋盘数据初始化坐标
this.board.map(async (v, index) => {
// 棋盘数据初始化坐标x
v.xy.x = index % 9
// 棋盘数据初始化坐标y
v.xy.y = Math.floor(index / 9)
//当前位置有棋子
if (v.code) {
// 棋子的图片初始化 当前index大于棋盘长度的一半时为红色棋子使用m开头的图片否则为黑色棋子使用v开头的图片
v.icon = ((index > this.board.length / 2 ? 'm' : 'v') + v.code).toLowerCase()
// 加载棋子的图片
v.image = await load_image(`${v.icon}.png`)
}
})
}
}
class Canvas {
constructor() {
// canvas的图片素材
this.image = {
board_bg: 'board.png',
chess_bg: "chess_default.png"
}
// 棋盘的格子大小
this.span = 60
// 棋子的配置
this.chess_config = {
span: this.span * 0.8,
margin_left: this.span * 0.1,
margin_top: this.span * 0.06,
}
// 获取canvas的dom节点
this.ctx = document.querySelector("#canvas")
this.canvas = this.ctx.getContext("2d")
console.log(this.canvas)
// 初始化canvas
this.init_canvas()
}
draw() {
// 清空画布
this.canvas.clearRect(0, 0, this.ctx.width, this.ctx.height)
// 绘制棋盘背景
console.log(this.image.board_bg)
this.canvas.drawImage(this.image.board_bg, 0, 0, this.ctx.width, this.ctx.height)
// 对棋盘上的棋子进行遍历
chess.board.map(v => {
v.span = this.chess_config.span
// 计算棋子的坐标xy
v.xy_x = v.xy.x * this.span + this.chess_config.margin_left
v.xy_y = v.xy.y * this.span + this.chess_config.margin_top
if (v.image) { // 当前位置有棋子
// 绘制棋子的背景
this.canvas.drawImage(this.image.chess_bg, v.xy.x * this.span, v.xy.y * this.span, this.span, this.span)
// 绘制棋子
this.canvas.drawImage(v.image, v.xy_x, v.xy_y, this.chess_config.span, this.chess_config.span)
}
})
}
async init_canvas() {
// 加载棋盘的背景图
this.image.board_bg = await load_image(this.image.board_bg)
// 加载棋盘的棋子默认底图
this.image.chess_bg = await load_image(this.image.chess_bg)
this.ctx.width = this.span * 9
this.ctx.height = this.span * 10
// 绘制棋盘
this.draw()
}
}
// 加载图片方法
async function load_image(src) {
return new Promise(r => {
const image = new Image()
image.src = './images/' + src
image.onload = () => {
r(image)
}
})
}
const chess = new Chess()
const canvas = new Canvas()