Hit UFO制作

UML图

在这里插入图片描述

具体实现

Disk属性

public class Disk : MonoBehaviour {
    
    
    public int type;
    public int score;                               
    public Color color;                    
}

DiskFactory

public class DiskFactory : MonoBehaviour {
    
    
    private List<Disk> useddisklist = new List<Disk>();
    private List<Disk> freedisklist = new List<Disk>();

    public GameObject GetDisk(int type) {
    
    
        GameObject disk_prefab = null;
        if (freedisklist.Count>0) {
    
    
            for(int i = 0; i < freedisklist.Count; i++) {
    
    
                if (freedisklist[i].type == type) {
    
    
                    disk_prefab = freedisklist[i].gameObject;
                    freedisklist.Remove(freedisklist[i]);
                    break;
                }
            }     
        }

        if(disk_prefab == null) {
    
    
            if(type == 1) {
    
    
                disk_prefab = Instantiate(
                Resources.Load<GameObject>("Prefabs/disk1"),
                new Vector3(0, -10f, 0), Quaternion.Euler(-90, 0f, 0f));
            }
            else if (type == 2) {
    
    
                disk_prefab = Instantiate(
                Resources.Load<GameObject>("Prefabs/disk2"),
                new Vector3(0, -10f, 0), Quaternion.Euler(-90, 0f, 0f));
            }
            else {
    
    
                disk_prefab = Instantiate(
                Resources.Load<GameObject>("Prefabs/disk3"),
                new Vector3(0, -10f, 0), Quaternion.Euler(-90, 0f, 0f));
            }

            disk_prefab.GetComponent<Renderer>().material.color = disk_prefab.GetComponent<Disk>().color;
        }

        useddisklist.Add(disk_prefab.GetComponent<Disk>());
        disk_prefab.SetActive(true);
        return disk_prefab;
    }

    public void FreeDisk() {
    
    
        for(int i=0; i<useddisklist.Count; i++) {
    
    
            if (useddisklist[i].gameObject.transform.position.y <= -10f) {
    
    
                freedisklist.Add(useddisklist[i]);
                useddisklist.Remove(useddisklist[i]);
            }
        }          
    }

    public void Reset() {
    
    
        FreeDisk();
    }

}

Interface

public interface ISceneController {
    
    
    void LoadResources();                                  
}

public interface IUserAction {
    
    
    void Hit(Vector3 pos);
    float GetScore();
    int GetRound();
    int GetTrial();
    void GameOver();
    void ReStart();
    bool Getflag();
    float GetTarget();
    bool GetStatus();
}

public enum SSActionEventType : int {
    
     Started, Competeted }

public interface ISSActionCallback {
    
    
    void SSActionEvent(SSAction source, 
        SSActionEventType events = SSActionEventType.Competeted,
        int intParam = 0, string strParam = null, Object objectParam = null);
}

Action

DiskFlyACtion

public class DiskFlyAction : SSAction {
    
    
    public float gravity = -1;//重力
    private Vector3 start_vector;//初速度
    private Vector3 gravity_vector = Vector3.zero;//y方向速度
    private float time;

    private DiskFlyAction() {
    
     }
    public static DiskFlyAction GetSSAction(int lor, float angle, float power) {
    
    
        //初速度
        DiskFlyAction action = CreateInstance<DiskFlyAction>();
        if (lor == -1) {
    
    
            action.start_vector = Quaternion.Euler(new Vector3(0, 0, -angle)) * Vector3.left * power;
        }
        else {
    
    
            action.start_vector = Quaternion.Euler(new Vector3(0, 0, angle)) * Vector3.right * power;
        }
        return action;
    }

    public override void Update() {
    
    
        time += Time.fixedDeltaTime;
        gravity_vector.y = gravity * time * 0.1f;
        transform.position += (start_vector + gravity_vector) * Time.fixedDeltaTime;
        if (this.transform.position.y < -10) {
    
    
            this.destroy = true;
            this.callback.SSActionEvent(this);      
        }
    }

    public override void Start() {
    
     }
}

FlyActionManager

public class FlyActionManager : SSActionManager {
    
    
    public DiskFlyAction fly;  
    public FirstController myscenecontroller;           

    protected void Start() {
    
    
        myscenecontroller = (FirstController)SSDirector.GetInstance().CurrentScenceController;
        myscenecontroller.actionmanager = this;     
    }
    public void DiskFly(GameObject disk, float angle, float power) {
    
    
        int lor = 1;
        if (disk.transform.position.x > 0) lor = -1;
        fly = DiskFlyAction.GetSSAction(lor, angle, power);
        this.RunAction(disk, fly, this);
    }
}

