多人 card/pet 游戏的 XMLSocket 方法

XMLSocket approach for a multiplayer card/pet game

我是多人游戏设计的新手,我正在努力寻找我需要继续同步的信息(你不能断开连接并稍后继续,类似于炉石传说),回合制,pvp "card" 游戏。我使用 AS3 (flash) 作为客户端,使用 node.js 和 javascript + mysql 作为服务器端处理。

在这个游戏中,卡片是由玩家自己创建的。重要的是要注意这些 "cards" 是由单独的构建块(库 swf 文件)组装而成的;数据库会跟踪这些卡片的状态 made/assembled。 因为每个玩家可能有数百张独特制作的卡片,我需要一种好方法来根据需要加载有关这些卡片的信息,以用于 pvp 战斗或 modding/deck 建筑目的。

到目前为止我取得的成就:

我真正需要回答的问题:

Flash 异步加载内容,所以我不确定如何为(有时是同时的)战斗动作、卡片信息或卡片组合(可能有很多卡片和卡片构建块,所以我觉得用一个请求加载所有数据效率很低)。我可以让 classes 负责进行这些调用,或者创建一个信使 class 来处理整个游戏的所有 requests/disconnects/reconnects/messages。

编辑: 我强烈倾向于使用单例 XMLSocket Wrapper 或某种扩展的 class 来处理所有网络事务,因为这对我来说似乎很直观。我非常感谢您对通知我的代码的最佳方法的反馈,即 Messenger 收到并解析了它要求的消息(因为即使数据不存在,Flash 也会继续执行,我需要一个好的方法来执行此操作。)。我读到使用自定义事件并不是那么好,还有更好的方法......但这就是我解决问题的方式。

例如我可以做到(伪代码)。

m:Messenger = new Messenger(); //this is my wrapper
m.addEventListener(new CustomEvent(CustomEvent.EVENTSTRING, parseData));
m.sendData(DataObject); //calls 

function parseData(e:CustomEvent) {
    xml(e.data);
}

import flash.net.XMLSocket;
import globals.*;
public class Messenger 
{
    public static var _Socket:XMLSocket; 
    public var xml:XML;

    public function Messenger() 
    {
        _Socket = new XMLSocket(vars._Server, vars._Port);
        _Socket.addEventListener(Event.CONNECT, onConnect);  
        _Socket.addEventListener(IOErrorEvent.IO_ERROR, onError); 
    }

    private function onConnect(evt:Event):void  {  
        trace("Connected");  
        _Socket.removeEventListener(Event.CONNECT, onConnect);  
        _Socket.removeEventListener(IOErrorEvent.IO_ERROR, onError);  

        _Socket.addEventListener(DataEvent.DATA, onDataReceived);
        _Socket.addEventListener(Event.CLOSE, onSocketClose);              
    }  

    private function onDataReceived(evt:DataEvent):void  {  
        //trigger correct event here based on data identifier w/ dispatchEvent(EVENTSTRING);
    }  
}

关于卡片组装——您应该将不需要重新计算的数据存储在数据库中,因此如果一张卡片是由多个 "building blocks" 构建的,例如,您可以将一系列块存储在一个数据库行,这样当检索对手的卡信息时,您只需 select from player_cards where player_id=... and deck_id=... 然后 assemble 在 AS3 端收集的数据。你绝对不应该把这个负载放在服务器上。

关于异步加载-确保你的PVP握手等待双方成功处理己方和敌方的卡片。您可以异步加载数据,但最好在向播放器显示 "Loading bla-bla" 屏幕时进行完整预加载,然后使用接收到的数据进行操作。是的,您可以向您的服务器发出多个请求,是的,您可以在显示 "Battle start" 屏幕之前等待所有请求成功,同时 AS3 将等待加载完成。但是,关于单个请求与多个请求——我说的是尽可能少,因为在初始阶段每个添加的请求都有可能向单个服务器添加一千个左右的请求,并且有可能给服务器带来太多压力您的服务器端,导致自启动的 DDoS。确保您的数据库结构允许将数据读取操作简化到客户端,这样您的服务器就不会因为准备数据而承受沉重的负载。但也要确保仔细检查客户端向服务器报告的任何内容,因为客户端-服务器游戏的主要规则是 "client always lies" 假设。

由于您计划让服务器在战斗中处理玩家操作,您可以在服务器上创建临时表(基于SQL)或包含当前游戏的状态对象(基于进程) state 链接到卡牌所具有的任何能力及其状态(在手,丢弃,在场,销毁等),这样当玩家的动作到来时,说 "this card changes state from A to B" 你可以很容易地验证该卡牌是否是处于 A 状态,然后将其切换到 B 状态,在服务器端和客户端执行此状态更改导致的任何操作。确保在战斗结束后清理这组数据。这需要对您的服务器端进行全面规划,这样您的游戏引擎就不会在 运行 一些动作序列由于过多的 SQL 请求而导致服务器停止运行,例如。

关于信使 - 也许您应该使用会话方法,连同 login/password 身份验证,这样您就可以将会话作为密钥来确定此数据包属于哪场战斗。我认为还可以让 AS3 端定期向服务器发送拉取请求,服务器应该快速解析这些请求,并尽快返回提交的 enemy/server 操作,这也将确保处理断开连接并允许重新连接。

总的来说,问题非常宽泛,只能给出提示,连例子都不能。