关于使用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();
}
}
}
这两个工具类写好了以后,就可以开始写主程序了;
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);
}
}
}
但是第二次以后再运行的时候,得到的trace结果是:
[java] view plaincopyprint?
url img_1.png already loaded
onLoaded img_1.png
url img_1.png already loaded
onLoaded img_1.png
可以看出来,第二次是使用的缓存到客户端的二进制数据了,从而我们想要的效果已经达到!
好了,废话少说,下面直接说说怎么使用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
可以看出来,第二次是使用的缓存到客户端的二进制数据了,从而我们想要的效果已经达到!
相关文章推荐
- 关于使用SharedObject来缓存游戏图片或者swf文件资源到客户端本地的研究
- 使用SharedObject缓存游戏框架到本地和版本更新的demo
- Node.js 使用http客户端得到网站的图片下载到本地
- 关于webview 加载本地图片资源 显示不出来的解决办法
- 关于fresco的使用之--CacheKey获取本地缓存
- [SDK2.2]Windows Azure Storage (16) 使用WCF服务,将本地图片上传至Azure Storage (上) 客户端代码
- 关于使用脚本请求服务器端资源无法缓存的问题
- 安卓加载大背景图片或者加载大量本地资源图片时经常导致内存溢出(Out of Memory Error)推荐几种解决方案
- ios7关于图片资源使用需要注意的问题
- 请求网络图片缓存到本地 ,还有一些现成的图片加载框架的使用 Ace网络篇(一)
- Android仿人人客户端(v5.7.1)——对从服务器端(网络)获取的图片进行本地双缓存处理(编码实现)
- 使用Volley获取网络图片,并作本地缓存
- QQ或者微信客户端加载本地图片是如何实现的?
- 关于webview 加载本地图片资源 显示不出来的解决办法
- webview 设定和使用缓存来获取网页中的js,css和图片资源
- 从缓存的源文件中读取资源文件,下载到本地(包括图片和样式脚本)
- Android仿人人客户端(v5.7.1)——对从服务器端(网络)获取的图片进行本地双缓存处理(编码实现)
- 关于ImageLoader加载本地缓存下来的图片的问题?
- 关于java/android中 Jar中使用图片资源
- 【Android】使用系统相机或者从相册中获取图片资源并进行适当裁剪