ScoreRecorder

public class ScoreRecorder : MonoBehaviour {
    
    
    private float score;
    void Start () {
    
    
        score = 0;
    }
    public void Record(GameObject disk) {
    
    
        score += disk.GetComponent<Disk>().score;
    }
    public float GetScore() {
    
    
        return score;
    }
    public void Reset() {
    
    
        score = 0;
    }
}

Singleton

public class Singleton<T> : MonoBehaviour where T : MonoBehaviour {
    
    
    protected static T instance;
    public static T Instance {
    
    
        get {
    
    
            if (instance == null) {
    
    
                instance = (T)FindObjectOfType(typeof(T));
                if (instance == null) {
    
    
                    Debug.LogError("An instance of " + typeof(T)
                        + " is needed in the scene, but there is none.");
                }
            }
            return instance;
        }
    }

}

UserGUI

public class UserGUI : MonoBehaviour {
    
    
    private IUserAction action;   
    GUIStyle button_style = new GUIStyle();
    GUIStyle start_style = new GUIStyle();
    GUIStyle text_style = new GUIStyle();
    GUIStyle text_style2 = new GUIStyle();
    GUIStyle over_style = new GUIStyle();
    GUIStyle round_style = new GUIStyle();
    GUIStyle target_style = new GUIStyle();
    GUIStyle red_style = new GUIStyle();
    GUIStyle yellow_style = new GUIStyle();
    GUIStyle green_style = new GUIStyle();
    private bool game_start = false;

    void Start () {
    
    
        action = SSDirector.GetInstance().CurrentScenceController as IUserAction;
    }
	
	void OnGUI () {
    
    
        start_style.fontSize = 35;
        button_style.fontSize = 20;
        text_style.fontSize = 18;
        text_style2.fontSize = 16;
        red_style.normal.textColor = Color.red;
        red_style.fontSize = 18;
        yellow_style.normal.textColor = Color.yellow;
        yellow_style.fontSize = 18;
        green_style.normal.textColor = Color.green;
        green_style.fontSize = 18;
        over_style.fontSize = 50;
        round_style.fontSize = 50;
        target_style.fontSize = 20;
        if (game_start) 
        {
    
    
            GUI.Label(new Rect(5, 5, 200, 50), "red disk=1", red_style);
            GUI.Label(new Rect(105, 5, 50, 50), "yellow disk=2", yellow_style);
            GUI.Label(new Rect(225, 5, 50, 50), "green disk=3", green_style);
            GUI.Label(new Rect(Screen.width-300, 5, 50, 50), "Score:"+ action.GetScore().ToString(), text_style);
            GUI.Label(new Rect(Screen.width-200, 5, 50, 50), "Round:" + action.GetRound().ToString(), text_style);
            GUI.Label(new Rect(Screen.width-100, 5, 50, 50), "Num:" + action.GetTrial().ToString(), text_style);
            if(action.Getflag())
            {
    
    
                GUI.Label(new Rect(Screen.width / 2 - 90, Screen.height / 2 - 60 , 100, 100), "Round"+(action.GetRound()+1).ToString(), round_style);
                GUI.Label(new Rect(Screen.width / 2 - 80, Screen.height / 2 +20 , 100, 100), "Target Score:"+(action.GetTarget()).ToString(), target_style);
            }
            if (action.GetStatus()==false) {
    
    
                GUI.Label(new Rect(Screen.width / 2 - 100, Screen.height / 2 - 80, 100, 100), "You Lose!", over_style);
                GUI.Label(new Rect(Screen.width / 2 - 45, Screen.height / 2, 50, 50), "Your Score:" + action.GetScore().ToString(), text_style2);
                if (GUI.Button(new Rect(Screen.width / 2 - 50, Screen.height / 2+40, 100, 50), "Restart")) {
    
    
                    action.ReStart();
                    return;
                }
                action.GameOver();
            }
            else if(action.GetStatus()==true&&action.Getflag())
            {
    
    
                GUI.Label(new Rect(Screen.width / 2 - 90, Screen.height / 2 - 60 , 100, 100), "Round"+(action.GetRound()+1).ToString(), round_style);
                GUI.Label(new Rect(Screen.width / 2 - 80, Screen.height / 2 +20 , 100, 100), "Target Score:"+(action.GetTarget()).ToString(), target_style);
            }
            if (action.GetRound() == 3 && action.GetTrial() == 11&&action.GetStatus()) {
    
    
                GUI.Label(new Rect(Screen.width / 2 - 100, Screen.height / 2 - 80, 100, 100), "You Win!", over_style);
                GUI.Label(new Rect(Screen.width / 2 - 45, Screen.height / 2, 50, 50), "Your Score:" + action.GetScore().ToString(), text_style2);
                if (GUI.Button(new Rect(Screen.width / 2 - 50, Screen.height / 2+40, 100, 50), "Restart")) {
    
    
                    action.ReStart();
                    return;
                }
                action.GameOver();
            }
        }
        else {
    
    
            GUI.Label(new Rect(Screen.width / 2 - 60, Screen.height / 2 - 100, 100, 100), "Hit UFO",start_style);
            if (GUI.Button(new Rect(Screen.width / 2 - 50, Screen.height / 2-20, 100, 50), "Start")) {
    
    
                game_start = true;
                action.ReStart();
            }
        }
    }

FirstController

public class FirstController : MonoBehaviour, ISceneController, IUserAction {
    
    
    public UserGUI gui;
    public DiskFactory diskfactory;
    public FlyActionManager actionmanager;
    public ScoreRecorder scorerecorder;
    private int round = 0;//记录是第几回合                                                  
    private int num = 0;//发射飞碟数
    private bool status=true;//status标记游戏是否结束,true则不结束
    public bool ifroundend=false;//如果回合结束则为ture,游戏暂停几秒,OnGUI中调用Getflag得到true,展示下一回合目标,然后开始下一回合
    public bool flag=false;//flag用于标记记录curtime

