网站建设中WebSockets特色的游戏-Battleships(战列舰)

发布时间:2014-12-6 8:06:26

网站建设中WebSockets特色的游戏-Battleships(战列舰)

  我们将研究一个更好地发挥了WebSockets特色的游戏,Battleships!(战列舰)。
  这个更加详细的WebSocket案例是一个流行的战略游戏一Battleships!,通常仅需要纸和笔就能开始。游戏规则很简单:每个玩家在一个规格为10x10的游戏区域上放置10条不同尺寸的船。这些船只之间不允许发生接触,可被水平或垂直放置,长度在两格到五格之间。其分配规则如下:1(艘船>x5(格)以及先放置好船只的玩家可以开始游戏,在敌方游戏区域选择一个格子开炮。若选择的格子里只有水,将轮到敌方行动>若选择的格子包含了船或船的一部分(命中),则该玩家可以继续开炮。双方轮流行动,直至一方所有船只的所有部分都被击沉。
  为将Battleships!转化为HTML5,我们需要在客户端使用一个带JavaScript库的HTML文件及一个CSS样式表。在服务器端上我们需要用到章节“WebSocket服务器”中介绍过的node-websocket-server服务器。所有程序相关文件都可在相关网站上找到:
  在HTML代码中,控制元素及游戏对话框都被定义为表单元素,根据游戏进程决定其为隐藏还是可见。其中的4个元素为信息窗口,通过posit[a-z]o[a-z]:fixed被显示在中心,内容为游戏邀请、拒绝邀请,以及游戏结束时的“祝贺”或是安慰。其他表单包括登录面板、自己及敌方的两个游戏区域、放置船只的数字组件,以及当前登录用户状态列表。
  加载页面时,你将见到一个登录面板,要求输入昵称。我们在测试中使用两个特殊用户-----testl及test2,他们的船只被自动放置,而用户testl永远先开始游戏。辅助页面testjan^html可以同时从两个用户视角观看游戏。在这里你可以通过内嵌的iframe元素同时登录两个不同的用户名,这也意味着你可以自己和自己对弈。这样做的好处是你永远是贏家,由此可以更方便地了解游戏的程序逻辑。测试页面地址为http://html5.komplett.cc/code/chap_websockets/game_test_en.htinl
  登录并单击OK后,一个到WebSocket服务器的连接将被创建,其作用仅限于在玩家之间交换信息以及更新用户列表。用户列表显示了每个用户的连接ID、昵称,以及当前游戏状态。
  所有信息以JSON字符串发送,大体来说分为两类:一类为发送给所有用户的信息,包括某个用户游戏状态的改变,另一类为当前正在游戏的两个玩家之间的私下信息交流。为了实现此目的,我们需要为node-websocket-server服务器的connection库添加一个额外的方法writeclientO,将信息仅发送给指定用户。
  在登录之后,你马上可以看见自己的游戏区域。和你对手的游戏区域一样,它由[a-z]o[a-z]l0的button元素构成,其值对应格子位置,取值范围从()(左上角)~(10)(右下角)。每个按钮都拥有一个class属性,并在游戏过程中可以多次改变。CSS样式表包含了表中出现的class(游戏中用到的部分)。
  在摆放船只之前,我们需要先找一个对手。在已登录用户列表中选择一个玩家,单击InvitePlayer按钮向他发送一个游戏邀请。此按钮的回调函数将定位玩家ID并向WebSocket服务器发送一个邀请信息:
  this.invitePlayer=function(){
  varopts=document.forms.loggedin.users.options;if(opts.selectedlndex丨=-1){wsMessage({task:*private',request:invite1,client:opts[opts.selectedlndex].value>});>;这会调用wsMessageO函数将信息以JSON字符串格式发送给服务器。此过程中还包括一些额外步骤,轡如检査信息有效性:
  varwsMessage=function(msg){
  game.websocket.send(3SON.stringify(msg));};代码中的game变量代表了核心游戏对象,包括了与游戏相关的所有变量。在服务器中,此邀请被鉴定为私人信息,与发送者个人信息一起发送给指定玩家。
  在game_server.js中显示为这段代码:
  elseif(msg.task==1private'){msg.from=USERSrconn.id];^conn.writeclient(DSON.stringify(msg),msg.client);目标用户将收到一个小窗,被邀请与你一同开始游戏(见图94)。若该用户拒绝,你将得到答复“Nothanks,notnow”,若该用户接受,用户列表将被隐藏,而用来放置船只的数字组件将被显示。首先我们来看一下邀请游戏的代码。在客户端,我们可以看到它是处理所有服务器端信息的回调函数onmessage的一部分:
  game.websocket.onmessage=function(e){varmsg=DSON.parse(e.data);if(msg.request==invite*){varfrm=document.forms.inviteConfirm;vartxt='strong^+msg干rom.nick+'/strong〉*;txt+='wantstoplayagamewithyou.1;txt+='Accept';frm.sender.previousSibling.innerHTML=txt;frm.sender.value=msg.from.id;frmsendernick.value=msg.from.nick;frm.style.display='inline';):}
  表单irwiteCcmflrm中包含了邀请发送者的ID及昵称,以及可显示的信息窗口。被邀请玩家单击Yes或No按钮的同时,相关回应通过服务器被回递给邀请者,宁波网站建设认为并再次返回给onmessage回调函数:
  elseif(msg.request=='confirm'){if(msg.choice==true){wsMessage({task:setPlaying*,client:msg.from.id});prepareGame(msg.from.id,msg.from.nick);document.forms.loggedin.style.display='none';else{show(’nothanks
  window.setTimeout(function(){
  hide('nothanks1);
  document.forms.users.style.display='inline';},0);>1
  若邀请答复为Yes,服务器将得到通知两个玩家正一起开始游戏,然后游戏开始,登录用户选择列表被隐藏。若答复为No,仅会将消息“Nothanks,notnow”显示两秒钟。
  同时,服务器会执行一些别的步骤,例如更新这两个用户的状态对象。若有别的玩家邀请他们,则会收到“Wearenowplayingtogether”的提示,表示他们目前无法参与别的游戏。
  在game_server.js中显示为这段代码:
  varsetBusy=function(id){.
  USERS[id].busy=true;
  varmsg={task:’isPlaying’,user:USERS[id]};conn.broadcast(N.stringify(msg));conn.write(DS0N.stringify(msg));};elseif(msg.task=='setPlaying'){setBusy(conn.id);1setBusy(msg.client);在客户端,回调函数onmessage将捕获到这段信息,并更新本地保存的登录用户列表。此更新将导致两个游戏中的玩家无法被选择,因为他们的option元素已通过一个disable属性设为无效:
  elseif(msg.task=='isPlaying'){
  varopts=document.forms.log^edin.users.options;for(vari=0:i}>
  在双方玩家同意开始游戏后,他们就开始放置船只。若作为用户testl或test2登录,则你的船只会被自动放置好,若以其他用户登录,你将看到一个下拉菜单,可以通过五个按钮来放置舰队。你先决定单个船只是水平还是垂直方向,然后通过单击决定船只类型,再次点击将船只放置在游戏区域的指定位置中。
  相关区域通过CSS类ship变成代表船只的格式,并被保存在3个JavaScript变量中。
  变量game.ships.isShip记录指定位置,变量variablegame.ships.parts以数组形式记录每个船只的所属区域,这些数组的副本将随着游戏进行在变量game.ShipS.partsTodo被持续修改。游戏结束时,失败方将只剩下10个空白数组,因为相关格子已经在每次遭到攻击时被删除。
  每次新放置船只,相关按钮的标签都会更新,以显示此类船只的剩余可用数量。在所有同类船只都被放置后,剩余数量将消失。一旦所有船只被放置,整个表单都将消失,并出现信息:Readytostartthegame!
  if(game.ships.parts.length==10){
  document.forms.digitize.style.display=*none1;game.me.grid['1-lv].parentNode.style.pointerEvents='none*;wsMessage({
  task:'private',request:'ready',client:game.you.id});1game.me.ready=true;秉着“先来先走”的原则,先放置完所有船只的玩家可以先开始游戏,动作较慢的玩家则需要迎接炮灰,承受对他舰队的第一次打击。在双方玩家都完成船只放置后,将出现第二个游戏区域让先行动的一方攻击敌方船只。
  攻击及船只沉没的游戏逻辑完全在客户端实现,服务器仅将游戏进展作为私人信息发送给双方玩家。活动游戏区域内的每一次单击都将调用以下函数:
  this.reveal=function(evt){wsMessage({task:'private',request:'challenge*,field:evt.target.value,client:game.you.id服务器将此信息传递给受攻击方,并检査攻击方玩家单击的区域是否包含了船只的一部分:
  elseif(msg.requestchallenge'){
  vardestroyed=0;if(game.snips.isShip[msg.field]){game.me.grid[msg.field].setAttribute("class","hit'*);图为游戏的演示模式。
  在炮击命中的情况下(isShip为true),受攻击方游戏区相关按钮被指定为hit类,依样式表将其颜色变成红色。若某艘船只被击中但还未被完全摧毁,攻击方将收到一条相应信息:
  wsMessage({
  task:'private1,request:'thisFieldls',result:hiti,field:msg.field,client:game.you.id});若信息的request部分为thisFieldls,攻击方所看到的这个区域也将作出对应处理:
  elseif(msg.request=='thisFieldls'){if(msg.result=='water'){gameyougrid[msgfield]setAttribute("class,msg.result):deactivateFieldo;elseif(msg.result=='hit'){game.you.grid[msg.field].setAttribute("class",1msg.result);从攻击方视角看来,hit应答将他单击的区域变成红色,而若应答为distroyed,则船只所属的所有区域将从红色变成绿色,表明该船被命中并摧毁。同时,在受攻击方玩家的游戏区域中,他的hit位置被标为红色,而如果是destroyed,则此前为红色的船体所有部分都将变为蓝色,由water代替,表明受攻击的船只已被摧毁。因此,在你的游戏区出现的蓝色越多,情况就越糟糕,敌方游戏区出现的绿色越多,你离胜利就越近。
  若应答为water,那么就是受攻击方玩家开始反击的时刻了(函数deactivateField()会阻止炮击落空的一方继续行动)。游戏如此持续进行,直至两个玩家中的一个摧毁了所有敌方船只并宣告胜利。如前所述,己方及敌方船只状态标记通过每个按钮元素的CSS样式实现《通过[a-z]o[a-z]nter-events:none及opacity:将当前待命玩家的游戏区域无效化,这保证了双方玩家能够轮流行动。
  在游戏结束时,双方玩家再次被分开,他们的状态重新被设为“Availabletoplay”,并可接受下一次邀请。在当前版本下,Battleships!并不允许与同一个玩家连续作战,但或许你想尝试一下开发这个新功能?开发Logout按钮或许也是个不错的主意,若你足够勇敢,甚至可以尝试一下开发多人作战模式。这个应用程序的未来拥有许多可能性,一切仅取决于你的想像力!
  此案例令人印象深刻地展示了通过WebSocket协议开发互动应用程序的许多新的可能。这个案例主要是处理用户之间的互动,而用WebSocket服务器从Internet上获取信息、处理信息,然后将它发送给连接用户也是一种很容易实现的功能,此前提到的广播当前股票交易价格的程序就是一个很好的例子。另外显示从Twitter中接收到的新信息也是一种可行应用。用WebSocket来实现这些的优点都很明显:客户端通过message事件接收更新,使得客户端及服务器端之间的数据流很小,一定程度上节省了网络带宽。
  本文由乐华网络编辑,转载请注明出处
  宁波网站建设www.leseo.net
上一篇:
在Web的年代,Web是由网站单方向供给数据,以静态数据居多,Web间没有相互串连与互动,搜索引擎也
下一篇:
供给网站地图给您的用户,宁波seo认为并在其间参加指向您网站重要有些的联接。假如网站地图大于约100
关于乐华
乐华介绍
乐华思维
人才招聘
使用条款
隐私保护
RSS订阅
网站地图
新闻动态
乐华观点
行业动态
频道介绍
服务介绍
案例展示
品牌研究
品牌理论
品牌体系
联系我们
400-680-2900
社会媒体
微信公众平台
微信公众平台