开源移动小游戏项目《FlappyBird》学习心得

少年乘勇气,百战过乌孙。这篇文章主要讲述开源移动小游戏项目《FlappyBird》学习心得相关的知识,希望能为你提供帮助。

开源移动小游戏项目《FlappyBird》学习心得

文章图片

游戏设计思路: 场景关卡:
  • 地图中会随机生成一个又一个的管道,每一个管道由上下管道组成,中间的空隙是固定的,每条管道的生成时间是随机的,所以它们之间的间距不一样
    开源移动小游戏项目《FlappyBird》学习心得

    文章图片
玩法:
  • 点击屏幕,小鸟便会被施加一个向上的速度,该速度随重力会逐渐减少。
  • 每当小鸟越过一个管道时,得分加1,当小鸟碰到地图上的管道或者掉入地面时,游戏结束。
  • 游戏中的得分没有上限
    开源移动小游戏项目《FlappyBird》学习心得

    文章图片
技术实现: GameState:用脚本写一个枚举类GmaeState,表明游戏的三个场景状态
public enum GameState { Intro, Playing, Dead }public static class GameStateManager { public static GameState GameState { get; set; }static GameStateManager () { GameState = GameState.Intro; } }

摄像机和场景:摄像机作为父物体,他的子物体如下:
开源移动小游戏项目《FlappyBird》学习心得

文章图片

分别是:background背景,Spawnerobject管道物体,Floor地板,Pipedestroy管道销毁模板,ceiling天花板,IntroGUI开始界面UI,Score得分计数,DeathGUI死亡时UI图标
摄像机:
非常简单,只需要每帧向右移动0.5即可,
void Start () { cameraZ = transform.position.z; }float cameraZ; void Update () { transform.position = new Vector3(Player.position.x + 0.5f, 0, cameraZ); }public Transform Player; }

Spawnerobject管道物体:
  • 定义了一个数组:里面有两个管道prefab,当游戏开始或结束重新开始时,会随机选择一个管道:
    开源移动小游戏项目《FlappyBird》学习心得

    文章图片

  • 【开源移动小游戏项目《FlappyBird》学习心得】管道物件是固定好的,每次生成只需调整它的y轴即可,y轴数值随机生成
  • 每隔一段随机的时间,在小鸟前面生成管道
