unity3D打飞碟游戏

游戏规则:

游戏有两轮,每个回合内有10个回合,每个回合都会从屏幕两侧随机发射若干飞碟 。
每个回合发射的飞碟的色彩、大小、发射位置、速度、角度、同时出现的个数都可能不同。它们由该回合的 ruler 控制,总体难度随回合数上升,也就是越到后面越难,飞碟的发射和速度会加快。
鼠标点中得分,得分规则按色彩、大小、速度不同计算,规则可自由设定。

类图:

展示视频:

打飞碟游戏zhan'shi

代码:

导演类:实现单实例

public class Director : System.Object {
    private static Director instance;
    public MainController mainController { get; set; }
    public static Director GetInstance() {
        if (instance == null) {
            instance = new Director();
        }
        return instance;
    }
}

飞碟工厂:负责飞碟的随机产生和回收

public class DiskFactory : MonoBehaviour {
    public GameObject diskPrefab; // 飞碟游戏对象,创建新的飞碟游戏对象的复制对象
    private List<DiskData> used; // 正在被游戏使用的飞碟对象
    private List<DiskData> free; // 没有被使用的空闲飞碟对象

    public void Start() {
        diskPrefab = GameObject.Instantiate(Resources.Load<GameObject>("Prefabs/Disk"), Vector3.zero, Quaternion.identity);
        diskPrefab.SetActive(false);
        used = new List<DiskData>();
        free = new List<DiskData>();
    }

    // 飞碟获取方法,根据ruler获取相应飞碟
    public GameObject GetDisk(Ruler ruler) {
        GameObject disk;

        // 从缓存中获取飞碟,没有则先创建
        int diskNum = free.Count;
        if (diskNum == 0) {
            disk = GameObject.Instantiate(diskPrefab, Vector3.zero, Quaternion.identity);
            disk.AddComponent(typeof(DiskData));
        }
        else {
            disk = free[diskNum - 1].gameObject;
            free.Remove(free[diskNum - 1]);
        }

        // 根据ruler设置disk的速度、颜色、大小、飞入方向
        disk.GetComponent<DiskData>().speed = ruler.speed;
        disk.GetComponent<DiskData>().color = ruler.color;
        disk.GetComponent<DiskData>().size = ruler.size;
        
        // 给飞碟上颜色
        if (ruler.color == "red") {
            disk.GetComponent<Renderer>().material.color = Color.red;
        }
        else if (ruler.color == "green") {
            disk.GetComponent<Renderer>().material.color = Color.green;
        }
        else {
            disk.GetComponent<Renderer>().material.color = Color.blue;
        }

        // 绘制飞碟大小
        disk.transform.localScale = new Vector3(1.2f, 0.1f * (float)ruler.size, 1.2f);
        
        // 选择飞碟飞入屏幕的起始位置
        disk.transform.position = ruler.beginPos;
        
        // 设置飞碟显示
        disk.SetActive(true);
    
        // 将飞碟加入使用队列
        used.Add(disk.GetComponent<DiskData>());

        return disk;
    }

    // 飞碟回收方法,将不使用的飞碟从使用队列放到空闲队列中
    public void FreeDisk(GameObject disk) {
        foreach (DiskData d in used) {
            if (d.gameObject.GetInstanceID() == disk.GetInstanceID()) {
                disk.SetActive(false);
                used.Remove(d);
                free.Add(d);
                break;
            }

        }
    }
}

回合控制器:控制游戏飞碟对象的发射和轮次的进行

public class RoundController : MonoBehaviour {
    private IActionManager actionManager; // 选择飞碟的运动类型
    private ScoreRecorder scoreRecorder; // 记分器
    private MainController mainController;
    private Ruler ruler; // 飞碟获取规则

    void Start() {
        // 一开始飞碟的运动类型默认为运动学运动
        actionManager = gameObject.AddComponent<CCActionManager>();
        gameObject.AddComponent<PhysisActionManager>();
        scoreRecorder = new ScoreRecorder();
        mainController = Director.GetInstance().mainController;
        gameObject.AddComponent<DiskFactory>();
        InitRuler();
    }

    void InitRuler() {
        ruler.trialNum = 0;
        ruler.roundNum = 0;
        ruler.sendTime = 0;
        ruler.roundDisksNum = new int [10];
        generateRoundDisksNum();
    }

    // 生成每trial同时发出的飞碟数量的数组,同时发出飞碟个数不超过4
    public void generateRoundDisksNum() {
        for (int i = 0; i < 10; ++i) {
            ruler.roundDisksNum[i] = Random.Range(0, 4) + 1;
        }
    }

