麻豆小视频在线观看_中文黄色一级片_久久久成人精品_成片免费观看视频大全_午夜精品久久久久久久99热浪潮_成人一区二区三区四区

首頁(yè) > 學(xué)院 > 開(kāi)發(fā)設(shè)計(jì) > 正文

C#開(kāi)發(fā)WPF/Silverlight動(dòng)畫及游戲系列教程(Game Tutorial):(三十九)向Silverlight移植①

2019-11-17 04:08:04
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友
一、主要改進(jìn):

1)Silverlight3.0上的右鍵實(shí)現(xiàn):

//注冊(cè)右鍵事件

HtmlPage.Document.AttachEvent("oncontextmenu", Game_MouseRightButtonDown);

//鼠標(biāo)右鍵事件

PRivate void Game_MouseRightButtonDown(object sender, HtmlEventArgs e) {

        e.PreventDefault(); //取消右鍵彈出菜單

……邏輯部分

}

通過(guò)上述方法還必須配合<param name="Windowless" value="true" />或System.Windows.Interop.Settings.Windowless = true才能實(shí)現(xiàn)右鍵功能。另外需要特別說(shuō)明的是,此方法并非官方所提供的解決方案,而是第三方間接的實(shí)現(xiàn)方式。因此,在使用前,您必須解為Silverlight解禁右鍵將付出的代價(jià):①Windowless = true將降低程序整體性能;②無(wú)法使用輸入法;③無(wú)法被所有的瀏覽器所兼容,例如在Google Chrome中,雖然可以激發(fā)出右鍵功能,但是取消不了彈出右鍵菜單。綜上,在Silverlight3.0中,您還是得謹(jǐn)慎再謹(jǐn)慎的考慮是否使用右鍵。





2)撤消精靈及其他所有控件中的x,y,z坐標(biāo)定位用關(guān)聯(lián)屬性,取而代之的是一個(gè)名為Coordinate的關(guān)聯(lián)屬性,其完整定義如下:

/// <summary>

/// 獲取或設(shè)置控件坐標(biāo)(關(guān)聯(lián)屬性)

/// </summary>

public Point Coordinate {

    get { return (Point)GetValue(CoordinateProperty); }

    set { SetValue(CoordinateProperty, value); }

}

public static readonly DependencyProperty CoordinateProperty = DependencyProperty.Register(

    "Coordinate",

     typeof(Point),

     typeof(QXSprite),

     new PropertyMetadata(ChangeCoordinateProperty)

);

private static void ChangeCoordinateProperty(DependencyObject d, DependencyPropertyChangedEventArgs e) {

     QXSprite obj = (QXSprite)d;

     if (obj.Visibility == Visibility.Visible) {

         Point p = (Point)e.NewValue;

         obj.SetValue(Canvas.LeftProperty, p.X - obj.CenterX);

         obj.SetValue(Canvas.TopProperty, p.Y - obj.CenterY);

         obj.SetValue(Canvas.ZIndexProperty, Convert.ToInt32(p.Y));

      }

}

Coordinate的類型為Point,因此,我將原先精靈移動(dòng)用的DoubleAnimation動(dòng)畫類型替換成了PointAnimation;這樣,不論是在代碼結(jié)構(gòu)還是性能上均得到很大的優(yōu)化。更改控件坐標(biāo)時(shí),只需修改它的Coordinate = new Point(x,y)即可,系統(tǒng)會(huì)判斷該關(guān)聯(lián)屬性的值是否發(fā)生改變而激發(fā)ChangeCoordinateProperty方法,從而更新該控件最終在畫面中的LeftProperty、TopProperty和ZIndexProperty。沒(méi)錯(cuò),關(guān)聯(lián)屬性就是這么強(qiáng)大。

3)A*移動(dòng)的優(yōu)化。我已留下接口,根據(jù)不同的參數(shù)設(shè)置,可以啟動(dòng)不同效率、不同路徑長(zhǎng)短、不同精確度的A*尋路,這里我給大家推薦兩種現(xiàn)成的方案,第一種—程序默認(rèn)A*尋路方案,此方案找到的路徑最精確,但性能消耗最高;另一種方案可以實(shí)現(xiàn)最高效的尋路,但得到的路徑并非最短:

PathFinderFast pathFinderFast = new PathFinderFast(varyObstruction) {

    HeavyDiagonals = false,

    HeuristicEstimate = 100,

};

