Godot Engine遊戲引擎 ① 製做玩家跳躍精靈和場景——KinematicBody2D、Sprite

寫在前面:

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

最終項目成果以下:

GIF.gif

知識內容:

  • 認識godot引擎編輯器
  • 基本的場景節點添加
  • 瞭解基本的碰撞體與碰撞形狀
  • 認識KinematicBody2D 基本操做
  • 幀動畫製做與切換

製做過程:

1. 新建項目

圖片.png

  • 1.填好項目名稱、選擇好一個項目目錄
  • 2.點擊「[建立|編輯]」打開項目,項目的全部文件都會保存在那個項目目錄下

若是你的菜單界面是英文,能夠在新建項目的上方找到語言en改爲zh_CN便可改爲中文node

2.初識編輯器佈局

圖片.png

3.添加項目資源

  • 1.在項目目錄下新建image目錄,把全部的圖片資源放到image目錄下 點我下載圖片
  • 2.能夠看到資源管理面板新增了image目錄和目錄下的圖片,godot會默認爲每個資源添加一個同名的後綴爲".import"的文本文件
    圖片.png

4.製做World場景——背景、太陽、雲

【編輯區的鼠標操做】:滾輪控制編輯區的放大縮小,鼠標中鍵按下並移動鼠標能夠移動編輯區內容,鼠標左鍵選中編輯區節點python

  • 1.添加一個根節點Node2D重命名爲「World"
    • (1)在場景窗口,點擊"+"號添加
      圖片.png
    • (2)在彈出的節點選中窗口中選中Node2D,點擊建立
      圖片.png
      *(3)鼠標單擊,重命名爲」world"
    1. 爲world添加子節點Sprite,並重命名爲bg

Sprite表示精靈節點,能夠爲該節點添加一個圖片Texture資源ruby

場景窗口中鼠標指向world,右鍵添加子節點,在節點選擇框搜索Sprite,選擇Sprite點擊建立,就在world下面新建了一個子節點,重命名爲bg 編輯器

圖片.png
圖片.png

  • 3 爲bg添加圖片 場景中選中bg節點,能夠看到bg的屬性值
    圖片.png
    將資源窗口中的image文件夾下bg.png文件拖到bg的Texture屬性位置
    GIF.gif
    鼠標選中編輯區bg移動,選中周圍的點拉大,撐滿遊戲窗口
    GIF.gif

編輯區那個紅綠線交叉點爲原點,第四象限的矩形框就是遊戲窗口,在godot中,遊戲窗口的原點(0,0)在左上角,往右爲x軸正方向,往下爲y軸正方向ide

    1. 添加太陽sun節點 這裏咱們採用直接把圖片拖進編輯區的方法,咱們直接將sun.png圖片拖曳進編輯區,在場景窗口也對應生成一個與圖片文件同名的Sprite節點,如圖:
      GIF.gif
    1. 參照上一個步驟,把兩片雲彩添加進來
      圖片.png

5.製做World場景——地面

由於主角須要和地面進行交互的,因此地面不能直接使用Sprite來作,咱們須要用到StaticBody2D節點,而後再給StaticBody2D添加Sprite子節點來顯示圖片函數

  • 1.給World添加子節點StaticBody2D並重命名爲floor,並選中編輯區組合按鈕,如圖解釋
    圖片.png
    咱們發現floor右邊有個黃色三角形的警告按鈕,你能夠點擊看看是由於什麼問題

由於咱們設置的floor節點屬於StaticBody2D,表示的是一個物理靜態體,記住全部的物理靜態體在godot裏都要添加碰撞形狀子節點佈局

    1. 先給floor添加圖片吧 以前說過Sprite節點能夠添加圖片,因此這裏咱們就給floor添加一個Sprite子節點,並將land.png圖片拖到texture屬性裏,將floor放到遊戲窗口底部,最後如圖顯示
      圖片.png
    1. 添加碰撞區域

在前面咱們知道floor右邊的警告三角形的信息須要添加一個形狀體,形狀體有兩種CollisionShape2D和CollisionPolygon2D,即規則形狀和多邊形形狀,學習

給floor添加CollisionShape2D子節點,而後選擇CollisionShape2D的Shape屬性,選擇「新建RectangleShape2D」,放大編輯區咱們能夠看到有一個淺藍色的矩形塊,這個矩形塊就是碰撞區域 動畫

圖片.png
選中藍色塊的邊緣兩個紅點其中一個,拖動設置藍色塊大小,
圖片.png
使其如圖所示,長度與圖片一致,寬度在垂直居中位置便可,這個藍色塊的上邊決定了待會角色站的位置
圖片.png

  • 4 同理複製粘貼第二個地面,拼接好兩個地面,最終效果如圖:
    圖片.png

作了這麼久尚未保存過唉,記得及時保存哦,萬一程序奔潰了呢,Ctrl+S保存,在彈出的窗口點擊保存便可

圖片.png
而後咱們能夠點擊右上角運行按鈕
圖片.png
, 若是彈出一個請選擇主場景點擊選擇便可,而後在新窗口選中咱們保存的World.tscn文件,點擊打開,就能夠看到彈出一個遊戲窗口,就能看到咱們佈置的場景啦,如圖
圖片.png

6.製做World場景 —— 椰樹、草叢

與第四步添加背景的流程是同樣的,你們本身添加(tree.png樹木, grass.png草叢),添加好以後的效果和場景節點順序如圖:

圖片

7.添加角色

咱們的角色要會走,會跳,並且還會站到地面上,能夠用KinematicBody2D節點來建立角色,而後添加子節點Sprite來給角色添加圖片,因此基本操做跟製做floor相似

