Skip to content

SCIJLab/gaming-platform-gui

 
 

Repository files navigation

通用对战平台前端

前端逻辑过程

  • 选择棋种,进入大厅
  • 选择创建房间或者选择加入已经创建的房间
  • 选择创建房间,将房间信息传给后端,若创建成功进入房间
  • 加入已创建的房间,向后端发送请求,若请求成功进入房间
  • 进入房间页面,此时尚未开始游戏
  • 尚未开始游戏,对棋盘点击为无效操作
  • 等待双方均点击开始后,计时开始,进行比赛
  • 开始游戏,进行暂停、继续、重新开始、悔棋、导出棋谱、棋子移动等操作
  • 点击空白区域/棋子,确定当前位置符合规范,进行操作
  • 点击暂停游戏,对棋盘点击为无效操作
  • 点击重新开始,清空信息,重新开始
  • 点击导出棋谱,导出棋谱信息

Room逻辑过程

进入大厅,和服务端建立连接后,服务端返回数据room_list,根据room_list建立已存在的房间列表。用户选择添加房间或者进入房间操作。

涉及的JS方法

方法 说明
parseUrl、addScript 对URL进行解析,引入需要的js(ChessGame)
AddRoomTable 向表格添加房间信息
join 加入房间
addroom 获取参数值,添加房间
ShowTable 根据接收到的room_list,创建房间列表表格

与后端的连接

房间列表
说明
mesg room_list
room_list [1,2,3,4] 房间id数组
添加房间
说明
mesg add_room
type amazons amazons或surakarta
args [10, 10] 棋盘大小
time 900 时间 (s)
order 1 1为先手,2为后手
加入房间
说明
mesg join
room_id 2 房间号
order 1 1为先手,2为后手

棋子移动的逻辑过程

苏拉卡尔塔棋

  • 点击棋子进行选中
  • 点击其他棋子进行更换
  • 点击空白处对棋子进行移动
  • 点击对方棋子进行吃子操作 ####亚马逊棋
  • 点击棋子进行选中
  • 点击其他棋子进行更换
  • 点击空白处对棋子进行移动
  • 点击空白处释放障碍

###游戏逻辑架构

几个重要的属性值:

//设置棋子及棋局
    this.chess=[];
    this.Map=[];
    this.MapList = [];
    this.LastChess=null;//用户上次指定的棋子
    this.LocalPlayer=BLACKPLAYER;//记录下棋方
    this.Player=BLACKPLAYER;//所属棋方
    this.GameType=1;//1-人人对弈;2-人机对弈;3-AI对弈
    this.ObstacleFlag=false;
    this.IsStep=false;
    //棋谱导出
    this.history=[];
    this.historyList=[];
    this.step=[]
}
ChessGame.prototype.xnum=0;
ChessGame.prototype.ynum=0;
ChessGame.prototype.rect=0;
ChessGame.prototype.border=0;
方法名 标注 描述
onclick 棋盘点击事件 if 轮到己方 and 开始游戏 --> 执行stageClick
stageClick 坐标转换 将画布坐标转换为棋盘坐标,if 没有超出范围 --> 执行PlayGame
PlayGame 对棋盘的操作 己方棋子的点击、空白区域的点击BlankOperation、敌方棋子的点击OpponentOperation,见伪代码
OverStep 判断是否执行完全部过程 更改状态值,发送数据,交换执棋方
MoveChess 移动棋子 执行Draw,将坐标存入history
Draw 绘制棋盘和剩余棋子 绘制棋盘drawBoard,绘制剩余棋子AddDrawOperation
IsBorder 判断是否越界 用于亚马逊棋移动过程画出可行域
IsMyChess 判断是否为己方棋子 用于PlayGame中,对棋子的点击事件进行判断
reversePlayer 调换下棋方 注意调换的值是LocalPlaye:表示当前执棋方,不表示己方
initGame 初始化棋局和棋子 对所有变量赋初值,清空棋谱和棋局历史
drawChess 绘制全部棋子 用于初始化棋局
AIGame 后端/算法接收数据

棋盘点击事件的伪代码如下:

PlayGame{
    if首次选择棋子-->判断棋子所属方,选中棋子  
    else if 之前选择过棋子-->  
        if 当前位置有棋子-->
            if 棋子完成走子-->不能更改选中棋子
            else 当前位置为己方棋子-->更换选中棋子
            else 当前位置为敌方棋子-->执行OpponentOperation()
        else 当前位置为空白-->BlankOperation()
    判断是否完成全部操作
}

判断是否执行完全部过程的伪代码如下:

OverStep{
    if 完成全部操作(isStep===true)-->
        设置isStep为false
        将棋盘存入棋局历史
        向后端发送坐标变化记录
        将坐标变化记录存入棋谱
        判断比赛是否结束
        改变玩家角色
}

