地图加载
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
1.为什么写这些?
今天开会,听同事主讲了<怎么样写出高质量代码?>.里面同事说到了"仿照国外的博客,公开自己写的有意思的代码或者思想"等等的建议.
因为很佩服他所讲的这些,所以决定尝试下抛玉引砖 ,不再潜水了.
顺便记录一下自己的编程成长经历.
2.抛玉引砖
抛出自己认为是玉的那部分,当然也希望在别人眼里也能够是玉.或者通过别人指点,能将这个璞玉雕琢的更加完美.
3.绪论
主要写一下地图的加载算法和想法.本人接触AS3 比较晚,去年7月毕业后才开始接触,到现在快满一年了.所以对AS 甚至编程中的很多东西都不明了,希望高手能指点.
最开始的地图算法是去年8月参照一个策划的方法(多加载一行一列地图切片,移动时将最左边不用的移动到最右边更新)写的,然后自创了一套新的制作思想(关键字做标记)和算法.
这套方法做个简单的比喻下就是拿代数题的方法去解决几何问题.
这个思想初中老师就已经教过了,所以非常简单
比如用代数方法解决几何学题目
I.建立直角坐标系
II.利用三角函数进行计算解题
准备分A,B两个部分写 A: 1.地图的预加载; (纯粹的多加载一圈地图切片)
2.地图的移动; (这里就讲我自己想到的方法)
3. 极限值 ; (利用极限值其实可以制作出很AI的东西,但这里只讲下自己怎么控制极限值让程序不报错...)
B: 还没优化完,暂时保密.A部分是以前写的,B部分是最近优化A部分的衍生物.
如果对此类思想感兴趣的话可以email我互相讨论下
AS3地图加载---A1.地图的预加载
1.为什么要多预加载一圈?
见图...
蓝色的就是地图了,由一块一块的大小为100 x 100 px的切片组成
红色的框就代表 swf的显示框大小为 300 x 300 px ,用户只能看到红框里面的内容
黑色的框表示必须加载的切片范围 4 x 4 枚切片(少于这个数量用户会在红框内看到空白背景)
绿色的框表示预加载多一圈的范围 6 x 6 (左右上下各多加1个切片)
青色的是辅助线请无视
当移动地图后 swf 在如图所示的位置
因为地图往往会比swf的显示范围大的多,一次全部加载速度很慢
而且很占用资源,所以为了满足需求最少要在swf显示范围上预加载一圈
因为不知道用户向四周哪个方向移动地图
在移动地图时会需要加载新的图片
预加载一圈的话,用户会先看到预加载的外围贴片,
如果不预加载,新的图片还在加载中没有显示
用户就会直接看到swf的空白背景,这样的使用体验不太友善
------------------------------------------------------------------------------
例图里都是纯色切片,实际地图肯定每个切片都不一样的
可以根据swf在地图上的相对坐标加载6 x 6 张对应地图切片
简单介绍下当时的需求
接下来就是重点了
→ A2.地图的移动
为了满足和提高用户体验度,在移动加载地图要保证动画的连贯性,同时保证加载多次的内存开销少.
我参考了谷歌地图的模式,制定了解决方案:
1.设定加载切片的loader的数量,因为太多loader一起load的时候很容易出现某一些loader 的load中止,并且不提示出错.
2.缓存一部分切片的图像数据BitmapData.使用队列的方式设置最大缓存数量.(删除最前面的,将最新的加到队列最后)
3.地图的拖动方式在当时使用的是startDarg.(可以拖动的最大范围即swf的显示框的对角线长度)
上面只是解决方案,下面主要讲地图移动后的逻辑判断.
举例: 移动前需要加载的切片位置标记为白色的A 设其范围为RectA
移动后需要加载的切片位置标记为黑色的B 设其范围为RectB
在移动地图后就需要加载只有B标记的切片地图,然后将只有A标记的切片从显示中删除
标记有AB切片的地图不需要做操作.
实现上述需求的老方法(几何方法)是
1.获取地图坐标
2.通过对比坐标来确定新切片满足不在RectA中
3.而在RectB中得到需要加载的切片对象
4和5.然后同理得到需要从先是列表中删除的切片对象.
(当然不一定是删除,根据项目不同的需求设置显示对象载体的变更方式,删除或者移动位置)
下面说说新方法(代数方法) 方法主要利用了集合和逻辑思想.
AS3中数组类型没那么多方便的集合操作方法,所以这里还要加上标记才能更简单的实现集合操作.
在地图加载的最开始设置一个Boolean型的标记flag,标记当前位置的切片是否显示.
即当前RectA中的切片的flag全部标记为true;
1.获取地图坐标
2.判断RectB中的flag , if(flag) 则flag = false , else flag = true; 并加载切片.(当然里面省略了很多缓存的判断操作,如果有缓存则直接拿缓存,没有则用loader加..老方法也会判断所以这里不做比较)
3. 判断RectA中的flag, if(flag) flag = false;并删除切片显示对象,else flag = true;
到这里去年8月新方法结束.
经过逻辑判断,不管用户怎么样拖动地图,最后也只有三种情况
RectA 和RectB 相同,相交,完全不相交
因为有预加载部分所以第三种可能也比较少.
新方法也完全能用于这三种情况,而且不复杂可以方便的扩展新的功能.
写成数字描述会更简单
但是地图加载在性能上还是有别的地方可以进行优化
如难道每次mouseMove都要进行新方法的判断吗?
是可以灵活的操作极限值来减少的.
简单的说明区别就是
过去mouseMove中进行新方法判断是以X = n轴或 Y = n轴即用一条线的比较来取舍是否来进行新方法.
灵活利用极限值的话可以将这一方法扩展为用多条线组成的一个范围区域来取舍是否进行新方法.
使用线的话在线的临界来回拖动的话就会每次都进行新方法.
使用范围的话在固定范围内不再会对新方法做2次执行,同样也能满足需求
详细请见
等待写好后在这里添加链接
极限值
要设置很多极限值去防止溢出的操作.
多预加载一圈切片将带来了更多新的问题.