webgame 地图加载(论坛摘录)
****************************************************************
没有必要从服务器发送请求的。
简单叙述一下。
我们先把一个完整地图做成切片,比如250*250.所有的切片按照自己的位置来命名。
比如第一行第一块切片命名 slice_1_1.png 第一行第二块命名为 slice_1_2.png.......
我们知道通常我们人物在行走的时候会有两个坐标,一个是屏幕坐标,一个是针对地图的坐标。
我们可以用人物的地图坐标 / 切片宽度(切片高度)——这里是250*250,得到人物现在处于第几行第几列的切片上。
有了这一块切片位置怎么用?
我们知道一般的游戏都是采用人物始终居中的,那么你可以知道这个切片周围8块切片了。加载他们。。
经过以上步骤你已经可以显示地图了。但是要让玩家感觉不出来你的加载过程,你必须预加载。预加载就是在当前的8块基础上,再扩展一圈。
最后你需要加载的切片是25片。
参考代码:
var map=new Sprite();//定义背景容器
map.name="map";
var fps:showtime = new showtime();
fps.y= 20;
fps.x = 30;
stage.addChild(fps);
var man_x:Number=840; //人物
var man_y:Number=840;
var man_SceneX:Number;
var man_SceneY:Number;
var speed:Number=4;
var man_status:int=2;
var mapWidth:int=9600; //地图设定
var mapHeight:int=7500;
var tileWidth:int=300;
var tileHeight:int=300;
var sceneWidth:int=800; //屏幕设定
var sceneHeight:int=550;
var sceneMinX:Number;
var sceneMaxX:Number;
var sceneMinY:Number;
var sceneMaxY:Number;
var tempX:Number=0;
var tempY:Number=0;
var minrow:int; //行列估算
var mincol:int;
var maxrow:int;
var maxcol:int;
var bfMinrow:int; //预加载的行列
var bfMincol:int;
var bfMaxrow:int;
var bfMaxcol:int;
var SliceArray:Array=new Array;
var clickPoint:Point=new Point();
//****************************************************
//程序运行主函数
//****************************************************
Init(man_x,man_y);
map.addEventListener(MouseEvent.CLICK,mouseclick);
human.addEventListener(MouseEvent.CLICK,sitdown);
function sitdown(evt:MouseEvent)
{
if(man_status!=17)
{
man_status=17;
human.gotoAndStop(man_status);
}
else
{
man_status=2;
human.gotoAndStop(man_status);
}
}
function Init(tempx:Number,tempy:Number):void
{
man_x=tempx;
man_y=tempy;
addChild(map);
addChild(frame);
addChild(human);
if (man_x<=sceneWidth/2)
{
sceneMinX=0;
sceneMaxX=sceneMinX+sceneWidth;
}
else if (man_x>mapWidth-sceneWidth/2)
{
sceneMaxX=mapWidth;
sceneMinX=sceneMaxX-sceneWidth;
}
else
{
sceneMinX=man_x-sceneWidth/2;
sceneMaxX=sceneMinX+sceneWidth;
}
if (man_y<=sceneHeight/2)
{
sceneMinY=0;
sceneMaxY=sceneMinY+sceneHeight;
}
else if (man_y>mapHeight-sceneHeight/2)
{
sceneMaxY=mapHeight;
sceneMinY=sceneMaxY-sceneHeight;
}
else
{
sceneMinY=man_y-sceneHeight/2;
sceneMaxY=sceneMinY+sceneHeight;
}
// trace("左上角坐标:"+sceneMinX+","+sceneMinY);
// trace("右下角坐标:"+sceneMaxX+","+sceneMaxY);
minrow=Math.floor(sceneMinX/tileWidth)+1;
mincol=Math.floor(sceneMinY/tileHeight)+1;
maxrow=Math.ceil(sceneMaxX/tileWidth);
maxcol=Math.ceil(sceneMaxY/tileHeight);
bfMinrow= (minrow==1) ? minrow: minrow-1;
bfMincol= (mincol==1) ? mincol: mincol-1;
bfMaxrow=(maxrow==mapWidth/tileWidth)? maxrow: maxrow+1;
bfMaxcol=(maxcol==mapHeight/tileHeight)? maxcol: maxcol+1;
//trace("切片的X从 "+minrow+" 到 "+maxrow+"。");
//trace("切片的Y从 "+mincol+" 到 "+maxcol+"。");
man_SceneX=man_x-sceneMinX;
man_SceneY=man_y-sceneMinY;
// trace("人物的坐标X:"+man_SceneX);
// trace("人物的坐标Y:"+man_SceneY);
// trace("内存:"+System.totalMemory+"bytes");
for (var i:int=bfMinrow; i<=bfMaxrow; i++)
{
for (var j:int=bfMincol; j<=bfMaxcol; j++)
{
var pictURL:String = "images/map_"+i+"_"+j+".jpg";
if (SliceArray.indexOf(pictURL)==-1)
{
SliceArray.push(pictURL);
var pictLdr:Loader = new Loader();
var pictURLReq:URLRequest = new URLRequest(pictURL);
//trace("开始加载:"+pictURL);
pictLdr.load(pictURLReq);
//pictLdr.contentLoaderInfo.addEventListener(Event.COMPLETE, loaded);
pictLdr.name=pictURL;
map.addChild(pictLdr);
pictLdr.x=(i-1)*tileWidth;
pictLdr.y=(j-1)*tileHeight;
pictLdr=null;
pictURLReq=null;
}
pictURL=null;
}
}
map.x=-sceneMinX;
map.y=-sceneMinY;
human.x=man_SceneX;
human.y=man_SceneY;
cacheAsBitmap
// trace(map.numChildren);
// trace("人物坐标:"+man_x+" ,"+man_y);
}
****************************************************************
更正一下,可加载的图,尺寸最大为4080X4080,bitmapdata构造函数的上线是2880
也就是说BitmapData在New的时候的内存上限是32M,加载的上限是64M
****************************************************************
请教一个问题,在加载切片的时候,在场景中运动会出现卡的现象/跳帧
不知道大家在预加载的时候有没有这么现象,然后怎么来规避这个问题呢?
用另外一个SWF加载,加载成功后通过LocalConnection传递,可以很大程度上减少停顿感觉
另外要控制加载速度,比如每秒只加载一幅图片
此外RFC有个很二的规定,建议浏览器,同一页面对同一IP的并发连接不超过2,因此实际你同时并发过多,只会卡,不会有任何的好处
本来IE没有这个限制的,现在为了遵循傻×的RFC规范,增加了这个限制
****************************************************************