| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246 | <!DOCTYPE html><html lang="en"><head>    <meta charset="UTF-8">    <meta http-equiv="X-UA-Compatible" content="IE=edge">    <meta name="viewport" content="width=device-width, initial-scale=1.0">    <title>游戏房间</title>    <link rel="stylesheet" href="css/common.css">    <link rel="stylesheet" href="css/game_room.css"></head><body>    <div class="nav">网络五子棋对战游戏</div>    <div class="container">        <div id="chess_area">            <!-- 棋盘区域, 需要基于 canvas 进行实现 -->            <canvas id="chess" width="450px" height="450px"></canvas>            <!-- 显示区域 -->            <div id="screen"> 等待玩家连接中... </div>        </div>        <div id="chat_area" width="400px" height="300px">            <div id="chat_show">                <p id="self_msg">你好!</p></br>                <p id="peer_msg">你好!</p></br>            </div>            <div id="msg_show">                <input type="text" id="chat_input">                <button id="chat_button">发送</button>            </div>        </div>    </div>    <script>        let chessBoard = [];        let BOARD_ROW_AND_COL = 15;        let chess = document.getElementById('chess');        //获取chess控件区域2d画布        let context = chess.getContext('2d');        // 将http协议切换为游戏房间的websocket长连接协议        var ws_url = "ws://" + location.host + "/room";        var ws_hdl = new WebSocket(ws_url);        // 设置离开当前页面立即断开websocket连接        window.onbeforeunload = function () {            ws_hdl.close();        }        // 保存房间信息与是否轮到己方走棋        var room_info;        var is_me;        function initGame() {            initBoard();            // 背景图片            let logo = new Image();            logo.src = "image/sky.jpeg";            logo.onload = function () {                // 绘制图片                context.drawImage(logo, 0, 0, 450, 450);                // 绘制棋盘                drawChessBoard();            }        }        function initBoard() {            for (let i = 0; i < BOARD_ROW_AND_COL; i++) {                chessBoard[i] = [];                for (let j = 0; j < BOARD_ROW_AND_COL; j++) {                    chessBoard[i][j] = 0;                }            }        }        // 绘制棋盘网格线        function drawChessBoard() {            context.strokeStyle = "#BFBFBF";            for (let i = 0; i < BOARD_ROW_AND_COL; i++) {                //横向的线条                context.moveTo(15 + i * 30, 15);                context.lineTo(15 + i * 30, 430);                 context.stroke();                //纵向的线条                context.moveTo(15, 15 + i * 30);                context.lineTo(435, 15 + i * 30);                 context.stroke();            }        }        //绘制棋子        function oneStep(i, j, isWhite) {            if (i < 0 || j < 0) return;            context.beginPath();            context.arc(15 + i * 30, 15 + j * 30, 13, 0, 2 * Math.PI);            context.closePath();            //createLinearGradient() 方法创建放射状/圆形渐变对象            var gradient = context.createRadialGradient(15 + i * 30 + 2, 15 + j * 30 - 2, 13, 15 + i * 30 + 2, 15 + j * 30 - 2, 0);            // 区分黑白子            if (!isWhite) {                gradient.addColorStop(0, "#0A0A0A");                gradient.addColorStop(1, "#636766");            } else {                gradient.addColorStop(0, "#D1D1D1");                gradient.addColorStop(1, "#F9F9F9");            }            context.fillStyle = gradient;            context.fill();        }        //棋盘区域的点击事件        chess.onclick = function (e) {            // 如果当前轮到对方走棋,则直接返回            if(is_me == false) {                return;            }            let x = e.offsetX;            let y = e.offsetY;            // 注意, 横坐标是列, 纵坐标是行            // 这里是为了让点击操作能够对应到网格线上            let col = Math.floor(x / 30);            let row = Math.floor(y / 30);            if (chessBoard[row][col] != 0) {                alert("当前位置已有棋子");                return;            }            // 发送走棋请求            send_chess(row, col);        }        // 发送走棋请求(websocket长连接通信,直接使用ws_hdl.send,而不是通过ajax)        function send_chess(r, c) {            var chess_info = {                optype: "put_chess",                room_id: room_info.room_id,                uid: room_info.uid,                row: r,                col: c            };            ws_hdl.send(JSON.stringify(chess_info));            console.log("click:" + JSON.stringify(chess_info));        }        // 聊天动作        // 给消息发送按钮添加点击事件        var chat_button_div = document.getElementById("chat_button");        chat_button_div.onclick = function() {            // 获取聊天输入框中的消息            var chat_msg = {                optype: "chat",                room_id: room_info.room_id,                uid: room_info.uid,                message: document.getElementById("chat_input").value            };            // 将消息发送给服务器            ws_hdl.send(JSON.stringify(chat_msg));         }                // websocket各种事件的执行函数        ws_hdl.onopen = function() {            console.log("游戏房间长连接建立成功");        }        ws_hdl.onclose = function() {            console.log("游戏房间长连接断开");        }        ws_hdl.onerror = function() {            console.log("游戏房间长连接建立出错");        }        // 更新screen显示的内容        function set_screen(me) {            var screen_div = document.getElementById("screen");            if(me) screen_div.innerHTML = "轮到己方走棋...";            else screen_div.innerHTML = "轮到对方走棋...";        }        ws_hdl.onmessage = function(evt) {            console.log("message:" + evt.data);            var resp = JSON.parse(evt.data);            // 收到room_ready响应消息            if(resp.optype == "room_ready") {                // 保存房间信息与执棋用户                room_info = resp;                 // 规定白棋先走                is_me = (room_info.uid == room_info.white_id ? true : false);                if(resp.result == false) {                    alert(resp.reason);                    location.replace("/login.html");                }                 else {                    // 更新screen显示的内容                    set_screen(is_me);                    // 初始化游戏                    initGame();                }            }            // 收到put_chess响应消息            else if(resp.optype == "put_chess") {                // 判断走棋是否成功                if(resp.result == false) {                    alert(resp.reason);                    return;                }                // 下棋坐标为-1表示对方掉线                if(resp.row != -1 && resp.col != -1) {                    // 绘制棋子                    isWhite = (resp.uid == room_info.white_id ? true : false);                    oneStep(resp.col, resp.row, isWhite);                    // 更新棋盘                    chessBoard[resp.row][resp.col] = 1;                                }                // 更新执棋玩家                is_me = !is_me;                // 更新screen显示的内容                set_screen(is_me);                // 判断是否有胜利者                winner = resp.winner;                if(winner == 0) return;                // 更新screen信息                var screen_div = document.getElementById("screen");                if(winner == room_info.uid) screen_div.innerHTML = resp.reason;                else screen_div.innerHTML = "游戏失败,再接再厉";                // 在chess_area区域下方添加返回大厅按钮                var chess_area_div = document.getElementById("chess_area");                var button_div = document.createElement("div");                button_div.innerHTML = "返回大厅";                button_div.onclick = function() {                    ws_hdl.close();                    location.replace("/game_hall.html");                }                chess_area_div.appendChild(button_div);            }            // 收到chat响应消息            else if(resp.optype == "chat") {                if(resp.result == false) {                    alert(resp.reason);                    document.getElementById("chat_input").value = "";                    return;                }                // 创建一个子控件,将消息内嵌到其中                var msg_div = document.createElement("p");                msg_div.innerHTML = resp.message;                // 添加属性                if(resp.uid == room_info.uid) msg_div.setAttribute("id", "self_msg");                else msg_div.setAttribute("id", "peer_msg");                // 添加换行                var br_div = document.createElement("br");                // 将消息与换行子控件渲染到聊天显示框中                var msg_show_div = document.getElementById("chat_show");                msg_show_div.appendChild(msg_div);                msg_show_div.appendChild(br_div);                // 清空输入框内容                document.getElementById("chat_input").value = "";            }        }    </script></body></html>
 |