网页游戏中PK系统的实现
在游戏开发过程中,写过一个简单的PK系统面板,涉及到前端和后端的交互,我将自己制作的流程分享给大家,大概流程是这样:前端发送PK邀请给后端,后端受到请求后将信息返回给前端处理,先来看下整个流程图及思路:

整个流程如上图所示,经过服务器和客户端的几次交互来确定PK双方的状态及是否能受到攻击。服务端将要给我五条协议,大概如下:
message m_role_pk_invite_tos<>[router=role,mod_role_handle]{
   required double                          role_id                 = ;//邀请PK的对象ID
}
message m_role_pk_invite_toc<>{
 required int32     err_code     = ;//0是已向对方发送邀请,请等待回应
}
message m_role_pk_info_toc<>{
   required string                          invite_name             = ;//邀请者名称
   required double                          invite_id                 = ;//邀请者ID
   required int32                           invite_level           = ;//邀请者level
   required double                          invite_time          = ;//计时结束时间戳
}
message m_role_pk_answer_tos<>[router=role,mod_role_handle]{
   required int32                          back_type                 = ;//0为同意,1为拒绝,2为超时
   required double                          to_id          = ;//同意/拒绝/超时的对象
}
message m_role_pk_answer_toc<>{
   required int32                          err_code                 = ;//0为成功(提示:开始PK)
   required double                          to_id          = ;     //成功时读取PK对象ID
}
其中toc代表服务端发给客户端的数据,tos表示客户端发给服务端的消息,他们都是封装好的数据结构信息,这些都是我们和后端约定好的协议,一般后端发给前端我们都会制定一个err_code,它表示该协议是否成功发送到客户端。
前端的代码处理比较简单,在编码过程中,将数据和视图分别放在不同的模块中,便于管理,在接受邀请后,我们会给被邀请方一个弹窗显示并给60秒的时间来处理。重点看下服务端发给客户端处理的代码:
package modules.invitePK {
  /* 五条协议 */
 import proto.m_role_pk_answer_toc;
 import proto.m_role_pk_answer_tos;
 import proto.m_role_pk_info_toc;
 import proto.m_role_pk_invite_toc;
 import proto.m_role_pk_invite_tos;
 public class InvitePKCase extends BaseModule {
  public function InvitePKCase() {
   super();
  }
  private var invitePKPanel:InvitePKPanel;
  private static var instance:InvitePKCase;
  public static function getInstance():InvitePKCase {
   return instance ||= new InvitePKCase(); //单例模式
  }
  override protected function initListeners():void {
   addMessageListener(ModuleCommand.INVITE_PK, toInvite); //调用侦听事件邀请PK
   addMessageListener(ModuleCommand.INVITE_ANSWER, toAnswer)
   addMessageListener(ModuleCommand.INVITE_OPENPANEL, toOpenPanel) //出面板
   /* 监听服务端发来的数据,包括三条协议 */
   addSocketListener(SocketCommand.ROLE_PK_INFO, onPKInfo);
   addSocketListener(SocketCommand.ROLE_PK_INVITE, onInvite);
   addSocketListener(SocketCommand.ROLE_PK_ANSWER, onAnswer);
  }
  private function toOpenPanel(vo:m_role_pk_info_toc):void {
   invitePKPanel = new InvitePKPanel(vo.invite_name, vo.invite_id, vo.invite_level, vo.invite_time); //new一个模板
   invitePKPanel.durTime = vo.invite_time;
   invitePKPanel.open(); //打开面板
   invitePKPanel.readTime(); //开始计时
  }
  private function onAnswer(vo:m_role_pk_answer_toc):void {
   if (vo.err_code == ) {
    if (vo.pk_type != ) {
     FightModule.getInstance().toOpenPanel(vo);//显示PK双方的信息
     InvitePKManager.pkRoleID = vo.to_id;
     MangerTime.last_time = ;   //MangerTime是管理时间类
     MangerTime.endTime(); //读取时间
    } else {
     InvitePKManager.pkRoleID = ;
     Dispatcher.dispatch(ModuleCommand.FIGHT_CLOSEPANEL); //发送关闭消息
    }
   } else {
    TopTip.addMouseTipsMsg(ErrorCode.getError(vo.err_code));
   }
  }
  private function toAnswer(back_type:int, id:Number):void {
   var vo:m_role_pk_answer_tos = new m_role_pk_answer_tos();  //发给服务端
   vo.back_type = back_type;
   vo.to_id = id;
   sendSocketMessage(vo);
  }
  private function onPKInfo(vo:m_role_pk_info_toc):void {
   dispatch(ModuleCommand.INVITE_OPENPANEL, vo); //开面板,显示邀请者的信息
  }
  private function onInvite(vo:m_role_pk_invite_toc):void {
   // 发给客户端的消息,提示我已经邀请你pk
   if (vo.err_code == ) {
    TopTip.addMouseTipsMsg("已邀请PK,请等待回应");  //表示发送成功
   } else {
    TopTip.addMouseTipsMsg(ErrorCode.getError(vo.err_code)); //返回失败的原因
   }
  }
  private function toInvite(tarid:Number):void {
   //这里面有调用者的ID,由客户端发给服务端
   var vo:m_role_pk_invite_tos = new m_role_pk_invite_tos();
   vo.role_id = tarid;
   sendSocketMessage(vo); //发送消息
  }
 }
}
上面的MangerTime类主要是用于PK双方时间的限定,如果在双方都接受邀请之后30秒内没有动作,或者30秒有攻击但是接着停下来没有继续攻击,时间又要重新开始计时,我这里用一个静态类来处理:
package modules.fight {
import com.managers.Dispatcher;
import com.scene.sceneManager.LoopManager;
import modules.ModuleCommand;
import modules.fight.FightView;
    public class MangerTime {
        public static var last_time:int = ;  //静态30秒,每次攻击玩可以重置这个时间
        public static function updateEndTime():void {
        last_time--;
        if (last_time < ) {
        last_time = ;
        LoopManager.removeFromSceond("updateTime");
        FightView.getInstance().toCloseWindow(); //pk结束,关闭面板
   }
}
    public static function readTime():void {
    LoopManager.addToSecond("updateTime", updateEndTime);  //启动一个定时器开始计时
    }
  }
}
在监听服务器发过来的fight事件的时候,可以改变last_time对时间进行重置,加入计时器,30秒到后就可以关闭双方的面板,但是一定要注意的是,我们这里用到AS3中的字典来存储函数的名称,所以在命名的时候一定不要重复命名,不然可能会导致程序运行出错或者PK双方只关闭一个面板。
总结:在遇到和服务器交互的时候只需要针对对应协议做出相应的逻辑判断,代码分别用模块化的形式来清晰表达出自己的思想,后面开发的同志看代码也就不会很困难,游戏行业的开发速度非常快,有好的框架开发起来速度会非常快,所以平时应该多专研这些面板底层机制是如何实现的,并记录一些自己的想法。
网页游戏中PK系统的实现的更多相关文章
- 用Python脚本做一些网页游戏中力所能及的自动化任务
		
