寫在前面:
寫文章時本人是在校大三學(xué)生,上周才接觸到Godot,也才初學(xué)三四天,如果文章有問題的話還請大佬們不吝賜教
這是第一篇教程,面向和我一樣的初學(xué)者,可能寫的有點(diǎn)啰嗦,請勿噴,哈哈;其中,有個單詞寫錯了,我是想寫World的結(jié)果寫成Word了,請原諒四級還沒過的我,淚目?。?!前半部分圖片上的錯字就不改了,大家知道就行,哈哈哈(不失禮貌的尬笑)
最終項目成果如下:

知識內(nèi)容:
- 認(rèn)識godot引擎編輯器
- 基本的場景節(jié)點(diǎn)添加
- 了解基本的碰撞體與碰撞形狀
- 認(rèn)識KinematicBody2D 基本操作
- 幀動畫制作與切換
制作過程:
1. 新建項目

- 1.填好項目名稱、選擇好一個項目目錄
- 2.點(diǎn)擊“[創(chuàng)建|編輯]”打開項目,項目的所有文件都會保存在那個項目目錄下
如果你的菜單界面是英文,可以在新建項目的上方找到語言en改成zh_CN即可改成中文
2.初識編輯器布局

3.添加項目資源
- 1.在項目目錄下新建image目錄,把所有的圖片資源放到image目錄下
點(diǎn)我下載圖片 -
2.可以看到資源管理面板新增了image目錄和目錄下的圖片,godot會默認(rèn)為每一個資源添加一個同名的后綴為".import"的文本文件
圖片.png
4.制作World場景——背景、太陽、云
【編輯區(qū)的鼠標(biāo)操作】:滾輪控制編輯區(qū)的放大縮小,鼠標(biāo)中鍵按下并移動鼠標(biāo)可以移動編輯區(qū)內(nèi)容,鼠標(biāo)左鍵選中編輯區(qū)節(jié)點(diǎn)
- 1.添加一個根節(jié)點(diǎn)Node2D重命名為“World"
-
(1)在場景窗口,點(diǎn)擊"+"號添加
圖片.png -
(2)在彈出的節(jié)點(diǎn)選中窗口中選中Node2D,點(diǎn)擊創(chuàng)建
圖片.png
*(3)鼠標(biāo)單擊,重命名為”world"
-
- 為world添加子節(jié)點(diǎn)Sprite,并重命名為bg
Sprite表示精靈節(jié)點(diǎn),可以為該節(jié)點(diǎn)添加一個圖片Texture資源
場景窗口中鼠標(biāo)指向world,右鍵添加子節(jié)點(diǎn),在節(jié)點(diǎn)選擇框搜索Sprite,選擇Sprite點(diǎn)擊創(chuàng)建,就在world下面新建了一個子節(jié)點(diǎn),重命名為bg