void Start() { SpawnObject = SpawnObjects[Random.Range(0, SpawnObjects.Length)]; Spawn(); }void Spawn() { if (GameStateManager.GameState == GameState.Playing) { //random y position float y = Random.Range(-0.5f, 1f); GameObject go = Instantiate(SpawnObject, this.transform.position + new Vector3(0, y, 0), Quaternion.identity) as GameObject; } Invoke(" Spawn" , Random.Range(timeMin, timeMax)); }private GameObject SpawnObject; public GameObject[] SpawnObjects; public float timeMin = 0.7f; public float timeMax = 2f; }

Floor地板:
游戏开始时,小鸟和相机绑定在一起,不断先前移动,为了实现一个小鸟一直往前飞的效果,此时地板只需不动就好
但地板的长度有限,所以要让它不断的向前刷新位置。
void Update() { if (transform.localPosition.x < -3.9f) { transform.localPosition = new Vector3(0, transform.localPosition.y, transform.localPosition.z); } transform.Translate(-Time.deltaTime, 0, 0); } }

Pipedestroy管道销毁模板:
每当管道触碰到它时,就销毁
ceiling天花板:
小鸟的飞行高度上限,防止飞出屏幕外
IntroGUI开始界面UI:
几张spite的简单UI
DeathGUI死亡时UI图标:
同上;
Score得分计数:
使用Sprite[] numberSprites数组来根据得分情况调用相应的spite图片;
void Start () { (Tens.gameObject as GameObject).SetActive(false); (Hundreds.gameObject as GameObject).SetActive(false); } // Update is called once per frame void Update () {if (previousScore != Score) //save perf from non needed calculations { if(Score < 10) { //just draw units Units.sprite = numberSprites[Score]; } else if(Score > = 10 & & Score < 100) { (Tens.gameObject as GameObject).SetActive(true); Tens.sprite = numberSprites[Score / 10]; Units.sprite = numberSprites[Score % 10]; } else if(Score > = 100) { (Hundreds.gameObject as GameObject).SetActive(true); Hundreds.sprite = numberSprites[Score / 100]; int rest = Score % 100; Tens.sprite = numberSprites[rest / 10]; Units.sprite = numberSprites[rest % 10]; } } }int previousScore = -1; public Sprite[] numberSprites; public SpriteRenderer Units, Tens, Hundreds; }

主角小鸟:
  • 屏幕点击,开始游戏。游戏中点击屏幕,小鸟向上飞跃,并触发音效
  • 小鸟越过管道,加分并触发加分音效
  • 小鸟碰到地板和管道,触发死亡和死亡音效
  • 小鸟恒定移动速度、向上飞跃速度、坠落速度的设置,飞跃时的角度修正
public class FlappyScript : MonoBehaviour {public AudioClip FlyAudioClip, DeathAudioClip, ScoredAudioClip; public Sprite GetReadySprite; public float RotateUpSpeed = 1, RotateDownSpeed = 1; public GameObject IntroGUI, DeathGUI; public Collider2D restartButtonGameCollider; public float VelocityPerJump = 3; public float XSpeed = 1; // Use this for initialization void Start() {}FlappyYAxisTravelState flappyYAxisTravelState; enum FlappyYAxisTravelState { GoingUp, GoingDown }Vector3 birdRotation = Vector3.zero; // Update is called once per frame void Update()//每帧侦测屏幕的点击状态 { //handle back key in Windows Phone if (Input.GetKeyDown(KeyCode.Escape)) Application.Quit(); if (GameStateManager.GameState == GameState.Intro) { MoveBirdOnXAxis(); if (WasTouchedOrClicked()) { BoostOnYAxis(); GameStateManager.GameState = GameState.Playing; IntroGUI.SetActive(false); ScoreManagerScript.Score = 0; } }else if (GameStateManager.GameState == GameState.Playing) { MoveBirdOnXAxis(); if (WasTouchedOrClicked()) { BoostOnYAxis(); }}else if (GameStateManager.GameState == GameState.Dead) { Vector2 contactPoint = Vector2.zero; if (Input.touchCount > 0) contactPoint = Input.touches[0].position; if (Input.GetMouseButtonDown(0)) contactPoint = Input.mousePosition; //check if user wants to restart the game if (restartButtonGameCollider == Physics2D.OverlapPoint (Camera.main.ScreenToWorldPoint(contactPoint))) { GameStateManager.GameState = GameState.Intro; Application.LoadLevel(Application.loadedLevelName); } }}void FixedUpdate() { //just jump up and down on intro screen if (GameStateManager.GameState == GameState.Intro) { if (GetComponent< Rigidbody2D> ().velocity.y < -1) //when the speed drops, give a boost GetComponent< Rigidbody2D> ().AddForce(new Vector2(0, GetComponent< Rigidbody2D> ().mass * 5500 * Time.deltaTime)); //调整开始界面小鸟的飞行状态} else if (GameStateManager.GameState == GameState.Playing || GameStateManager.GameState == GameState.Dead) { FixFlappyRotation(); // 角度修正 } }bool WasTouchedOrClicked() { if (Input.GetButtonUp(" Jump" ) || Input.GetMouseButtonDown(0) || (Input.touchCount > 0 & & Input.touches[0].phase == TouchPhase.Ended)) return true; else return false; }void MoveBirdOnXAxis() { transform.position += new Vector3(Time.deltaTime * XSpeed, 0, 0); }void BoostOnYAxis() { GetComponent< Rigidbody2D> ().velocity = new Vector2(0, VelocityPerJump); GetComponent< Audiosource> ().PlayOneShot(FlyAudioClip); }/// < summary> /// when the flappy goes up, it‘ll rotate up to 45 degrees. when it falls, rotation will be -90 degrees min /// < /summary> private void FixFlappyRotation() { if (GetComponent< Rigidbody2D> ().velocity.y > 0) flappyYAxisTravelState = FlappyYAxisTravelState.GoingUp; else flappyYAxisTravelState = FlappyYAxisTravelState.GoingDown; float degreesToAdd = 0; switch (flappyYAxisTravelState)//根据小鸟的状态,来选择相应的角度计算数值 { case FlappyYAxisTravelState.GoingUp: degreesToAdd = 6 * RotateUpSpeed; break; case FlappyYAxisTravelState.GoingDown: degreesToAdd = -3 * RotateDownSpeed; break; default: break; } //solution with negative eulerAngles found here: http://answers.unity3d.com/questions/445191/negative-eular-angles.html//clamp the values so that -90< rotation< 45 *always* birdRotation = new Vector3(0, 0, Mathf.Clamp(birdRotation.z + degreesToAdd, -90, 45)); //生成新的方向 transform.eulerAngles = birdRotation; //根据方向生成新的角度 }/// < summary> /// check for collision with pipes /// < /summary> /// < param name=" col" > < /param> void OnTriggerEnter2D(Collider2D col) { if (GameStateManager.GameState == GameState.Playing)//如果游戏开始 { if (col.gameObject.tag == " Pipeblank" ) //pipeblank is an empty gameobject with a collider between the two pipes如果 { GetComponent< AudioSource> ().PlayOneShot(ScoredAudioClip); ScoreManagerScript.Score++; } else if (col.gameObject.tag == " Pipe" )//col的 { FlappyDies(); } } }void OnCollisionEnter2D(Collision2D col) { if (GameStateManager.GameState == GameState.Playing) { if (col.gameObject.tag == " Floor" )//小鸟触发到了地板 { FlappyDies(); } } }void FlappyDies()//小鸟死亡 { GameStateManager.GameState = GameState.Dead; DeathGUI.SetActive(true); //使用死亡UI GetComponent< AudioSource> ().PlayOneShot(DeathAudioClip); //使用死亡音效 }}








    推荐阅读