我在Silverlight引擎中封裝的A*尋路DLL,是根據(jù)教程第七節(jié)的老外A*改編而成。因此,您完全可以將之作為一個(gè)調(diào)試器,調(diào)試不同的搭配方案,然后將參數(shù)賦予pathFinderFast里:



例如上圖,我通過(guò)模擬測(cè)試,發(fā)現(xiàn)最終找到路徑所消耗的時(shí)間為0.0071秒,假如我已對(duì)此設(shè)置所產(chǎn)生的路徑長(zhǎng)度與性能感到滿意,那么接下來(lái)要做的就是將此方案的配置記錄下來(lái): Diagonals = true ; Heavy Diagonals = true ; Henuristic = 5 ; Formula = Max(DX,DY) ; Use Tie Breaker = false ; Search Limit = 40000 ; 尋路對(duì)象使用的是FastPathFinder。

OK,最后來(lái)在Silverlight引擎中,我就可以這樣來(lái)啟動(dòng)A*尋路:

PathFinderFast pathFinderFast = new PathFinderFast(varyObstruction) {

    Diagonals = true,

    HeavyDiagonals = true,

    HeuristicEstimate = 5,

    Formula = HeuristicFormula.MaxDXDY,

    TieBreaker = false,

    SearchLimit = 40000,

};

嘿嘿,其實(shí)使用A*是可以如此簡(jiǎn)單的,不是嗎?

二、主要優(yōu)化:

1)  地圖切片實(shí)現(xiàn)了最優(yōu)化加載方法。即不需要額外做多余判斷,也無(wú)需每次對(duì)切片容器進(jìn)行Clear。只需按從0到8的順序?qū)@9個(gè)切片重新賦值Source即可,性能真的很優(yōu)哦:

private void ChangeMapSection() {

……

        countSection = 0;

        for (int x = startSectionX; x <= endSectionX; x++) {

           for (int y = startSectionY; y <= endSectionY; y++) {

              mapSection[countSection].Source =

Super.GetImage(string.Format("/Image/Map/{0}/Surface/{1}_{2}.jpg", mapCode, x, y));

              Canvas.SetLeft(mapSection[countSection], x * mapSectionWidth);

              Canvas.SetTop(mapSection[countSection], y * mapSectionHeight);

              countSection++;

        }

……

}

2)改進(jìn)了 “托盤式”主位地圖移動(dòng)模式。首先我想向一些朋友道歉,一時(shí)找不到是哪篇文章后面評(píng)論中有提到對(duì)一個(gè)Canvas進(jìn)行移動(dòng)而不是遍歷所有精靈,這樣可以提升邏輯方面的性能;我當(dāng)時(shí)有測(cè)試過(guò),為什么一直堅(jiān)持不行,因?yàn)槲覜](méi)轉(zhuǎn)過(guò)彎,主角和其他所有對(duì)象是完全可以放在一個(gè)Canvas里的,這也意味著它們的ZIndex順序照樣可以很好的處理,同時(shí)實(shí)現(xiàn)“托盤式”地圖移動(dòng)模式。最終在QQ群里“內(nèi)Cool超人”的感化下,我才得以覺(jué)醒。這樣,雖然畫面性并無(wú)提升,但是,配合上Coordinate坐標(biāo)關(guān)聯(lián)屬性的回調(diào)方法使用,可以去掉循環(huán)遍歷地圖上所有對(duì)象位置,在邏輯上大大的提升了性能。

3)隱藏遠(yuǎn)離畫面窗口的精靈對(duì)象。這是基于Web游戲所必須做的處理,它將大大減少不必要元素的呈現(xiàn)及邏輯運(yùn)算:

……

//隱藏及顯示區(qū)域范圍內(nèi)精靈

      if ((Math.Abs(sprite.Coordinate.X - Leader.Coordinate.X) > this.ActualWidth / 2) || (Math.Abs(sprite.Coordinate.Y - Leader.Coordinate.Y) > this.ActualHeight / 2)) {

           sprite.Visibility = Visibility.Collapsed;

           sprite.Timer.Stop();

      }else {

             if (!sprite.Timer.IsEnabled) {

                  sprite.Visibility = Visibility.Visible;

                  sprite.Timer.Start();

             }

      ……

}

……

