全国 [ 切换城市 ]
咨询热线 : 400-969-7660
首页 > IT知识库 > IT教程 >

IT教程

在线五子棋实战项目解析

来源: 优逸客小编 浏览量: 日期: 2018-12-04

本片讲了web socket 的基本原理以及其运行机制,在其基础之上实现在线五子棋的实战。

一、实现原理
众所周知,Web 应用的交互过程通常是客户端通过浏览器发出一个请求,服务器端接收请求后进行处理并返回结果给客户端,客户端浏览器将信息呈现,这种机制对于信息变化不是特别频繁的应用尚可,但对于实时要求高、海量并发的应用来说显得捉襟见肘,尤其在当前业界移动互联网蓬勃发展的趋势下,高并发与用户实时响应是 Web 应用经常面临的问题,比如金融证券的实时信息,Web 导航应用中的地理位置获取,社交网络的实时消息推送等。
二、代码实现
3. 在线五子棋实战
了解了其运作原理后,我们使用socket.io这个js库来制作我们的在线五子棋,库的更多内容,大家可以访问其官网 http://socket.io 了解更多的信息。
前台技术 Java script + socket.io.js
后台技术 node.js + express + socket.io模块
首先是HTML代码
<!doctype HTML><HTML>
<head>
<meta char set="utf-8"/>
<title>Five-in-Row</title>
<meta name="vIEw port" content="width=device-width, initial-scale=1">
<link rel="style sheet" href="/style sheets/index.CSS"/>
</head>
<body>
<!-- js脚本动态生成内容追加到此处 -->
<div class="sense" id="sence"></div>
<script src="/Javascripts/socket.io-1.3.7.js"></script>
<script src="/Javascripts/index.js"></script>
</body></HTML>
CSS文件,处理一些简单的样式
body{
    background:#4b4843;
    font-family:"微软雅黑";
    color:#666;
}.sense{
    width:600px;
    height:600px;
    margin:50px auto;
    border-right:none;
    border-bottom:none;
    position:relative;
    box-shadow:-10px 10px 15px black;
    background:#8d6d45;
    border:2px solid black;
}.sense .block{
    float:left;
    margin-right:1px;
    margin-bottom:1px;
    border-radius:50%;
    position:relative;
    z-index:8884;
}.sense .row,.sense .col{
    background:#4d392b;
    position:absolute;
}.sense .row{
    width:100%;
    height:1px;
    left:0;
}.sense .col{
    width:1px;
    height:100%;
    top:0;
}.white{
    background: #ffffff;
}.black{
    background: #2c1d1b;
}
Java script实现思路,主要为画出场景,落子绘画,输赢判断,监听网络
window.on load = function(){
  var socket = io(),
      sence = document.get Element ById('sence'),
      //棋盘大小
      ROW = 10,NUM = ROW*ROW,
 
      //场景宽度
      Sence Width = sence.offsetWidth,
 
      //每颗棋子宽度
      Block Width =Math.floor( (sence Width-ROW)/ROW ) +'px',
 
      //用户开始默认可以落子
      Can Drop = true,
 
      //用户默认落子为白棋
      color='white',
 
      //两个字典,用来存放白棋和黑子的已落子位置;以坐标为键,值为true;
      White Blocks = {},black Blocks = {};
  //创建场景
  (function (){
    var el,
        //在棋盘上画横线
        Row line,
        //在棋盘上画竖线
        Col line;
    for ( var i = 0;  i < ROW;  i++){
      //按照计算好的间隔放置横线
      Row line = document.create Element('div');
      Row line.set Attribute('class','row');
      Row line.style.top =  (sence Width/ROW)/2 + (sence Width/ROW)*i + 'px';
      sence. APP endChild(rowline);
      //按照计算好的间隔放置竖线
      colline = document.createElement('div');
      colline.setAttribute('class','col');
      colline.style.left = (senceWidth/ROW)/2 + (senceWidth/ROW)*i + 'px';
      sence.APPendChild(colline);
      for ( var j = 0;  j < ROW;  j++ ){
        el = document.createElement('div');
        el.style.width =  blockWidth;
        el.style.height = blockWidth;
        el.setAttribute('class','block');
        el.setAttribute('id', i + '_' + j );
        sence.APPendChild(el);
      }
    }
  })();
  var  id2Position = function(id){
    return {x:Number(id.split('_')[0]),y:Number(id.split('_')[1])};
  };
  var position2Id  = function(x,y){
    return  x + '_' + y ;
  };
  //判断落子后该色棋是否连5;
  var  isHasWinner= function(id,dic){
    var x = id2Position(id).x;
    var y = id2Position(id).y;
    //用来记录横,竖,左斜,右斜方向的连续棋子数量
    var rowCount = 1,colCount = 1, leftSkewLineCount = 1, rightSkewLineCount = 1;
    //tx ty 作为游标,左移,右移,上移,下移,左上,右下,左下,右上移动,
    //每次数完某个方向的连续棋子后,游标会回到原点.
    var tx,ty;
    //注意,以下判断5连以上不算成功 如果规则有变动,条件改为大于5即可
    tx = x; ty = y; while(dic[ position2Id(tx,ty+1) ]){rowCount++;ty++;}
    tx = x; ty = y; while(dic[ position2Id(tx,ty-1) ]){rowCount++;ty--;}
    if( rowCount == 5 ) return true;
    tx = x; ty = y; while(dic[ position2Id(tx+1,ty) ]){colCount++;tx++;}
    tx = x; ty = y; while(dic[ position2Id(tx-1,ty) ]){colCount++;tx--;}
    if( colCount == 5 ) return true;
    tx = x; ty = y; while(dic[ position2Id(tx+1,ty+1) ]){leftSkewLineCount++;tx++;ty++;}
    tx = x; ty = y; while(dic[ position2Id(tx-1,ty-1) ]){leftSkewLineCount++;tx--;ty--;}
    if( leftSkewLineCount == 5 ) return true;
    tx = x; ty = y; while(dic[ position2Id(tx-1,ty+1) ]){rightSkewLineCount++;tx--;ty++;}
    tx = x; ty = y; while(dic[ position2Id(tx+1,ty-1) ]){rightSkewLineCount++;tx++;ty--;}
    if( rightSkewLineCount == 5 ) return true;
    return false;
  };
  //处理对手发送过来的信息
  socket.on('drop one',function(data){
    canDrop = true;
    var el = document.getElementById(data.id);
    el.setAttribute('has-one','true');
    if(data.color == 'white'){
      color = 'black';
      el.setAttribute('class','block white')
      whiteBlocks[data.id] = true;
     if(isHasWinner(data.id,whiteBlocks)){
        alert('白棋赢');
        location.reload();
      }
    }else{
      el.setAttribute('class','block black');
      blackBlocks[data.id] = true;
      if(isHasWinner(data.id,blackBlocks)){
        alert('黑棋赢');
        location.reload();
      }
    }
  });
  //事件委托方式处理用户下棋
  sence.onclick = function(e){
    var el = e.target;
    if( !canDrop ||  el.hasAttribute('has-one') || el == this  ) {
      return;
    }
    el.setAttribute('has-one','true');
    canDrop = false;
    var id = el.getAttribute('id');
    if( color == 'white' ){
      el.setAttribute('class','block white');
      whiteBlocks[id] = true;
      socket.emit('drop one', {id:id,color:'white'});
      if(isHasWinner(id,whiteBlocks)){
        alert('白棋赢');
        location.reload();
      }
    }
    if(color == 'black'){
      el.setAttribute('class','block black');
      blackBlocks[id] = true;
      socket.emit('drop one', {id:id,color:'black'});
      if(isHasWinner(id,blackBlocks)){
        alert('黑棋赢');
        location.reload();
      }
    }
  };
};
服务器端实现代码
var express = require('express');var APP = express();var http = require('http').Server(APP);var io = require('socket.io')(http);
io.on('connection', function(socket){
  socket.on('drop one', function(data){
    socket.broadcast.emit('drop one', data);
  });
});
APP.use(express.static('public'));
APP.get('/', function(req, res){
  res.sendFile(__dirname + '/index.HTML');
});
http.listen(3000, function(){
  console.log('listening on *:3000');
});
读者可以跟着注释去理清楚思路,自己去完整的实现整个代码。至此,我们利用Web Socket技术完成了一个有趣的人人对战五子棋游戏。
以上内容来源:优逸客出版《HTML5实战宝典》一书。关于web全栈课程以及知识更多的分享,请期待下期哦
 
分享: