GML學習特別篇——學以致用
起個頭啊啊啊
前兩篇學習手記呢也是學到了很多東西,所以就想把學到的東西用一下。額,我的做法呢是在原有的一個教程上做一定的修改。這個教程就是GMS2的官方教程系列。一共有八篇,這八篇也是在順子大佬的知乎專欄和B站賬號上都有發表,而且是他自己經過漢化和解釋的,我也是照著這個入門的,很適合像我這樣的萌(丑)新。而這次呢,我想要把之前學到的一點點皮毛,運用到裡面去,對原來的教程教我做的遊戲進行一點點小小的升級!!!其間還請教了我的高中同桌,他編程可厲害了!!!
一、移動篇
首先,我們來看看原教程中,使玩家移動的代碼。
if (keyboard_check(vk_right)) x = x + 4 ; //原教程的代碼
這一行代碼很簡單,就是當檢測到右方向鍵被按下的時候,玩家的x加4,就是向右4個單位。但是,這個遊戲的子彈發射是由滑鼠控制的,所以在遊戲時,就會出現左手按鍵盤的上下左右,右手控制滑鼠,這樣的操作讓我覺得不舒服,經常被怪物撞死!!於是,我在想能不能把移動改成「WASD」,這樣就不會這麼蹩腳!首先我很自作聰明的做了以下的修改:
if (keyboard_check(vk_W)) x = x + 4 ; //自作聰明的修改,結果發現是錯的
然後,我就發現了「vk_W」變成了藍色,原來是被編譯器檢測成了一個變數,所以這裡就有些超出我的學習範圍了,於是我就查了一下。發現了ord("XXXXXX")這個函數,這個可以檢測到鍵盤上的這些字母按鍵,但是必須是字元串的形式。所以,我就進行了以下的修改:
if (keyboard_check(ord("D")) || keyboard_check(vk_right)) //成功的修改
這裡還是用到了「||」(或運算),上面的這行代碼便是成功的修改,運用或運算在保留了原有的移動方式的前提下,添加了新的移動方式!!!別的按鍵以此類推。
二、怪物生成篇
一開始學了怪物隨機生成,哇,好牛逼啊!下面是原教程的代碼:
instance_create_layer(random(room_width),random(room_height),"EnemyLayer",obj_enemyspawn)
但是,進入遊戲之後,我就發現了一個蛋疼的問題,玩著玩著,這怪物咋在我旁邊一厘米的地方就生成了,一不小心就碰到了。不行,這樣對玩家太不友好了,要改!這裡需要switch、case、break(啊啊啊啊啊啊啊啊啊,這三個還沒有給大家介紹過啊,算了大家先看個大概吧)。然後,進行了如下的修改:
//請不要在意我對對象和圖層的命名switch(floor(random(4))){case 0:instance_create_layer(random(room_width),0,"direna",suijishengcheng);break;case 1:instance_create_layer(random(room_width),room_height,"direna",suijishengcheng);break;case 2:instance_create_layer(room_width,random(room_height),"direna",suijishengcheng);break;case 3:instance_create_layer(0,random(room_height),"direna",suijishengcheng);break;}
然後,我解釋一下上面的代碼。首先是floor(random(4))這句(這個我同學教我的,嘻嘻),floor的作用是取整,random(4)的意思是範圍為[0,4),所以floor(random(4))的作用就是[0,4)這個範圍內取整,就是0,1,2,3這四個數。接下來是switch()這個函數,這個東西說白了就是,switch後面的()內的數字如果是0,就執行case 0後面的語句,最後使用break來跳出switch語句。好了,第一種情況就是random(room_width),0這一條,這條的意思是這個場景的下邊界,下面的三條也以此類推。於是,怪物成功的在場景的四個邊界出生,再也不用擔心距我一厘米的地方忽然冒怪了!!!
三、遊戲難度篇
玩著玩著,問題來了,怪物在四個邊界生成了,不需要任何走位了,這遊戲真簡單,沒意思了啊!!!不行,難度要增加!!!還是先來看原教程的怪物生成器代碼。
spawnrate = 60 ; alarm[0] = spawnrate ; //創建時所擁有的屬性(create中的代碼)
而在alarm[0]的事件中有這條語句:alarm[0] = spawnrate;它意味著倒計時到0的時候,就會執行一次生成怪物的代碼。
於是,就有了以下的修改:
global.spawnrate = 60;alarm[0] = global.spawnrate;alarm[1] = global.spawnrate; //修改後的create中的代碼
注意: 我再創建了一個alarm[1]事件,並且填入了以下代碼:
global.spawnrate /= 1.005;alarm[1] = 60;
上面的/=在之前的手記中說過,是讓這個變數除以一個數並等於除之後的結果,所以alarm[1]中,我讓global.spawnrate這個變數一直除以1.005,慢慢的倒計時的時間會越來越短,怪物生成的速度就會越來越快,難度就會逐漸提高。我調過一個較大的數字,然後開局就有一億隻怪物涌過來。不過數值調的過大,就直接不出怪了,意味著你慢慢玩的話,熬過一個最難的點,就沒有怪了,你就通關了。
四、玩家升級篇
怪物越來越多,玩家要是還這麼垃圾豈不是要被暴捶!不行,咱要升級,咱要變得牛逼!然後,這個毫無卵用的積分終於有了他的作用,那就是升級需要花費積分。按照這個思路走下去,修改的地方很多,很雜,我不知道自己能不能說清楚= =。
我分步慢慢說:
1、原來的表示分數多少的變數thescore,要修改為全局變數global.thescore。而且所有的地方都要改成全局變數。因為,我們會在別的地方用到它。
2、回到我們的玩家對象上。首先在create事件中加入下面兩行代碼:
cd = 100;turn = 0;global.gongjili = 1; //玩家攻擊力為1strength_buy_gongjili_cost = 50; //升級攻擊力要50積分strength_buy_gongjili_add = 1; //升級後攻擊力加1
還是在玩家對象中,這次是step事件中,我們加入下面的代碼:
if turn < cd turn++;if (keyboard_check(vk_f1) && global.thescore >=s trength_buy_gongjili_cost && turn==cd) {global.gongjili += strength_buy_gongjili_add;global.thescore -= strength_buy_gongjili_cost;turn = 0;}
我先解釋一下為什麼我加了cd、turn這兩個變數還有if turn < cd turn++;這條語句。因為當我按下F1這個按鍵時,它會瞬間檢測上百下。這就會導致一個問題,我只想升一級攻擊力,但是我只要輕輕的按一下F1這個按鍵,它就一下升了幾十級。所以我就設置了這個類似冷卻時間的東西,當turn這個變數小於cd的時候,turn就一直遞增(這個也在之前學到過哦)。下面的代碼意思是如果檢測到F1按鍵被按下並且分數變數的值大於需要花費的值並且turn的值等於cd時,就使global.gongjili這個變數加上strength_buy_gongjili_add
的值,並等於加好之後的值。這也是以前學到過的。最後,再讓turn這個變數變回0就好了。3、還沒完,原教程當中,在子彈的碰撞事件中有下面的代碼:
with(other){ hp = hp - 1 ; }instance_destroy() ;
最後,我們把這裡的hp = hp - 1;替換成hp = hp - global.gongjili;就可以了。這樣我們的升級攻擊力就做好了。除此之外我還製作了玩家移速和子彈速度的升級,過程也都是舉一反三。但還是要注意變數的形式。
五、奇怪的跟蹤導彈
加一個跟蹤導彈吧,這樣更加牛逼一些。然後,我就成功做出了一個還算跟蹤導彈的跟蹤導彈,我先拿出來給各位看看。首先再創建一個子彈對象。給大家看一下代碼。
create事件:
spd=10;genzong=1;direction = direction + random_range(-4,4);alarm[0] = 2;
step事件:
if(genzong){if (instance_exists(A2cc)){move_towards_point(A2cc.x,A2cc.y,spd);}}else{speed = global.gongsu;}image_angle = direction;
碰撞事件:
with (other){hp = hp - global.gongjili;}instance_destroy();
alarm[0]事件:
genzong = 0;
額,雖然我不太清楚問題出在哪裡,但是這個跟蹤導彈在遊戲中總覺得怪怪的。
六、地圖邊界篇
之前發現過這個問題,就是玩家可以控制飛船飛出地圖,這是個蠻蛋疼的問題,我的想法呢也很簡單,不是給地圖加邊界,而是玩家到了邊界就不能繼續移動下去。首先,還是來看看原教程的代碼:
if (keyboard_check(vk_right)) x = x + 4 ;
我修改之後的:
if (keyboard_check(ord("D"))||keyboard_check(vk_right))if(x < area_right) x = x + global.selfspeed;
global.selfspeed這個變數是移速。要注意的是area_right這個變數需要在玩家的create事件中提前聲明,這個變數的值就等與你這個地圖的右邊界的X值。所以,上面的的代碼的意義就是只有飛船的X小於右邊界的X值才能往右走。別的邊界也是一樣,以此類推。這樣就可以設置出邊界了!!!
結尾
很早就做了這些更新,但這篇文章,寫了很久、很久、很久......寒假到了,控制不住的摸魚啊啊啊啊啊啊啊。好的,總結一下,學習學習,學了之後就要會用,做遊戲也是一樣嘛=3=。這次,通過之前兩篇手記里的一些知識就可以進行大部分的修改,很多不理解的點我就請教我的高中同桌,總體來說還是蠻順的。
推薦閱讀:
TAG:獨立遊戲 | 遊戲開發 | GameMakerStudio |