在間隔0.5秒的輔助計(jì)時(shí)器事件中進(jìn)行類似如上判斷,當(dāng)某個(gè)精靈超出了主角可視范圍,即在我們屏幕窗口所能看到的區(qū)域以外,則將之隱藏掉,并停止它的切幀動(dòng)作,否則反之。這對(duì)提升游戲整體性能起著決定性關(guān)鍵作用。如果是網(wǎng)絡(luò)版,我們則可以拓展出2級(jí)范圍,其中1級(jí)范圍即為上述范圍;而2級(jí)范圍則為:當(dāng)某個(gè)已被隱藏的精靈遠(yuǎn)離主角到了更遙遠(yuǎn)的地方,則我們將之移除掉,從而減少邏輯且實(shí)現(xiàn)不必要資源的及時(shí)釋放與回收。



4)改進(jìn)了時(shí)時(shí)障礙物系統(tǒng)。整個(gè)游戲有兩個(gè)障礙物數(shù)組(可以記錄0-255,0代表障礙物,除0外的所有其他字節(jié)均代表無(wú)障礙。這里我使用1標(biāo)識(shí)無(wú)任何對(duì)象可通行區(qū)域,10-19用來(lái)標(biāo)識(shí)傳送點(diǎn)。如果以后需要加入新的地形效果拓展,那么同樣可以使用類似設(shè)定:例如20用來(lái)標(biāo)識(shí)可通行水域,21標(biāo)識(shí)可通行沙漠等等;這樣,現(xiàn)當(dāng)主角在這些區(qū)域中移動(dòng)時(shí),會(huì)發(fā)出相應(yīng)的腳步聲,使游戲效果更為逼真)。動(dòng)態(tài)障礙物系統(tǒng)實(shí)現(xiàn)代碼如下,首先定義一個(gè)固定數(shù)組和一個(gè)動(dòng)態(tài)數(shù)組:

byte[,] fixedObstruction, varyObstruction;

fixedObstruction是地圖加載后永遠(yuǎn)不變的地圖信息描述載體,它記錄了地圖中肯定無(wú)法通過(guò)的地形及傳送點(diǎn)的位置等等。varyObstruction是時(shí)時(shí)的動(dòng)態(tài)地圖信息,會(huì)根據(jù)所有精靈時(shí)時(shí)的位置來(lái)填充障礙物。

在每次A*移動(dòng)時(shí),我們通過(guò)先去掉精靈腳底的障礙物區(qū)域(HoldWidth和HoldHeight),然后啟動(dòng)A*尋路,找到路徑后再補(bǔ)回精靈的腳底障礙物區(qū)域:

……

SetSpriteObstruction(sprite, 1);

AStarMove(sprite, GetSpriteEdge(enemy));

sprite.UseAStarMove = true;

SetSpriteObstruction(sprite, 0);

……

其中SetSpriteObstruction方法為:

/// <summary>

/// 設(shè)置精靈占位障礙物對(duì)應(yīng)值

/// </summary>

private void SetSpriteObstruction(QXSprite sprite, byte sign) {

        int x = (int)(sprite.Coordinate.X / gridSizeX);

        int y = (int)(sprite.Coordinate.Y / gridSizeY);

        for (int m = x - sprite.HoldWidth; m <= x + sprite.HoldWidth; m++) {

            for (int n = y - sprite.HoldHeight; n <= y + sprite.HoldHeight; n++) {

                if (fixedObstruction[m, n] != 0) {

                    varyObstruction[m, n] = sign;

                }

            }

        }

}
發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 91久久夜色精品国产网站 | 国产午夜亚洲精品 | 国产精品免费看 | 欧美一级免费看 | 久久久三区 | 久久综合给合久久狠狠狠97色69 | 国产精品自在线拍 | 一本色道久久综合亚洲精品图片 | 中文字幕在线观看国产 | 国产午夜精品一区二区三区免费 | 一区二区三区视频播放 | 精品一区二区三区在线视频 | 4p嗯啊巨肉寝室调教男男视频 | 成人啪啪18免费网站 | 免费在线看a | 欧美城网站地址 | 猫咪av在线 | 久久里面有精品 | 国产一区二区三区网站 | 在线免费观看精品 | 欧美一区二区三区久久精品视 | 娇喘视频在线观看 | 九色在线78m| 他也色在线视频 | 免费a级毛片大学生免费观看 | 国产成年人视频网站 | 黄色一级电影网 | 极品销魂一区二区三区 | 亚洲成人在线免费观看 | 国内精品伊人久久久久网站 | 久久国产精品小视频 | 久久久久久久国产视频 | 国产精品久久久网站 | 销魂美女一区二区 | 国内成人自拍视频 | 神马久久蜜桃 | 少妇色诱麻豆色哟哟 | 午夜精品久久久久久中宇 | 性少妇videosexfreexx入片 | 日日爱影院| 欧美亚洲一级 |