AIGame源代码:

AIGame{
    var kw = data.kw;
    if(kw===0){//置放棋子
        var pos1 = new Point();
        pos1.x=data.move.from[1];
        pos1.y=data.move.from[0];
        var pos2 = new Point();
        pos2.x=data.move.to[1];
        pos2.y = data.move.to[0];
        this.PlayGame(pos1.x,pos1.y);
        this.PlayGame(pos2.x,pos2.y);
    }
    else if(kw===1){//置放障碍
        var pos3 = new Point();
        pos3.x=data.move.to[1];
        pos3.y = data.move.to[0];
        this.PlayGame(pos3.x,pos3.y);
    }
}

###棋子逻辑架构

参数 标注
player 所属棋方:WHITEPLAYER/BLACKPLAYER
chessName 棋子名称
pos 棋子在棋盘中的位置
x,y 棋子在画布上的位置
area 可行走范围
rect 棋子半径
border 棋子边界值
selctShape 设置选中时边框的样式(circular/Square),默认为圆形

注:由于画布(0,0)对应位置并非是棋盘的(0,0),对于苏拉卡尔塔棋,由于存在轨道因此边距值为最大的轨道半径,对于亚马逊棋,由于棋子的位置在放歌内,棋子圆心位置并非对应棋盘的(0,0),因此需要添加边距值。

方法名 标注 描述
setPosition 棋子在棋盘中的具体位置 传入参数为对应的棋盘坐标。setPosition添加两类坐标一类为棋盘坐标,一类为对应的画布坐标
showChess 显示棋子 根据棋子在画布中的坐标绘制棋子
drawSelectedChess 画选中棋子的示意边框线 根据棋子形状selctShape不同,绘制出不同的示意边框线
showArea 显示棋子可移动范围 针对亚马逊棋可行范围设定

###苏拉卡尔塔棋的编写 寄生组合式继承chess 设置苏拉卡尔塔棋的棋子半径rect、边距border、选中形状selctShape,不再添加的属性 寄生组合式继承chessgame 设置苏拉卡尔塔棋的游戏逻辑xnum,ynum,rect,border,添加原型属性:

  • passArc:是否经过圆弧
  • track:存储两轨道坐标数据
  • arclist:存储圆弧坐标数据

注:苏拉卡尔塔棋规则由双向链表DoublyList实现

方法名 标注
initChess 初始化棋子,并将其添加到棋盘数据Map中
AddInitOperation 添加初始化操作,初始化轨道坐标initArray(与苏拉卡尔塔棋的走法有关)
drawBoard 绘制棋盘
OpponentOperation 目标位置有敌方棋子,判断是否能进行吃子操作IsAbleToEat,如果可以移动棋子MoveChess,设置IsStep=true
BlankOperation 目标位置为空白, 判断是否能进行走子操作IsAbleToMove,如果可以移动棋子MoveChess,设置IsStep=true
GameOver 判断游戏是否结束

####与规则有关的编写

方法名 标注
initArray 初始化轨道坐标
IsAbleToEat 判断是否能执行吃子操作,先判断是否两棋子在同一轨道上,再判断是否可达且是否经过圆弧
IsAbleToMove 判断逻辑上是否能走子,建立可行域pointArray,判断目标坐标是否在可行域内
searchChess 判断棋子是否在轨道中,在IsAbleToEat中调用
checkChess 判断是否可达是否经过圆弧,在IsAbleToEat中调用
searchChessNext 顺查找判断两棋子间是否有其他棋子是否经过圆弧,在checkChess中调用
searchChessPrevious 顺查找判断两棋子间是否有其他棋子是否经过圆弧,在checkChess中调用
searchCircle 判断是否经过圆弧,在searchChessNext和searchChessPrevious中调用

###亚马逊棋的编写 寄生组合式继承chess 设置亚马逊棋的棋子半径rect、边距border、选中形状selctShape,添加原型属性:

  • obstacle:障碍列表 寄生组合式继承chessgame 设置亚马逊棋的游戏逻辑xnum,ynum,rect,border,添加原型属性:

  • direction:方向

  • area:棋子移动范围

  • obstacle:当前释放的障碍坐标

方法名 标注
initChess 初始化棋子,并将其添加到棋盘数据Map中
AddInitOperation 添加初始化操作,初始化八个走子方向InitDirection(与亚马逊棋塔棋的走法有关)
drawBoard 绘制棋盘
BlankOperation 目标位置为空白, 判断进行走子操作还是置换操作,见伪代码
GameOver 判断游戏是否结束

目标移动位置为空白的操作:

