谈谈前端实现五子棋游戏

栏目: 后端 · 发布时间: 6年前

内容简介:闲来无事,记录下自己完成的五子棋,纯前端实现,使用到的知识点是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部分内容 。如果能留下一颗小星星就更好了。文章原文请戳 谈谈前端实现五子棋游戏-原文

谈谈前端实现五子棋游戏

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

高效程序员的45个习惯

高效程序员的45个习惯

Venkat Subramaniam、Andy Hunt / 钱安川、郑柯 / 人民邮电出版社 / 2010-01 / 35.00元

“书中‘切身感受’的内容非常有价值——通过它我们可以做到学有所思,思有所悟,悟有所行。” ——Nathaniel T. Schutta,《Ajax基础教程》作者 “此书通过常理和经验,阐述了为什么你应该在项目中使用敏捷方法。最难得的是,这些行之有效的实战经验,竟然从一本书中得到了。” ——Matthew Johnson,软件工程师 十年来,软件行业发生了翻天覆地的变化。敏捷......一起来看看 《高效程序员的45个习惯》 这本书的介绍吧!

在线进制转换器
在线进制转换器

各进制数互转换器

HTML 编码/解码
HTML 编码/解码

HTML 编码/解码