遊戲程式設計中的小技巧 遊戲輸入的處理

2021-09-17 18:29:01 字數 3000 閱讀 4832

遊戲的輸入裝置,指的是日常玩家用於控制遊戲的一些外部/內部裝置:pc機和家用遊戲機的鍵盤,滑鼠,手柄;移動機上則以觸控,重力感應,攝像頭的手勢識別為主;還有最近用於ar/vr的裝置,如wiimote,kinect,vr眼鏡一體機,索尼playstation vr等。這些在遊戲中已經成為玩家獲取遊戲體驗感的重要**。既要簡化使用者對遊戲的操作,又要能夠提公升遊戲對使用者輸入反饋的處理能力,這是提公升遊戲體驗感的乙個重要方面。

目前對於端遊和手遊的輸入模式主要分為兩種:數字和模擬。數字形式的輸入只有兩種狀態:按下去,沒有按。不存在介於兩者之間的情況;而模擬形式則是對使用者的輸入返回乙個特定區間的值,一般是介於 -1 ~ 1 之間,對於一些比較複雜的操作,或者格鬥類遊戲的組合鍵下主要使用模擬形式。

當然,針對玩家日益提公升的遊戲能力,遊戲中也需要考慮對「同時按鍵」和「序列按鍵」的支援。這種需求在格鬥類,角色扮演類,體育類遊戲中用的很多,例如拳皇和街霸中的各種連續技,組合技,nba2k19中各種運球投籃動作等。

除了文字類遊戲,現今大多數圖形類遊戲又不再使用標準輸入,因為控制台是不會長時間開啟,大多數遊戲會使用一些庫來封裝對這些裝置輸入的查詢,例如****** directmedia layer(sdl)的跨平台庫。當使用者進行按鍵控制時,系統會將該按鍵對應的索引置為true,從而反饋到遊戲中。

但僅僅這樣是不夠的,我們知道遊戲和軟體系統不一樣,使用者往往會在同一時間,甚至在短短1s內使用多個按鍵,而且遊戲一般執行在30fps ~ 60fps之間,使用者在這一幀按下的操作,通常在往後的幾幀中得到顯示和反饋,這就是玩家所說的「按鍵延遲」的一種情況,在網路不好的時候尤為突出。

目前較好的優化方法是追蹤遊戲上下幀的狀態。

這樣我們可以只針對使用者的操作提前進行處理而不是等到使用者已經操作後再進行處理,這會大大降低遊戲的流暢度。(還有一種情況,如果遊戲中需要「充能」操作,即長按某個按鍵蓄力,我們可以在「使用者剛剛輸入」時開始賦予初始值,每一幀增加定量,知道「使用者剛剛鬆開」後完成「充能」)。

模擬輸入會反饋一組範圍值,因為輸入後的數值波動非常開,在整個遊戲之中系統不一定能及時處理到反饋而值就已經消失了,或者當玩家沒有使用手柄時,實際上模擬輸入的值也不會是0,這就是輸入偏差。基於這樣一般虛擬輸入不會直接應用到角色的移動中。不過凡事沒有絕對,我們可以採用一種「模擬輸入過濾」的方式來消除偏差。

在手柄搖桿中,半徑為整個可移動範圍的半徑的10%內,所有返回的值均置為0,即相當於靜止;當半徑處於10% ~ 100%時才視為有效。

但是對於一些遊戲來說,對使用者操作非常敏感,那麼就無法利用到低於10%的值,那麼我們可以換一種方法,可以使用向量運算來完成無效區域的過濾。

vector2 inp = get user input

float len = inp.length()

float pct = (len - minvalue) / (maxvalue - minvalue)

這樣就能充分利用0 ~ 100%的有效區域。

針對一般的遊戲場景,遊戲本身是不會主動反饋資訊給使用者的。那麼對於輸入系統來說,很多的**都會「輪詢」輸入,比如主動檢查某某鍵是否觸發對應的操作,那麼每一幀都要去呼叫,去輪詢,不僅**量大,而且容易消耗記憶體,產生一定的bug。

