五子棋游戏
涛涛最近在参加一个新浪 SAE 双 11 活动,可以通过提交关于新浪云的稿件来赚取云豆,可以得到非常非常多的云豆。涛涛因为空间消耗比较大,所以就参加了这个活动,涛涛的稿件是一个利用新浪云实现的简易双人在线五子棋游戏,用到了新浪云中的KVDB 分布式键值对数据存储服务以及 WebSocket 实时推送服务。
这个活动已结束,而涛涛现在工作以后就只有晚上才能写文章了,哎,好累啊,不过还好按时完成了。下面涛涛详细介绍一下步骤,下面我们开始吧:
1.首先我们介绍一下功能:这是一个简易的双人在线五子棋游戏,由玩家 1 在线邀请另一名玩家进入游戏,共同完成游戏。首先玩家 1 访问下面的页面:http://eric.applinzi.com/my-page/chess/,如下图所示:
设置自己是黑方还是白方、先手还是后手后点击 “获取地址” 按钮,就会得到一个唯一的 URL 链接,如下图所示:
我们得到的 URL 链接是:http://eric.applinzi.com/my-page/chess/join.php?url=r9tN5TwPxWzym8C1fFdJf7omBIn2XjmO。然后我们可以把这个链接发送给好友(以下简称玩家 2),邀请他们一同加入游戏。在浏览器中打开上述链接,如下面右图所示(左边是玩家 1 的界面,右边是玩家 2 的界面):
首先会询问玩家 2 是否愿意加入游戏,当选择 “确定” 时则会提示玩家 2 是黑方还是白方、先手还是后手(黑方、白方、先手、后手是由玩家 1 确定的,当玩家 1 选择黑方先手时,玩家 2 自动设为白方后手),如下右图所示:
当玩家 2 加入游戏后,玩家 1 就会得到一个通知,如下左图所示:
由于玩家 1 选择的是黑方先手,所以由玩家 1 先下子,显示 “请下子”,而此时玩家 2 无法下子,显示 “等待对方下子”,如下图所示:
玩家 1 下子后玩家 2 会实时显示出玩家 1 的下子(如下右图所示),而玩家 1 的提示信息就会变为 “等待对方下子”,此时玩家 2 的提示信息显示为 “请下子”,如下图所示:
玩家 2 下子后如下图所示:
玩家 1 和玩家 2 交替下子,当有任何一方达到 5 子连续时则胜利,另一方失败,如下图所示:
下面是一个 GIF 截图:
2、下面涛涛简单介绍一下代码原理。首先玩家 1 登录到游戏页面,设置好参数(黑方、白方、先手、后手)后点击 “获取地址” 按钮,此时会向后台发送一个请求,后台接收到后会将游戏参数保存在新浪云的KVDB 中(KVDB 是一个新浪云提供了一个分布式键值对数据存储服务,类似于数据库但比数据库更容易操作),然后返回一个唯一的 URL。玩家 2通过这个 URL 加入游戏时后台会从 KVDB 中读取出该 URL 对应的参数,告诉玩家 2 是黑方还是白方、先手还是后手。玩家 1 和玩家 2之间的通信是通过新浪云的 WebSocket 服务实现的。它是新浪云推出的一个实时推送服务,使用非常方便。玩家 1 创建游戏时后台会生成一个 WebSocket 地址保存到 KVDB 中,玩家 2 登录后读取到这个 WebSocket 地址,这样就和玩家 1 建立了联系。玩家的下子信息就是通过 WebSocket 相互传递的。
3、整个工程一个 5 个 PHP 文件和一些图片,分别是:
config.php:项目配置文件:
<?php
//应用的AccessKey
$accessKey = ‘3wjloo5xy3’;
//服务器ID
$serverKey = ‘FiveChessServer’;
?>
send.php:实现了消息发送:
<?php
include(“config.php”);
//发送请求
$channel = new SaeChannel();
$msg = $_GET[‘msg’];
$ret = $channel->sendMessage($serverKey, $msg);
var_dump($ret);
?>
wsnew.php:实现了后台创建 WebSocket 地址并保存到 KVDB 中:
<?php
include(“config.php”);
//获取随机字符串
function getRandString($len)
{
$str = null;
$strPol = ‘ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz’;
$max = strlen($strPol) – 1;
for($i=0; $i<$len; $i++)
{
$str .= $strPol[rand(0, $max)];
}
return $str;
}
//创建一个有效时间为1小时的Channel
$channel = new SaeChannel();
$addr = $channel->createChannel($serverKey, 3600);
//执黑子还是白子
$black = ($_GET[‘black’] === ‘1’) ? ‘1’ : ‘0’;
//先手还是后手
$first = ($_GET[‘first’] === ‘1’) ? ‘1’ : ‘0’;
//把参数组合成JSON格式
$key = getRandString(32);
$value = ‘{“url”:’.””$addr””””.’