2017-04-09 54 views
4

我很好奇我的遊戲使用什麼。計時器:使用計時器與更新來運行遊戲SpriteKit

let goodFPS = SKAction.wait(forDuration: 0.01666) 
let mainGameRunner = SKAction.run { 
//my code is here 
} 
let toRepeat = SKAction.repeatForever(SKAction.sequence([goodFPS,mainGameRunner])) 
inGameHighScore.run(toRepeat,withKey:"mainGame") 

或更新功能:

override func update(_ currentTime: TimeInterval){ 
//my code is here 
} 

可提供較快更加一致的更新?

注:我的幀速率是45〜58

+0

我猜'update'函數在'SKScene'上?使用那個。 – EmilioPelaez

+0

@EmilioPelaez有沒有更快或者更快的速度,但是運行速度不變 – joshLor

+0

我添加了一個正確的答案。 – EmilioPelaez

回答

1

我決定徹底改寫我的答案,使其更清晰。

首先,我認爲你錯誤地採取了FPS問題。您不能「強制」比設備可以提供的更快的幀速率。如果你將遊戲中的動作假設爲每幀都是一致的,那麼你就錯了。這實際上是他們在早期做的,因爲CPU太慢了,一代人到新人的差距一開始並不算太差。但是在較年輕的硬件上運行舊的DOS遊戲會很棘手,因爲幀率太高以至於整個遊戲機制變得不穩定或者太快而無法玩。

這裏的概念是認爲「隨着時間的推移」,並縮小與兩幀之間的時間關係的任何行動。

update()方法通過每幀提供當前系統時鐘狀態爲您提供了這種機會。通過跟蹤最後一幀的時間,您可以計算當前幀的時間差異,並使用該差異來縮減您正在進行的操作。

不建議使用定時器以獲得一致的幀速率更新,也不實用。您可能會在給定的時間間隔內調用更新閉包,但閉包內部的代碼需要時間自行執行,根據您的遊戲邏輯,它甚至可能有不同的執行時間。所以也許暫停時間是一致的,但暫停前後運行的代碼可能不一致。那麼如果在較慢的CPU上運行遊戲會發生什麼?代碼速度會更改,使您的時間不準確。

反對在你的遊戲循環中使用SKAction的另一點就是它們。一個動作是內存中的一個對象,可以被多個對象重用。如果您正在進行「跳轉」操作,例如,建議將該操作存儲在某處,並在每次需要「跳轉」時重複使用同一個對象,而不管該節點是什麼節點。你的遊戲循環是爲了每幀執行,但不是由不同的對象執行。行動也是一次性的。這意味着即使它正在運行,你也可以殺死一個動作。如果你將遊戲循環放在一個動作中,它可能會由SKScene運行。如果在場景中使用另一個動作,它就會立即變成一個難題,因爲只有兩種方法可以刪除動作,除了讓它達到目的:刪除所有動作或使用標識符鍵創建動作並使用該動作刪除任何動作與那個關鍵。如果您還沒有看到它,那麼它會強制您在場景運行的每個動作上放置標識符,並逐個刪除它們。而且他們再次打開了一扇可以擺脫遊戲循環的錯誤,因爲記住,操作是可以避免的!那麼也沒有保證你的行爲會在每一幀中被執行。

爲什麼要使用update()方法?只是因爲它建立在你的場景中。無論如何,每幀,update()被首先調用。那麼,這些行爲就會被執行。您無法像動作一樣意外清除update()方法。您不必小心造成內存泄漏的強/弱關係,因爲您像從動作一樣引用閉包內的對象。

推薦閱讀:

  1. SKAction API reference:你清楚地錯過了這點。
  2. SKScene API reference:閱讀有關spritekit中的幀處理的內容。這將有助於你理解他們如何將每件事物放在一起。

我希望它使事情更清晰。

1

我敢肯定,SKAction的計時設施,基於相同的遊戲循環正在調用update的範圍內。

SKAction的優勢在於它爲您帶來火花而忘記,而使用update會因設置和檢查一堆計時器變量而變得尷尬。

+0

我一直在測試出來,似乎都不是那麼好 – joshLor

1

我沒有一噸的經驗SpriteKit,但我有一些經驗製作遊戲和動畫中的iOS。

有一個名爲CADisplayLink的類,每次刷新屏幕時都會觸發委託,這是在遊戲中或動畫中更新屏幕的好方法,因爲您可以知道它會是稱爲每一幀,不再。

我不知道如果SpriteKit使用了類火update方法,但我敢肯定它使用類似的東西。這通常稱爲運行循環。在此運行圈頂部

SKActions運行。

通過使用wait動作創建自己的運行循環,不僅沒有獲得任何好處,還可能在邏輯運行方式中引入不一致。

想象一下,你有你的等待行動設置爲0.01秒(爲簡單起見,我將其舍入)。如果屏幕刷新速度比你期望的,並且操作每0.009秒第一次它的檢查更新,它不會火,因爲有一個在wait命令剩餘0.001秒,所以另一個0.009秒總會過去的,你的代碼將在0.018秒後執行,而不是您想要的0.01。不僅如此,在執行之間還會傳遞兩幀。

如果使用update功能,你可以知道你的邏輯將被執行一次屏幕刷新,並沒有更多的。

+0

嗨埃米利奧 - 這正是我想知道的! CADisplayLink與SpriteKit中的更新一樣嗎? – Fattie

+0

@Fattie這很難說,但我會說這可能是相同的機制。雖然我不會在'update()'上使用自定義的'CADisplayLink'。 – EmilioPelaez