Unity小游戏-打飞碟

Unity小游戏-打飞碟

我使用Unity引擎和C#编程语言开发了一个简单而有趣的打飞碟游戏。在游戏中,玩家需要点击飞碟,随着击中的飞碟数量增加,玩家的分数也会增加。我将逐步介绍游戏的主要功能以及实现过程中的关键点。

在这里插入图片描述


游戏概述

这是一个简单而有趣的打飞碟游戏,玩家需要点击飞碟,每次点击飞碟分数增加,当分数达到一定值时,游戏结束并显示胜利信息。游戏中的飞碟会在屏幕上随机出现,玩家需要在飞碟出现后尽快点击,以获取更高的分数。


游戏要素

1. 飞碟对象
  • 飞碟具有不同的颜色。
  • 飞碟具有随机的方向和速度,并且随机对飞碟施加力和力矩,增加游戏难度和趣味性。
2. 分数系统
  • 玩家每次点击飞碟,分数增加。
  • 分数显示在游戏界面上,随着得分的增加而动态更新。
3. 游戏流程控制
  • 游戏开始时,飞碟开始随机出现。
  • 玩家点击飞碟后,飞碟消失,分数增加。
  • 当玩家的分数达到一定值,游戏结束,显示胜利信息。

游戏设计

1. 飞碟生成

  • 使用对象池技术,预先生成一定数量的飞碟对象,避免在游戏运行时频繁创建和销毁对象。
  • 飞碟的方向和速度随机生成,可以在屏幕上的不同位置出现。

2. 飞碟交互

  • 当玩家鼠标点击飞碟时,飞碟消失,分数增加。

3. 分数计算

  • 每次点击飞碟,玩家的分数增加,具体增加分数根据ScriptableObject中设定的最大最小分数之间取随机数。

4. 游戏结束

  • 当玩家的分数达到一定值时,游戏结束。
  • 游戏结束后,显示胜利信息,告知玩家取得了胜利。

设计实现

飞碟预制体制作

其中需要Rigidbody、Box Collider和Mesh Rednderer
在这里插入图片描述

对象池的原理

在下面的 UML 图中,展示了对象池的基本原理和关键组件,包括 DiskPool 类、DiskConfig 类和 DiskController 类。

在这里插入图片描述

伪代码 - 对象池的原理

以下是伪代码,描述了对象池的基本原理:

class DiskPool:
    - diskPrefab: GameObject
    - diskPool: Queue<GameObject>

    constructor(diskPrefab: GameObject):
        this.diskPrefab = diskPrefab
        this.diskPool = new Queue<GameObject>()
        InitializePool()

    method InitializePool():
        for i from 0 to 10:
            disk = Instantiate(diskPrefab)
            disk.SetActive(false)
            diskPool.Enqueue(disk)

    method GetDiskFromPool(): GameObject:
        if diskPool is not empty:
            disk = diskPool.Dequeue()
            disk.SetActive(true)
            return disk
        else:
            newDisk = Instantiate(diskPrefab)
            return newDisk

    method ReturnDiskToPool(disk: GameObject):
        disk.SetActive(false)
        diskPool.Enqueue(disk)

    method RecycleDisk(disk: GameObject):
        yield return WaitForSeconds(5)
        ReturnDiskToPool(disk)
对象配置方法

使用 ScriptableObject 配置不同的飞碟
在这里插入图片描述

伪代码 - 对象配置方法

以下是伪代码,描述了对象配置的方法:

class DiskConfig (ScriptableObject):
    - MinSpeed: float
    - MaxSpeed: float
    - MinScore: int
    - MaxScore: int

class DiskPool:
    - diskConfigs: DiskConfig
    - diskPrefab: GameObject
    - diskPool: Queue<GameObject>

    method InitializePool():
        for i in range(10):
            disk = Instantiate(diskPrefab)
            // 根据diskConfigs中的配置调整disk的属性
            disk.SetActive(false)
            diskPool.Enqueue(disk)

    method GetDiskFromPool(): GameObject:
        if diskPool is not empty:
            return diskPool.Dequeue()
        else:
            newDisk = Instantiate(diskPrefab)
            // 根据diskConfigs中的配置调整newDisk的属性
            return newDisk

    method ReturnDiskToPool(disk: GameObject):
        disk.SetActive(false)
        diskPool.Enqueue(disk)