相比於讓**「輪詢」,還不如我們一開始就設定乙個事件機制推送系統。在基於事件的遊戲系統下,每一部分的**都需要註冊其關心的事件通知,當輸入事件發生時,系統發出通知到所有已註冊的**,它們在收到通知後會立即執行其相應操作。當然,輪詢是不可避免的,我們只能將多個地方的輪詢彙總成乙個地方進行輪詢,降低記憶體消耗。

字典,是由一系列「key-value」值組成的集合。在遊戲系統中使用字典會提公升遍歷的速度。在這個系統中,key就是繫結的名字(如「horizontal」,「jump」,「fire」),value則是按鈕的資訊,包括對應的按鍵和按鍵對應的觸發時機。

每一幀,輸入系統都會檢查這個字典的所有鍵值,並判斷此時key所對應的狀態,然後再進行更改。字典首先會將更改的操作提供給ui系統,ui系統會判斷哪些ui會受到這些操作的影響,然後再傳遞到遊戲中進一步的處理。(注意,比如「b」按鍵,有可能同時對應揹包系統快捷鍵以及遊戲場景的某個操作,這時必須先判斷ui層 --遊戲場景層)。

隨著遊戲向移動端的大量湧入,大多數遊戲也需要開發出移動端。相比於pc端,移動端的輸入方式有限,但是又要盡量做到pc端一樣的操作複雜度,在輸入系統上也需要花費一定的時間去設計完善。

1.觸屏和手勢

觸屏,是所有移動端遊戲的首選輸入方式。通過玩家手指與螢幕的互動,來達到像pc上玩家用滑鼠控制遊戲的精準度。不過大多數的移動裝置支援了多點觸控,這是和滑鼠的乙個較大不同點。多點觸控的好處是能讓玩家在移動端上對遊戲進行快捷流暢的操作,又能在這基礎上增加操作的複雜度,提公升移動端遊戲的可玩性。

手勢操作,是目前移動端基於觸屏衍生的一種操作。玩家通過雙指及以上的手勢操作來達到一些快捷的功能實現,比如「兩指縮放」,「雙擊放大縮小」等。除了系統自帶的手勢識別功能,我們也可以自定義一些複雜度較低的新操作:在android上

我們可以用「gestures bulider」程式,在ios上,我們可以寫乙個類繼承「uigesturerecognizer」來實現。

2.加速器和陀螺儀

加速器,檢測移動裝置在座標軸上的加速度。例如,當你豎著拿手機的時候,向上移動,就會得到y軸方向的加速度,當你平放手機,向上移動,就會得到z軸方向的加速度。

陀螺儀,則是檢測移動裝置的軸向旋轉。比如我們在玩賽車類的遊戲時(狂野飆車8),玩家控制賽車的轉向,就是利用手機的陀螺儀來感知手機的軸向,從而實現對遊戲的控制,這樣相對於觸屏控制來說玩家的操作性更高更流暢。

總結不易,如有不足,懇請指導!

小A的遊戲

題目描述 解題思路 舉個栗子 midud k 2 很顯然是 uncertain 因為如果刪除u 隨便乙個d,剩下的串 mid 是相同的 如果兩個相同字元之間的字元 假設數量zfs 是小於k的,那麼把之間的字元刪除掉,再刪掉兩個相同字元之一,剩下的 k zfs 1 個字元隨便刪,得出的串都一定會是 u...

遊戲裡的程式設計遊戲

我想寫一本書,當然本身帶有功利性,不必諱言,它並不是一本正兒八經的技術著作,它主要關於我人生裡的遊戲,遊戲裡的程式設計。最終未必能出書也並不特別重要,出不了無非是筆者水平不足或沒有遇到自己的伯樂。同樣重要的是,如果我能通過這個平台去分享我的遊戲經歷,我的人生,能得到諸位關注和共鳴,也是人生的一件快事...

小珂的遊戲

時間限制 1000 ms 記憶體限制 65535 kb 難度 3 描述 假設有2k個人圍著乙個圓桌坐著,前k個是好人,後k個是壞人 現在開始,每m個人踢掉乙個,比如有6個人,m 5,那麼,被踢掉的人依次是5,4,6,2,3,1。現在要求,在踢掉第乙個好人前,必需把所有的壞人踢掉,問,給定乙個k,求滿...