-
3 為bg添加圖片
場景中選中bg節(jié)點(diǎn),可以看到bg的屬性值
圖片.png
將資源窗口中的image文件夾下bg.png文件拖到bg的Texture屬性位置
GIF.gif
鼠標(biāo)選中編輯區(qū)bg移動,選中周圍的點(diǎn)拉大,撐滿游戲窗口
GIF.gif
編輯區(qū)那個紅綠線交叉點(diǎn)為原點(diǎn),第四象限的矩形框就是游戲窗口,在godot中,游戲窗口的原點(diǎn)(0,0)在左上角,往右為x軸正方向,往下為y軸正方向
-
添加太陽sun節(jié)點(diǎn)
這里我們采用直接把圖片拖進(jìn)編輯區(qū)的方法,我們直接將sun.png圖片拖曳進(jìn)編輯區(qū),在場景窗口也對應(yīng)生成一個與圖片文件同名的Sprite節(jié)點(diǎn),如圖:
GIF.gif
-
-
參照上一個步驟,把兩片云彩添加進(jìn)來
圖片.png
-
5.制作World場景——地面
因為主角需要和地面進(jìn)行交互的,所以地面不能直接使用Sprite來做,我們需要用到StaticBody2D節(jié)點(diǎn),然后再給StaticBody2D添加Sprite子節(jié)點(diǎn)來顯示圖片
-
1.給World添加子節(jié)點(diǎn)StaticBody2D并重命名為floor,并選中編輯區(qū)組合按鈕,如圖解釋
圖片.png
我們發(fā)現(xiàn)floor右邊有個黃色三角形的警告按鈕,你可以點(diǎn)擊看看是因為什么問題
因為我們設(shè)置的floor節(jié)點(diǎn)屬于StaticBody2D,表示的是一個物理靜態(tài)體,記住所有的物理靜態(tài)體在godot里都要添加碰撞形狀子節(jié)點(diǎn)
-
先給floor添加圖片吧
之前說過Sprite節(jié)點(diǎn)可以添加圖片,所以這里我們就給floor添加一個Sprite子節(jié)點(diǎn),并將land.png圖片拖到texture屬性里,將floor放到游戲窗口底部,最后如圖顯示
圖片.png
-
- 添加碰撞區(qū)域
在前面我們知道floor右邊的警告三角形的信息需要添加一個形狀體,形狀體有兩種CollisionShape2D和CollisionPolygon2D,即規(guī)則形狀和多邊形形狀,
給floor添加CollisionShape2D子節(jié)點(diǎn),然后選擇CollisionShape2D的Shape屬性,選擇“新建RectangleShape2D”,放大編輯區(qū)我們可以看到有一個淺藍(lán)色的矩形塊,這個矩形塊就是碰撞區(qū)域

選中藍(lán)色塊的邊緣兩個紅點(diǎn)其中一個,拖動設(shè)置藍(lán)色塊大小,

使其如圖所示,長度與圖片一致,寬度在垂直居中位置即可,這個藍(lán)色塊的上邊決定了待會角色站的位置

-
4 同理復(fù)制粘貼第二個地面,拼接好兩個地面,最終效果如圖:
圖片.png
做了這么久還沒有保存過唉,記得及時保存哦,萬一程序奔潰了呢,Ctrl+S保存,在彈出的窗口點(diǎn)擊保存即可
圖片.png
然后我們可以點(diǎn)擊右上角運(yùn)行按鈕,圖片.png
如果彈出一個請選擇主場景點(diǎn)擊選擇即可,然后在新窗口選中我們保存的World.tscn文件,點(diǎn)擊打開,就可以看到彈出一個游戲窗口,就能看到我們布置的場景啦,如圖圖片.png
6.制作World場景 —— 椰樹、草叢
與第四步添加背景的流程是一樣的,大家自己添加(tree.png樹木, grass.png草叢),添加好之后的效果和場景節(jié)點(diǎn)順序如圖:

