您的位置:首页 > 移动开发 > Objective-C

关于使用SharedObject来缓存游戏图片或者swf文件资源到客户端本地的研究

2012-07-02 17:45 405 查看
目前市面上已经有很多游戏采用了把图片缓存到玩家客户端的做法,这种方法有利有弊,因为并不是所有的玩家都希望自己的电脑的某个角落被放入过多的缓存文件,久而久之造成电脑性能下降;但是总的来说这种技术还是好的:第一,webgame的总体资源也是有限的,不会有太大的容量占用,而且对于程序来说一般只缓存一些核心资源,比如使用很频繁的资源以及需要下载较长时间的大背景大图片或者容量稍大的swf文件等;第二,可以大幅度提升玩家第二次进入游戏的速度,某种意义上可以提升游戏体验度;

好了,废话少说,下面直接说说怎么使用SharedObject来做到把图片或者swf文件缓存到客户端,并在第二次进入程序的时候直接使用缓存的数据还原成想要的原始图片或者swf文件;主要思想是:通过URLStream把显示对象加载进来获得其ByteArra的原始数据,然后通过shareObject把二进制保存到客户端的本地,那么下次进入程序的时候直接可以通过ShareObject获得上次保存的二进制数据,有了二进制数据,只需要通过Loader.loadByte()函数就可以把二进制数据转换成DisplayObject对象;

1.首先我们使用SharedObject来写一个Cookie类:Cookie.as的代码如下:

[java] view plaincopyprint?

////////////////////////////////////////////////////////////////////////////////

// WEBGAME Confidential

// Copyright 2011. All rights reserved.

//

// Cookie.as

// Summary // TODO Auto-generated summary stub

// Version 1.0

// Author txiejun

// Created Nov 4, 2011 10:46:36 PM

////////////////////////////////////////////////////////////////////////////////

package aurora.store

{

import flash.events.NetStatusEvent;

import flash.net.SharedObject;

import flash.net.SharedObjectFlushStatus;

import flash.utils.getQualifiedClassName;

/**

*

* @author txiejun

* @contact txiejun@126.com

* @created Nov 4, 2011 10:46:36 PM

*/

public class Cookie

{

private var _name:String = null;

private var _path:String = null;

private var _shdobj:SharedObject;

private var flushStatus:String = null;

/**

* minDiskSpace KB 空间的存储量 小于 minDiskSpace的数量将不会有提示框弹出

*/

public var minDiskSpace:int = 0;

public function Cookie(name:String,path:String=null,minDiskSpace:int=0)

{

_name = name;

_path = path;

this.minDiskSpace = minDiskSpace;

_shdobj = SharedObject.getLocal(name,_path);

}

private function onFlushStatus(event:NetStatusEvent):void

{

switch (event.info.code)

{

case "SharedObject.Flush.Failed":

trace(getQualifiedClassName(this)+".onFlushStatus() Error: Failed write SharedObject to disk.");

break;

}

_shdobj.removeEventListener(NetStatusEvent.NET_STATUS, onFlushStatus);

}

private function flushValue():void

{

flushStatus =null;

try

{

flushStatus = _shdobj.flush(minDiskSpace);

}

catch (error:Error)

{

trace(getQualifiedClassName(this)+".setCookie() Error: Could not write SharedObject to disk.");

}

if(flushStatus != null)

{

switch(flushStatus)

{

case SharedObjectFlushStatus.PENDING:

trace(getQualifiedClassName(this)+".setCookie() Requesting permission to save value.");

_shdobj.addEventListener(NetStatusEvent.NET_STATUS, onFlushStatus);

break;

}

}

}

public function getName():String

{

return _name;

}

public function getPath():String

{

return _path;

}

/**

* 如果value==null 意味着删除此key

* 如果此Key已经有值了,则原来的值被替换,并返回原来的值

* @param key

* @param value

* @return

*

*/

public function setData(key:String,value:*):*

{

if(key == null)

{

throw new ArgumentError("cannot put a value with undefined or null key!");

return undefined;

}

else if(value == null)

{

return remove(key);

}

else

{

var oldValue:* = getData(key);

_shdobj.data[key]=value;

flushValue();

return oldValue;

}

}

public function getData(key:String):*

{

if(!hasKey(key))

{

return undefined;

}

else

{

return _shdobj.data[key];

}

}

public function remove(key:*):*

{

if(!hasKey(key))

{

return null;

}

var temp:* = _shdobj.data[key];

delete _shdobj.data[key];

return temp;

}

public function hasData(key:String):Boolean

{

if(!hasKey(key))

{

return false;

}

else

{

return _shdobj.data[key]!=null;

}

}

public function hasKey(key:*):Boolean

{

return _shdobj.data.hasOwnProperty(key);

}

/**

* 清除所有数据并从磁盘删除共享对象

*

*/

public function clear():void

{

_shdobj.clear();

}

}

}

