<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      Java究竟怎么玩?

      天地程序已定棋,人間大數待變局

        博客園  :: 首頁  :: 新隨筆  :: 聯系 :: 訂閱 訂閱  :: 管理

      眾所周知,Java應用的運行速度雖然不慢,卻也談不上快,以最新的JRE1.6表現來說,至多也就是優勝于一些純粹的解釋型語言,距離C/C++等編譯型的執行效率還有一定差距。

       

      平心而論,如果我們使用Java去制作一些簡單的桌面應用,那么目前Java組件的繪圖速度勉強還能接受;但如果用Java來進行游戲開發,尤其是制作一些需要高FPS才能滿足的動態效果,就必須利用技術手段對其加以優化,解決其繪圖效率問題,其它才有的談。

       

      什么是FPS

       

      這里所說的FPS,并非指射擊游戲,而是指俗稱的“幀率”(Frames per Second,縮寫:FPS)或“赫茲”(Hz)。筆者在以前的博文中曾給出過專門的解釋及Java實現示例,此處不再贅述。

       

      受到人類眼球的生理結構制約,通常情況下只要我們所見畫面高于每秒16幀,就會認為畫面是連貫的,生物學上稱此現象為視覺暫留,這也就是為什么電影膠片是一格一格拍攝出來,然而我們卻認為它是連續的一段。當然,所謂的16幀也只是一個中值,并非放之四海而皆準,根據具體視覺對象不同,幀率的具體標準會有所變化。在最壞情況下,動畫不低于每秒12幀,現代電影不低于24幀,動作游戲不低于30幀,在人眼中的畫面才是連續不間斷的。

       

      總之,FPS數值越高則畫面流暢度便越高,越低則越顯停滯,要提高Java游戲運行效率,那么焦點就必然要集中在如何提高程序的FPS之上。

       

      我們該從什么地方入手,才能提高FPS

       

      Java繪圖最終要通過native,這是地球人都知道的事情。這意味著除非我們學習SWT重寫本地圖形接口,否則顯示部分我們無法干涉;這樣便決定了我們對FPS的優化必然要集中在本地圖形系統調用之前,而非之后。也就是說,提高Java應用的FPS,還要老生常談的從ImageGraphics及其相關子類入手。

       

      那么,對這些盡人皆知的Java繪圖組件,我們究竟能改進那些部分呢?

       

      我在不久前發布的博文《Java游戲開發中應始終堅持的10項基本原則》中,曾經就如何構建一個高效的Java游戲發表過一些見解,其中第7點“始終雙緩沖游戲圖像”,它不但是解決Java圖像閃爍問題的關鍵所在,而且同樣是提高Java游戲幀率的制勝法寶之一。是的,Java繪圖機能的優化與改進,關鍵就在于如何對其緩沖區域進行優化處理。

       

      下面,我將展示三種不同的Java緩沖繪圖方式。

       

      1、采用BufferedImage對象進行緩沖

       

         這種方法是最簡單,同時也是最常用的雙緩沖構建方式,也就是構建一個BufferedImage緩沖當前繪圖,所有Graphics操作在其上進行,僅在需要時才將貼圖paint于窗體之上,使用上再簡單不過,但效率如何呢?文章進行到此處時尚不得而知。

       

      2、采用BufferStrategy構建緩沖區

       

      使用BufferStrategy構建緩沖能夠獲得系統所提供的硬件加速,Java系統會根據本地環境選擇最適合的BufferStrategy。要創建 BufferStrategy ,需要使用 createBufferStrategy() 方法告訴系統你所期望的緩沖區數目(通常使用雙緩沖,也就是填入“2”),并使用 getDrawGraphics() 方法在緩沖區之間進行交換,該方法返回下一個要使用的緩沖區。BufferStrategy最大的缺點與優點都在于其受本地圖形環境影響,既不會出現很快的圖形環境跑出很慢的FPS,也別指望很慢的圖形環境跑出很快的FPS

       

      3、完全在BufferedImageDataBuffer中進行圖像處理

       

      每個BufferedImage都有一個與之對應得WritableRaster對象(getRaster方法獲得),通過它我們獲得指定BufferedImageDataBuffergetDataBuffer方法獲得),與方法1類似,我們同樣構建一個BufferedImage緩沖當前所有繪圖,所有操作都在其上進行,僅在需要時才將貼圖paint于窗體之上。但區別在于,由于DataBuffer可以轉化為描述BufferedImage象素點的int[]byte[]short[]等數組集合,因此我們不再使用Java提供的Graphics對象,而是直接操作像素點進行所有繪圖的實現。 但是,這樣進行數組操作會快嗎?

       

      現在我們為其各自構建三個示例,盡量以比較趨同的處理流程構建,分別測算三種方法的具體效率。

       

      PS:寫完才突然想起,這臺2002年買的電腦實在不適合測試FPS-_-|||),較新機型的FPS至少能達到此測試結果的2倍以上,特此聲明……)

       

      PS:以下圖像素材源自成都漢森信息技術有限公司首頁,特此聲明)

       

      以下開始將分別對三種方法分別進行繪制1名角色、繪制100名角色、繪制1000名角色的簡單FPS繪圖效率測算。

       

      一、采用BufferedImage對象進行緩沖

       

      源碼如下:

       

      1DoubleBufferGameFrame.Java

       

       

      2DoubleBufferCanvas.Java

       

       

       

      場景圖1、角色圖1 FPS 60 - 70

       pt0


      場景圖1、角色圖100 FPS 20 - 25

      pt1


      場景圖1、角色圖1000 FPS 13 - 17

      pt2

       

      二、采用BufferStrategy構建緩沖區(雙緩沖)

       

      1、BufferStrategyGameFrame.java

       

       

       

      2BufferStrategyCanvas.java

       

       

      場景圖1、角色圖1 FPS 80 - 90

      bs0

      場景圖1、角色圖100 FPS 25 - 35

      bs1

      場景圖1、角色圖1000 FPS 3 - 6

      bs2

       

      三、完全在BufferedImageDataBuffer中進行圖像處理

       

      實際上在Java網游海盜時代、Java網游暗影世界等等網絡游戲、還有netbaens以及其它種種不算慢的Java應用中,都存在大量使用DataBuffer進行的圖像渲染;但在使用方式上,卻只有暗影使用的JGnet引擎與常用的ImageGraphics搭配模式較為接近,所以此示例使用了JGnet的部分代碼構建。

       

      PS:實際上漢森的JGnet客戶端引擎目前并未開源,此部分代碼得自其主頁homepage.jar的反編譯,是前天我看csdnCTO欄目專訪漢森老總后去其首頁發現的;視頻中說JGnet有部分代碼準備開源,我估計應該是homepage.jar里這部分,因為沒有混淆且功能較少,其網站地址http://www.handseeing.com,純Applet站點)。

       

      為給不愿反編譯的看客提供方便,這里我稍微對JGnet進行一點分析(即homepage.jar中的那部分)。

       

      就代碼來看,JGnet中所有UI繼承自GUIWidgetGUIWidget繼承自Container),所有JGnet產生的GUI組件也都應當繼承它。JGnet提供了一個GUIRoot為底層面板,所有GUIWidget衍生組件都應附著于GUIRoot之上,另外該引擎提供有AbstractGameClientClientContext接口及相關實現用以調度相關組件,JGnetGUIRoot載體可以使用Applet或者Frame

       

      JGnet中大部分資源采用zip打包,當然也可以讀取單圖,JGnet資源加載依賴于其提供的ImageFactory類,ImageFactory的操作可分為如下兩步:

       

      第一步是addArchive,進行此步驟時指定的zip資源會被加載,其后將read圖像資源為ShortBufferImage,再根據zip中該資源對應路徑緩存到daff.utill包自備的HashMap中。

       

      第二步是getImage,即獲得指定路徑的ShortBufferImage對象,此步驟以緩存優先,如果獲得失敗會嘗試調用loadImage方法再次加載,并緩存到daff包自備的HashMap對象中。其中loadImage方法會根據后綴判定加載的資源類型,其中jpggif或者png后綴文件會調用daff包中提供的AwtImageLoader類轉化為ShortBufferImage,而非此后綴文件會直接按照ShortBufferImage格式進行加載。

       

      JGnet的圖像繪制主要使用其內部提供的ShortBufferImageShortBufferGraphics以及相關衍生類。ShortBufferImage是一個抽象類,沒有父類,所有JGnet中圖形資源都將表現為ShortBufferImage,繪制ShortBufferImage需要使用daff.gui包提供的專用畫布ShortBufferGraphics,實際上ShortBufferGraphics是一個針對于ShortBufferImage的象素渲染器,內部以short數組形式保存有一個空白BufferedImageDataBuffer,所有繪制基于其上。

       

      同大多數網游一樣,JGnet中大量使用自定義圖形格式(后綴.img),其解釋與轉化通過CompressedImage類得以完成,由于自定義格式通常能更簡潔的聲明圖像中各元素關系,所以JGnet處理其自定義格式資源會比加載普通圖像資源更快。

       

      JGnet會根據環境的不同會采用MsJvmGraphicsSunJvmGraphics兩套繪圖組件(皆繼承自ShortBufferGraphics),據此我們可以初步斷定其運行環境上兼容微軟jvm,也就是最低可運行于JRE1.1之上。

       

      講解結束,下面我以JGnet進行針對DataBuffer進行渲染的FPS測試(對其某些細節進行了使用習慣上的擴展)。

       

       

       

      1DataBufferGameFrame.java

       

      2DataBufferCanvas.java

       

      場景圖1、角色圖1 FPS 140 - 160

      j0

      場景圖1、角色圖100 FPS 115 - 125

      j1

      場景圖1、角色圖1000 FPS 55 - 70

      j2

       

      通過簡單比較后我們可以發現,Graphics繪圖無論在直接BufferedImage雙緩沖或者利用BufferStrategy以換取硬件加速的前提下,都無法與使用DataBuffer直接進行像素繪圖的ShortBufferGraphics相比,BufferStrategy在繪制千人時更出現了令筆者整個人都斯巴達了的4|||,即使在測試中筆者改BufferedImageVolatileImage也收效甚微,在配置較高的微機上應當會有些許改善,但用戶使用機型卻并非我們所能控制的。

       

      由于JGnet中直接獲得圖像DataBuffershort[]形式,并以此進行圖像繪制,所以 ShortBufferImageShortBufferGraphics稱得上是一組先天的Java圖形緩沖對象,就效率上講,使用ShortBufferGraphics繪圖獲得的FPS明顯高于使用Graphics2D繪圖,這是數組操作先天性的效率優勢所決定的。但缺點在于,ShortBufferImageShortBufferGraphics其并非直接繼承自ImageGraphics,兩者間函數不能完全對應,有些常用方法尚待實現,很多常用方法尚需ShortBufferGraphics使用者自行解決。

       

      單就效率而言,應該說采取DataBuffer進行緩沖繪圖明顯優于單純利用BufferStrategy或者BufferedImage獲得Graphics后進行繪圖。

       

      總體上看,如果我們追求最高FPS,則使用BufferedImage產生DataBuffer進行象素處理是最為高效的,與方法二混用后效率還將更高,但遺憾的是目前缺少相關開源組件,可用資源上略顯不足,有待相關公司或者個人提供,另外我們也可以考慮功能混用,即主體部分使用DataBuffer渲染,未實現部分以Graphics補足,但這肯定會對運行效率產生影響。

       

      由于JGnet目前屬于閉源項目,所以我無法公開其任何代碼實現。為此我自制了一個非常簡單的DataBuffer中圖像處理類SimpleIntBufferImage,以供各位看客參考。

       

      SimpleIntBufferImage.java源碼如下:

       

       

      簡單應用:

       

       

      效果如下:

      copy

       

       

       

       

       

      posted on 2009-04-03 20:03  cping  閱讀(638)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 国产成人精品国产成人亚洲| 91福利国产午夜亚洲精品| 亚洲av永久无码精品天堂久久| 无码国内精品人妻少妇| 超碰人人超碰人人| 香蕉久久夜色精品国产成人| 久热这里只有精品12| 亚洲中文字幕久久精品蜜桃| 久久精品av国产一区二区| 沾益县| 日本国产精品第一页久久| 最新国产精品亚洲| 色吊丝一区二区中文字幕| 中文字幕在线无码一区二区三区 | gogogo在线播放中国| 新密市| 欧美日韩中文字幕视频不卡一二区| 特黄特色的大片观看免费视频| 中文字幕无线码中文字幕| 亚洲人妻系列中文字幕| 欧美精品一区二区在线观看播放 | 色爱综合激情五月激情| 又黄又无遮挡AAAAA毛片| 国产熟女激情一区二区三区| 国产精品久久久一区二区三区 | 日本亚洲中文字幕不卡| 日本一区二区三区后入式| 日本熟妇浓毛| 亚洲自在精品网久久一区| 亚洲熟女精品一区二区| av午夜福利一片免费看久久| 亚洲欧美综合人成在线| 亚洲日本VA午夜在线电影| 亚洲老妇女亚洲老熟女久| 久久99久国产精品66| 四虎永久免费很黄的视频| 亚洲精品毛片一区二区| 国偷自产一区二区三区在线视频 | 色94色欧美sute亚洲线路二| 国产啪视频免费观看视频| 中文字幕久久国产精品|