iT邦幫忙

2023 iThome 鐵人賽

DAY 5
0
SideProject30

初探 Godot系列 第 5

[DAY 5] 旋轉 (rotation, rotated)

  • 分享至 

  • xImage
  •  

今日目標:旋轉物件


事前準備(詳細作法及註解參考 Day2, Day4)

  1. 建立一個 Sprite2D 場景 及 main 場景。
  2. 在 main 場景的 Node 節點上附加腳本,加上基本資訊。
@export var to_be_created:PackedScene
var godot:Node

func _ready():
	godot = to_be_created.instantiate()
	add_child(godot)
  1. 專案 -> 專案設定 -> 輸入映射,將上下左右鍵各自綁定到:“click_up”、“click_down”、“click_left”、“click_right”。

出發

首先先定義一下這次和 Day3 的差別:
https://ithelp.ithome.com.tw/upload/images/20230920/20162875DZT0y4uQJm.png
這次要達到的目標是能讓物件左轉及右轉,像車子移動的感覺。

  • 介紹旋轉(rotation)
# 透過 rotation 可以取得到物件的弧度值
# 透過更改此值旋轉:正為順時針旋轉、負值為逆時針旋轉
godot.rotation += 0.1
  • 在 process 中對左鍵及右鍵增加以下程式碼旋轉。
func _process(delta):
	if Input.is_action_pressed("click_left"):
		godot.rotation -= 0.1
	if Input.is_action_pressed("click_right"):
		godot.rotation += 0.1

現在可以在播放時測試左右旋轉的狀態。

  • 接著是要加上上下移動的邏輯。

這邊如果直接使用 Day3 的方法(如下)會沒辦法離開 y 軸,因為 position 取得的是畫面的 y 軸而不是物件旋轉後的前後方。

    # 錯誤寫法
	if Input.is_action_pressed("click_up"):
		godot.y -= 1
	if Input.is_action_pressed("click_down"):
		godot.y += 1
  • 因此這裡我們要新增一個向量讓他跟著我們的物件一起旋轉,這樣前進後退的時候可以讓物件加上這個旋轉後的向量,朝著我們想要的方向前進。
# 因為我們希望前進的方向初始時是物件的上方因此設置為 Vector2.UP
var rotated_vector:Vector2 = Vector2.UP

接著我們需要在旋轉物件時同時旋轉我們的向量,這邊要介紹一個新的 Vector2 方法。

Vector2 rotated(angle: float) const
Returns the result of rotating this vector by angle (in radians). See also @GlobalScope.deg_to_rad().

這個方法讓我們可以透過設定 angle 取得旋轉 angle 弧度後的向量。

  • 現在將著個旋轉方法加到我們左右轉時同時更新。
func _process(delta):
	if Input.is_action_pressed("click_left"):
		godot.rotation -= 0.1
        # 新增此行
		rotated_vector = rotated_vector.rotated(-0.1)
	if Input.is_action_pressed("click_right"):
		godot.rotation += 0.1
        # 新增此行
		rotated_vector = rotated_vector.rotated(0.1)
  • 此時我們終於獲得了想要的向量,將這個向量交給上下鍵移動。
	if Input.is_action_pressed("click_up"):
        # 將現在位置加上朝前的向量前進
		godot.position += rotated_vector
	if Input.is_action_pressed("click_down"):
        # 將現在位置減去朝前的向量後退
		godot.position -= rotated_vector

現在播放便能完整的操作選轉了!
目前的程式碼:

extends Node

@export var to_be_created:PackedScene

var godot:Node
var rotated_vector:Vector2 = Vector2.UP

# Called when the node enters the scene tree for the first time.
func _ready():
	godot = to_be_created.instantiate()
	add_child(godot)


# Called every frame. 'delta' is the elapsed time since the previous frame.
func _process(delta):
	if Input.is_action_pressed("click_left"):
		godot.rotation -= 0.1
		rotated_vector = rotated_vector.rotated(-0.1)
	if Input.is_action_pressed("click_right"):
		godot.rotation += 0.1
		rotated_vector = rotated_vector.rotated(0.1)
	if Input.is_action_pressed("click_up"):
		godot.position += rotated_vector
	if Input.is_action_pressed("click_down"):
		godot.position -= rotated_vector

最後小優化

extends Node

@export var to_be_created:PackedScene
# 新增速度變數方便隨時調整
@export var speed:float = 10
# 新增選轉弧度變數方便隨時調整
@export var rotate_radians:float = 0.1

var godot:Node
var rotated_vector:Vector2 = Vector2.UP

# Called when the node enters the scene tree for the first time.
func _ready():
	godot = to_be_created.instantiate()
	add_child(godot)


# Called every frame. 'delta' is the elapsed time since the previous frame.
func _process(delta):
	if Input.is_action_pressed("click_left"):
        # 用變數取代數值
		godot.rotation -= rotate_radians
		rotated_vector = rotated_vector.rotated(-rotate_radians)
	if Input.is_action_pressed("click_right"):
        # 用變數取代數值
		godot.rotation += rotate_radians
		rotated_vector = rotated_vector.rotated(rotate_radians)
	if Input.is_action_pressed("click_up"):
        # 增加速度
		godot.position += rotated_vector * speed
	if Input.is_action_pressed("click_down"):
        # 增加速度
		godot.position -= rotated_vector * speed

執行

Yes

完成!

:)


上一篇
[DAY 4] 移動 (move_toward, lerp)
下一篇
[DAY 6] 自動消滅 (Timer)
系列文
初探 Godot30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言