iT邦幫忙

2023 iThome 鐵人賽

DAY 23
0
SideProject30

初探 Godot系列 第 23

[DAY 23] 組合移動障礙 (VisibleOnScreenNotifier2D)

  • 分享至 

  • xImage
  •  

今日目標:加入移動障礙


▍事前準備

先前我們除了不會動的障礙物之外,也有做了會移動的障礙物,今天將他加到遊戲中。

準備 main 場景以及 obstacle_move 場景。

  • 介紹 VisibleOnScreenNotifier2D

    Detects when the node extents are visible on screen.

    The VisibleOnScreenNotifier2D detects when it is visible on the screen. It also notifies when its bounding rectangle enters or exits the screen or a viewport.

      這個節點可以偵測到是否顯現在畫面上或是進入離開螢幕。
    

▍出發

  • 編輯我們的移動障礙物的程式,新增離開畫面時自動釋放的邏輯。
    1. 在根節點下新增 VisibleOnScreenNotifier2D 節點
    2. 在程式碼中使用 screen_exited 訊號並連結到釋放資源方法中。
    var notifier:VisibleOnScreenNotifier2D
    func _ready():
        # ...
        notifier = $VisibleOnScreenNotifier2D
        notifier.screen_exited.connect(_on_screen_exited)
    # ...
    func _on_screen_exited():
        queue_free()
    
    1. 接著我們需要編輯這個 notifier 的偵測範圍,使用方式和 collision 一樣,透過在 2D 畫面中拖曳紅色點來調整到符合物件的範圍
      https://ithelp.ithome.com.tw/upload/images/20231008/201628750lqbToDRww.png
    2. 現在可以播放這個場景並在 遠端 頁面確認結果。
  • 接著我們建立在主場景中的生成邏輯。
    1. 在主場景根節點新增腳本。
    2. 在主場景根節點下新增 Timer 作為生成觸發並編輯主場景程式碼。
    # 宣告我們生成計時器
    var move_obstacles_timer:Timer
    # 開始時初始化,MoveObstacleSpwanTimer 是場景中 Timer 的名字
    func _ready():
        move_obstacles_timer = $MoveObstacleSpwanTimer
        # 綁定觸發方法。
    # 新增處理遊戲開始的方法,並開始計時。
    func handle_game_start():
        move_obstacles_timer.start()
    
    1. 撰寫訊號觸發以及執行邏輯。
    # 宣告場景,之後要記得在屬性面板指定場景。
    @export var move_obstacle_scene:PackedScene
    
    func _ready():
        # ...
        # 計時器訊號綁定方法
        move_obstacles_timer.timeout.connect(_on_move_obstacle_timeout)
    
    # 建立方法
    func _on_move_obstacle_timeout():
        # 生成實例
        var instantiated_obj = move_obstacle_scene.instantiate()
        # 在畫面上方隨機取一個位置
        var randf_pos = Vector2(randf_range(0, get_viewport().size.x), -3)
        # 更新位置
        instantiated_obj.position = randf_pos
        # 加入場景
        add_child(instantiated_obj)
    
    1. 這時候可以在障礙物場景調整我們障礙物的移動速度、旋轉頻率等等數值符合目標,或是之後透過程式碼隨著遊戲進展來調整。

▍執行

這邊為了方便觀察,我們先在場景開始時直接呼叫 handle_game_start 開始。

func _ready():
	move_obstacles_timer = $MoveObstacleSpwanTimer
	move_obstacles_timer.timeout.connect(_on_move_obstacle_timeout)
	
	## FOR TEST
	handle_game_start()

Yes

▍完成

完整檔案

extends Node

@export var move_obstacle_scene:PackedScene

var move_obstacles_timer:Timer

# Called when the node enters the scene tree for the first time.
func _ready():
	move_obstacles_timer = $MoveObstacleSpwanTimer
	move_obstacles_timer.timeout.connect(_on_move_obstacle_timeout)


# Called every frame. 'delta' is the elapsed time since the previous frame.
func _process(delta):
	pass
	
func handle_game_start():
	move_obstacles_timer.start()
	
func _on_move_obstacle_timeout():
	var instantiated_obj = move_obstacle_scene.instantiate()
	var randf_pos = Vector2(randf_range(0, get_viewport().size.x), -3)
	instantiated_obj.position = randf_pos
	add_child(instantiated_obj)

:)


上一篇
[DAY 22] 組合角色
下一篇
[DAY 24] UI 設置 (CanvasLayer, Button, Label, await)
系列文
初探 Godot30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言