下面是一段自动登录360传奇霸业游戏的脚本: from pymouse import PyMouse import time import webbrowser from pykeyboard imp ...
 - 网页游戏开发秘笈 PDF扫描版
		
精选10种常见的游戏类型,透过典型实例,深入剖析游戏引擎及工具的选用技巧,详细讲解每款游戏的制作过程,为快速掌握网页游戏开发提供系统而实用的指南. 网页游戏开发秘笈 目录: 译者序 前 言 导 言 ...
 - arpg网页游戏特效播放(一)
		
网页游戏中的特效,主要包括:场景特效,攻击特效和UI特效三种.场景特效是在地图层上播放的特效,攻击特效主要是技能触发的一些特效,UI特效是面板上的一些特效,还有一些在人物身上播放的特效,例如脚底光圈特 ...
 - 【腾讯GAD暑期训练营游戏程序开发】游戏中的动画系统作业
		
游戏中的动画系统作业说明文档 一.实现一个动画状态机:至少包含3组大的状态节点
 - IOS中调用系统的电话、短信、邮件、浏览功能
		
iOS开发系列--通讯录.蓝牙.内购.GameCenter.iCloud.Passbook系统服务开发汇总 2015-01-13 09:16 by KenshinCui, 26990 阅读, 35 评 ...
 - Unity网页游戏
		
