iT邦幫忙

2023 iThome 鐵人賽

DAY 17
0
SideProject30

初探 Godot系列 第 17

[DAY 17] 障礙建置 Part.1 (randf_range)

  • 分享至 

  • xImage
  •  

今日目標:建立障礙物


▍事前準備

我們現在有能持續滾動的背景,以及能夠操控的角色,現在希望增加一些障礙物或敵人等等的作為整個遊戲的核心,今天先來嘗試建立障礙物。

  • 介紹 randf_range(from: float, to: float)

    float randf_range(from: float, to: float)

    Returns a pseudo-random float between from and to (inclusive).

      這個方法會在 from 到 to 中隨機取浮點數值。
    

▍出發

  • 首先我們根據 Day9 可以建構出如下結構的節點:

    # 目前先簡化所有美術以最基本的方式呈現
    |--Area2D
    |   |--CollisionShape2D # 未來如果有客製化範圍可以改成 CollisionPolygon2D
    |   |--Polygon2D # 未來如果有美術圖可以改成 AnimatedSprite2D/ Sprite2D
    

    CollisionShape2D 要記得在右邊屬性面板選擇形狀。

  • 先透過 Polygon2D 決定障礙物的形狀,再使用 CollisionShape2D 符合碰撞範圍(Day9)。
    https://ithelp.ithome.com.tw/upload/images/20231002/20162875Y4YRfNyEyg.png

  • 這個障礙物我們先讓他作為不移動的障礙物,所以直接儲存場景到 Scene 資料夾,名稱此處以 obstacle_not_move 為例。

  • 現在我們在檔案系統頁面中對剛剛儲存的場景右鍵,選擇 重複,並賦予新名稱複製一份來編輯,此處以 obstacle_move 為例。
    https://ithelp.ithome.com.tw/upload/images/20231002/20162875WTT48SF5Dz.png

  • 複製完成後調整一下形狀作為區別。
    https://ithelp.ithome.com.tw/upload/images/20231002/20162875skBJXR9qck.png

  • 開啟複製後的場景,在根節點上附加新腳本開始編輯。

    這個障礙物,我們讓他是會移動的障礙物,因此給予他移動的邏輯。
    這裡我們使用 Day5 的邏輯來移動。

    1. 宣告並初始化一個 計時器 作為更改移動方向的時間間隔(參考 Day6)。
    var timer:Timer
    # Called when the node enters the scene tree for the first time.
    func _ready():
        timer = Timer.new()
        timer.set_wait_time(1)
        timer.timeout.connect(_on_rotate_timeout)
        add_child(timer)
        timer.start()
    
    1. 建立倒數結束時觸發的方法邏輯,這裡取用隨機的浮點數並限制範圍在 -0.3 到 0.3 之間作為旋轉區間,讓障礙物能持續以朝下的方向前進。
    var rand_rotate:float
    
    func _on_rotate_timeout():
        rand_rotate = randf_range(-0.3, 0.3)
    
    1. 持續更新障礙物的旋轉方向、移動向量,以及實際更新位置並移動。
    @export var speed:float = 2
    
    var rotated_vector:Vector2 = Vector2.DOWN
    
    func _process(delta):
        # 使用 Day4 lerp 達到較平滑的移動。
        var target = lerp(rotation, rand_rotate, 0.1)
        rotated_vector = rotated_vector.rotated(target - rotation)
        rotation = target
    
        position += rotated_vector * speed
    

▍執行

Yes

▍完成

完整檔案

extends Area2D

@export var speed:float = 2

var rotated_vector:Vector2 = Vector2.DOWN
var rand_rotate:float
var timer:Timer
# Called when the node enters the scene tree for the first time.
func _ready():
	timer = Timer.new()
	timer.set_wait_time(1)
	timer.timeout.connect(_on_rotate_timeout)
	add_child(timer)
	timer.start()

# Called every frame. 'delta' is the elapsed time since the previous frame.
func _process(delta):
	var target = lerp(rotation, rand_rotate, 0.1)
	rotated_vector = rotated_vector.rotated(target - rotation)
	rotation = target
	
	position += rotated_vector * speed

func _on_rotate_timeout():
	rand_rotate = randf_range(-0.3, 0.3)

:)


上一篇
[DAY 16] 優化移動顯示 Part.2 (angle_to)
下一篇
[DAY 18] 障礙建置 Part.2 (export_enum, extends, match)
系列文
初探 Godot30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言