• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            牽著老婆滿街逛

            嚴(yán)以律己,寬以待人. 三思而后行.
            GMail/GTalk: yanglinbo#google.com;
            MSN/Email: tx7do#yahoo.com.cn;
            QQ: 3 0 3 3 9 6 9 2 0 .

            程序響應(yīng)性

            程序響應(yīng)性
            譯者:緋紅KING
            來(lái)源:http://www.gamasutra.com/view/feature/1942/programming_responsiveness.php
            【如果你不能在游戲中控制你的行動(dòng),是否應(yīng)該責(zé)怪這個(gè)游戲呢?在這篇技術(shù)文章中,Neversoft的合伙人Mick West會(huì)闡述游戲中造成響應(yīng)延遲(Lag)的問題,并提出一些必要的解決方案?!?/span>
            響應(yīng)性是一種可以在第一時(shí)間成就或毀壞一個(gè)游戲的東西。在一些游戲的雜志評(píng)論中,可以明顯體會(huì)到響應(yīng)性差的游戲會(huì)被形容為“遲鈍的”,“沒反應(yīng)的”,“浮躁的”或“懶散的”。而好的游戲會(huì)被評(píng)價(jià)為“緊湊的”或“有響應(yīng)的”。
            響應(yīng)性可以從幾個(gè)方面來(lái)理解,本文主要是從一個(gè)程序員的角度來(lái)闡述,提供一些可以提高游戲響應(yīng)性的方法。
            響應(yīng)延遲
            響應(yīng)延遲是指從玩家觸發(fā)一個(gè)事件到玩家收到事件發(fā)生的反饋(通常是視覺上的)之間的時(shí)間遲滯。如果時(shí)間遲滯過(guò)長(zhǎng),游戲會(huì)顯得沒有響應(yīng)。有幾個(gè)因素決定了響應(yīng)延遲時(shí)間長(zhǎng)度。
            如果你的游戲是沒有響應(yīng)的,這很可能是45個(gè)不同因素造成的累積效應(yīng)。只是單獨(dú)調(diào)整其中一個(gè)因素,是不能起到明顯作用的。但是找出所有的因素,并調(diào)整它們,會(huì)帶來(lái)顯而易見的改進(jìn)。
            玩家,有時(shí)甚至是游戲設(shè)計(jì)師,都不能把他們?cè)谟螒蛑胁僮饔X得不適的地方用語(yǔ)言表達(dá)出來(lái)。通常他們會(huì)試著做一些需要同步操作的事情,但是失敗了,他們不會(huì)告訴你“這個(gè)事件在我輸入后的0.10秒才發(fā)生作用”,而是會(huì)說(shuō)這個(gè)游戲有些“遲緩”,“不緊湊”或者“難度高”。
            或者他們根本不告訴你一些重點(diǎn),只是單純說(shuō)這個(gè)游戲很爛,但不知道為什么很爛。
            設(shè)計(jì)師和程序員需要時(shí)刻注意響應(yīng)延遲以及它對(duì)游戲的負(fù)面作用,甚至在測(cè)試玩家沒有直接匯報(bào)這一點(diǎn)時(shí)。
            為什么發(fā)生延遲
            要了解延遲發(fā)生的原因,你需要理解事件的發(fā)生序列:從用戶按下一個(gè)按鈕,到結(jié)果顯示在屏幕上。為了理解這一點(diǎn),我們需要看一下游戲的主循環(huán)結(jié)構(gòu)。主循環(huán)進(jìn)行了兩個(gè)基本任務(wù):邏輯和渲染。
            主循環(huán)的邏輯部分更新了游戲的狀態(tài)(游戲?qū)ο蠛铜h(huán)境的內(nèi)部實(shí)現(xiàn)),渲染部分則創(chuàng)建了需要顯示在電視上的一幀畫面。
            在主循環(huán)的一些階段,通常是開始時(shí),我們會(huì)接受到用戶的輸入,作為主循環(huán)的第三項(xiàng)任務(wù),但也通常把它作為邏輯任務(wù)的一部分。在這里我把輸入單獨(dú)提出來(lái),是為了看清楚事件發(fā)生的順序。
            有幾種方式來(lái)描述主循環(huán)結(jié)構(gòu)。最簡(jiǎn)單的一種如表1所示,交替調(diào)用邏輯和渲染的代碼。我們假設(shè)游戲運(yùn)行在固定幀率,通常是60fps30fpsNTSC制式家用機(jī)游戲,而一些幀的同步發(fā)生在調(diào)用Rendering()中。
            1:簡(jiǎn)單的主循環(huán)
            while (1) {
            Input();
            Logic();
            Rendering();
            }
            在這里主循環(huán)只展現(xiàn)了故事的一半。對(duì)Rendering()的調(diào)用是在CPU端處理渲染任務(wù),這些任務(wù)包括場(chǎng)景、物體、剔除、動(dòng)畫、排序、設(shè)置變換、構(gòu)造一個(gè)供GPU處理的顯示列表。這是一個(gè)迭代的過(guò)程。
            實(shí)際上GPU渲染是在CPU渲染之后進(jìn)行的,通常是異步的。所以當(dāng)主循環(huán)開始進(jìn)行到下一幀時(shí),GPU仍然在渲染前一幀。
            那么延遲在什么時(shí)候發(fā)生?要理解造成延遲的原因,你需要理解從用戶按鍵輸入到接受反饋之間的事件序列。
            在最頂層,用戶按下一個(gè)按鍵;游戲邏輯讀取這個(gè)按鍵輸入,更新游戲狀態(tài);CPU渲染函數(shù)準(zhǔn)備好渲染這個(gè)新狀態(tài)的一幀,然后GPU將其渲染;最后這個(gè)新的一幀被顯示在屏幕上。
            1:當(dāng)玩家按下一個(gè)鍵,游戲要占用3幀(最理想情況)來(lái)創(chuàng)建一個(gè)視覺反饋,程序問題會(huì)引入多余的幀造成延遲。實(shí)際延遲的時(shí)間是每一幀時(shí)間長(zhǎng)度的乘積。
            1顯示了圖形化的序列內(nèi)容。在第一幀的某一時(shí)刻,玩家按下一個(gè)鍵來(lái)開槍。輸入過(guò)程完成后,這個(gè)輸入會(huì)被讀取到第二幀。第二幀更新了基于按鍵輸入的邏輯狀態(tài)(開火)。
            仍然在第二幀,渲染的CPU端開始執(zhí)行這個(gè)新的邏輯狀態(tài)。然后在第三幀,GPU執(zhí)行了這個(gè)新邏輯狀態(tài)的實(shí)際渲染。最后在第四幀的開始,新渲染出來(lái)的一幀畫面從幀緩沖中呈現(xiàn)給玩家。
            那么這個(gè)延遲有多長(zhǎng)時(shí)間?這要看一幀有多長(zhǎng)時(shí)間(這里“一幀”是指主循環(huán)的一個(gè)完整迭代過(guò)程)。從用戶輸入到轉(zhuǎn)換成視覺反饋,需要占用3幀。
            如果我們的游戲在30fps下運(yùn)行,延遲就是3/30,即十分之一秒。如果游戲在60fps下運(yùn)行,那這個(gè)延遲會(huì)是3/60,即二十分之一秒。
            這個(gè)計(jì)算說(shuō)明了一個(gè)關(guān)于60fps30fps之間的差異的判斷錯(cuò)誤。因?yàn)檫@兩個(gè)幀率之間的差異是1/60秒,人們推斷出響應(yīng)性之間的差異也是1/60
            但實(shí)際上,從6030并沒有給延遲增加一個(gè)垂直同步,它的效果是乘積形式的,加倍了延遲響應(yīng)的過(guò)程管線。在我們圖1中的理想示例中,增加了3/60秒,并不是1/60。如果事件管線再長(zhǎng)一些,這個(gè)結(jié)果會(huì)變得更多,這是極有可能發(fā)生的情況。
            實(shí)際上圖1展示的是事件序列的最佳狀態(tài)。按鍵輸入通過(guò)最短路徑轉(zhuǎn)換為視覺反饋。我們可以在事件序列中清楚的看到這一點(diǎn)。
            作為一個(gè)程序員,熟悉這些事件發(fā)生的順序,是理解游戲中事物運(yùn)作原理的重要環(huán)節(jié)。如果對(duì)事件發(fā)生的順序不加注意的話,很容易造成多余幀的延遲(意味著一個(gè)1/601/30秒的延遲)。
            舉一個(gè)簡(jiǎn)單的例子,如果我們把主循環(huán)中的Logic()Rendering()交換一下,想想會(huì)發(fā)生什么。來(lái)看一下圖1的第二幀:這里GPU邏輯(渲染)發(fā)生在CPU邏輯之后,所以在第二幀開始時(shí)輸入會(huì)影響CPU邏輯,之后是同一幀里的GPU邏輯。
            然而如果GPU邏輯在前面進(jìn)行,那么輸入就得到下一幀才能影響到GPU邏輯,因此造成了一個(gè)多余幀的延遲。雖然這只是一個(gè)初學(xué)者犯得錯(cuò)誤,但程序員仍要牢記不要讓它發(fā)生。
            造成延遲的多余幀可能在一些微小的行為中產(chǎn)生,但結(jié)果會(huì)影響游戲邏輯的整個(gè)序列。在我們的例子中,是開槍的過(guò)程。
            假如現(xiàn)在我們的引擎用一個(gè)物理引擎來(lái)設(shè)置場(chǎng)景中物體的位置信息,并且需要處理的事件在更新中增加了(例如碰撞事件)。這種情況下,輸入的序列或邏輯如表2所示。
            2:更新物理之后是事件處理
            void Logic() {
            HandleInput();
            UpdatePhysics();
            HandleEvents();
            }
            基于消息的事件處理(Event Handling)是用于低耦合系統(tǒng)的一個(gè)不錯(cuò)的手段,程序員也通常會(huì)使用它來(lái)控制事件。要使槍開火,HandleInput()函數(shù)會(huì)發(fā)出一個(gè)事件,告訴槍去開火。
            HandleEvents()函數(shù)會(huì)處理這個(gè)事件,并使槍實(shí)際開火。但是在這一幀里,物理更新已經(jīng)發(fā)生了,這個(gè)效果直到下一幀才能同步,這樣就產(chǎn)生了一個(gè)多余幀的延遲。
            更多延遲的原因
            低層的行為順序會(huì)造成更多的延遲。例如,考慮一個(gè)跳躍。反饋內(nèi)容是角色實(shí)際的移動(dòng)。要使游戲中的物體移動(dòng),你可以直接設(shè)置速度,或者給物體加一個(gè)作用力,例如加速度,或者瞬間的推力。
            這個(gè)情景會(huì)產(chǎn)生一個(gè)問題,就是如果你的物理引擎在速度改變之前更新位置信息——這是很多游戲編程入門教程中的常見情況。
            盡管在處理輸入事件后,物體跳躍的速度變化已經(jīng)在同一幀里更新了,但是物體直到下一幀才能開始改變位置,這樣就產(chǎn)生了一個(gè)多余幀的延遲。
            要記住,問題都是累積起來(lái)的,并且很難單獨(dú)去辨識(shí),這些組合的效果會(huì)使你的游戲操作變得很艱難。
            假設(shè)你同時(shí)犯了以上三個(gè)錯(cuò)誤:你在邏輯之前進(jìn)行渲染,你在物理狀態(tài)進(jìn)行之后處理邏輯事件,并且你在速度變化之前更新位置信息。這是從玩家輸入到接受反饋的三個(gè)主循環(huán)的完整迭代,在這三幀之上,你至少創(chuàng)建了6幀的延遲。
            60fps的游戲中,這會(huì)是1/10秒,已經(jīng)足夠糟糕了。但如果你的游戲是在30fps下,這個(gè)延遲會(huì)加倍,變?yōu)闊o(wú)法忍受的1/5秒,即200毫秒。
            綜合以上的問題,一些其他因素也可以導(dǎo)致延遲。動(dòng)作可以由動(dòng)畫來(lái)驅(qū)動(dòng),由動(dòng)畫特定時(shí)間點(diǎn)的速度變化來(lái)實(shí)現(xiàn)。例如,如果一個(gè)動(dòng)畫師為了讓動(dòng)畫與視覺更匹配,在動(dòng)畫中設(shè)置了一個(gè)不到一秒的跳躍速度變化,這可能看起來(lái)挺好,但實(shí)際上感覺卻很糟。
            動(dòng)畫師可以修正這個(gè)問題,只要確保速度變化是在動(dòng)畫的第一幀發(fā)生,玩家可以迅速得到反饋。但又有一個(gè)問題產(chǎn)生了,就是如何觸發(fā)一個(gè)動(dòng)畫,并轉(zhuǎn)換為實(shí)際的動(dòng)作?看起來(lái)動(dòng)畫的更新是由Render()函數(shù)來(lái)處理的。但任何以動(dòng)畫形式觸發(fā)的事件,都需要在增加一幀后的循環(huán)中才能處理。
            此外,觸發(fā)一個(gè)動(dòng)畫可能在下一幀才會(huì)發(fā)生作用,又造成一幀的延遲。我們的延遲會(huì)從6幀增加到8幀。即使在每秒60幀的情況下,這也就幾乎不能玩了。
            這些也并不是全部。還有很多方式使多余的延遲幀潛入一個(gè)游戲。你也許會(huì)把你的物理部分單獨(dú)辟出一個(gè)線程(或者一個(gè)物理處理單元)。
            如果你使用三倍緩沖來(lái)使你的幀率更平滑呢? 你也許用抽象事件通過(guò)系統(tǒng)的并行過(guò)程分解成真實(shí)事件。你也許在用一種腳本語(yǔ)言讓等待事件時(shí)增加額外的一幀。
            你可以通過(guò)組合各種關(guān)于時(shí)間和事件的概念,使你的游戲邏輯更靈活,這是非常必要的。但是在實(shí)現(xiàn)它們的時(shí)候,程序員可能會(huì)忽視發(fā)生在表面之下的事情,使造成延遲的多余幀悄悄潛入。
            響應(yīng)性,不是反應(yīng)時(shí)間
            有一個(gè)關(guān)于響應(yīng)性的極大的誤解,和人類的反應(yīng)時(shí)間相關(guān)。人類不能通過(guò)視覺刺激做出身體上的反應(yīng),并且在0.1秒內(nèi)移動(dòng)他們的手指。
            游戲玩家的頂峰反應(yīng)時(shí)間分布在0.15秒至0.30秒,這取決于他有多“高橋名人”(形容按鍵反應(yīng)迅速)。像這些可以計(jì)量的信息,通常在討論游戲響應(yīng)性時(shí)會(huì)提到。但它們之間是沒有聯(lián)系的。
            不是玩家對(duì)游戲的反應(yīng)有多塊,而是游戲?qū)ν婕业姆磻?yīng)有多快。問題并不在于反應(yīng)時(shí)間,而是在于同步性。
            用吉他英雄來(lái)舉例,這個(gè)游戲中會(huì)有一些符號(hào)出現(xiàn),玩家需要在恰當(dāng)?shù)臅r(shí)間按下相應(yīng)的按鍵(當(dāng)目標(biāo)物體在特定區(qū)域范圍時(shí))。你是在預(yù)判斷事件,這里不涉及任何反應(yīng)時(shí)間。
            缺乏響應(yīng)性的問題一般是游戲沒有及時(shí)反饋玩家的操作,并且事件發(fā)生時(shí)目標(biāo)物體已經(jīng)超出目標(biāo)范圍了。
            如果你在正確時(shí)間按下鍵,你絕不希望物體會(huì)在爆炸前再多移動(dòng)幾個(gè)像素。但是物體通常在每幀會(huì)移動(dòng)幾個(gè)像素,有幾幀的延遲使物體滑過(guò)目標(biāo)。
            有許多基于預(yù)測(cè)和按鍵輸入的游戲。在一個(gè)滑板游戲中,你想要在到達(dá)軌道終點(diǎn)之前跳躍。在一個(gè)第一人稱射擊游戲中,你朝一個(gè)前方快速跑動(dòng)的敵人開槍。
            再提一次,響應(yīng)性并不是反應(yīng)時(shí)間。你通常會(huì)在射擊的半秒前看見你的目標(biāo),或許更長(zhǎng)時(shí)間,你會(huì)移動(dòng)你的槍,或者等待目標(biāo)跑到你的準(zhǔn)星上。
            對(duì)響應(yīng)性問題是不能靠直覺來(lái)解決的,程序員全面了解問題本身才是非常重要的。最重要的一點(diǎn),是要清楚按鍵觸發(fā)行為任務(wù)到創(chuàng)建視覺反饋這個(gè)過(guò)程中邏輯和渲染的逐幀過(guò)程。一旦你理解了這個(gè)過(guò)程,你就能夠優(yōu)化它,使它工作在最佳狀態(tài)。

            posted on 2008-10-25 10:43 楊粼波 閱讀(488) 評(píng)論(0)  編輯 收藏 引用


            只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。
            網(wǎng)站導(dǎo)航: 博客園   IT新聞   BlogJava   博問   Chat2DB   管理


            久久国产视频99电影| 久久99精品国产麻豆宅宅| 久久影视综合亚洲| 2020久久精品亚洲热综合一本| 精品久久久久久久国产潘金莲 | 久久毛片一区二区| 久久婷婷五月综合成人D啪 | 品成人欧美大片久久国产欧美... 品成人欧美大片久久国产欧美 | 伊人久久大香线蕉AV一区二区 | 久久人人爽人人爽人人爽| 精品无码久久久久久尤物| 伊人久久免费视频| 欧美精品国产综合久久| 国产成人精品久久免费动漫| 精品国产乱码久久久久久浪潮| 97香蕉久久夜色精品国产| 97r久久精品国产99国产精| 伊人久久大香线蕉精品不卡| 俺来也俺去啦久久综合网| 伊人久久无码精品中文字幕| 国内精品久久久久影院日本| 天天综合久久一二三区| 久久91精品国产91久久户| 亚洲伊人久久综合中文成人网| 久久国产精品久久久| 人妻无码精品久久亚瑟影视| 国产激情久久久久影院小草| 亚洲αv久久久噜噜噜噜噜| 久久人人爽人人精品视频| 91久久婷婷国产综合精品青草| 亚洲伊人久久成综合人影院| 亚洲国产成人久久精品影视| 久久久久99精品成人片欧美| 亚洲欧洲中文日韩久久AV乱码| 久久免费小视频| 久久久久人妻精品一区二区三区 | 精品久久久久久久久中文字幕| 色综合久久夜色精品国产| 久久久精品国产亚洲成人满18免费网站| 亚洲色大成网站WWW久久九九| 欧美精品福利视频一区二区三区久久久精品|