給world添加子節點KinematicBody2D並更名「player」,選中組合按鈕防止子節點被選中,給player添加子節點Sprite(texture屬性使用stand.png圖片)和CollisionShape2D並設置碰撞區爲圖片大小,移動到遊戲窗口中央,以下圖所示:

圖片.png

8.讓角色動起來——添加腳本

godot使用內置的GDScript腳本,是一種相似python的語言,若是你不懂GDScript可是有其餘高級面嚮對象語言(Java,python,JavaScript,ruby等)基礎的話,能夠參考官方文檔GDScript入門 固然Godot還支持C#語言開發,你能夠本身嘗試學習

    1. 給player添加腳本,鼠標右鍵單擊選擇添加腳本,在彈出的窗口中選擇建立,這時編輯區會顯示腳本編輯窗口
      圖片.png
      player.gd腳本文件內容以下,它繼承了KinematicBody2D這個類,因此在腳本里面能夠直接使用這個類或這個類的父類方法或屬性; 其中_ready()函數是初始化函數,_process(delta)函數是每一幀會運行一次,通俗的講就是這個函數裏的內容會隔一段時間就運行一次,delta參數是相鄰兩次運行的間隔時間
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. 移動角色腳本編寫

腳本內容以下所示:

extends KinematicBody2D

var speed = 200   # 移動速度
var motion = Vector2()  # 移動向量

func _process(delta):  # 每幀執行一次
	if Input.is_action_pressed("ui_right"): # 當按下右方向鍵時
		motion.x = speed;  # 移動向量設置x正方向的向量變化值
	elif Input.is_action_pressed("ui_left"): # 當按下右方向鍵時
		motion.x = -speed; # 移動向量設置x負方向的向量變化值
	else: # 沒有按鍵按下
		motion.x = 0  # 設置x軸方向移動向量爲0
	move_and_slide(motion) # 按移動向量方向移動

複製代碼

Vector2是godot裏面的一個數據類型,表示的是二維的向量,有x和y兩個方向屬性 move_and_slide方法是KinematicBody2D對象的一個移動控制方法,第一個參數是移動向量,第二個參數是地面初始化向量,具體參考:

圖片.png

最後點擊運行,按下鍵盤的左右方向鍵,有如下效果:

GIF.gif

10. 讓角色有重力效果

添加移動變量y方向加速度值,修改代碼_process()函數內以下:

func _process(delta):  # 每幀執行一次
	motion.y += 9.8  # 添加向下的加速度
	if Input.is_action_pressed("ui_right"): # 當按下右方向鍵時
		motion.x = speed;  # 移動向量設置x正方向的向量變化值
	elif Input.is_action_pressed("ui_left"): # 當按下右方向鍵時
		motion.x = -speed; # 移動向量設置x負方向的向量變化值
	else: # 沒有按鍵按下
		motion.x = 0  # 設置x軸方向移動向量爲0
	move_and_slide(motion) # 按移動向量方向移動
複製代碼

運行後咱們會看到角色先掉到地板上,而後咱們能夠控制角色左右移動

GIF.gif

11.讓角色跑起來

咱們發現如今的角色移動起來太搞笑了,不生動對吧,那咱們就讓角色加點動畫

    1. 第一步,把player的Sprite節點換成AnimatedSprite節點,在場景中選中player右鍵點擊「更換類型」,在節點選擇窗口搜索選擇AnimatedSprite
  • 2.切換成AnimatedSprite發現編輯區的角色不見了!選擇AnimatedSprite子節點,在屬性Frames選擇「新建SpriteFrames」
    圖片.png
    1. 點擊Frames屬性的SpriteFrames內容,打開動畫編輯窗口以下:
      圖片.png
    1. 重命名幀動畫default爲run,而後把幀動畫圖片添加進右邊的動畫幀,操做以下圖:
      GIF.gif
  • 5 再添加一個幀動畫stand,如圖:
    GIF.gif
  • 6 ok,動畫製做好了,咱們再去修改腳本:

由於咱們是直接更新類型了,因此AnimatedSprite子節點的名字仍是以前的Sprite,這裏記得修改下sprite爲AnimatedSprite

圖片.png

腳本更新以下

func _process(delta):  # 每幀執行一次
	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),獲取子節點的節點對象,這樣就能夠調用子節點的方法,如AnimatedSprite的play方法

GIF.gif

咱們發現奇怪的一幕出現了,當角色往左行進的時候角色的朝向是右邊,由於run幀動畫的圖片都是向右的!該如何解決這個問題呢?咱們能夠設置AnimatedSprite的flip_h屬性爲true使其發生水平鏡像改變

修改腳本以下:

func _process(delta):  # 每幀執行一次
	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. 跳躍起來吧

主角如今能夠正常的左右跑動了,如今咱們要讓他跳起來;固然,主角必須在地面上才能夠跳躍,因此不能只要按住上方向鍵就改變移動向量的y值。咱們須要先判斷它是否在地板上,這個時候move_and_slide()的第二個參數就能夠用啦 設置向上初識向量爲 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):  # 每幀執行一次
	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) # 修改了這裏
複製代碼

當整個demo運行比較久時,發現角色跳躍後降低的速度變快了!緣由就是咱們的motion.y加速度一直在增長,因此爲了不這種狀況,要把motion的值賦爲當前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):  # 每幀執行一次
	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. 拓展

你也能夠給雲朵添加動畫,防止角色跳出屏幕等功能,如圖

GIF.gif

寫在最後

第一次以爲寫文檔好累,不過感受還挺好,若是你喜歡就點個贊吧

相關文章
相關標籤/搜索