在游戏开发过程中,写过一个简单的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. Struts2学习第四课 通过Aware接口获取WEB资源

    使用XxxAware接口 看代码: package logan.struts2.study; import java.util.Map; import org.apache.struts2.inter ...

  2. hdu1074

    #include <iostream> #include <string> #include <cstring> #include <stack> #i ...

  3. 修改TABLE中的Column的属性

    删除主键名 这个主键名并不是列名,而是主键约束的名字,如果当时设置主键约束时没有制定约束的名字 设置主键的语句:ALTER TABLE P add constraint pk PRIMARY KEY ...

  4. Boost Python官方样例(二)

    返回值 使用return_by_value有点像C++ 11的auto关键字,可以让模板自适应返回值类型(返回值类型必须是要拷贝到新的python对象的任意引用或值类型),可以使用return_by_ ...

  5. SAS笔记(6) PROC MEANS和PROC FREQ

    PROC MEANS和PRC FREQ在做描述性分析的时候很常用,用法也比较简单,不过这两个过程步的某些选项容易忘记,本文就梳理一下. 在进入正文前,我们先创建所需的数据集TEST_SCORES: D ...

  6. Educational Codeforces Round 57D(DP,思维)

    #include<bits/stdc++.h>using namespace std;char s[100007];long long a[100007];long long dp[100 ...

  7. UPC11073(DP,思维)

    #include<bits/stdc++.h>using namespace std;long long dp[507][507];const long long mod = 998244 ...

  8. Codeforces Round #523 (Div. 2)D(二分,多重集)

    #include<bits/stdc++.h>using namespace std;const long long N=1e5+5;const long long MOD=1e9+7;l ...

  9. JavaScript 性能优化

    加载和执行 1. </body>闭合标签之前,将所有的<script> 标签放在页面底部,确保在脚步执行之前页面已经完成渲染. 2. 合并脚本.下载单个 100KB 的文件将比 ...

  10. angularJs解决模态框下echarts不显示问题

    例如:摸态框myModal.html,给它命名一个id,id='myModal'; myModal.html页面想画一个echarts图表 这里是angularJs已经封装好的echarts在html ...