    public void Reset() {
        InitRuler();
        scoreRecorder.Reset();
    }

    public void Record(DiskData disk) {
        scoreRecorder.Record(disk);
    }

    public int GetScores() {
        return scoreRecorder.score;
    }

    public void SetRoundSum(int roundSum) {
        ruler.roundSum = roundSum;
    }

    // 设置游戏模式,同时支持物理运动模式和动力学运动模式
    public void SetPlayDiskModeToPhysis(bool isPhysis) {
        if (isPhysis) {
            actionManager = Singleton<PhysisActionManager>.Instance as IActionManager;
        }
        else {
            actionManager = Singleton<CCActionManager>.Instance as IActionManager;
        }
    }

    // 发射飞碟
    public void LaunchDisk() {
        // 使飞碟飞入位置尽可能分开,从不同位置飞入使用的数组
        int [] beginPosY = new int [4]{0, 0, 0, 0};

        for (int i = 0; i < ruler.roundDisksNum[ruler.trialNum]; ++i) {
            // 获取随机数
            int randomNum = Random.Range(0, 3) + 1;
            // 飞碟速度随回合数增加而变快,这样难度增加
            ruler.speed = randomNum * (ruler.roundNum + 4);

            // 重新选取随机数,并根据随机数选择飞碟颜色
            randomNum = Random.Range(0, 3) + 1;
            if (randomNum == 1) {
                ruler.color = "red";
            }
            else if (randomNum == 2) {
                ruler.color = "green";
            }
            else {
                ruler.color = "blue";
            }

            // 重新选取随机数,并根据随机数选择飞碟的大小
            ruler.size = Random.Range(0, 3) + 1;

            // 重新选取随机数,并根据随机数选择飞碟飞入的方向
            randomNum = Random.Range(0, 2);
            if (randomNum == 1) {
                ruler.direction = new Vector3(3, 1, 0);
            }
            else {
                ruler.direction = new Vector3(-3, 1, 0);
            }

            // 重新选取随机数,并使不同飞碟的飞入位置尽可能分开
            do {
                randomNum = Random.Range(0, 4);
            } while (beginPosY[randomNum] != 0);
            beginPosY[randomNum] = 1;
            ruler.beginPos = new Vector3(-ruler.direction.x * 4, -0.5f * randomNum, 0);

            // 根据ruler从工厂中生成一个飞碟
            GameObject disk = Singleton<DiskFactory>.Instance.GetDisk(ruler);
        
            // 设置飞碟的飞行动作
            actionManager.PlayDisk(disk, ruler.speed, ruler.direction);
        }
    }

    // 释放工厂飞碟
    public void FreeFactoryDisk(GameObject disk) {
        Singleton<DiskFactory>.Instance.FreeDisk(disk);
    }

    // 释放所有工厂飞碟
    public void FreeAllFactoryDisk() {
        GameObject[] obj = FindObjectsOfType(typeof(GameObject)) as GameObject[];
        foreach (GameObject g in obj) {
            if (g.gameObject.name == "Disk(Clone)(Clone)") {
                Singleton<DiskFactory>.Instance.FreeDisk(g);
            }
        }
    }

    void Update() {
        if (mainController.GetGameState() == (int)GameState.Playing) {
            ruler.sendTime += Time.deltaTime;
            // 每隔2s发送一次飞碟(trial)
            if (ruler.sendTime > 2) {
                ruler.sendTime = 0;
                // 如果为无限回合或还未到设定回合数
                if (ruler.roundSum == -1 || ruler.roundNum < ruler.roundSum) {
                    // 发射飞碟,次数trial增加
                    mainController.SetViewTip("");
                    LaunchDisk();
                    ruler.trialNum++;
                    // 当次数trial等于10时,说明一个回合已经结束,回合加一,重新生成飞碟数组
                    if (ruler.trialNum == 10) {
                        ruler.trialNum = 0;
                        ruler.roundNum++;
                        generateRoundDisksNum();
                    }
                }
                // 否则游戏结束,提示重新进行游戏
                else {
                    mainController.SetViewTip("Click Restart and Play Again!");
                    mainController.SetGameState((int)GameState.GameOver);
                }
                // 设置回合数和trial数目的提示
                if (ruler.trialNum == 0) mainController.SetViewRoundNum(ruler.roundNum);
                else mainController.SetViewRoundNum(ruler.roundNum + 1);
                mainController.SetViewTrialNum(ruler.trialNum);
            }
        }
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值