class DiskController:
    - diskConfig: DiskConfig
    - minForce: float
    - maxForce: float
    - randomTorque: float
    - speed: float
    - diskscore: int

    method Awake():
        // 初始化速度和分数
        // 根据diskConfig中的配置调整属性

    method OnEnable():
        // 添加力和扭矩,启用时调用

    method OnMouseDown():
        // 处理鼠标点击事件,增加分数并回收飞碟

    method SetColor():
        // 设置飞碟颜色

    method SetMovementParameters(direction: Vector3):
        // 设置飞碟的移动参数

class ScoreManager:
    - score: int
    - diskConfig: DiskConfig

    method IncreaseScore(diskscore: int):
        score += diskscore
        if score >= diskConfig.MaxScore:
            // 游戏胜利逻辑

总体设计

在这里插入图片描述
游戏的总体设计伪代码,包含了游戏管理、对象池、对象配置和得分管理的逻辑。

class GameManager:
    - Instance: GameManager
    - gameStarted: bool

    method Awake():
        Instance = this

    method StartGame():
        gameStarted = true

    method EndGame(message: string):
        gameStarted = false
        // 显示游戏结束消息

class DiskPool:
    - Instance: DiskPool
    - diskConfigs: DiskConfig
    - diskPool: Queue<GameObject>

    method Awake():
        Instance = this

    method GetDiskFromPool(): GameObject:
        if diskPool is not empty:
            return diskPool.Dequeue()
        else:
            newDisk = Instantiate(diskConfigs.diskPrefab)
            return newDisk

    method ReturnDiskToPool(disk: GameObject):
        disk.SetActive(false)
        diskPool.Enqueue(disk)

class DiskController:
    - minForce: float
    - maxForce: float
    - randomTorque: float
    - speed: float
    - diskscore: int

    method OnEnable():
        // 添加力和扭矩,启用时调用

    method OnMouseDown():
        // 处理鼠标点击事件,增加分数并回收飞碟

    method SetColor():
        // 设置飞碟颜色

    method SetMovementParameters(direction: Vector3):
        // 设置飞碟的移动参数

class ScoreManager:
    - Instance: ScoreManager
    - score: int

    method Awake():
        Instance = this

    method IncreaseScore(diskscore: int):
        score += diskscore
        if score >= 50:
            GameManager.Instance.EndGame("You Win!")

具体实现

在游戏的开发过程中,我们充分利用了Unity引擎的物理引擎,使用C#编程语言编写游戏逻辑,实现了飞碟的生成、交互和分数的管理。以下是我们在具体实现中的一些关键点:

飞碟的配置和对象池管理

我们使用了DiskConfig类来配置飞碟的外观和运动参数,包括颜色、初始速度和随机方向范围。这样,我们可以通过调整DiskConfig的属性来实现不同飞碟的外观和运动特性。
在这里插入图片描述

// DiskConfig类(DiskConfig.cs文件中)
public class DiskConfig : ScriptableObject
{
    
    
    public float MinSpeed;
    public float MaxSpeed;
    public int MinScore;
    public int MaxScore;
}

// DiskPool类(DiskPool.cs文件中)
public class DiskPool : MonoBehaviour
{
    
    
    // ...
}

DiskPool类中,我们利用对象池技术管理飞碟对象,提高了游戏性能和效率。在游戏开始时,我们初始化了一定数量的飞碟对象,并在需要时从对象池中获取飞碟,避免了频繁地创建和销毁对象。

