在游戏开发过程中,写过一个简单的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. Luogu 4556 雨天的尾巴

    主席树+线段树合并. 首先我们想一想如果只有一个结点的话,我们弄一个权值线段树就可以随便维护了. 那么我们可以运用差分的思想,把一个询问拆成四个操作,对于一个询问$(x, y, v)$,我们在$x$的 ...

  2. 高性能服务器设计(Jeff Darcy's notes on high-performance server design

    高性能服务器设计(Jeff Darcy's notes on high-performance server design 我想通过这篇文章跟大家共享一下我多年来怎样开发“服务器”这类应用的一些想法和 ...

  3. HierarchyId通过父节点创建一个新的子节点

    --HierarchyId通过父节点创建一个新的子节点 CREATE TABLE #temp( node HierarchyID ); insert into #temp select '/' uni ...

  4. 【原创】谈谈redis的热key问题如何解决

    引言 讲了几天的数据库系列的文章,大家一定看烦了,其实还没讲完...(以下省略一万字). 今天我们换换口味,来写redis方面的内容,谈谈热key问题如何解决. 其实热key问题说来也很简单,就是瞬间 ...

  5. Webpack 4教程 - 第八部分 使用prefetch和preload进行动态加载

    转载请注明出处:葡萄城官网,葡萄城为开发者提供专业的开发工具.解决方案和服务,赋能开发者.原文出处:https://wanago.io/2018/08/13/webpack-4-course-part ...

  6. boost asio one client one thread

    总结了一个简单的boost asio的tcp服务器端与客户端通信流程.模型是一个client对应一个线程.先做一个记录,后续再对此进行优化. 环境:VS2017  + Boost 1.67 serve ...

  7. GPT分区

    GUID分区表(简称GPT.使用GUID分区表的磁盘称为GPT磁盘).它具有如下优点: 1.支持2TB以上的硬盘.    2.分区个数没有限制.但是Windows系统最多支持128个分区.    3. ...

  8. 从输入URL到浏览器显示页面

    去看经典是不会错的,如果觉得太长,那就休息一下继续看. 经验告诉我,读一篇经典足矣,不要浪费时间去搜索其他地方到处复制粘贴的博文. 所以奉上我过滤的经典: 1.How browser work 2.h ...

  9. 安装mongodb并配置

    下载网址http://dl.mongodb.org/dl/win32/x86_64 mongodb-win32-x86_64-2008plus-ssl-v3.4-latest.zip 解压d盘命名mo ...

  10. 每次打开 excel2010 都要配置如何解决

    遇到这种情况有以下几种解决方法 1.修改原有office启动名称 打开"C:/Program Files/Common Files/Microsoft Shared/OFFICE14/Off ...