GMS2中遊戲暫停的實現(2/2)

大家好,距離上一篇說遊戲暫停實現機制的文又過去快半個月了,恰好HeartBeast第14集教程也是介紹如何實現遊戲暫停,並且就是我們上次提到的將當前場景對象臨時禁用的這種方法,今天我們就來介紹一下這一種實現遊戲暫停的方式。

不同於我們上次介紹的方式,這個方法是在遊戲當前場景中進行暫停,不涉及遊戲場景的切換,同時引入了持久化對象的概念,對象屬性勾上了持久化(Persistent)以後,該對象一旦創建實例,對應的實例就會存在於後續所有的遊戲場景中(除非手動銷毀),從而可以用於控制一些所有場景中都需要調用的方法和機制。

本文的具體操作會有別於HB的教程,但思路是一致的

HeartBeast的教程已經傳到B站了——簡單實現遊戲暫停

控制暫停對象

如上文所說,我們需要創建一個新的對象,並把對象的持久化屬性打上勾

接著我們創建一個「Create」事件,並在其中定義兩個全局變數:

global.paused_ = false ;global.screen_pic = noone;

這裡我們使用全局變數的目的是便於不同的對象都能正確調用和修改這兩個值,這兩個變數分別是:

  • paused_:標識當前是否暫停狀態
  • screen_pic:用來保存暫停前的遊戲畫面

因為剛才我們創建的是一個暫停按鈕,我希望用戶在點擊這個按鈕時能觸發暫停操作,因此可以創建一個點擊事件,這裡使用「Tap」或「Mouse->Left Down」都可以

然後在這個事件里寫暫停相關的代碼:

if !global.paused_{ global.paused_ = true if sprite_exists(global.screen_pic) sprite_delete(global.screen_pic) ; global.screen_pic = sprite_create_from_surface(application_surface,0,0,room_width,room_height,false,false,0,0) instance_deactivate_all(all) instance_create_layer(room_width/2,room_height/2,"pipe",obj_continue)}

這段代碼整體在一個if判斷中,第一哈昂的if判斷就是判斷當玩家點擊這個暫停按鈕時,當前遊戲是否處於「非暫停」即正常遊戲狀態,注意這裡我們前面用了一個感嘆號"!"來表示否定,這裡也可以使用下面這種寫法(HB就是這麼寫的)

if not global.paused_

當判斷條件成立時就直接進入執行暫停的操作,首先是把這個暫停的變數設置為「true」標記將要進入暫停狀態

然後我們要給當前畫面截屏,在截屏之前我們也做了一個if判斷,這個判斷是判斷當前遊戲中是不是已經有相同名稱的截屏存在,如果有則要先把之前的截屏刪除

這裡用了sprite_exists()來判斷精靈圖像是否存在,然後用sprite_delete()來執行刪除操作

if sprite_exists(global.screen_pic) sprite_delete(global.screen_pic) ;

然後我們創建一個新的截屏圖像

global.screen_pic = sprite_create_from_surface(application_surface,0,0,room_width,room_height,false,false,0,0)

這裡我們使用sprite_create_from_surface()這個方法獲取當前應用窗口的界面圖像並生成一個精靈圖像,然後將其保存到了之前創建的全局變數global.screen_pic中。

這裡使用的application_surface是一個默認的surface表面,就是當前整個應用窗口的表層圖像窗口。

然後我們用 instance_deactivate_all()這個方法禁用所有的實例,並單獨新建了一個用於恢復遊戲的按鈕"obj_continue"

instance_deactivate_all(all)instance_create_layer(room_width/2,room_height/2,"pipe",obj_continue)

在HB的教程中因為他使用的是鍵盤按鍵來控制暫停事件,因此直接禁用和恢復實例就能實現暫停的效果,而我們這裡是通過點擊畫面中的按鈕來實現的,因此恢復遊戲的按鈕也需要單獨創建出來才可以。

恢復遊戲對象

好,在剛才我們已經完成了遊戲的暫停操作,但是我們要如何解除暫停狀態恢復正常遊戲呢?

首先同樣新建一個對象,由於這個對象也是一個按鈕,我們同樣創建一個「Tap」事件來執行恢復遊戲的操作

在這個「Tap」事件中我們放入的代碼如下:

instance_activate_all();global.paused_ = false;instance_destroy();

第一行是用instance_activate_all()恢復整個場景中所有的實例,這些實例會保留禁用之前的所有屬性,包括坐標、狀態等等。

第二行則是重新將暫停狀態標記為「未暫停」的狀態,表示即將正常恢復遊戲

最後則是把自身這個恢復遊戲的按鈕銷毀,因為在正常的遊戲過程中這個按鈕應該是不會出現的。

到此為止,其實遊戲的暫停和恢復基本已經完成了,但是還不夠完美。

因為在暫停按鈕被按下時所有的實例都被禁用了,因此整個場景中所有的對象實例都會消失不見,整個畫面是空的(tiles和背景等還會保留)

希望你還記得我們之前曾經在暫停時單獨保存了一張遊戲畫面的截屏,也希望你在上一張圖片中有留意到這個恢復遊戲的按鈕事件中有一個「draw」事件,我們就要在這個「draw」事件中把之前的截屏繪製到屏幕上,用這張圖片來欺騙玩家的眼睛,讓他以為因為遊戲被「暫停」了所以上面的內容都靜止不動了。

draw_sprite(global.screen_pic,0,0,0)draw_self()

在這個draw事件中,我們首先把剛才截屏畫面的精靈圖像直接繪製到屏幕上,然後同樣不要忘記當我們自定義「draw」事件以後一定要加上一個"draw_self",否則這個按鈕本身就不會被繪製出來了。

這裡還要注意這兩行代碼的順序,因為根據繪製順序不同的內容的深度也不同,後繪製的內容在上方,如果你先寫了"draw_self",那繪製截圖的時候就會把按鈕給擋住,玩家同樣會看不到那個恢復遊戲的按鈕了。

以上就是通過禁用實例和恢復實例的方式來實現遊戲暫停機制的方法。

HB的教學視頻中使用了用戶事件來封裝暫停的操作,而其實也可以用腳本來單獨封裝,HB沒有使用腳本的原因是他的教學視頻採用了試用版,對腳本的數量有限制。

而我也沒有封裝這個暫停操作,是因為感覺沒什麼必要,好像並沒有很多不同的地方會去觸發暫停,既然沒什麼復用的需求也就偷個懶了


推薦閱讀:

TAG:GameMakerStudio | 遊戲開發 |