    public float []target=new float[3]{
    
    10,25,40};//每回合的目标分数                                             
    private bool ifrun = false;//是否运行,点击游戏开始会调用ReStart使之变true
    private float curtime=0;//进入回合前记录当前时间,用于等待
    private int interval = 0;//每次发飞碟的间隔时间
    void Start () 
    {
    
    
        SSDirector director = SSDirector.GetInstance();     
        director.CurrentScenceController = this;
        gui = gameObject.AddComponent<UserGUI>() as UserGUI;
        diskfactory = Singleton<DiskFactory>.Instance;
        actionmanager = gameObject.AddComponent<FlyActionManager>() as FlyActionManager;
        scorerecorder = Singleton<ScoreRecorder>.Instance;
    }
	void Update () 
    {
    
    
        if(ifrun) 
        {
    
    
            if(round==0)
            {
    
    
                num=0;
                ifroundend=true;
                if(flag==false)
                {
    
    
                    curtime=System.DateTime.Now.Hour*3600+System.DateTime.Now.Minute*60+System.DateTime.Now.Second;
                    flag=true;
                }
                else
                {
    
    
                    float tmp=System.DateTime.Now.Hour*3600+System.DateTime.Now.Minute*60+System.DateTime.Now.Second;
                    if(tmp<(curtime+3)) return;//第一回合前等待3秒
                    ifroundend=false;
                    flag=false;
                    round+=1;
                }  
           }
            interval++;
            if (Input.GetButtonDown("Fire1")) 
            {
    
    
                Vector3 pos = Input.mousePosition;
                Hit(pos);
            }
            if(round==1)
            {
    
    
                    if (interval >= 180) 
                    {
    
    
                        if(ifroundend)
                        {
    
    
                            float tmp=System.DateTime.Now.Hour*3600+System.DateTime.Now.Minute*60+System.DateTime.Now.Second;
                            if(tmp<(curtime+3)) return;//第二回合前等待3秒
                            else
                            {
    
    
                                num=0;
                                round=2;
                                ifroundend=false;
                            }
                        }
                        
                        if (num == 20) 
                        {
    
    
                            if(flag==false)
                            {
    
    
                                curtime=System.DateTime.Now.Hour*3600+System.DateTime.Now.Minute*60+System.DateTime.Now.Second;
                                flag=true;
                            }
                            else
                            {
    
    
                                float tmp=System.DateTime.Now.Hour*3600+System.DateTime.Now.Minute*60+System.DateTime.Now.Second;
                                if(tmp<(curtime+3)) return;//等待三秒结算
                                flag=false;
                                curtime=System.DateTime.Now.Hour*3600+System.DateTime.Now.Minute*60+System.DateTime.Now.Second;
                                checkstatus();
                                if(status==true)
                                {
    
    
                                    ifroundend=true;
                                }
                            }  
                        }
                        else{
    
    
                                interval = 0;
                                SendDisk(1);
                                num += 1;
                        }
                    }
                }
            if(round==2)
            {
    
    
                    if (interval >= 120) 
                    {
    
    
                        if(ifroundend)
                        {
    
    
                            float tmp=System.DateTime.Now.Hour*3600+System.DateTime.Now.Minute*60+System.DateTime.Now.Second;
                            if(tmp<(curtime+3)) return;//第三回合前等待3秒
                            else
                            {
    
    
                                num=0;
                                round=3;
                                ifroundend=false;
                                flag=false;
                            }
                        }
                        
                        if (num == 18) 
                        {
    
    
                            if(flag==false)
                            {
    
    
                                curtime=System.DateTime.Now.Hour*3600+System.DateTime.Now.Minute*60+System.DateTime.Now.Second;
                                flag=true;
                            }
                            else
                            {
    
    
                                float tmp=System.DateTime.Now.Hour*3600+System.DateTime.Now.Minute*60+System.DateTime.Now.Second;
                                if(tmp<(curtime+3)) return;//等待三秒结算
                                flag=false;
                                curtime=System.DateTime.Now.Hour*3600+System.DateTime.Now.Minute*60+System.DateTime.Now.Second;
                                checkstatus();
                                if(status==true)
                                {
    
    
                                    ifroundend=true;
                                }
                            }
                        }
                        else
                        {
    
    
                            interval = 0;
                            if (num % 2 == 0) SendDisk(1);
                            else SendDisk(2);
                            num += 1;
                        }
                    }
                }
            if(round==3)
            {
    
    
                    if (interval >= 80) 
                    {
    
    
                        
                        if (num == 10) 
                        {
    
    
                            if(flag==false)
                            {
    
    
                                curtime=System.DateTime.Now.Hour*3600+System.DateTime.Now.Minute*60+System.DateTime.Now.Second;
                                flag=true;
                            } 
                            else
                            {
    
    
                                float tmp=System.DateTime.Now.Hour*3600+System.DateTime.Now.Minute*60+System.DateTime.Now.Second;
                                if(tmp<(curtime+3)) return;//等待三秒结算
                                flag=false;
                                ifrun=false;
                                num+=1;
                                checkstatus();
                            }  
                        }
                        else{
    
    
                            interval = 0;
                            if (num % 3 == 0) SendDisk(1);
                            else if(num % 3 == 1)SendDisk(2);
                            else SendDisk(3);
                            num += 1;
                        }
                    }

                }
            diskfactory.FreeDisk();
        }
        
    }
    

