切水果 学习
1 using UnityEngine; 2 using System.Collections; 3 4 /// <summary> 5 /// 水果 6 /// </summary> 7 public class FruitDispenser : MonoBehaviour { 8 9 /// <summary> 10 /// 水果预设列表 11 /// </summary> 12 public GameObject[] fruits; 13 /// <summary> 14 /// 炸弹预设 15 /// </summary> 16 public GameObject bomb; 17 18 public float z; 19 20 public float powerScale; 21 22 /// <summary> 23 /// 是否暂停 24 /// </summary> 25 public bool pause = false; 26 /// <summary> 27 /// 是否开始 28 /// </summary> 29 bool started = false; 30 31 /// <summary> 32 /// 每个水果发射的计时 33 /// </summary> 34 public float timer = 1.75f; 35 36 void Start () { 37 38 } 39 40 void Update () { 41 42 if(pause) { 43 return; 44 } 45 46 timer -= Time.deltaTime; 47 48 if (timer <= 0 && !started) 49 { 50 timer = 0f; 51 started = true; 52 } 53 54 //根据等级调整发射水果的时间间隔 55 if (started) 56 { 57 if (SharedSettings.LoadLevel == 0) 58 { 59 if (timer <= 0) 60 { 61 FireUp(); 62 timer = 2.5f; 63 } 64 } 65 else 66 if (SharedSettings.LoadLevel == 1) 67 { 68 if (timer <= 0) 69 { 70 FireUp(); 71 timer = 2.0f; 72 } 73 } 74 else 75 if (SharedSettings.LoadLevel == 2) 76 { 77 if (timer <= 0) 78 { 79 FireUp(); 80 timer = 1.75f; 81 } 82 } 83 else 84 if (SharedSettings.LoadLevel == 3) 85 { 86 if (timer <= 0) 87 { 88 FireUp(); 89 timer = 1.5f; 90 } 91 } 92 } 93 } 94 95 /// <summary> 96 /// 发射 97 /// </summary> 98 void FireUp() 99 { 100 if (pause) return; 101 102 //每次必有的水果 103 Spawn(false); 104 105 if (SharedSettings.LoadLevel == 2 && Random.Range(0, 10) < 2) 106 { 107 Spawn(true); 108 } 109 if(SharedSettings.LoadLevel == 3 && Random.Range(0, 10) < 4) 110 { 111 Spawn(true); 112 } 113 114 //炸弹 115 if (SharedSettings.LoadLevel == 1 && Random.Range(0, 100) < 10) 116 { 117 Spawn(true); 118 } 119 if (SharedSettings.LoadLevel == 2 && Random.Range(0, 100) < 20) 120 { 121 Spawn(true); 122 } 123 if (SharedSettings.LoadLevel == 3 && Random.Range(0 ,100) < 30) 124 { 125 Spawn(true); 126 } 127 } 128 129 /// <summary> 130 /// 发射水果/炸弹 131 /// </summary> 132 void Spawn(bool isBomb) 133 { 134 135 float x = Random.Range(-3.1f, 3.1f); 136 137 z = Random.Range(14f, 19.8f); 138 139 GameObject ins; 140 141 if (!isBomb) 142 ins = Instantiate(fruits[Random.Range(0, fruits.Length)], transform.position + new Vector3(x, 0, z), Random.rotation) as GameObject; 143 else 144 ins = Instantiate(bomb, transform.position + new Vector3(x, 0, z), Random.rotation) as GameObject; 145 146 float power = Random.Range(1.5f, 1.8f) * -Physics.gravity.y * 1.5f * powerScale; 147 Vector3 direction = new Vector3(-x * 0.05f * Random.Range(0.3f, 0.8f), 1, 0); 148 direction.z = 0f; 149 150 ins.GetComponent<Rigidbody>().velocity = direction * power; 151 ins.GetComponent<Rigidbody>().AddTorque(Random.onUnitSphere * 0.1f, ForceMode.Impulse); 152 } 153 154 void OnTriggerEnter(Collider other) 155 { 156 Destroy(other.gameObject); 157 } 158 }
1 using UnityEngine; 2 using System.Collections; 3 using UnityEngine.UI; 4 5 /// <summary> 6 /// GUI管理 7 /// </summary> 8 public class GUIManager : MonoBehaviour { 9 10 /// <summary> 11 /// 剩余点数 12 /// </summary> 13 public Text guiPoints; 14 15 /// <summary> 16 /// 鼠标控制 17 /// </summary> 18 MouseControl mouseControl; 19 20 /// <summary> 21 /// 游戏是否暂停 22 /// </summary> 23 bool gamePause = false; 24 25 /// <summary> 26 /// 暂停按钮文本 27 /// </summary> 28 public Text pauseButtonText; 29 /// <summary> 30 /// 31 /// </summary> 32 public FruitDispenser fd; 33 public Timer timer; 34 35 void Start () { 36 37 mouseControl = GameObject.Find("Game").GetComponent<MouseControl>(); 38 39 } 40 41 void Update () { 42 43 guiPoints.text = "Points: " + mouseControl.points; 44 45 } 46 47 public void Pause() 48 { 49 Rigidbody[] rs = GameObject.FindObjectsOfType<Rigidbody>(); 50 51 gamePause = !gamePause; 52 53 if (gamePause) 54 { 55 foreach(Rigidbody r in rs) 56 { 57 r.Sleep(); 58 pauseButtonText.text = "Resume"; 59 fd.pause = true; 60 timer.PauseTimer(gamePause); 61 } 62 } 63 else 64 { 65 foreach(Rigidbody r in rs) 66 { 67 r.WakeUp(); 68 pauseButtonText.text = "Pause"; 69 fd.pause = false; 70 timer.PauseTimer(gamePause); 71 } 72 } 73 } 74 }
1 using UnityEngine; 2 using System.Collections; 3 4 /// <summary> 5 /// 鼠标控制 6 /// </summary> 7 public class MouseControl : MonoBehaviour { 8 9 /// <summary> 10 /// 屏幕坐标 11 /// </summary> 12 Vector2 screenInp; 13 14 /// <summary> 15 /// 鼠标是否按着 16 /// </summary> 17 bool fire = false; 18 19 bool fire_prev = false; 20 21 /// <summary> 22 /// 鼠标是否按下 23 /// </summary> 24 bool fire_down = false; 25 /// <summary> 26 /// 鼠标是否抬起 27 /// </summary> 28 bool fire_up = false; 29 30 /// <summary> 31 /// 线条渲染器 32 /// </summary> 33 public LineRenderer trail; 34 35 Vector2 start, end; 36 37 Vector3[] trailPositions = new Vector3[10]; 38 39 int index; 40 int linePart = 0; 41 float lineTimer = 1.0f; 42 43 /// <summary> 44 /// 线条透明度 45 /// </summary> 46 float trail_alpha = 0f; 47 int raycastCount = 10; 48 49 //积分 50 public int points; 51 52 bool started = false; 53 54 //果汁效果预制品 55 public GameObject[] splashPrefab; 56 public GameObject[] splashFlatPrefab; 57 58 void Start () { 59 60 } 61 62 void BlowObject(RaycastHit hit) 63 { 64 if (hit.collider.gameObject.tag != "destroyed") 65 { 66 //生成切开的水果的部分 67 hit.collider.gameObject.GetComponent<ObjectKill>().OnKill(); 68 69 //删除切到的水果 70 Destroy(hit.collider.gameObject); 71 72 if (hit.collider.tag == "red") index = 0; 73 if (hit.collider.tag == "yellow") index = 1; 74 if (hit.collider.tag == "green") index = 2; 75 76 //水果泼溅效果 77 if (hit.collider.gameObject.tag != "bomb") 78 { 79 Vector3 splashPoint = hit.point; 80 splashPoint.z = 4; 81 Instantiate(splashPrefab[index], splashPoint, Quaternion.identity); 82 splashPoint.z += 4; 83 Instantiate(splashFlatPrefab[index], splashPoint, Quaternion.identity); 84 } 85 86 //切到炸弹 87 if (hit.collider.gameObject.tag != "bomb") points++; else points -= 5; 88 points = points < 0 ? 0 : points; 89 90 hit.collider.gameObject.tag = "destroyed"; 91 } 92 } 93 94 void Update () { 95 96 Vector2 Mouse; 97 98 screenInp.x = Input.mousePosition.x; 99 screenInp.y = Input.mousePosition.y; 100 101 fire_down = false; 102 fire_up = false; 103 104 fire = Input.GetMouseButton(0); 105 106 if(fire && !fire_prev) { 107 fire_down = true; 108 } 109 if(!fire && fire_prev) { 110 fire_up = true; 111 } 112 fire_prev = fire; 113 114 Control(); 115 116 //设置线段的相应颜色 117 Color c1 = new Color(1, 1, 0, trail_alpha); 118 Color c2 = new Color(1, 0, 0, trail_alpha); 119 trail.SetColors(c1, c2); 120 121 if(trail_alpha > 0) { 122 trail_alpha -= Time.deltaTime; 123 } 124 } 125 126 /// <summary> 127 /// 画线 128 /// </summary> 129 void Control() 130 { 131 //鼠标按下 132 if (fire_down) 133 { 134 trail_alpha = 1.0f; 135 136 start = screenInp; 137 end = screenInp; 138 139 started = true; 140 141 linePart = 0; 142 lineTimer = 0.25f; 143 AddTrailPosition(); 144 } 145 146 //鼠标拖动中 147 if (fire && started) 148 { 149 start = screenInp; 150 151 var a = Camera.main.ScreenToWorldPoint(new Vector3(start.x, start.y, 10)); 152 var b = Camera.main.ScreenToWorldPoint(new Vector3(end.x, end.y, 10)); 153 154 //判断用户的鼠标(触屏)移动大于0.1后,我们认为这是一个有效的移动,就可以进行一次“采样”(sample) 155 if (Vector3.Distance(a, b) > 0.1f) 156 { 157 linePart++; 158 lineTimer = 0.25f; 159 AddTrailPosition(); 160 } 161 162 trail_alpha = 0.75f; 163 164 end = screenInp; 165 } 166 167 //线的alpha值大于0.5的时候,可以做射线检测 168 if (trail_alpha > 0.5f) 169 { 170 for (var p = 0; p < 8; p++) 171 { 172 for (var i = 0; i < raycastCount; i++) 173 { 174 Vector3 s = Camera.main.WorldToScreenPoint(trailPositions[p]); 175 Vector3 e = Camera.main.WorldToScreenPoint(trailPositions[p+1]); 176 Ray ray = Camera.main.ScreenPointToRay(Vector3.Lerp(s, e, i / raycastCount)); 177 178 RaycastHit hit; 179 if (Physics.Raycast(ray, out hit, 100, 1 << LayerMask.NameToLayer("fruit"))) 180 { 181 BlowObject(hit); 182 } 183 } 184 185 } 186 } 187 188 if (trail_alpha <= 0) linePart = 0; 189 190 //根据时间加入一个点 191 lineTimer -= Time.deltaTime; 192 if (lineTimer <= 0f) 193 { 194 linePart++; 195 AddTrailPosition(); 196 lineTimer = 0.01f; 197 } 198 199 if (fire_up && started) started = false; 200 201 //拷贝线段的数据到linerenderer 202 SendTrailPosition(); 203 } 204 205 /// <summary> 206 /// 添加线条位置 207 /// </summary> 208 void AddTrailPosition() 209 { 210 if (linePart <= 9) 211 { 212 for (int i = linePart; i <= 9; i++) 213 { 214 trailPositions[i] = Camera.main.ScreenToWorldPoint(new Vector3(start.x, start.y, 10)); 215 } 216 } 217 else 218 { 219 for (int ii = 0; ii <= 8; ii++) 220 { 221 trailPositions[ii] = trailPositions[ii + 1]; 222 } 223 224 trailPositions[9] = Camera.main.ScreenToWorldPoint(new Vector3(start.x, start.y, 10)); 225 } 226 } 227 228 void SendTrailPosition() 229 { 230 var index = 0; 231 foreach(Vector3 v in trailPositions) 232 { 233 trail.SetPosition(index, v); 234 index++; 235 } 236 } 237 }
1 using UnityEngine; 2 using System.Collections; 3 4 /// <summary> 5 /// 消灭物体 6 /// </summary> 7 public class ObjectKill : MonoBehaviour { 8 9 bool killed = false; 10 11 public GameObject[] prefab; 12 13 public float scale = 1f; 14 15 public void OnKill() 16 { 17 if (killed) return; 18 19 foreach(GameObject go in prefab) 20 { 21 GameObject ins = Instantiate(go, transform.position, Random.rotation) as GameObject; 22 23 Rigidbody rd = ins.GetComponent<Rigidbody>(); 24 if (rd != null) 25 { 26 rd.velocity = Random.onUnitSphere + Vector3.up; 27 rd.AddTorque(Random.onUnitSphere * scale, ForceMode.Impulse); 28 } 29 } 30 31 32 killed = true; 33 } 34 }
1 using UnityEngine; 2 using System.Collections; 3 4 /// <summary> 5 /// 销毁粒子 6 /// </summary> 7 public class ParticleDestroy:MonoBehaviour { 8 9 /// <summary> 10 /// 粒子系统 11 /// </summary> 12 private ParticleSystem ps; 13 14 void Start() { 15 ps = GetComponent<ParticleSystem>(); 16 Destroy(gameObject,ps.startLifetime + 0.5f); 17 } 18 }
1 using UnityEngine; 2 using System.Collections; 3 using UnityEngine.UI; 4 5 /// <summary> 6 /// 关卡准备阶段 7 /// </summary> 8 public class PrepareLevel:MonoBehaviour { 9 10 /// <summary> 11 /// Ready文本 12 /// </summary> 13 public GameObject GetReady; 14 /// <summary> 15 /// Go文本 16 /// </summary> 17 public GameObject GO; 18 19 void Awake() { 20 GetComponent<Timer>().timeAvailable = SharedSettings.ConfigTime; 21 } 22 23 void Start() { 24 25 GameObject.Find("GUI/LevelName/LevelName").GetComponent<Text>().text = SharedSettings.LevelName[SharedSettings.LoadLevel]; 26 StartCoroutine(PrepareRoutine()); 27 28 } 29 30 /// <summary> 31 /// 准备协程 32 /// </summary> 33 IEnumerator PrepareRoutine() { 34 //等待1秒 35 yield return new WaitForSeconds(1.0f); 36 37 //显示GetReady 38 GetReady.SetActive(true); 39 40 //等待2秒 41 yield return new WaitForSeconds(2.0f); 42 GetReady.SetActive(false); 43 44 GO.SetActive(true); 45 46 yield return new WaitForSeconds(1.0f); 47 GO.SetActive(false); 48 } 49 }
1 using UnityEngine; 2 using System.Collections; 3 4 /// <summary> 5 /// 共享设置 6 /// </summary> 7 public class SharedSettings:MonoBehaviour { 8 9 /// <summary> 10 /// 计时器剩余时间 11 /// </summary> 12 public static int ConfigTime = 60; 13 14 /// <summary> 15 /// 游戏难度 16 /// </summary> 17 public static int LoadLevel = 2; 18 19 20 /// <summary> 21 /// 游戏难度名称 22 /// </summary> 23 public static string[] LevelName = new string[] { "Easy","Medium","Hard","Extreme" }; 24 25 }
1 using UnityEngine; 2 using System.Collections; 3 using UnityEngine.UI; 4 5 /// <summary> 6 /// 文本淡出 7 /// </summary> 8 public class TextFadeOut : MonoBehaviour { 9 10 /// <summary> 11 /// 淡出速度 12 /// </summary> 13 public float speed = 0.5f; 14 15 Color color; 16 17 void Start () { 18 19 color = GetComponent<Text>().color; 20 21 } 22 23 void Update () { 24 25 if (gameObject.activeSelf) 26 { 27 color.a -= Time.deltaTime * speed; 28 GetComponent<Text>().color = color; 29 } 30 31 } 32 }
1 using UnityEngine; 2 using System.Collections; 3 using UnityEngine.UI; 4 5 /// <summary> 6 /// 计时器 7 /// </summary> 8 public class Timer:MonoBehaviour { 9 10 /// <summary> 11 /// 是否在运行 12 /// </summary> 13 bool run = false; 14 /// <summary> 15 /// 是否显示剩余时间 16 /// </summary> 17 bool showTimeLeft = true; 18 /// <summary> 19 /// 计时是否结束 20 /// </summary> 21 bool timeEnd = false; 22 23 /// <summary> 24 /// 起始时间 25 /// </summary> 26 float startTime = 0.0f; 27 /// <summary> 28 /// 当前时间 29 /// </summary> 30 float curTime = 0.0f; 31 32 /// <summary> 33 /// 当前时间字符串 34 /// </summary> 35 string curStrTime = string.Empty; 36 37 /// <summary> 38 /// 是否暂停 39 /// </summary> 40 bool pause = false; 41 42 /// <summary> 43 /// 剩余时间 44 /// </summary> 45 public float timeAvailable = 30f; 46 /// <summary> 47 /// 显示在文本的剩余时间 48 /// </summary> 49 float showTime = 0; 50 51 public Text guiTimer; 52 public GameObject finishedUI; 53 54 void Start() { 55 RunTimer(); 56 } 57 58 /// <summary> 59 /// 运行计时器 60 /// </summary> 61 public void RunTimer() { 62 run = true; 63 64 startTime = Time.time; 65 } 66 67 /// <summary> 68 /// 暂停计时器 69 /// </summary> 70 public void PauseTimer(bool b) { 71 pause = b; 72 } 73 74 public void EndTimer() { 75 76 } 77 78 void Update() { 79 //如果暂停 80 if(pause) { 81 //将起始时间加上每帧持续的时间 82 startTime = startTime + Time.deltaTime; 83 return; 84 } 85 86 //如果运行 87 if(run) { 88 89 curTime = Time.time - startTime; 90 } 91 92 if(showTimeLeft) { 93 showTime = timeAvailable - curTime; 94 if(showTime <= 0) { 95 timeEnd = true; 96 showTime = 0; 97 98 //弹出UI界面,告诉用户本轮游戏结束。 99 //暂停/停止游戏 100 finishedUI.SetActive(true); 101 } 102 } 103 104 int minutes = (int)(showTime / 60); 105 int seconds = (int)(showTime % 60); 106 int fraction = (int)((showTime * 100) % 100); 107 108 curStrTime = string.Format("{0:00}:{1:00}:{2:00}",minutes,seconds,fraction); 109 guiTimer.text = "Time: " + curStrTime; 110 111 } 112 }
视频:https://pan.baidu.com/s/1geAqJTL
项目:https://pan.baidu.com/s/1mhUzJyo