在游戏开发过程中,写过一个简单的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系统的实现的更多相关文章

  1. 用Python脚本做一些网页游戏中力所能及的自动化任务

    下面是一段自动登录360传奇霸业游戏的脚本: from pymouse import PyMouse import time import webbrowser from pykeyboard imp ...

  2. 网页游戏开发秘笈 PDF扫描版

    精选10种常见的游戏类型,透过典型实例,深入剖析游戏引擎及工具的选用技巧,详细讲解每款游戏的制作过程,为快速掌握网页游戏开发提供系统而实用的指南. 网页游戏开发秘笈 目录: 译者序  前 言  导 言 ...

  3. arpg网页游戏特效播放(一)

    网页游戏中的特效,主要包括:场景特效,攻击特效和UI特效三种.场景特效是在地图层上播放的特效,攻击特效主要是技能触发的一些特效,UI特效是面板上的一些特效,还有一些在人物身上播放的特效,例如脚底光圈特 ...

  4. 【腾讯GAD暑期训练营游戏程序开发】游戏中的动画系统作业

    游戏中的动画系统作业说明文档   一.实现一个动画状态机:至少包含3组大的状态节点

  5. IOS中调用系统的电话、短信、邮件、浏览功能

    iOS开发系列--通讯录.蓝牙.内购.GameCenter.iCloud.Passbook系统服务开发汇总 2015-01-13 09:16 by KenshinCui, 26990 阅读, 35 评 ...

  6. Unity网页游戏

    Unity网页游戏是跑在浏览器的UnityWebPlayer插件中的,运行的模式是webplayer.unity3d+html 在嵌入UnityWebPlayer的网页中会调用UnityObject2 ...

  7. qq开放平台可以应用到网页游戏的api整理

    创建角色界面api整理 一.需求描述 1.  创建角色名称可以用qq空间昵称代替 2.  如果玩家是在新区玩的话,赠送老玩家支持礼包 3.  可以看到,好友xxx也在玩,而且到了多少等级,如果加为好友 ...

  8. 游戏中的人工智能——初探AI

    一.游戏中的人工智能 让游戏具有挑战性: 让游戏好玩的关键因素是为之找到合适的难度等级: 人工智能在游戏中的作用是通过提供富有挑战性的竞争对象来让游戏更好玩,而在游戏中行动逼真的非玩家角色(NPC), ...

  9. 用TypeScript开发了一个网页游戏引擎,开放源代码

    最开始学习电脑编程的原动力之一就是想自己编写游戏,一方面很好奇这些游戏是怎么做出来的,另一方面觉得有些地方设计的不合理,希望电脑游戏既能让人玩的有趣,又不浪费时间. 学校五年,毕业十年,学用了十多种编 ...

随机推荐

  1. sklearn保存模型

    # View more python tutorials on my Youtube and Youku channel!!! # Youtube video tutorial: https://ww ...

  2. HDU 5973 Game of Taking Stones (威佐夫博弈+高精度)

    题意:给定两堆石子,每个人可以从任意一堆拿任意个,也可以从两堆中拿相同的数量,问谁赢. 析:直接运用威佐夫博弈,floor(abs(a, b) * (sqrt(5)+1)/2) == min(a, b ...

  3. 《Linux内核设计与实现》读书笔记(一)-内核简介

    本篇简单介绍内核相关的基本概念. 主要内容: 单内核和微内核 内核版本号 1. 单内核和微内核   原理 优势 劣势 单内核 整个内核都在一个大内核地址空间上运行. 1. 简单.2. 高效:所有内核都 ...

  4. Spring Security 入门原理及实战

    目录 从一个Spring Security的例子开始 创建不受保护的应用 加入spring security 保护应用 关闭security.basic ,使用form表单页面登录 角色-资源 访问控 ...

  5. [CentOS7] gzip, bzip2, xz 压缩与解压缩

    声明:本文主要总结自:鸟哥的Linux私房菜-第八章.檔案與檔案系統的壓縮,打包與備份,如有侵权,请通知博主 gzip命令: 选项参数: -c :将压缩后的数据显示到屏幕上,可以用于重定向: -d : ...

  6. 【WIP】客户端JavaScript 事件处理

    创建: 2017/10/15 完成: 2017/10/15   更新: 2017/11/04 加粗事件的参数 更新: 2017/12/12 增加事件处理时获取事件对象的方法 更新: 2019/05/2 ...

  7. 树的直径+rmq+(伪)单调队列 -HDU4123

    给定一棵n个点并且有边权的树,每个点的权值为该点能走的最远长度,并输入m个询问,每次询问最多有多少个编号连续的点,他们的最大最小点权差小于等于Q.N<=50000 M<=500 Q< ...

  8. 洛谷P2258 子矩阵

    P2258 子矩阵 题目描述 给出如下定义: 子矩阵:从一个矩阵当中选取某些行和某些列交叉位置所组成的新矩阵(保持行与列的相对顺序)被称为原矩阵的一个子矩阵. 例如,下面左图中选取第2.4行和第2.4 ...

  9. loj#6517. 「雅礼集训 2018 Day11」字符串(回滚莫队)

    传送门 模拟赛的时候纯暴力竟然骗了\(70\)分-- 首先对于一堆\(g\)怎么计算概率应该很好想,用总的区间数减去不合法的区间数就行了,简而言之对\(g\)排个序,每一段长为\(d\)的连续序列的区 ...

  10. react native ios打包到真机,即生产包

    参考文章:http://www.devio.org/2017/02/09/React-Native%E5%8F%91%E5%B8%83APP%E4%B9%8B%E6%89%93%E5%8C%85iOS ...