iT邦幫忙

2026 iThome 鐵人賽

DAY 19
0
Build on Google AI

從基礎到實作:使用 Google AI 學習程式設計系列 第 19 篇

Day 19|讓目標動起來並偵測玩家攻擊

  • 分享至 

  • xImage
  •  

讓目標從洞口冒出來

昨天完成了目標的生成系統,今天則繼續製作目標的移動與玩家攻擊判定。
這次希望目標不只是出現在洞口,而是能夠從土堆中冒出來,停留一段時間後再縮回去。如果玩家在這段時間內成功點擊目標,就會直接擊敗地鼠。

製作目標移動與受擊判定

這次建立了Mole,負責控制目標的升降、停留時間,以及受到攻擊後的血量判定。

using System.Collections;
using UnityEngine;

public class Mole : MonoBehaviour
{
    [Header("地鼠基本屬性")]
    public int maxHp = 1;              // 最大血量(第一種目標為 1)
    private int currentHp;

    [Header("移動與時間設定")]
    public float riseDistance = 1.2f;  // 向上冒出的距離
    public float speed = 5f;           // 升降速度
    public float showDuration = 1.0f;  // 露頭停留時間

    private Vector3 startPos;
    private Vector3 targetPos;
    private bool isDefeated = false;   // 是否已被玩家打倒

    private void Start()
    {
        currentHp = maxHp;
        startPos = transform.position;
        targetPos = startPos + new Vector3(0, riseDistance, 0);

        StartCoroutine(MoleRoutine());
    }

    private IEnumerator MoleRoutine()
    {
        // 1. 往上升起
        while (Vector3.Distance(transform.position, targetPos) > 0.01f)
        {
            transform.position = Vector3.MoveTowards(transform.position, targetPos, speed * Time.deltaTime);
            yield return null;
        }
        transform.position = targetPos;

        // 2. 停留等待玩家打擊
        yield return new WaitForSeconds(showDuration);

        // 3. 往下滑回土堆
        while (Vector3.Distance(transform.position, startPos) > 0.01f)
        {
            transform.position = Vector3.MoveTowards(transform.position, startPos, speed * Time.deltaTime);
            yield return null;
        }
        transform.position = startPos;

        // 4. 自然縮回後直接銷毀
        Destroy(gameObject);
    }

    // 玩家點擊時呼叫
    public void OnHit()
    {
        if (isDefeated) return;

        currentHp--;

        if (currentHp <= 0)
        {
            isDefeated = true;
            Debug.Log("擊中地鼠!");
            // 可以在這裡加入打擊音效或消失特效
            Destroy(gameObject);
        }
    }
}

這裡使用 Coroutine 控制地鼠的移動流程,並透過Vector3.MoveTowards()讓目標逐漸升起與縮回。玩家成功擊中地鼠後,則會扣除血量,當血量歸零時就會將目標銷毀。

偵測玩家的點擊

接著建立PlayerClicker,負責偵測玩家的滑鼠或手機觸控,並利用2D射線判斷是否點擊到目標。

using UnityEngine;

public class PlayerClicker : MonoBehaviour
{
    private void Update()
    {
        // 1. 處理電腦滑鼠點擊
        if (Input.GetMouseButtonDown(0))
        {
            CheckHit(Input.mousePosition);
        }

        // 2. 處理手機多點觸控(Touch)
        if (Input.touchCount > 0)
        {
            foreach (Touch touch in Input.touches)
            {
                // 當手指剛接觸螢幕的瞬間(Began)
                if (touch.phase == TouchPhase.Began)
                {
                    CheckHit(touch.position);
                }
            }
        }
    }

    // 統一進行 2D 射線點擊判斷
    private void CheckHit(Vector3 screenPosition)
    {
        Vector3 mousePos = Camera.main.ScreenToWorldPoint(screenPosition);
        Vector2 mousePos2D = new Vector2(mousePos.x, mousePos.y);

        // 射出 2D 射線檢測是否擊中地鼠
        RaycastHit2D hit = Physics2D.Raycast(mousePos2D, Vector2.zero);

        if (hit.collider != null)
        {
            Mole mole = hit.collider.GetComponent<Mole>();
            if (mole != null)
            {
                mole.OnHit();
            }
        }
    }
}

這段程式碼會在玩家點擊螢幕時進行碰撞判定。如果成功點擊到具有Collider2D的地鼠,就會呼叫OnHit(),讓地鼠執行受擊判定。

第十九天的成果與之後目標

今天完成了目標的升降、停留、受擊判定,以及玩家的點擊偵測。
目前玩家成功擊中目標後,目標就會消失;如果沒有擊中,目標則會在停留一段時間後縮回洞口。
接下來預計製作玩家血量機制,讓目標逃走時會影響玩家的生命值,逐步增加遊戲的挑戰性,再來製作多種目標,會因目標不同會有不同受擊次數。


上一篇
Day 18|製作打地鼠的生成系統
下一篇
Day 20|加入玩家血量與愛心顯示機制
系列文
從基礎到實作:使用 Google AI 學習程式設計 共 24 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言