内容简介:闲来无事,记录下自己完成的五子棋,纯前端实现,使用到的知识点是canvas和类。运行的时候请使用谷歌浏览器哈:arrow_right:休闲游戏--五子棋:blush:五子棋的下法我就不介绍了,下面讲下实现的几个点:嗯,一步一步来讲解下,在下棋的时候,得有棋盘吧,我这里使用
闲来无事,记录下自己完成的五子棋,纯前端实现,使用到的知识点是canvas和类。运行的时候请使用谷歌浏览器哈:arrow_right:休闲游戏--五子棋:blush:
五子棋的下法我就不介绍了,下面讲下实现的几个点:
- 实现人人对战
- 实现悔棋功能
- 实现撤消悔棋功能
- 胜利提示功能
嗯,一步一步来讲解下,在下棋的时候,得有棋盘吧,我这里使用 canvas 进行绘制:
画棋盘
这里分为两种棋盘的表现,一种是看得见的,如下:
// 画出棋盘
drawChessBoard() {
const {options} = this;
const context = this.chessboard.getContext('2d');
const {count,padding,borderColor} = options.gobangStyle; // 传入棋盘格数,边距和边框颜色
this.chessboard.width = this.chessboard.height = padding * count;
context.strokeStyle = borderColor;
for(var i = 0; i < count; i++){
context.moveTo(15 + i * padding , 15);
context.lineTo(15 + i * padding , count * padding - 15);
context.stroke();
context.moveTo(15 , 15 + i * padding);
context.lineTo(count * padding - 15 , 15 + i * padding);
context.stroke();
}
}
复制代码
画出的视觉上的棋盘效果如下:
在画出棋盘之后,还是不能够下棋的,需要有一个看不见的棋盘来记录落子的位置,这里使用到矩阵的形式了:
// 初始棋盘矩阵
initChessboardMatrix() {
const {options} = this;
const checkerboard = [];
for(let x = 0; x < options.gobangStyle.count; x++){
checkerboard[x] = [];
for(let y = 0; y < options.gobangStyle.count; y++){
checkerboard[x][y] = 0;
}
}
this.checkerboard = checkerboard;
}
复制代码
下棋
在棋盘准备好之后,就是刻画棋子了,无棋子怎么下棋呢?棋子要考虑到黑白两色的,代码如下:
// 刻画棋子
drawChessman(x,y,isBlack ){
const context = this.chessboard.getContext('2d');
context.beginPath();
context.arc(15 + x * 30, 15 + y * 30, 13, 0, 2 * Math.PI);// 画圆
context.closePath();
//渐变
var gradient = context.createRadialGradient(15 + x * 30 + 2, 15 + y * 30 - 2, 13, 15 + x * 30 + 2, 15 + y * 30 - 2, 0);
if(isBlack){ // 黑子
gradient.addColorStop(0,'#0a0a0a');
gradient.addColorStop(1,'#636766');
}else{ // 白子
gradient.addColorStop(0,'#d1d1d1');
gradient.addColorStop(1,'#f9f9f9');
}
context.fillStyle = gradient;
context.fill();
// 每次落子完成后都要判断下输赢
setTimeout(() => {
this.checkReferee(x,y,isBlack ? 1 : 2);
},0);
}
复制代码
如何下去呢?上面已将打好基础了,在点击棋盘的时候,顺便记录下矩阵上点的位置,如 (0,1),(3,1) 等位置,然后将绘制好的相应棋子填充在相应的位置就可以了:
// 落子
listenDownChessman() {
console.log('落子');
this.chessboard.onclick = event => {
// 获取棋子的位置(x,y) => (0,1)
let {
offsetX: x,
offsetY: y
} = event;
x = Math.round((x-15) / this.lattice.width);
y = Math.round((y-15) / this.lattice.height);
// console.log(x , y)
// 空的位置才可以落子
if(this.checkerboard[x][y] !== undefined && Object.is(this.checkerboard[x][y] , 0)){
// 落子后更新矩阵,切换角色,并且记录
this.checkerboard[x][y] = this.role;
// 刻画棋子
this.drawChessman(x,y,Object.is(this.role , 1));
// 落子完之后有可能悔棋之后落子,这种情况下应该重置历史记录
this.history.length = this.currentStep;
this.history.push({
x,
y,
role: this.role
});
// 保存坐标,切换角色和保存快照
this.currentStep++;
this.role = Object.is(this.role , 1) ? 2 : 1;
}
}
}
复制代码
悔棋
实现悔棋,也就是撤销画布的棋子,这里采取重新绘制覆盖已有的棋子方法:
// 销毁棋子
minusStep(x,y) {
let {options} = this;
const {count} = options.gobangStyle;
const context = this.chessboard.getContext('2d');
context.clearRect(x * 30, y * 30, 30, 30);
// 重画该圆周围的格子,对边角的格式进行特殊的处理
if(x<=0 && y <=0){
this.fixchessboard(15,15,15,30,15,15,30,15);
}else if(x>=count-1 && y<=0){
this.fixchessboard(count*30-15,15,count*30-30,15,count*30-15,15,count*30-15,30);
}else if(y>=count-1 && x <=0){
this.fixchessboard(15,count*30-15,15,count*30-30,15,count*30-15,30,count*30-15);
}else if(x>=count-1 && y >= count-1){
this.fixchessboard(count*30-15,count*30-15,count*30-30,count*30-15,count*30-15,count*30-15,count*30-15,count*30-30);
}else if(x <=0 && y >0 && y <count-1){
this.fixchessboard(15,30*y+15,30,30*y+15,15,30*y,15,30*y+30);
}else if(y <= 0 && x > 0 && x < count-1){
this.fixchessboard(x*30+15,15,x*30+15,30,x*30,15,x*30+30,15);
}else if(x>=count-1 && y >0 && y < count-1){
this.fixchessboard(count*30-15,y*30+15,count*30-30,y*30+15,count*30-15,y*30,count*30-15,y*30+30);
}else if(y>=count-1 && x > 0 && x < count-1){
this.fixchessboard(x*30+15,count*30-15,x*30+15,count*30-30,x*30,count*30-15,x*30+30,count*30-15);
}else{
this.fixchessboard(15+x*30,y*30,15+x*30,y*30 + 30,x*30,y*30+15,(x+1)*30,y*30+15)
}
}
// 修补删除后的棋盘
fixchessboard (a , b, c , d , e , f , g , h){
const context = this.chessboard.getContext('2d');
context.beginPath();
context.moveTo(a , b);
context.lineTo(c , d);
context.moveTo(e, f);
context.lineTo(g , h);
context.stroke();
}
复制代码
在进行简单的功能开发之后,就可以简单的玩下小游戏了,放出 gif demo 图 :
如有要改善的点,欢迎留言该静。相关的详细代码,请前往我的仓库 gobang部分内容 。如果能留下一颗小星星就更好了。文章原文请戳 谈谈前端实现五子棋游戏-原文
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:- 前端谈谈实现五子棋
- 前端仔教你一步步实现人人对战五子棋小游戏【canvas详细版】
- canvas 五子棋游戏
- 使用 ink + react 制作一个命令行的在线五子棋游戏客户端
- 前端科普系列(三):CommonJS 不是前端却革命了前端
- 前端科普系列(三):CommonJS 不是前端却革命了前端
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
HTML Dog
Patrick Griffiths / New Riders Press / 2006-11-22 / USD 49.99
For readers who want to design Web pages that load quickly, are easy to update, accessible to all, work on all browsers and can be quickly adapted to different media, this comprehensive guide represen......一起来看看 《HTML Dog》 这本书的介绍吧!