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规范,增加了这个限制

****************************************************************

原文地址:https://www.cnblogs.com/axyz/p/2263227.html