[java] view plaincopyprint?

////////////////////////////////////////////////////////////////////////////////

// WEBGAME Confidential

// Copyright 2011. All rights reserved.

//

// BitmapUtil.as

// Summary // TODO Auto-generated summary stub

// Version 1.0

// Author txiejun

// Created Nov 4, 2011 1:57:07 PM

////////////////////////////////////////////////////////////////////////////////

package aurora.graphic

{

import flash.display.Bitmap;

import flash.display.BitmapData;

import flash.display.DisplayObject;

import flash.display.Loader;

import flash.display.LoaderInfo;

import flash.display.Sprite;

import flash.events.Event;

import flash.events.IOErrorEvent;

import flash.geom.Matrix;

import flash.utils.ByteArray;

import flash.utils.getQualifiedClassName;

/**

*

* @author txiejun

* @contact txiejun@126.com

* @created Nov 4, 2011 1:57:07 PM

*/

public class BitmapUtil

{

public function BitmapUtil()

{

}

/**

*  把 ByteArray装换成DisplayObject

* @param byteArray

* @param callBack

*

*/

public static function toDisplayObject(byteArray:ByteArray,callBack:Function):void

{

if(byteArray==null)

{

if(callBack!=null)

{

callBack.call(null,null);

}

return;

}

var loader:Loader = new Loader();

var onCompleteHandler:Function = function(event:Event):void

{

var loaderInfo:LoaderInfo = event.currentTarget as LoaderInfo;

var content:DisplayObject = loaderInfo.content;

loaderInfo.removeEventListener(Event.COMPLETE, onCompleteHandler);

loaderInfo.removeEventListener(IOErrorEvent.IO_ERROR, onIoErrorHandler);

if(callBack!=null)

{

callBack.call(null,content);

}

loader = null;

}

var onIoErrorHandler:Function = function(event:IOErrorEvent):void

{

var loaderInfo:LoaderInfo = event.currentTarget as LoaderInfo;

loaderInfo.removeEventListener(Event.COMPLETE, onCompleteHandler);

loaderInfo.removeEventListener(IOErrorEvent.IO_ERROR, onIoErrorHandler);

trace(getQualifiedClassName(this)+".toDisplayObject() :"+event.text);

if(callBack!=null)

{

callBack.call(null,null);

}

}

loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onCompleteHandler);

loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, onIoErrorHandler);

loader.loadBytes(byteArray);

}

}

}

////////////////////////////////////////////////////////////////////////////////
// WEBGAME Confidential
// Copyright 2011. All rights reserved.
//
// BitmapUtil.as
// Summary // TODO Auto-generated summary stub
// Version 1.0
// Author txiejun
// Created Nov 4, 2011 1:57:07 PM
////////////////////////////////////////////////////////////////////////////////
package aurora.graphic
{
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.DisplayObject;
import flash.display.Loader;
import flash.display.LoaderInfo;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.IOErrorEvent;
import flash.geom.Matrix;
import flash.utils.ByteArray;
import flash.utils.getQualifiedClassName;

/**
*
* @author txiejun
* @contact txiejun@126.com
* @created Nov 4, 2011 1:57:07 PM
*/
public class BitmapUtil
{
public function BitmapUtil()
{
}

/**
*	把 ByteArray装换成DisplayObject
* @param byteArray
* @param callBack
*
*/
public static function toDisplayObject(byteArray:ByteArray,callBack:Function):void
{
if(byteArray==null)
{
if(callBack!=null)
{
callBack.call(null,null);
}
return;
}

var loader:Loader = new Loader();
var onCompleteHandler:Function = function(event:Event):void
{
var loaderInfo:LoaderInfo = event.currentTarget as LoaderInfo;
var content:DisplayObject = loaderInfo.content;
loaderInfo.removeEventListener(Event.COMPLETE, onCompleteHandler);
loaderInfo.removeEventListener(IOErrorEvent.IO_ERROR, onIoErrorHandler);

if(callBack!=null)
{
callBack.call(null,content);
}
loader = null;
}
var onIoErrorHandler:Function = function(event:IOErrorEvent):void
{
var loaderInfo:LoaderInfo = event.currentTarget as LoaderInfo;
loaderInfo.removeEventListener(Event.COMPLETE, onCompleteHandler);
loaderInfo.removeEventListener(IOErrorEvent.IO_ERROR, onIoErrorHandler);
trace(getQualifiedClassName(this)+".toDisplayObject() :"+event.text);
if(callBack!=null)
{
callBack.call(null,null);
}
}
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onCompleteHandler);
loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, onIoErrorHandler);
loader.loadBytes(byteArray);
}

}
}


