JS简易实现五子棋游戏(三)

一、简介

本篇为对 JS实现双人五子棋简易游戏(上) 进行补充,添加了悔棋的功能,并修改部分页面效果。

若想实现人机的游戏方式可以看之前:JS实现五子棋单人双人简易游戏(下)

二、效果

三、代码

  1. index.html
<!DOCTYPE HTML>
<html>

<head>
    <title> 五子棋 </title>
    <link rel="stylesheet" type="text/css" href="./css/style.css">
    <link rel="stylesheet" href="./css/popup.css">
</head>

<body>

    <div class="centre">
        <canvas id='canvas' class="canvas" width='450' height='450'></canvas>
        <button id="btnNew" class='btn'>新游戏</button>
        <button id='btnClean' class="btn btnClean">悔棋</button>
        <p class="txtClean">tip</p>
    </div>

    <!-- popup -->
    <div id="popup">
        <div class="pop">
            <!-- popup-header -->
            <div class="popup-header">
                <p>tip</p>
                <span id="btnClose" class="close">&times;</span>
            </div>
            <!-- popup-content -->
            <div class="popup-content">
                <p id="popup-txt" ></p>
                <button id="consent">Yes</button>
                <button id="dissent">No</button>
            </div>
            <!-- popup-footer -->
            <div class="popup-footer"></div>
        </div>
    </div>

</body>

<script src="./js/tool.js"></script>
<script src="./js/popup.js"></script>

</html>
  1. style.css

body{
    margin: 0;
    background-color: #eee;
}

.centre{
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%,-50%);
}

.canvas{
    display: block; /* 块元素 */
    margin: 20px auto;
    background-color: #946136;
}

.btn{
    position: relative;
    margin: 15px 5px;
    width: 100px;
    height: 35px;
    font-size: 16px;
    color: #000000;
    background-color: #ffffff;
    border-radius:10px; /* 按钮圆角 */
    border: none; /* 按钮边框 */
    box-shadow: 1px 2px 2px #000000; /* 按钮添加阴影 */
}

.btn:hover {/* 按钮鼠标悬停 */
    color: #000000;
    cursor: pointer; /* 显示的光标的类型 */
    box-shadow: 1px 5px 5px #ccc; /* 按钮添加阴影 */
    border: 1px solid #000000; /* 按钮边框 */
}

.btn:active {/* 按钮鼠标点击 */
    border: none; /* 按钮边框 */
    transform: translateY(4px);/*对按钮进行移动*/
}

.txtClean{
    padding: 8px;
    display: inline;  /* 行内元素 */
    border: 2px solid #000000;
}

  1. popup.css

#popup {
    display: none;
    position: fixed;
    z-index: 1;
    left: 0;
    top: 0;
    width: 100%;
    height: 100%;
    overflow: auto;
    background: rgba(0, 0, 0, 0.5);
}

#popup .pop {
    width: 300px;
    height: 100px;
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%,-50%);
    animation: animate 0.01s;
}

.pop .popup-header {
    height: 42px;
    background: white;
    color: #000;
    line-height: 45px;
    border-bottom: 1px solid #000000;
}

.pop .popup-header p {
    display: inline-block;
    margin: 0;
    position: absolute;
    left: 12px;
}

.pop .popup-header .close {
    position: absolute;
    right: 18px;
    font-size: 20px;
    cursor: pointer;
}

.pop .popup-content {
    background: white;
    height: 90px;
    text-align: center;
}

.pop .popup-content p {
    margin: 0;
    padding: 10px;
}

.pop .popup-content button{
    margin: 10px;
    float: right;
    width: 36px;
    height: 24px;
    color: #000000;
    background-color: #ffffff;
    border-radius: 2px; 
    border: 1px solid #000000; 
    box-shadow: 1px 2px 2px #ccc; 
    cursor: pointer; /* 显示的光标的类型 */
}

.pop .popup-footer {
    position: relative;
    height: 25px;
    background: white;
    border-top: 1px solid #000000;
}

