Godot3游戲引擎入門之五:上下左右移動動畫(下)

godot_cover.jpg

一、前言

本篇是上一節(jié)文章:Godot3游戲引擎入門之五:上下左右移動動畫(上)的繼續(xù)。上一篇使用動畫和代碼實現(xiàn)了玩家的上下左右移動功能,接下來我們解決一個問題:給游戲添加碰撞體,讓玩家在有限的地圖中移動。

注意:我目前使用的是 Godot 3.1 預覽版,與 Godot 3.0 正式版有一些區(qū)別,不過界面上影響不大,如果要使用我所上傳的 Github Demo 代碼,記得去官網下載 3.1 預覽版然后就可以正常打開運行 Demo 了。 Good luck!

主要內容: Godot 2D 中玩家的上下左右移動及碰撞實現(xiàn)
閱讀時間: 4-5 分鐘
永久鏈接:http://liuqingwen.me/blog/2018/10/11/introduction-of-godot-3-part-5-the-basic-top-down-movement-part-2/
系列主頁:http://liuqingwen.me/blog/tags/Godot/

二、正文

本篇目標

  1. 使用 AnimationPlayer 節(jié)點工具創(chuàng)建狀態(tài)動畫(上)
  2. 使用代碼控制玩家的上下左右移動功能(上)
  3. 簡單的攝像機使用和地圖碰撞檢測實現(xiàn)(上下)
  4. 通過代碼實現(xiàn) RigidBody2D 剛體節(jié)點的運動(下)

場景和代碼

基本場景的制作已經在上篇中詳細解說過了,另外我們還在場景中增加了一個 Camera2D 攝像機節(jié)點,讓場景的視窗時刻聚焦在玩家周圍,但是玩家依然可以“鯉魚躍龍門”,對場景中的墻壁視而不見,豪邁奔放!游戲運行結果如下:

godot_5_result2.gif

接下來利用物理引擎相關知識解決玩家移動范圍限制的問題。

添加碰撞體

首先要做的是給墻壁添加上碰撞體,限制場景運動區(qū)域范圍。由于墻壁是靜止不動的物體,所以我們給它添加一個 StaticBody2D 靜態(tài)碰撞體節(jié)點。你可以直接在 Sprite 節(jié)點下添加一個靜態(tài)碰撞體,并設置好碰撞體大??;也可以把 Sprite 作為 StaticBody2D 的子節(jié)點,這也是推薦的流程。但是在沒有特殊用途下(比如不需要添加代碼等),你可以隨便安排, Godot 中的節(jié)點是非常靈活的。

這里為了正確設置碰撞體的形狀,我把之前單一的墻壁背景拆分為了四面獨立的墻,然后分別設置碰撞體形狀。接著要在玩家節(jié)點上添加碰撞體,這里我們需要謹慎操作:第一是注意節(jié)點的類型,和墻壁不同,玩家是可以移動的,且擁有物理屬性,所以不能使用靜態(tài)碰撞體;第二是節(jié)點的父子關系的順序問題,我們因為要移動碰撞體,而不是 Sprite 精靈圖片節(jié)點,所以 Sprite 應該作為碰撞體節(jié)點的子節(jié)點,且不能弄反!詳細解說在我的入門文章第二篇中有詳述: Godot3 游戲引擎入門之二:第一個簡單的游戲場景。

和大名鼎鼎的 Box2D 開源物理引擎類似, Godot 中也有三種常用的物理碰撞體: StaticBody2D | RigidBody2D | KinematicBody2D ,同屬于 PhysicsBody2D 類型下,它們之間的異同點大致如下;

節(jié)點名 StaticBody2D RigidBody2D KinematicBody2D
節(jié)點名稱 靜態(tài)碰撞節(jié)點( 2D ) 剛體節(jié)點( 2D ) 運動學節(jié)點( 2D )
基本特性 自動碰撞檢測,位置固定不變 自動碰撞檢測,產生碰撞響應:有線速度、角速度等 參與碰撞檢測,無自動響應,完全由代碼控制移動
使用場景 一般用于固定的墻壁、地面等 一般用于受外界影響而產生運動的物體,比如球體、隕石等 主要用于由代碼控制的帶物理屬性的玩家

