Создание игр типа казино. Часть первая : Рулетка (Интерактивная среда и Сервер)
В данной статье, как я и обещал , мы поговорим уже о подключении сервера, и нескольких потугах с ним, а именно простейший чат, и трансляция видео канала.
Поехали...
1. Сервер.
Может пол года назад я писал такую весчь http://www.flasher.ru/forum/blog.php?b=407 , возможно не очень красивым языком, но да неважно, смысл в том, что работать мы будем ( показывать схему ) на WMS. Однако, как мне кажется, схемы работы на других медиа-серверах вообщем то похожи.
public class ServerManager { private static const _nc :NetConnection = new NetConnection(); private static const _sender :Object = new Object(); private static var _listener :EventDispatcher; public static function connect(address:String , listener:EventDispatcher ):void { _nc.connect(address); _nc.client = _sender; _listener = listener; _sender.onBetsDone = onBetsDone; _sender.onGameOver = onGameOver; _sender.onGameResult = onGameResult; _sender.onGameStart = onGameStart; _sender.onDealerLogin = onDealerLogin; _nc.addEventListener(NetStatusEvent.NET_STATUS, connectionStatus); } public static function disconnect():void { _nc.close(); } private static function connectionStatus(e:NetStatusEvent) :void { const info : String = "NetConnection.Connect.Success" ; if (e.info.code == info ) _listener.dispatchEvent( new C2SEvents(C2SEvents.CONNECT)); else _listener.dispatchEvent( new C2SEvents(C2SEvents.DISCONNECT)); } // Далее идут on и do методы. В чем их различие ? - опишем ниже. private static function onGameResult(balance:String):void { // on _listener.dispatchEvent( new C2SEvents(C2SEvents.ON_GAME_RESULT , balance )); } public static function playerEnter(playerId:int, tableId:int ):void { // do _nc.call('doPlayerEnter', new Responder(setPlayerEnter), playerId , tableId ); _sender.onPlayerEnter = onPlayerEnter; } }
б). Что есть on методы. Это методы, которые будут вызваны во флеше - сервером, без участия флеша, как такового. Такой коллбек может поймать от сервера сколько угодно параметров, в моем примере 1 параметр balance. Чтобы подписаться на on методы, стоит сначала _nc.client = _sender; задать клиента, тоесть повесить объект который будет хавать данные, а затем на этот объект вешать методы сервера _sender.ServerMethod = ClientMethod;
в). Что есть do методы. Это методы, с помощью которых клиент дергает сервер, заставляя произвести его ту или иную операцию. Дерганье производится так _nc.call('ServerMethod', new Responder(CallBackFromServer), ...rest ); Причем CallBackFromServer может иметь только 1 параметр и не более.
Думаю более менее понятно о чем идет речь.
2. Простенький чат.
Собственно говорить тут особо не о чем, чат реально простой в нашем случае. Постановка такая, - клиент отправляет сообщение серверу, сервер его проверяет и если все окей, рассылает обратно клиенту, после чего мы обновляем информацию в текстовом поле. На сервере метод может быть организован несколько шире, например - если сообщение отправляет дилер, то оно приходит ВСЕМ клиентам, а не только лично какому то.
Думаю код здесь излишен, но на всякий случай :
_listener.addEventListener (C2SEvents.CHAT_MESSAGE , chatMessage); _listener.addEventListener (C2SEvents.ON_CHAT_MESSAGE , onChatMessage); private function chatMessage(e:C2SEvents):void { if (e.vars == '0' ) { // было оговорено, что если в do коллбеке приходит 0, значит отправка сообщения прошла успешно, и в этом случае отработает on метод ниже. // все круто } else { // ошибка } } private function onChatMessage(e:C2SEvents):void { _chatField.htmlText += '<font color="#FFFF00">' + e.vars[0] + ' : </font>' + e.vars[1] + '\n'; _chatField.scrollV = _chatField.maxScrollV; // скрола для поля нету, поэтому с каждым новым сообщением прокручиваем список вручную по последней строчке }
3. Видео сервисы - поток.
С видео каналом работать не сложнее , чем с событиями мыши, достаточно посмотреть справку от адоба. Перепишем под свои нужды :
package com.roulette { import com.roulette.skins.SkinManager; import com.roulette.utils.Config; import flash.display.DisplayObjectContainer; import flash.events.Event; import flash.events.NetStatusEvent; import flash.media.SoundTransform; import flash.media.Video; import flash.net.NetConnection; import flash.net.NetStream; /** * ... * @author in4core */ public class CameraViewer extends NetConnection { private var _video:Video; private var _stream:NetStream; private var _success:Boolean = false; private var _videoStream:String = Config.CAMERA_CONNECTION; private var _videoURL:String = Config.STREAM_ADDRESS; // CONST // public static const CAN_LIVE:String = 'can_live'; public static const CAM_LIVE_ERROR:String = 'cam_live_error'; public static const CAM_PLAY:String = 'cam_play'; public static const CAM_RESET:String = 'cam_reset'; public function CameraViewer() { super(); } public function createConnect():void { this.connect(_videoStream); this.addEventListener(NetStatusEvent.NET_STATUS, netStatusHandler); } private function netStatusHandler(e:NetStatusEvent):void { switch (e.info.code) { case "NetConnection.Connect.Success": this.dispatchEvent(new Event(CAN_LIVE)); trace('connection good'); break; case "NetStream.Play.StreamNotFound": this.dispatchEvent(new Event(CAM_LIVE_ERROR)); trace("Stream not found: " + _videoStream); break; } } public function createStream(video:Video):void { _stream = new NetStream(this); _video = video; _stream.addEventListener(NetStatusEvent.NET_STATUS, StreamStatusHandler); _stream.client = new CustomClient(); _stream.play(_videoURL); _video.attachNetStream(_stream); } private function StreamStatusHandler(e:NetStatusEvent):void { switch (e.info.code) { case 'NetStream.Play.Reset': this.dispatchEvent(new Event(CAM_RESET)); break; case 'NetStream.Play.Start': this.dispatchEvent(new Event(CAM_PLAY)); // убираю звук с камеры, дабы не мешал в ходе тестирования, кодом ниже /*var aud:SoundTransform = new SoundTransform(0); _stream.soundTransform = aud; aud.volume = 0; */ // да к сожалению так криво приходится работать со звуком, адобе не удивил break; } } public function get video():Video { return _video; } } } import com.in4core.utils.Debug; import com.roulette.utils.ServerErrors; internal class CustomClient { public function onMetaData(info:Object):void { for (var i:String in info) Debug.echo('<font color="#999999">*CAMERA SETTINGS*</font> ' + i + ' = ' + info[i]); } public function onCuePoint(info:Object):void { for (var i:String in info) Debug.echo('<font color="#999999">*CAMERA POINTER*</font> ' + i + ' = ' + info[i]); } public function onSDES(info:Object):void { //Debug.echo(ServerErrors.$SES + info.CNAME); } }
Ну вот собственно мы и получили наш видео канал, смотрим и радуемся :
_camera = new CameraViewer(); _camera.addEventListener(CameraViewer.CAN_LIVE , showVideo); _camera.addEventListener(CameraViewer.CAM_LIVE_ERROR , onLiveError); _camera.addEventListener(CameraViewer.CAM_RESET , onCamReset); _camera.addEventListener(CameraViewer.CAM_PLAY , onCamPlay); _camera.createConnect(); private function showVideo(e:Event):void { const $v:MovieClip = SkinManager.getVideoPlayer(); // супер кривые coords ибо скины как обычно делали в AI с шириной типа 154.45 _videoInst = new Video( int( $v.width - 14 ) , int ( $v.height - 12) ); _videoInst.x = int ( $v.x + 7 ); _videoInst.y = int ( $v.y + 6 ); _camera.createStream(_videoInst); } private function onCamPlay(e:Event):void { _view.addChild(_videoInst); }
В следующей статье мы перейдем конкретно на рулеточные столы, а их целых 2. И научимся быдлокодить вместе)))
Всего комментариев 4
Комментарии
16.01.2012 17:32 | |
16.01.2012 17:45 | |
А зачем такой ужас "чистомойный" показывать? Если решили выложить, да ещё и в качестве урока, будьте любезны причесать. Отмазки не канают.
|
16.01.2012 17:47 | |
ПРичесал - отмазки не канают согласен.
|
Последние записи от in4core
- Система диалогов, создаем подобие old School типа Fallout. (07.05.2014)
- MVC в игорной индустрии (27.11.2012)
- Якорь мне .... ))) Или History API (06.11.2012)
- FSD - учим php/sql (28.06.2012)
- I4Logger - простой и компактный логгер (06.05.2012)