/*添加动画*/
@keyframes animate {
    from {
        top: 0;
        opacity: 0
    }

    to {
        top: 50%;
        opacity: 1
    }
}
  1. tool.js

var canvas = document.querySelector('#canvas');//获取画布元素
var btnNew = document.querySelector('#btnNew');//获取按钮元素
var btnClean = document.querySelector('#btnClean');//获取悔棋按钮
var ctx = canvas.getContext('2d');//获取绘制环境
var chesscolor = ['BLACK','WHITE'];//落子颜色
var step = 0;//记录当前步数
var flag = true;//记录游戏状态
var maparr = [];//记录棋盘状态
var chessXY = [, ];//记录落棋坐标
var txtClean = document.querySelector('.txtClean'); //tip文本
var popup = document.querySelector("#popup"); //弹窗
var btnClose = document.querySelector("#btnClose"); //弹窗关闭按钮
var popupContent = document.querySelector('.popup-content'); //弹窗主体
var popupTxt = document.querySelector('#popup-txt'); //弹窗文本
var consent = document.querySelector("#consent"); //弹窗确认按钮
var dissent = document.querySelector("#dissent"); //弹窗取消按钮
var numClean = 3; //悔棋次数

//检测棋子方向
var mode = [
    [1,0],//水平
    [0,1],//垂直 
    [1,1],//左上右下
    [1,-1]//右上左下
];

//绘制文字
ctx.font="70px Arial";
ctx.fillText('Start Game!',40,235);

//开始新游戏
btnNew.onclick = function(){    
    consent.style.visibility="visible"; //显示弹窗按钮
    dissent.style.visibility="visible"; //显示弹窗按钮
    btnClose.style.visibility = "hidden"; //隐藏弹窗关闭按钮
    popupTxt.innerHTML = "本局是否允许悔棋?"; //修改弹窗文本
    popupContent.style = "height: 90px;"; //修改弹窗高度
    popup.style.display = "block"; //显示弹窗
    startGame();
    cleanChessBoard();
    drawChessBoard();    
};
//悔棋按钮
btnClean.onclick = function(){    
    if(!flag){//判断游戏是否结束
        consent.style.visibility="hidden"; //隐藏弹窗按钮
        dissent.style.visibility="hidden"; //隐藏弹窗按钮
        btnClose.style.visibility="visible"; //显示弹窗关闭按钮
        popupTxt.innerHTML = "Game Over!"; //修改弹窗文本
        popupContent.style = "height: 45px;"; //修改弹窗高度
        popup.style.display = "block"; //显示弹窗            
        return;            

    }else if(numClean != 0){//判断能否悔棋
        cleanChessBoard();
        drawChessBoard();
        cleanChess(chessXY);
    }else{ //悔棋次数为0
        consent.style.visibility="hidden"; //隐藏弹窗按钮
        dissent.style.visibility="hidden"; //隐藏弹窗按钮
        btnClose.style.visibility="visible";
        popupTxt.innerHTML = "Can't do this!"; //修改弹窗文本
        popupContent.style = "height: 45px;";
        popup.style.display = "block";    
        return;
    }        
};

checkchess(canvas);

//开始游戏
function startGame(){
    //记录棋盘状态
    for(var i=0;i<14;i++){
        maparr[i] = [];
        for(var j=0;j<14;j++){
            maparr[i][j] = 0;                
        }    
    }
    flag = true;
    step = 0;
    numClean = 3;
}

//绘制棋盘
function drawChessBoard(){
    for(var i=1;i<15;i++){/*绘制路径*/
        ctx.moveTo(30*i,30);
        ctx.lineTo(30*i,420);
        ctx.moveTo(30,30*i);
        ctx.lineTo(420,30*i);                
    }
    ctx.stroke();/* 绘制(轮廓) */
    ctx.beginPath();/* 提笔 */
}

//清除棋盘
function cleanChessBoard(){
    ctx.fillStyle = '#946136';
    ctx.fillRect(0, 0, canvas.width, canvas.height);    
}