了解了這三種節(jié)點后,得出的結論是不是應該給我們的主角添加一個 KinematicBody2D 運行學節(jié)點呢?嗯……然而并不是,如果使用 KinematicBody2D 節(jié)點,我們需要自己手動控制物理反饋,雖然絕大多數的游戲應該這樣,但是這不是本篇文章的做法,盡量不要動代碼是我的出發(fā)點,以后再介紹 KinematicBody2D 節(jié)點,現(xiàn)在我們暫時使用簡單一點的 RigidBody2D 剛體節(jié)點進行嘗試。(是不是聽上去有點不符合直覺?其實在有些游戲中,比如太空飛船射擊游戲,就可以使用 RigidBody2D 作為玩家節(jié)點進行開發(fā)。)

理論到此為止,給我們的游戲場景添加一個 RigidBody2D 剛體節(jié)點,改名為 Player ,然后把之前的玩家 PlayerSprite )節(jié)點拖到 RigidBody2D 節(jié)點下作為其子節(jié)點,同時 AnimationPlayer 節(jié)點也要作為剛體節(jié)點的子節(jié)點,保持和 Player 節(jié)點平級的關系,最后添加一個 CollisionShape2D 節(jié)點用于設置碰撞體的形狀。

godot_5_rigidbody2d.jpg

最終場景中的節(jié)點如上圖,唯一要設置的是把 RigidBody2D 的重力影響屬性 Gravity Scale 設置為 0 ,即完全擺脫重力的影響,不這么設置的話,你會發(fā)現(xiàn)玩家會“情不自禁”地做自由落體運動。另外,值得注意的是,我在改名的過程中,原來的 Player 節(jié)點自動更名為 Player1 ,然后動畫全部失效,解決辦法很簡單,在動畫面板里把軌道的名字改過來即可,如下圖:

![
godot_5_change_node.jpg

最終代碼

場景一切就緒,接下來的任務就是修改代碼了!因為我們的節(jié)點關系產生了變化,還有節(jié)點的行為也變了( Sprite -> RigidBody2D ),所以對于新手朋友我要特別提醒的是:玩家已經轉變成 RigidBody2D 剛體節(jié)點了,剛體節(jié)點是會自動產生物理響應的,所以我們不能像剛才那樣直接使用代碼操作玩家的位置,相反,我們應該通過設置剛體的線速度、角速度來實現(xiàn)對剛體運動的控制!

具體修改我都在代碼中做了注釋,代碼量不大,相信大家都能看懂吧。這里全部的代碼我就不貼出來了,修改部分如下:

onready var animationPlayer = $Player/AnimationPlayer # 修改后
onready var camera = $Camera2D

player.linear_velocity = velocity # 添加部分,設置線速度,速度為0時有用
player.angular_velocity = 0 # 添加部分,設置角速度,防止player打轉
# 速度不為0,移動玩家位置,同時更新攝像機
if velocity.length() > 0:
    # 注意這里normalize速度矢量
    # player.position += velocity.normalized() * speed * delta # 刪除
    player.linear_velocity = velocity.normalized() * speed # 添加,更新速度
    # 更新攝像機,玩家始終在視窗內活動
    updateCameraPosition()
    # 省略代碼……

終于完工,按 F5 運行游戲,看看我們的杰作吧:

godot_5_result3.gif

三、小結(下)

相對來說,這篇的知識點還是非常簡單的,當然對于編程初學者來說,代碼還是一個需要克服的地方。在接下來的文章里,我會針對 2D 游戲中的地圖創(chuàng)建做幾篇文章,也就是 TileMap 節(jié)點的功能介紹和使用,打造一個游戲該有的豐富世界!

最后,本篇上下節(jié)結束后,我要提醒新手朋友們幾個注意點:

  1. 我們實際項目中使用 RigidBody2D 來作為玩家還是比較少的,相對多的還是 KinematicBody2D 節(jié)點
  2. 我們對物理碰撞的處理不應該放在 _process(delta) 方法中,而應該放在 _physics_process(delta) 方法中,后續(xù)再講
  3. 地圖太簡單了,這也是這篇要埋下的伏筆,下篇介紹,“等著瞧”,哈哈

原創(chuàng)實屬不易,希望大家喜歡! :smile:

我的博客地址: http://liuqingwen.me ,歡迎關注我的微信公眾號:

IT自學不成才

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容