BlankOperation{
    if 棋子完成走子-->
        if 当前位置符合置放障碍的规则-->置放障碍,往坐标移动记录中添加障碍坐标记录
        else-->给出提示信息“当前位置不符合释放障碍的规则”  
    else 棋子未完成走子-->
        if 当前位置符合走子的规则-->移动棋子、设置并显示可置放障碍的范围
        else-->给出提示信息“当前位置不符合移动棋子的规则”

####与规则有关的编写

方法名 标注
IsAbleToPut 判断是否可以置放障碍
IsAbleToMove 判断棋子是否可以移动
PutObstacle 置放障碍
ChessArea 棋子的移动/释放障碍范围

###与后端程序的对接

方法名 标注
onopen 建立连接 ,向后端发送建立连接请求
SendData 发送坐标变化数据
AddRoom 添加房间
JoinRoom 加入房间
SendStart 点击开始
RollBack 悔棋
onmessage 接收信息

onmessage代码给出:

socket.onmessage = function (event) {
var data;
let reader = new FileReader();
reader.onload = () => {
    data = reader.result;
    data = JSON.parse(data);
    if (data.mesg === 'move') {//移动
        game.AIGame(data);
        data.playerId = player;
        notifyClient(JSON.stringify(data));
    }
    else if (data.mesg === 'add_room') {//进入房间
        var type = data.type;
        player = data.playerId;
        setOrder(data.order);
        $('.room').removeClass('active').removeClass('show').addClass('hide');
        $('.game-room').removeClass('hide').addClass('active').addClass('show');
    }
    else if (data.mesg === 'join') {//加入房间
        var type = data.type;
        player = data.playerId;
        setOrder(data.order);
        $('.room').removeClass('active').removeClass('show').addClass('hide');
        $('.game-room').removeClass('hide').addClass('active').addClass('show');
    }
    else if (data.mesg === 'room_list') {//连接成功返回房间列表
        var room_list = data.room_list;
        ShowTable(room_list);
    }
    else if (data.mesg === 'start') {
        StarGame();
        var btnVal = document.getElementById("startbtn");
        btnVal.value = "  Stop Game  ";
        notifyClient('start');
    }
};
reader.readAsText(event.data);
};

####api文档

开始
说明
mesg start
返回值
说明
state ready 如果对方没有开始则返回ready,否则返回start
移动
说明
mesg move
location {'from': [0, 0], 'to': [1, 1]} 移动坐标
kw 0 如果棋种是亚马逊棋, 0为移动棋子, 1为移动障碍; 苏拉卡尔塔棋可空
悔棋
说明
mesg rollback
返回值
说明
board [[]] 棋盘
房间列表
说明
mesg room_list
room_list [1,2,3,4] 房间id数组
添加房间
说明
mesg add_room
type amazons amazons或surakarta
args [10, 10] 棋盘大小
time 900 时间 (s)
order 1 1为先手,2为后手
加入房间
说明
mesg join
room_id 2 房间号
order 1 1为先手,2为后手
添加和加入房间的返回值
说明
playerId 'A' 玩家ID

###与博弈程序的对接

var webSocketServer = require('ws');
var port = 6666;
var wss = null;
window.onerror = function err(msg, url, line) {
    if(msg === 'Uncaught Error: listen EADDRINUSE :::6666')
        wss = new webSocketServer.Server({ 'port': port + 1 });
        wss.on('connection', function connection(ws) {
            ws.send(player);
            ws.on('message', function incoming(mesg) {
                mesg = JSON.parse(mesg);
                game.AIGame(mesg);
            })
        })
}
wss = new webSocketServer.Server({ 'port': port });
wss.on('connection', function connection(ws) {
    ws.send(player);
    ws.on('message', function incoming(data) {
        data = JSON.parse(data);
        game.AIGame(data);
    })
})
function notifyClient(data) {
    wss.clients.forEach(function each(client) {
        if (client.readyState === WebSocket.OPEN) {
            client.send(data);
        }
    });
}

Button

方法名 标注 描述
InitGame 对开始/继续按钮的操作 根据按钮值,对程序进行开始、继续、暂停操作。开始:调用SendStart(后端缺少对继续暂停操作的API,只在前端实现)
StarGame 开始游戏 接收到后端返回的state进行调用
StartTime 开始计时 在StartGame中进行调用
ResetGame 重新开始 后端未给出API,仅在前端实现
WithDraw 悔棋 后端未给出API,仅在前端实现
GetBoards 输出棋谱 调用saveAs输出棋谱(该方法在file.js中实现)
SetTime 计算黑方和白方时间

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • JavaScript 48.3%
  • CSS 24.7%
  • Python 17.0%
  • HTML 10.0%