7.添加角色
我們的角色要會走,會跳,而且還會站到地面上,可以用KinematicBody2D節(jié)點(diǎn)來創(chuàng)建角色,然后添加子節(jié)點(diǎn)Sprite來給角色添加圖片,所以基本操作跟制作floor類似
給world添加子節(jié)點(diǎn)KinematicBody2D并改名“player”,選中組合按鈕防止子節(jié)點(diǎn)被選中,給player添加子節(jié)點(diǎn)Sprite(texture屬性使用stand.png圖片)和CollisionShape2D并設(shè)置碰撞區(qū)為圖片大小,移動到游戲窗口中央,如下圖所示:
8.讓角色動起來——添加腳本
godot使用內(nèi)置的GDScript腳本,是一種類似python的語言,如果你不懂GDScript但是有其他高級面向?qū)ο笳Z言(Java,python,JavaScript,ruby等)基礎(chǔ)的話,可以參考官方文檔GDScript入門
當(dāng)然Godot還支持C#語言開發(fā),你可以自己嘗試學(xué)習(xí)
- 給player添加腳本,鼠標(biāo)右鍵單擊選擇添加腳本,在彈出的窗口中選擇創(chuàng)建,這時編輯區(qū)會顯示腳本編輯窗口
圖片.png
player.gd腳本文件內(nèi)容如下,它繼承了KinematicBody2D這個類,所以在腳本里面可以直接使用這個類或這個類的父類方法或?qū)傩裕?br> 其中_ready()函數(shù)是初始化函數(shù),_process(delta)函數(shù)是每一幀會運(yùn)行一次,通俗的講就是這個函數(shù)里的內(nèi)容會隔一段時間就運(yùn)行一次,delta參數(shù)是相鄰兩次運(yùn)行的間隔時間
- 給player添加腳本,鼠標(biāo)右鍵單擊選擇添加腳本,在彈出的窗口中選擇創(chuàng)建,這時編輯區(qū)會顯示腳本編輯窗口
extends KinematicBody2D
# class member variables go here, for example:
# var a = 2
# var b = "textvar"
func _ready():
# Called when the node is added to the scene for the first time.
# Initialization here
pass
#func _process(delta):
# # Called every frame. Delta is time since last frame.
# # Update game logic here.
# pass
9. 移動角色腳本編寫
腳本內(nèi)容如下所示:
extends KinematicBody2D
var speed = 200 # 移動速度
var motion = Vector2() # 移動向量
func _process(delta): # 每幀執(zhí)行一次
if Input.is_action_pressed("ui_right"): # 當(dāng)按下右方向鍵時
motion.x = speed; # 移動向量設(shè)置x正方向的向量變化值
elif Input.is_action_pressed("ui_left"): # 當(dāng)按下右方向鍵時
motion.x = -speed; # 移動向量設(shè)置x負(fù)方向的向量變化值
else: # 沒有按鍵按下
motion.x = 0 # 設(shè)置x軸方向移動向量為0
move_and_slide(motion) # 按移動向量方向移動
Vector2是godot里面的一個數(shù)據(jù)類型,表示的是二維的向量,有x和y兩個方向?qū)傩?br>move_and_slide方法是KinematicBody2D對象的一個移動控制方法,第一個參數(shù)是移動向量,第二個參數(shù)是地面初始化向量,具體參考:圖片.png
最后點(diǎn)擊運(yùn)行,按下鍵盤的左右方向鍵,有以下效果:

10. 讓角色有重力效果
添加移動變量y方向加速度值,修改代碼_process()函數(shù)內(nèi)如下:
func _process(delta): # 每幀執(zhí)行一次
motion.y += 9.8 # 添加向下的加速度
if Input.is_action_pressed("ui_right"): # 當(dāng)按下右方向鍵時
motion.x = speed; # 移動向量設(shè)置x正方向的向量變化值
elif Input.is_action_pressed("ui_left"): # 當(dāng)按下右方向鍵時
motion.x = -speed; # 移動向量設(shè)置x負(fù)方向的向量變化值
else: # 沒有按鍵按下
motion.x = 0 # 設(shè)置x軸方向移動向量為0
move_and_slide(motion) # 按移動向量方向移動
運(yùn)行后我們會看到角色先掉到地板上,然后我們可以控制角色左右移動
11.讓角色跑起來
我們發(fā)現(xiàn)現(xiàn)在的角色移動起來太搞笑了,不生動對吧,那我們就讓角色加點(diǎn)動畫
- 第一步,把player的Sprite節(jié)點(diǎn)換成AnimatedSprite節(jié)點(diǎn),在場景中選中player右鍵點(diǎn)擊“更換類型”,在節(jié)點(diǎn)選擇窗口搜索選擇AnimatedSprite
-
2.切換成AnimatedSprite發(fā)現(xiàn)編輯區(qū)的角色不見了!選擇AnimatedSprite子節(jié)點(diǎn),在屬性Frames選擇“新建SpriteFrames”
圖片.png -
點(diǎn)擊Frames屬性的SpriteFrames內(nèi)容,打開動畫編輯窗口如下:
圖片.png
-
-
重命名幀動畫default為run,然后把幀動畫圖片添加進(jìn)右邊的動畫幀,操作如下圖:
GIF.gif
-
-
5 再添加一個幀動畫stand,如圖:
GIF.gif - 6 ok,動畫制作好了,我們再去修改腳本:
因為我們是直接更新類型了,所以AnimatedSprite子節(jié)點(diǎn)的名字還是之前的Sprite,這里記得修改下sprite為AnimatedSprite
圖片.png
腳本更新如下
func _process(delta): # 每幀執(zhí)行一次
motion.y += 9.8
if Input.is_action_pressed("ui_right"):
motion.x = speed;
$AnimatedSprite.play("run")
elif Input.is_action_pressed("ui_left"):
motion.x = -speed;
$AnimatedSprite.play("run")
else:
motion.x = 0
$AnimatedSprite.play("stand")
move_and_slide(motion)
$childNodeName符號表示的是get_node(childNodeName),獲取子節(jié)點(diǎn)的節(jié)點(diǎn)對象,這樣就可以調(diào)用子節(jié)點(diǎn)的方法,如AnimatedSprite的play方法

