arpg網頁遊戲之地圖(三)

來源:互聯網
上載者:User

標籤:

地圖分塊載入類MapEngine,主要包含以下屬性:

    1. g 地圖層graphics,地圖將畫在上面
    2. buffPixelRange 地圖載入範圍矩形
    3. viewPort 螢幕視窗
    4. currZoneArr 已經載入過的地圖塊
    5. waitLoadZone 待載入地圖塊
    6. showZone 載入完成即將顯示的地圖塊
    7. preLoaderNmu 預先載入塊數

單獨說下地圖層graphics,Graphics實際上為一個shape對象,我把所有的載入的地圖塊,draw到graphics上,也有很多建立多個bitmap對象或者shape對象堆疊到地圖層,或者建立和螢幕視窗一樣的大的bitmap每次都draw到這個上面,我一開始接觸網頁的遊戲的時候,就是這種方法。嘗試過後,發後面的方式,在推圖的時候,鬥的較厲害,直接畫在graphics上,可能給玩具啊最好的體驗,這也是破解了多款網頁遊戲代碼之後,參考大部分網頁遊戲推圖演算法,最後加以總結歸納,形成了我現在現在所用的。另外說下預先載入塊數,preLoaderNmu 我設定為1,就是相對螢幕視窗,實際計算出來的地圖塊,我上下左右都多載入一塊,以此來提供玩家體驗。具體的載入演算法如下:

public function calcLoadZone() : void        {            var rect:Rectangle = viewPort.viewRect;            var tileSize:int = SceneConfig.TILE_SIZE;            var scale:Number = 1 / tileSize;            var leftX:int = int(rect.x * scale) - preLoaderNmu;            var leftY:int = int(rect.y * scale) - preLoaderNmu;            var rightX:int = int(rect.x + rect.width) * scale + preLoaderNmu;            var rightY:int = int(rect.y + rect.height) * scale + preLoaderNmu;            leftX = max(0, leftX);            leftY = max(0, leftY);            rightX = min(rightX, maxMapCountX);            rightY = min(rightY, maxMapCountY);            buffPixelRange.x = leftX * tileSize;            buffPixelRange.y = leftY * tileSize;            buffPixelRange.width = (rightX - leftX + 1) * tileSize;            buffPixelRange.height = (rightY - leftY + 1) * tileSize;            var centerX:int = (leftX + rightX) * 0.5;            var centerY:int = (leftY + rightY) * 0.5;            var temp:int = 0;            var key:int = 0;            var zone:Zone = null;            while (leftY <= rightY)            {                temp = leftX;                while (temp <= rightX)                {                    key = temp + leftY * titleX;                    zone = currZoneArr[key];  // 判斷是否載入過此地圖塊                    if (zone == null)                    {                        zone = new Zone();                        zone.xpos = temp;                        zone.ypos = leftY;                        currZoneArr[key] = zone;                        zone.dis = pow(temp - centerX, 2) + pow(leftY - centerY, 2); //計算離載入範圍中心的距離                        waitLoadZone[waitLoadZone.length] = zone; // 添加到載入隊列                    }                    temp++;                }                leftY++;            }            waitLoadZone.sort(sortByDis); // 對要即在的地圖塊進行排序        }

上面的代碼,重要的部分已經注釋。那個sort函數,單獨說下,有很多載入地圖的效果,會有一個動畫效果,就是地圖塊的顯示,是從中心開始顯示,然後逐步擴充到四周。所以離載入範圍中心進的地圖塊優先載入,這樣就會保證離中心近的,先載入,也就會優先顯示出來。

玩家進入地圖之前,會優先下載小地圖,所以在所有 地圖塊載入之前,把小地圖放大後,直接畫在graphics上,這樣就實現馬賽克效果。為了提高玩家的體驗,在每幀的迴圈裡,只載入一張地圖塊,並且只顯示有給地圖塊。一般網頁的幀率是沒秒30幀,理論上一針顯示一張地圖塊。代碼如下

public function render(param1:int, param2:Number) : void        {            var zone2:Zone;            var zone:Zone;            var loadInfo:ILoadInfo;            var size:int;            var stepFrame:int = param1;            var stepTime:Number = param2;            if (waitLoadZone.length > 0) // 只載入一張地圖塊            {                zone = waitLoadZone.shift();                loadInfo = api.loadCenter.getNewLoadInfo();                loadInfo.url = getPath(getMapId(), zone.xpos + "_" + zone.ypos);                loadInfo.completeHanlder = function (param1:Bitmap) : void                {                    var key:int = zone.xpos + zone.ypos * titleX;                    if (loadingDic[key] != undefined)                    {                        loadingDic[key] = null;                        delete loadingDic[key];                    }                    if (!zone.isComplete)                    {                        zone.bpd = param1.bitmapData;                        showZone.push(zone);                    }                    loadedDic.push(loadInfo.url);                    return;                }                api.loadCenter.addLoadInfo(loadInfo);            }            while (showZone.length) // 只顯示一張已經載入過的地圖塊            {                                zone2 = showZone.shift();                size = SceneConfig.TILE_SIZE;                g.beginBitmapFill(zone2.bpd);                g.drawRect(zone2.xpos * size, zone2.ypos * size, size, size);                break;            }            return;        }
可能會有人疑惑,為什麼每幀載入一塊,而且只顯示一塊地圖塊?為什麼不根據,一下在都載入完,或者載入完,為什麼不直接畫在地圖層。我們都知道AS3.0 渲染機制,即跑道模型。如果AS每幀處理的事情太多,就會出現卡幀的情況。這樣做的目的,就是盡量把一些運算平均分攤到這個幀上,盡量以平穩流暢為主,算是一種最佳化策略。可能有的人機器配置高,或者網速快,他的體驗就會更好,的確是這樣。但是人眼能識別出的最低頻率24幀,一些電影就是以24幀的頻率動畫播放,所以把一些運算分攤到各個幀上,對於玩家來說,體驗並不會差多少,範圍提高了平穩性和流暢性。

arpg網頁遊戲之地圖(三)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.