// DiskPool类中的初始化飞碟对象池方法
private void InitializePool()
{
    
    
    foreach (var config in diskConfigs)
    {
    
    
        for (int i = 0; i < 10; i++) // 初始化10个飞碟对象
        {
    
    
            GameObject disk = Instantiate(diskPrefab, transform);
            disk.GetComponent<Renderer>().material.color = config.diskColor;
            disk.SetActive(false);
            diskPool.Enqueue(disk);
        }
    }
}

飞碟的控制和交互

飞碟的控制和交互主要在DiskController类中实现。在Awake()方法中,我们根据DiskConfig中的配置初始化了飞碟的速度和分数。在OnEnable()方法中,我们给飞碟施加了随机的力和旋转力,使得飞碟在游戏中具有随机的运动轨迹。当玩家点击飞碟时,OnMouseDown()方法被触发,分数增加,并将飞碟回收到对象池中。

// DiskController类中的控制和交互方法
private void Awake()
{
    
    
    // 根据DiskConfig中的配置初始化飞碟的速度和分数
    speed = Random.Range(diskConfig.initialSpeed - diskConfig.randomDirectionRange, diskConfig.initialSpeed + diskConfig.randomDirectionRange);
    diskscore = Random.Range(diskConfig.MinScore, diskConfig.MaxScore);
}

private void OnEnable()
{
    
    
    // 给飞碟施加随机的力和旋转力
    rb.AddForce(Random.Range(minForce, maxForce) * transform.forward);
    rb.AddTorque(Random.onUnitSphere * randomTorque);
}

private void OnMouseDown()
{
    
    
    // 处理鼠标点击事件,增加分数并回收飞碟
    ScoreManager.Instance.IncreaseScore(diskscore);
    DiskPool.Instance.ReturnDiskToPool(gameObject);
}

分数管理和游戏流程控制

分数的管理在ScoreManager类中实现。在每次点击飞碟时,分数增加,当分数达到一定值时,游戏结束。

// ScoreManager类中的分数管理方法
public void IncreaseScore(int diskscore)
{
    
    
    // 增加分数并检查是否满足胜利条件
    score += diskscore;
    UpdateScoreText();
    if (score >= 50)
    {
    
    
        // 游戏胜利逻辑,例如显示胜利信息
        score = 0;
        UpdateScoreText();
        GameManager.Instance.EndGame("You Win!");
    }
}

游戏流程的控制在GameManager类中实现。在游戏开始时,飞碟会以一定的时间间隔生成,当玩家点击飞碟时,分数增加,当玩家分数达到胜利条件时,游戏结束并显示胜利信息。
其中游戏的提示信息和按钮通过Canvas的UI实现。
在这里插入图片描述

// GameManager类中的游戏流程控制方法
private void Start()
{
    
    
    // 游戏开始,开始生成飞碟
    InvokeRepeating("SpawnDisk", 1f, spawnInterval);
}

private void SpawnDisk()
{
    
    
    if (gameStarted)
    {
    
    
        // 生成飞碟的逻辑,使用DiskPool来获取飞碟对象
        // ...
    }
}

public void EndGame(string message)
{
    
    
    // 游戏结束,显示胜利信息或失败信息
    gameStarted = false;
    restartButton.gameObject.SetActive(true);
    Debug.Log(message);
    winText.enabled = true;
    winText.gameObject.SetActive(true);
}

public void RestartGame()
{
    
    
    // 重新开始游戏,重置分数等游戏状态
    winText.enabled = false;
    winText.gameObject.SetActive(false);
    StartGame();
}

在游戏的开发过程中,我们充分发挥了Unity引擎和C#编程语言的优势,通过对象池技术管理飞碟对象,提高了游戏的性能和效率。同时,通过配置不同的DiskConfig对象,我们实现了飞碟的多样化,为游戏增加了趣味性和挑战性。

总结

通过这次开发实践,我学到了如何使用对象池技术管理游戏对象,提高了游戏的性能和效率。同时,我也深入理解了游戏中各个部分的交互逻辑,包括飞碟的生成、交互和分数的管理。

视频展示

unity小游戏-打飞碟

代码仓库

Helianthus_254

猜你喜欢

转载自blog.csdn.net/helianthus_254/article/details/134222827