Unity网页游戏是跑在浏览器的UnityWebPlayer插件中的,运行的模式是webplayer.unity3d+html 在嵌入UnityWebPlayer的网页中会调用UnityObject2 ...
 - qq开放平台可以应用到网页游戏的api整理
		
创建角色界面api整理 一.需求描述 1. 创建角色名称可以用qq空间昵称代替 2. 如果玩家是在新区玩的话,赠送老玩家支持礼包 3. 可以看到,好友xxx也在玩,而且到了多少等级,如果加为好友 ...
 - 游戏中的人工智能——初探AI
		
一.游戏中的人工智能 让游戏具有挑战性: 让游戏好玩的关键因素是为之找到合适的难度等级: 人工智能在游戏中的作用是通过提供富有挑战性的竞争对象来让游戏更好玩,而在游戏中行动逼真的非玩家角色(NPC), ...
 - 用TypeScript开发了一个网页游戏引擎,开放源代码
		
最开始学习电脑编程的原动力之一就是想自己编写游戏,一方面很好奇这些游戏是怎么做出来的,另一方面觉得有些地方设计的不合理,希望电脑游戏既能让人玩的有趣,又不浪费时间. 学校五年,毕业十年,学用了十多种编 ...
 
随机推荐
- 36、EST-SSR标记开发
			
转载:http://fhqdddddd.blog.163.com/blog/static/1869915420124131096557/ MISA工具提供批量识别和定位简单重复序列(SSR),EST序 ...
 - 9、IPA通路分析相关网页教程
			
IPA FAQ: http://ingenuity.force.com/ipa/IPATutorials# ####有各种相关教程和帮助文件. IPA 分析结果展示: http://www.lucid ...
 - DNA甲基化及其测量方法(转)
			
转自声明的奥秘 www.lifeomics.com DNA甲基化与肿瘤发生: DNA甲基化水平和模式的改变是肿瘤发生的一个重要因素.这些变化包括CpG岛局部的高甲基化和基因组DNA低甲 ...
 - <转>哥舒意:关于米奇的三个真相 (米奇·阿尔博姆)
			
http://book.douban.com/review/6436827/ <时光守护者>的故事也不算复杂,虽然有三条线同时进行,但是三条线的情节都条理分明,而且这次他使用了类似于奇 ...
 - code first迁移和部署
			
从"工具"菜单中,选择"NuGet 包管理器" > "包管理器控制台". 在PM>提示符处输入以下命令: enable-migr ...
 - 对 React Context 的理解以及应用
			
在React的官方文档中,Context被归类为高级部分(Advanced),属于React的高级API,但官方并不建议在稳定版的App中使用Context. 很多优秀的React组件都通过Conte ...
 - 学习笔记:首次进行JUnit+Ant构建自动的单元测试(一)
			
指导博客:https://blog.csdn.net/Cceking/article/details/51692010 基于软件测试的需求,使用JUnit+Ant构建自动的单元测试. IDE:ecli ...
 - 洛谷P4332 [SHOI2014]三叉神经树(LCT)
			
传送门 FlashHu大佬太强啦%%% 首先,我们可以根据每一个点的权值为$1$的儿子的个数把每个点记为$0~3$,表示这一个点的点权 先考虑一下暴力的过程,假设从$0$变为$1$,先更改一个叶子结点 ...
 - Windows 命令行方式打印和设置变量
			
echo %PATH% http://blog.csdn.net/snlei/article/details/7211770
 - gitlab web端使用
			
https://jenkins.io/zh/doc/pipeline/tour/getting-started/ http://www.cnblogs.com/cheng95/p/6542036.ht ...