昨天我們完成了顯示的圖示場景,今天要將場景和前天完成的角色場景結合,讓我們在移動時能夠有個參考的輔助圖示。
準備物品:
介紹 angle_to(to: Vector2)
float angle_to(to: Vector2) const
Returns the angle to the given vector, in radians.
Illustration of the returned angle.
這個方法會回傳到 to 向量的弧度值。
首先開啟我們的角色場景,我們將會把輔助圖示放入此場景,不過目前場景中的根節點是會隨操作移動的 CharacterBody2D
如果我們把圖加到根節點下會導致圖示跟著移動,不是我們期望的結果,因此我們再新增一個 Node
節點並點擊右鍵選擇 設置為場景根節點
,將根節點替換為此節點。
點擊新的根節點後在新增節點(+
圖示)旁邊的圖示,實例化一個場景在此場景。
選擇昨天建立的場景,此時場景中會出現昨天建立好的場景實例。
將節點重新命名成好懂的名字(這裡先以 MovementUI
為例)。
# 架構如下
|--Node
| |--CharacterBody2D
| | |--CollisionShape2D
| | |--AnimatedSprite2D
| |
| |--MovementUI
開始編輯前天完成的角色程式碼:
var movement_ui: Node2D
func _ready():
movement_ui = $"../MovementUI"
movement_ui.visible = false
func _input(event):
if event is InputEventScreenTouch:
if event.is_pressed():
# <...> 之前寫的不更改故省略,完整內容參考底部完整程式碼。
movement_ui.visible = true
movement_ui.position = event.position
elif event.is_released():
# <...>
movement_ui.visible = false
angle_to
獲得向上的向量(因為我們圖示中顯示方向的小圓在上方)到我們前天計算的 direction
向量旋轉的弧度。 if event is InputEventScreenDrag:
direction = (event.position - oriPos).normalized()
# 新增下面此行
movement_ui.rotation = Vector2.UP.angle_to(direction)
# <...>
完整檔案(更新前天程式碼):
extends CharacterBody2D
var direction:Vector2
var speed:float = 5
var dragged:bool = false
var oriPos: Vector2
var player: CharacterBody2D
var player_anime: AnimatedSprite2D
var movement_ui: Node2D
# Called when the node enters the scene tree for the first time.
func _ready():
movement_ui = $"../MovementUI"
movement_ui.visible = false
player = $"."
player_anime = player.get_node("AnimatedSprite2D")
# Called every frame. 'delta' is the elapsed time since the previous frame.
func _process(delta):
if dragged:
player.position += direction*speed
func _input(event):
if event is InputEventScreenTouch:
if event.is_pressed():
oriPos = event.position
dragged = true
player_anime.play()
movement_ui.visible = true
movement_ui.position = event.position
elif event.is_released():
direction = Vector2.ZERO
dragged = false
player_anime.stop()
movement_ui.visible = false
if event is InputEventScreenDrag:
direction = (event.position - oriPos).normalized()
movement_ui.rotation = Vector2.UP.angle_to(direction)
if abs(direction.y) > abs(direction.x):
player_anime.animation = "default"
elif direction.x > 0:
player_anime.animation = "turn_right"
elif direction.x < 0:
player_anime.animation = "turn_left"
:)