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>
|