iT邦幫忙

2023 iThome 鐵人賽

DAY 16
0
SideProject30

初探 Godot系列 第 16

[DAY 16] 優化移動顯示 Part.2 (angle_to)

  • 分享至 

  • xImage
  •  

今日目標:將輔助顯示加到移動操作中


▍事前準備

昨天我們完成了顯示的圖示場景,今天要將場景和前天完成的角色場景結合,讓我們在移動時能夠有個參考的輔助圖示。

準備物品:

  1. 昨天的圖示場景
  2. 前天的角色場景
  • 介紹 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 節點並點擊右鍵選擇 設置為場景根節點,將根節點替換為此節點。
    https://ithelp.ithome.com.tw/upload/images/20231001/201628755LduHKmDWh.png

  • 點擊新的根節點後在新增節點(圖示)旁邊的圖示,實例化一個場景在此場景。
    https://ithelp.ithome.com.tw/upload/images/20231001/20162875ZNFEJtn3Rg.png

  • 選擇昨天建立的場景,此時場景中會出現昨天建立好的場景實例。
    將節點重新命名成好懂的名字(這裡先以 MovementUI 為例)。
    https://ithelp.ithome.com.tw/upload/images/20231001/20162875RAO1tRg8mZ.png

    # 架構如下
    |--Node
    |   |--CharacterBody2D
    |   |   |--CollisionShape2D
    |   |   |--AnimatedSprite2D
    |   |
    |   |--MovementUI
    
  • 開始編輯前天完成的角色程式碼:

    1. 宣告變數表示我們的輔助圖示並初始化,初始化時我們先將此節點關閉顯示。
    var movement_ui: Node2D
    
    func _ready():
        movement_ui = $"../MovementUI"
        movement_ui.visible = false
    
    1. 更新我們的拖放判定程式碼,
      a. 當使用者開始拖曳時,我們顯示這個圖示,放開時關閉顯示。
      b. 同時更新我們圖示的位置。
    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
    
    1. 最後在我們更新角色位置時同時更新我們圖示的旋轉角度,獲得方式使用 angle_to 獲得向上的向量(因為我們圖示中顯示方向的小圓在上方)到我們前天計算的 direction 向量旋轉的弧度。
        if event is InputEventScreenDrag:
            direction = (event.position - oriPos).normalized()
            # 新增下面此行
            movement_ui.rotation = Vector2.UP.angle_to(direction)
            # <...>
    

▍執行

Yes

▍完成

完整檔案(更新前天程式碼):

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"

:)


上一篇
[DAY 15] 優化移動顯示 Part.1 (_draw, draw_arc, draw_circle)
下一篇
[DAY 17] 障礙建置 Part.1 (randf_range)
系列文
初探 Godot30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言