页游中通讯数据精简方案示例

网络游戏的及时网络通讯是很大的资源消耗,数据量越小这种消耗就越少,游戏在通讯上的性能就越好

精简通讯中的数据是一种有效的方案。
假定在通讯中一个数据本来要传输8个字节, 而你有方法使之只传输4个字节,那么传送和处理的效率就会有不错的提升。也

许有人会输不久多4个字节嘛,但是如果这个信息会高频的发送,每秒没人5次,100人也需要同步到那么这个量就很大了。

精简数据的方案很多,这里只是两个2D游戏中的具体实现。这两个实现是为了解决游戏中"速度"这个信息网络数据传输的数

据精简。

速度与很多表示方式,但首先要知道 速度是个矢量,有大小也有方向。

速度第一种表示方式是将速度分解为x轴上的标量和y轴上的标量,例如(3.0,4.0),在flash中就表示向右下运动的速度。
速度的每一个标量是一个浮点数,如果将浮点数直接存到字节数据中,那么一个浮点数至少要占据4个字节,那么一个速度信

息就要使用8个字节来存放,这里有一种方案可以将速度信息只存放在4 个字节里。
这个方案的原理是将上述浮点数的整数部分和小数部分,由分析得知,速度数值一般不会过100那么无论是整数部分还是小数

部分都可以存放在一个字节中。在2D游戏中,一个速度信息就只需要4个字节就可以保存了。
如何实现呢?
下面代码中的sfloatToInts(...)方法是将一个上述的浮点数分解为两个整数
下面代码中的intsToSfloat(...)方法是将两个表示整数部分和小数部分的整数合成为一个上述分浮点数
可能有人会说这样计算出来结果有偏差,只是这个偏差一般是在所需精度的范围内,所以没关系

速度的第二种表示方式是由一个表示速度大小的浮点数和一个表示速度方向(角度)的浮点数来表示一个速度信息
例如(5.5,350.23)在flash中也表示向右下运动的速度。
存放速度大小(上面的5.5)要用两个字节(由上例可知), 当然这个大小可以直接存放在客户端而不用每次的传输。
表示速度方向似乎两个byte存放不下,可是分析下就有办法了。虽然角度值范围是 0.0到360.0,但是其也可以表示为
-180.0 到 +180.0,这样的话就有办法用两个字节来存放这个角度值了。
用两个字节来存放浮点数的角度值,在第二个字节中存放 0到180范围内的浮点整数部分的值。
再用第一个字节8位的最左边这一位来表示符号(正数或者负数),第一个字节剩余的7位来存放浮点小数部分。
这样的话,就可以用两个字节来存放角度值的浮点数了。
实现:
下面代码中的sfloatToInts2(...)方法是将一个上述的角度浮点数分解为两个整数,每个整形值是可以放在byte里的
而且第一个整形的最左边的位如果是1的话就表示是负值,反之为正值,其余7为表示浮点数的小数部分
下面代码中的intsToSfloat2(...)方法是将sfloatToInts2(...)方法生成的数据还原为浮点数。

as实现:

//
package
{
	import flash.utils.ByteArray;
	import flash.utils.Endian;
	/**
	 * DataTransform
	 * 
	 * 特殊数据的转换
	 * 
	 * @author vilylei
	 */
	public class DataTransform 
	{
		
		public function DataTransform() 
		{
			
		}
		/**
		 * 将一个 -128.0 -> +128.0 内的浮点数转换为两个整数,这两个整数都在 -128.0 -> +128.0 的范围内
		 * */
		public static function sfloatToInts(f:Number):Vector.<int> {
			if (f < 128.0 && f > -128.0) {
				var k:int = Math.floor(f);
				f = Math.round(100 * (f - k));
				var vs:Vector.<int> = new Vector.<int>();
				vs.push(k, f);
				return vs;
			}else {
				throw Error("Error: 传入的浮点数值 只能在-128.0 -> +128.0这个范围内");
			}
			return null;
		}
		/**
		 * 将 sfloatToInts 生成的数据还原
		 * 
		 * */
		public static function intsToSfloat(ia:int,ib:int):Number {
			if (ia < 128.0 && ia > -128.0 && ib < 128.0 && ib > -128.0) {
				var f:Number = ia + 0.01 * ib;
				return f;
			}else {
				throw Error("Error: 传入的int值 只能在-128.0 -> +128.0这个范围内");
			}
			return 0.0;
		}
		/**
		 * 只能接受 -255.0 -> +255.0
		 * 将 -255.0 -> +255.0 范围内的数字转化为两个int型并且保存符号
		 * 这两个 int型 实际各自都是byte"范围"内的值, 因此可以只用两个字节就保存了这样的浮点数
		 * */
		public static function sfloatToInts2(f:Number):Vector.<int> {
			if (f > -255.0  && f < 255.0) {
				var vs:Vector.<int> = new Vector.<int>();
				var k:int = 0;
				if (f < 0) {
					k = 1;
					k <<= 7;
					//trace();
				}
				f = Math.abs(f);
				var tf:Number = Math.floor(f);
				f = Math.round((f - tf) * 100);
				k += f;
				vs.push(k, tf);
				return vs;
			}else {
				throw Error("Error: 传入的f内的int值 只能在-255.0 -> +255.0这个范围内");
			}
			return null;
		}
		/**
		 * 将 sfloatToInts2 生成的数据还原
		 * */
		public static function intsToSfloat2(ia:int,ib:int):Number {
			if (ia < 255.0 && ia > -255.0 && ib < 255.0 && ib > -255.0) {
				var k:int = 1;
				k <<= 7;
				k = k & ia;
				//trace("k: ",k);
				if (k == 128) {
					//是负值
					k = -1;
					ia -= 128;
				}else {
					k = 1;
				}
				var f:Number = (0.01 * ia + ib) * k;
				return f;
			}else {
				throw Error("Error: 传入的int值 只能在-128.0 -> +128.0这个范围内");
			}
			return 0.0;
		}
		
	}

}
//

 

posted @ 2013-04-27 20:47  vily_雷  阅读(351)  评论(0编辑  收藏  举报