# 游戏专题 SD近期为游戏开发者提供了很多助力,在游戏开发上提供了一些便利性组件,下面我们来看看SD是怎么为游戏开发者解决痛点的。 ## 延迟队列 游戏一般对消息队列有一定的使用需求,但一般的开源消息队列并没有很好的处理延时消息的派发。比如rabbitmq虽然它是可以通过死信队列来模拟延时队列但是不仅难用还有很大的限制。 SD提供了一个简单可靠的延迟消息队列模块[TimerCallBack](TimerCallBack.md)。 ``` $token = yield TimerCallBack::addTimer(2,TestModel::class,'testTimerCall',[123]); ``` 简单的通过下面一段代码就可以实现延迟2s执行TestModel中的testTimerCall函数。而且没有任何副作用,即使重启服务器延时队列也会很好的完成使命。 ## Actor 本篇文章将重点介绍下Actor,什么是Actor你可以把它当成一个运算单元,用于模拟任何的事与物,Actor存在于内存中分布在不同的进程,或者分布在不同的机器上,Actor间可以互相通讯,Controller,Model甚至Actor自身都可以创建一个Actor,Actor同样也可以调用Model和Task。 拿棋牌举例子,你可以为房间创建一个RoomActor,为房间里的每一个人创建一个PlayerActor,RoomActor负责处理一共有多少局,轮到谁出牌了,PlayerActor则可以负责玩家的一系列行为,甚至玩家掉线充当玩家的AI。 利用好Actor可以简化你游戏的逻辑,使其更加拟人,逻辑表达更加的清晰,使用Actor的哲学就是万物的交流靠通讯。 1. 创建Actor ``` $name = session_create_id(); Actor::create(TestActor::class, $name); ``` 每一个Actor都必须是不重名的。 2. 与Actor通讯 ``` $rpc = Actor::getRpc("Test2"); try { $beginid = yield $rpc->beginCo(); $result = yield $rpc->test1(); $result = yield $rpc->test2(); //var_dump($result); $result = yield $rpc->test3(); //var_dump($result); } finally { //var_dump("finally end"); $rpc->end(); } ``` 与Actor通讯都是RPC形式,和调用一个函数一样,支持事务。 3. 销毁Actor ``` Actor::destroyActor($name);//销毁某一个Actor Actor::destroyAllActor();//销毁所有Actor ``` 4. Actor状态机 Actor具有自动恢复的功能,即使服务器关闭,再次启动时会自动恢复所有没有被主动销毁的Actor,当然记录这个Actor的前提是该Actor使用了状态机。 使用setStatus可以创建状态,创建状态的时候或者恢复状态的时候会执行registStatusHandle方法,我们可以在次方法里处理状态对应的逻辑。 ``` $this->setStatus('status', 1); public function registStatusHandle($key, $value); ``` 5. Actor的定时器 ``` public function tick($ms, $callback, $user_param = null);//定时器 public function after($ms, $callback, $user_param = null);//延时执行 public function clearTimer($id);//清除定时器 ``` Actor销毁的时候会自动销毁全部的定时器。 6. Actor集群 在集群环境下Actor同样可以执行,不同机器的Actor间可以相互通讯,还是要注意的一点就是一定要保证Actor名称的唯一性,如果创建了2个名称一样的Actor,那么这2个Actor均会收到属于这个名称的所有消息。 7. 稳定性 SD已验证了50W个Actor的创建与恢复,创建越多的Actor会消耗越多的内存。 ## 结束语 使用好这些模块,会加快你的游戏开发进程,SD之后也会推出更多的面向特定行业的优质模块。