    public void LoadResources() {
    
    
        diskfactory.GetDisk(round);
        diskfactory.FreeDisk();
    }
    
    private void SendDisk(int type) {
    
    
        GameObject disk = diskfactory.GetDisk(type);

        float ran_y = 0;
        float ran_x = Random.Range(-1f, 1f) < 0 ? -1 : 1;

        float power = 0;
        float angle = 0;
        if (type == 1) {
    
    
            ran_y = Random.Range(1f, 5f);
            power = Random.Range(4f, 6f);
            angle = Random.Range(25f,30f);
        }
        else if (type == 2) {
    
    
            ran_y = Random.Range(2f, 3f);
            power = Random.Range(5f, 7f);
            angle = Random.Range(15f, 17f);
        }
        else {
    
    
            ran_y = Random.Range(5f, 6f);
            power = Random.Range(6f, 8f);
            angle = Random.Range(10f, 12f);
        }
        disk.transform.position = new Vector3(ran_x*16f, ran_y, 0);
        actionmanager.DiskFly(disk, angle, power*0.2f);
    }
    //检测游戏是否结束
    public void checkstatus(){
    
    
        status=GetScore()>=target[round-1] ? true:false;
    }
    //射击
    public void Hit(Vector3 pos) {
    
    
        Ray ray = Camera.main.ScreenPointToRay(pos);
        RaycastHit[] hits;
        hits = Physics.RaycastAll(ray);
        for (int i = 0; i < hits.Length; i++) {
    
    
            RaycastHit hit = hits[i];
            if (hit.collider.gameObject.GetComponent<Disk>() != null) {
    
    
                scorerecorder.Record(hit.collider.gameObject);
                hit.collider.gameObject.transform.position = new Vector3(0, -10, 0);
            }
        }
    }

    public float GetScore() {
    
    
        return scorerecorder.GetScore();
    }
    public bool GetStatus() {
    
    
        return status;
    }
    public float GetTarget(){
    
    
        return target[round];
    }
    public int GetRound() {
    
    
        return round;
    }
    public bool Getflag() {
    
    
        return ifroundend;
    }
    public int GetTrial() {
    
    
        return num;
    }

    //重新开始
    public void ReStart() {
    
    
        ifrun = true;
        scorerecorder.Reset();
        diskfactory.Reset();
        round = 0;
        num = 1;
        status=true;
    }
    //游戏结束
    public void GameOver() {
    
    
        ifrun = false;
    }
}

演示效果

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/lydsera/article/details/127947044
ufo