我們發(fā)現(xiàn)奇怪的一幕出現(xiàn)了,當(dāng)角色往左行進(jìn)的時候角色的朝向是右邊,因為run幀動畫的圖片都是向右的!該如何解決這個問題呢?我們可以設(shè)置AnimatedSprite的flip_h屬性為true使其發(fā)生水平鏡像改變
修改腳本如下:
func _process(delta): # 每幀執(zhí)行一次
motion.y += 9.8
if Input.is_action_pressed("ui_right"):
motion.x = speed;
$AnimatedSprite.play("run")
$AnimatedSprite.flip_h = false
elif Input.is_action_pressed("ui_left"):
motion.x = -speed;
$AnimatedSprite.play("run")
$AnimatedSprite.flip_h = true
else:
motion.x = 0
$AnimatedSprite.play("stand")
move_and_slide(motion)
12. 跳躍起來吧
主角現(xiàn)在可以正常的左右跑動了,現(xiàn)在我們要讓他跳起來;當(dāng)然,主角必須在地面上才可以跳躍,所以不能只要按住上方向鍵就改變移動向量的y值。我們需要先判斷它是否在地板上,這個時候move_and_slide()的第二個參數(shù)就可以用啦
設(shè)置向上初識向量為 const UP = Vector2(0,-1)
修改的代碼如下:
extends KinematicBody2D
var speed = 200 # 移動速度
var motion = Vector2() # 移動向量
const UP = Vector2(0, -1)
const JUMP_HEIGHT = -380
func _process(delta): # 每幀執(zhí)行一次
motion.y += 9.8
if Input.is_action_pressed("ui_right"):
motion.x = speed;
$AnimatedSprite.play("run")
$AnimatedSprite.flip_h = false
elif Input.is_action_pressed("ui_left"):
motion.x = -speed;
$AnimatedSprite.play("run")
$AnimatedSprite.flip_h = true
else:
motion.x = 0
$AnimatedSprite.play("stand")
if is_on_floor():
if Input.is_action_just_pressed("ui_up"):
motion.y = JUMP_HEIGHT
move_and_slide(motion, UP) # 修改了這里
當(dāng)整個demo運(yùn)行比較久時,發(fā)現(xiàn)角色跳躍后下降的速度變快了!原因就是我們的motion.y加速度一直在增加,所以為了避免這種情況,要把motion的值賦為當(dāng)前motion值,修改最后一句代碼就行
func _process(delta):
...
motion = move_and_slide(motion, UP)
13.最終代碼
player.gd
extends KinematicBody2D
var speed = 200 # 移動速度
var motion = Vector2() # 移動向量
const UP = Vector2(0, -1)
const JUMP_HEIGHT = -380
func _process(delta): # 每幀執(zhí)行一次
motion.y += 9.8
if Input.is_action_pressed("ui_right"):
motion.x = speed;
$AnimatedSprite.play("run")
$AnimatedSprite.flip_h = false
elif Input.is_action_pressed("ui_left"):
motion.x = -speed;
$AnimatedSprite.play("run")
$AnimatedSprite.flip_h = true
else:
motion.x = 0
$AnimatedSprite.play("stand")
if is_on_floor():
if Input.is_action_just_pressed("ui_up"):
motion.y = JUMP_HEIGHT
motion = move_and_slide(motion,UP)
14. 拓展
你也可以給云朵添加動畫,防止角色跳出屏幕等功能,如圖

寫在最后
第一次覺得寫文檔好累,不過感覺還挺好,如果你喜歡就點(diǎn)個贊吧




