这两个工具类写好了以后,就可以开始写主程序了;

ShareObjectTest.as文件如下:

[java] view plaincopyprint?

////////////////////////////////////////////////////////////////////////////////

// WEBGAME Confidential

// Copyright 2011. All rights reserved.

//

// ShareObjectTest.as

// Summary // TODO Auto-generated summary stub

// Version 1.0

// Author txiejun

// Created Nov 5, 2011 12:31:10 AM

////////////////////////////////////////////////////////////////////////////////

package

{

import aurora.graphic.BitmapUtil;

import aurora.store.Cookie;

import flash.display.DisplayObject;

import flash.display.Sprite;

import flash.display.StageAlign;

import flash.display.StageScaleMode;

import flash.events.Event;

import flash.events.IOErrorEvent;

import flash.net.URLRequest;

import flash.net.URLStream;

import flash.utils.ByteArray;

/**

*

* @author txiejun

* @contact txiejun@126.com

* @created Nov 5, 2011 12:31:10 AM

*/

public class ShareObjectTest extends Sprite

{

private var assests:Array = ["mc_1.swf","img_1.png"];

private var cookie:Cookie ;

private var index:int = 1;

public function ShareObjectTest()

{

super();

if(stage)

{

stage.align = StageAlign.TOP_LEFT;

stage.scaleMode = StageScaleMode.NO_SCALE;

stage.stageFocusRect = false;

}

cookie = new Cookie("ShareObjectTest");

// cookie.clear();

loadAssest(assests[index]);

}

private function loadAssest(url:String):void

{

//检查是否已经加载过资源

if(cookie.hasData(url))

{

//获得缓存的二进制数据

var byteArray:ByteArray = cookie.getData(url);

//转换成显示对象

BitmapUtil.toDisplayObject(byteArray,onLoaded);

trace("url",url,"already loaded");

}

else

{

//加载二进制数据

var urlstream:URLStream = new URLStream();

urlstream.addEventListener(Event.COMPLETE,onStreamComplete);

urlstream.addEventListener(IOErrorEvent.IO_ERROR,onIOError);

urlstream.load(new URLRequest(url));

trace("url",url,"need load");

}

}

private function onLoaded(content:DisplayObject):void

{

this.addChild(content);

content.x = index*100;

content.y = index*50;

trace("onLoaded ",assests[index]);

}

private function onStreamComplete(event:Event):void

{

var urlstream:URLStream = event.currentTarget as URLStream;

urlstream.removeEventListener(Event.COMPLETE,onStreamComplete);

urlstream.removeEventListener(IOErrorEvent.IO_ERROR,onIOError);

var byteArray:ByteArray = new ByteArray();

urlstream.readBytes(byteArray);

//转换成显示对象

BitmapUtil.toDisplayObject(byteArray,onLoaded);

//保存二进制数据到本地客户端

cookie.setData(assests[index],byteArray);

trace("cookie.setData",assests[index]);

}

private function onIOError(event:IOErrorEvent):void

{

var urlstream:URLStream = event.currentTarget as URLStream;

urlstream.removeEventListener(Event.COMPLETE,onStreamComplete);

urlstream.removeEventListener(IOErrorEvent.IO_ERROR,onIOError);

}

}

}

[java] view plaincopyprint?

url img_1.png need load

cookie.setData img_1.png

onLoaded  img_1.png

url img_1.png need load
cookie.setData img_1.png
onLoaded  img_1.png

但是第二次以后再运行的时候,得到的trace结果是:

[java] view plaincopyprint?

url img_1.png already loaded

onLoaded img_1.png

url img_1.png already loaded
onLoaded img_1.png
可以看出来,第二次是使用的缓存到客户端的二进制数据了,从而我们想要的效果已经达到!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