今天尝试用Socket和AMF3来开发web游戏引擎,用Flash的好处就是因为插件普及率高,无需用户另行安装,所以用Flash来开发丰富的Web游戏成为很好的选择。服务端仍然采用apache mina+AMF3来写Socket服务程序。
演示效果图:
客户端代码:游戏角色类
- /**
- * ...
- * @author Kinglong
- * @version 0.1
- */
- package project.test {
- import flash.display.*;
- import flash.events.*;
- import gs.TweenLite;
- public class GameRole extends Sprite {
- private var _id:uint;
- private var tween:TweenLite;
- public function GameRole(id:uint,self:Boolean= false ) {
- mouseChildren = false ;
- mouseEnabled = false ;
- _id = id;
- if (self){
- this .graphics.beginFill( 0xFF0000 );
- }else {
- this .graphics.beginFill( 0x000000 , 0.6 );
- }
- this .graphics.drawRoundRect( - 10 , - 10 , 20 , 20 , 10 , 10 );
- this .graphics.endFill();
- }
- public function move(x:Number,y:Number): void {
- remove();
- this .x = x;
- this .y = y;
- }
- public function to(x:Number, y:Number): void {
- remove();
- tween = TweenLite.to(this , 1 , { x:x, y:y } );
- }
- public function get id():uint {
- return _id;
- }
- private function remove(): void {
- if (tween != null ) {
- TweenLite.removeTween(tween);
- tween = null ;
- }
- }
- }
- }
/** * ... * @author Kinglong * @version 0.1 */ package project.test { import flash.display.*; import flash.events.*; import gs.TweenLite; public class GameRole extends Sprite { private var _id:uint; private var tween:TweenLite; public function GameRole(id:uint,self:Boolean=false) { mouseChildren = false; mouseEnabled = false; _id = id; if(self){ this.graphics.beginFill(0xFF0000); }else { this.graphics.beginFill(0x000000, 0.6); } this.graphics.drawRoundRect( -10, -10, 20, 20, 10, 10); this.graphics.endFill(); } public function move(x:Number,y:Number):void { remove(); this.x = x; this.y = y; } public function to(x:Number, y:Number):void { remove(); tween = TweenLite.to(this, 1, { x:x, y:y } ); } public function get id():uint { return _id; } private function remove():void { if (tween != null) { TweenLite.removeTween(tween); tween = null; } } } }
文档类
- /**
- * ...
- * @author Kinglong
- * @version 0.1
- */
- package project.test {
- import flash.display.*;
- import flash.events.*;
- import flash.net.Socket;
- import flash.net.ObjectEncoding;
- import flash.text.TextField;
- import flash.utils.ByteArray;
- import flash.utils.Dictionary;
- import com.klstudio.data.Map;
- public class TestGame extends Sprite {
- private var _socket:Socket;
- private var _id:uint;
- private var _lists:Map;
- private var _info:TextField;
- public function TestGame() {
- _info = new TextField();
- _info.selectable = false ;
- _info.text = "未连接" ;
- addChild(_info);
- stage.addEventListener(MouseEvent.MOUSE_UP, handler);
- _lists = new Map();
- _socket = new Socket();
- _socket.objectEncoding = ObjectEncoding.AMF3;
- configureListeners(_socket);
- _socket.connect("localhost" , 110 );
- }
- private function configureListeners(dispatcher:IEventDispatcher): void {
- dispatcher.addEventListener(Event.CLOSE, handler);
- dispatcher.addEventListener(Event.CONNECT, handler);
- dispatcher.addEventListener(IOErrorEvent.IO_ERROR, handler);
- dispatcher.addEventListener(SecurityErrorEvent.SECURITY_ERROR, handler);
- dispatcher.addEventListener(ProgressEvent.SOCKET_DATA, handler);
- }
- private function handler(event:Event): void {
- switch (event.type) {
- case ProgressEvent.SOCKET_DATA:
- var bytes:ByteArray = new ByteArray();
- _socket.readBytes(bytes);
- bytes.uncompress();
- receive(bytes.readObject());
- break ;
- case Event.CLOSE:
- debug("连接关闭" );
- removeAll();
- break ;
- case Event.CONNECT:
- debug("连接中..." );
- break ;
- case IOErrorEvent.IO_ERROR:
- case SecurityErrorEvent.SECURITY_ERROR:
- debug("连接失败" );
- break ;
- case MouseEvent.MOUSE_UP:
- var mEvent:MouseEvent = event as MouseEvent;
- send(this .mouseX, this .mouseY);
- break ;
- }
- }
- private function send(x:Number, y:Number): void {
- if (!_socket.connected) {
- return ;
- }
- var bytes:ByteArray = new ByteArray();
- bytes.writeObject( { event:"move" , x:x, y:y } );
- bytes.compress();
- _socket.writeBytes(bytes);
- _socket.flush();
- }
- private function receive(object:Object): void {
- switch (object.event) {
- case "init" :
- init(object.id);
- for (var i:uint = 0 ; i < object.list.length; i++ ) {
- var item:Object = object.list[i];
- add(item.id, item.x, item.y);
- }
- break ;
- case "move" :
- move(object.id, object.x, object.y);
- break ;
- case "remove" :
- remove(object.id);
- break ;
- case "add" :
- add(object.id);
- break ;
- }
- }
- private function init(id:uint): void {
- this ._id = id;
- add(id);
- }
- private function add(id:uint, x:Number = undefined, y:Number = undefined): void {
- x = x || stage.stageWidth / 2 ;
- y = y || stage.stageHeight / 2 ;
- if (_lists.containsKey(id)) {
- return ;
- }
- var role:GameRole = new GameRole(id,_id == id);
- role.move(x,y);
- addChild(role);
- _lists.put(id, role);
- }
- private function move(id:uint, x:Number, y:Number): void {
- if (_lists.containsKey(id)) {
- var role:GameRole = _lists.get(id);
- role.to(x, y);
- }
- }
- private function remove(id:uint): void {
- if (_lists.containsKey(id)) {
- var role:GameRole = _lists.remove(id);
- trace(role);
- if ( this .contains(role)) {
- removeChild(role);
- }
- role = null ;
- }
- }
- private function removeAll(): void {
- var keys:Array = _lists.keys();
- for (var i:uint = 0 ; i < keys.length; i++ ) {
- var role:GameRole = _lists.remove(keys[i]);
- if ( this .contains(role)) {
- removeChild(role);
- }
- role = null ;
- }
- }
- private function debug(msg:String): void {
- _info.text = msg;
- trace(msg);
- }
- }
- }
/** * ... * @author Kinglong * @version 0.1 */ package project.test { import flash.display.*; import flash.events.*; import flash.net.Socket; import flash.net.ObjectEncoding; import flash.text.TextField; import flash.utils.ByteArray; import flash.utils.Dictionary; import com.klstudio.data.Map; public class TestGame extends Sprite { private var _socket:Socket; private var _id:uint; private var _lists:Map; private var _info:TextField; public function TestGame() { _info = new TextField(); _info.selectable = false; _info.text = "未连接"; addChild(_info); stage.addEventListener(MouseEvent.MOUSE_UP, handler); _lists = new Map(); _socket = new Socket(); _socket.objectEncoding = ObjectEncoding.AMF3; configureListeners(_socket); _socket.connect("localhost", 110); } private function configureListeners(dispatcher:IEventDispatcher):void { dispatcher.addEventListener(Event.CLOSE, handler); dispatcher.addEventListener(Event.CONNECT, handler); dispatcher.addEventListener(IOErrorEvent.IO_ERROR, handler); dispatcher.addEventListener(SecurityErrorEvent.SECURITY_ERROR, handler); dispatcher.addEventListener(ProgressEvent.SOCKET_DATA, handler); } private function handler(event:Event):void { switch(event.type) { case ProgressEvent.SOCKET_DATA: var bytes:ByteArray = new ByteArray(); _socket.readBytes(bytes); bytes.uncompress(); receive(bytes.readObject()); break; case Event.CLOSE: debug("连接关闭"); removeAll(); break; case Event.CONNECT: debug("连接中..."); break; case IOErrorEvent.IO_ERROR: case SecurityErrorEvent.SECURITY_ERROR: debug("连接失败"); break; case MouseEvent.MOUSE_UP: var mEvent:MouseEvent = event as MouseEvent; send(this.mouseX, this.mouseY); break; } } private function send(x:Number, y:Number):void { if (!_socket.connected) { return; } var bytes:ByteArray = new ByteArray(); bytes.writeObject( { event:"move", x:x, y:y } ); bytes.compress(); _socket.writeBytes(bytes); _socket.flush(); } private function receive(object:Object):void { switch(object.event) { case "init": init(object.id); for (var i:uint = 0; i < object.list.length; i++ ) { var item:Object = object.list[i]; add(item.id, item.x, item.y); } break; case "move": move(object.id, object.x, object.y); break; case "remove": remove(object.id); break; case "add": add(object.id); break; } } private function init(id:uint):void { this._id = id; add(id); } private function add(id:uint, x:Number = undefined, y:Number = undefined):void { x = x || stage.stageWidth / 2; y = y || stage.stageHeight / 2; if (_lists.containsKey(id)) { return; } var role:GameRole = new GameRole(id,_id == id); role.move(x,y); addChild(role); _lists.put(id, role); } private function move(id:uint, x:Number, y:Number):void { if (_lists.containsKey(id)) { var role:GameRole = _lists.get(id); role.to(x, y); } } private function remove(id:uint):void { if (_lists.containsKey(id)) { var role:GameRole = _lists.remove(id); trace(role); if (this.contains(role)) { removeChild(role); } role = null; } } private function removeAll():void { var keys:Array = _lists.keys(); for (var i:uint = 0; i < keys.length; i++ ) { var role:GameRole = _lists.remove(keys[i]); if (this.contains(role)) { removeChild(role); } role = null; } } private function debug(msg:String):void { _info.text = msg; trace(msg); } } }
这个尝试的游戏引擎功能很简单的,接下来可以加上更丰富的功能了 ...