//落子机制
function checkchess(canvas){
    canvas.addEventListener('click',function(e){
        //棋子坐标
        var px = Math.floor((e.offsetX+15)/30)-1;
        var py = Math.floor((e.offsetY+15)/30)-1;

        chessXY[0] = px;chessXY[1] = py;

        //判断游戏是否结束
        if(!flag){
            consent.style.visibility="hidden"; //隐藏弹窗按钮
            dissent.style.visibility="hidden"; //隐藏弹窗按钮            
            btnClose.style.visibility="visible";
            popupTxt.innerHTML = "Game Over!";
            popupContent.style = "height: 45px;";
            popup.style.display = "block";            
            return;
        }
        //检测是否在棋盘上落子
        if((px+1)*30==0 || (py+1)*30==0 || (px+1)*30==450 || (py+1)*30==450){
            return;
        }

        if(maparr[px][py] == 0){
            //落子
            drawchess((px+1)*30,(py+1)*30,chesscolor[step%2]);
            //记录落子颜色
            maparr[px][py] = chesscolor[step%2];
            //检测哪方胜负
            for(var i=0;i<mode.length;i++){
                checkwin(px,py,chesscolor[step%2],mode[i]);
            }
            step++;
        }
    });
}

//悔棋机制
function cleanChess(chessXY){
    //修改棋盘状态
    for(var x=0;x<14;x++){
        for(var y=0;y<14;y++){
            if(maparr[x][y] != 0){
                if(x==chessXY[0] && y==chessXY[1]){
                    maparr[x][y] = 0;    
                    --step;
                    --numClean;
                    txtClean.innerHTML = `tip:本局允许悔棋,剩余 <samp style="color: red;">`+numClean+`</samp> 次`;
                    continue;
                } 
                drawchess((x+1)*30,(y+1)*30,maparr[x][y]);    
            }
    
        }    
    }
}

//绘制棋子
function drawchess(x,y,color){//传入颜色,位置,绘制棋子
    ctx.fillStyle = color;//填充颜色
    ctx.arc(x,y,15,0,Math.PI*2,false);//画圆: 圆心 半径 弧度 逆时针
    ctx.fill();//填充
    //ctx.stroke();
    ctx.beginPath();//提笔    
}

//输赢机制
function checkwin(x,y,color,mode){//状态: 黑 白 没赢    
    var count = 0;//记录个数
    for(var i=1;i<5;i++){
        if(maparr[x+i*mode[0]]){
            if(maparr[x+i*mode[0]][y+i*mode[1]] == color){
                count++;
            }else{
                break;
            }
        }
        
    }
    for(var i=1;i<5;i++){
        if(maparr[x-i*mode[0]]){
            if(maparr[x-i*mode[0]][y-i*mode[1]] == color){
                count++;
            }else{
                break;
            }
        }
    }
    
    //判断个数是否达到胜利个数    
    if(count >= 4){
        consent.style.visibility="hidden"; //隐藏弹窗按钮
        dissent.style.visibility="hidden"; //隐藏弹窗按钮
        btnClose.style.visibility = "visible";
        popupTxt.innerHTML = color + " WIN !";
        popupContent.style = "height: 45px;";
        popup.style.display = "block";            
        ctx.font="70px Arial";
        ctx.fillText("Game Over!",40,235);
        flag = false;//游戏结束
    }

}
  1. popup.js

window.onload = function () {
    var txtClean = document.querySelector('.txtClean');
    var consent = document.querySelector("#consent");
    var dissent = document.querySelector("#dissent");
    var btnClose = document.querySelector("#btnClose");
    var popup = document.querySelector("#popup");

    btnClose.onclick = function () {
        popup.style.display = "none"; // 关闭popup
    }

    consent.onclick = function () {
        popup.style.display = "none";
        txtClean.innerHTML = `tip:本局允许悔棋,剩余 <samp style="color: red;">3</samp> 次`;
        btnClean.disabled = false;
    }

    dissent.onclick = function () {
        popup.style.display = "none";
        txtClean.innerHTML = "tip:本局不允许悔棋";
        btnClean.disabled = true;
    }

}

四、结语

感兴趣的话可以点进来在线试下效果如何 五子棋 )

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值