美文网首页
Unity3D开发实战之守护森林

Unity3D开发实战之守护森林

作者: TonyWan_AR | 来源:发表于2016-12-30 10:36 被阅读138次

框架视图

守护森林.png

关键代码

Bird

public class Bird : MonoBehaviour
{

    //控制材料中的贴图状态 要知道计时器 每秒总帧数 帧数计算器

    //定义计时器变量

    public float timer = 0;

    //定义帧数量 也就是每秒钟要显示帧数;

    public int frameNumber = 10;

    //定义帧数计数器

    public int frameCount = 0;


    //定义两个变量 是否播放动画 是否控制跳跃;
    public bool animation = false;
    public bool canJump = false;

    void Start()
    {

        //添加刚体组件

        //给刚体施加一个向右的力(速度)
        // gameObject.GetComponent<Rigidbody>().velocity = new Vector3(5,0,0);
        //  gameObject.GetComponent<Rigidbody>().velocity = new Vector3(2, 0, 0);
        //第二种加力的方法;
        // gameObject.GetComponent<Rigidbody>().AddForce(Vector3.right*50,ForceMode.Force);

    }


    void Update()
    {

        //判断是否是可以播放动画的时候
        //if (animation)
        //{
        if (GameMannger._intance.gameState ==GameMannger.GAMESTATE_PLAYING)
        {
            //给一个恒定的速度,测试之用
            //Vector3 vel = gameObject.GetComponent<Rigidbody>().velocity;
            //gameObject.GetComponent<Rigidbody>().velocity = new Vector3(5, vel.y, vel.z);
            //计时
            timer += Time.deltaTime;

            //如果时间超过每秒钟显示的总帧数 帧数++;时间重新归零 
            if (timer >= 1.0f / frameNumber)
            {
                //帧数++;
                frameCount++;
                // timer -= Time.deltaTime ;
                timer -= Time.deltaTime + 0.05f;  //加个时间让她抖动的慢点

                //定义每帧的下标;取余  framrcount++  1/3取余是1 2/3取余是2 3/3取余是0 4/3 取余是1 5/3取余是2 6/3取余是0 或者理解理解成0,1,2,0,1,2...
                int frameIndex = frameCount % 3;
                //更新材质的 偏移值 X;
                //怎样去设置这个偏移值 X 的属性呢?
                //获取本游戏对象下的 渲染组件 的 材质(材质复数时是数组)的设置 贴图偏移值 x

                gameObject.GetComponent<Renderer>().material.SetTextureOffset("_MainTex", new Vector2(0.3333f * frameIndex, 0));//参数1:表示本材质的主要贴图(着色器的主要贴图),参数2:要改变的二维向量;

            }
        }

        //判断是否跳跃的时候才可以跳跃
        //if (canJump)
        //{

        if (GameMannger._intance.gameState == GameMannger.GAMESTATE_PLAYING)
        {
            //判断点击鼠标 给一个向上的速度 向上跳跃

            if (Input.GetMouseButtonDown(0))
            {
                //添加声音后按下跳跃时播放扇动翅膀的声音
                gameObject.GetComponent<AudioSource>().Play();

                //获取当前的速度;
                Vector3 vel2 = gameObject.GetComponent<Rigidbody>().velocity;
                //给y轴向上的速度;

                gameObject.GetComponent<Rigidbody>().velocity = new Vector3(vel2.x, 5.0f, vel2.z);

            }
        }

    }


    /// <summary>
    /// 激活小鸟的方法 用来发送方法来调用的;
    /// </summary>
    public void getLife() {        
        gameObject.GetComponent<Rigidbody>().useGravity = true; 
        gameObject.GetComponent<Rigidbody>().velocity = new Vector3(2,0,0);
    
    }

    /// <summary>
    ///     接触地面后 加大阻力 不让小鸟再次滚动;
    /// </summary>
    /// <param name="coll"></param>
    void OnCollisionEnter(Collision coll) {


      //  Debug.Log(coll.gameObject.name);

        if (coll.gameObject.name == "back")
        {
            //this.gameObject.GetComponent<Rigidbody>().velocity = new Vector3(0, 0, 0);
            this.gameObject.GetComponent<Rigidbody>().drag = 1000f;
            this.gameObject.GetComponent<Rigidbody>().angularDrag = 1000f;

           // Debug.Log(this.gameObject.name);
        }
    
    }
}

FollowBird

public class FollowBird : MonoBehaviour {

    //跟随相机
    //定义一个游戏对象用来寻找小鸟的
    private GameObject bird;

    //为跟随位置定义好的变量
    private Transform birdTransform;

    //定义好一个偏移值的变量;
    Vector3 offset;

    void Start () {

        //寻找游戏对象 小鸟 并且赋值;
        bird = GameObject.FindGameObjectWithTag("Player");//gameobject是单数,不是复数;
        birdTransform = bird.transform;
        //计算偏移值;
         offset = gameObject.GetComponent<Transform>().position - birdTransform.position;   
    }
    

    void Update () {

        Vector3 birdPos = birdTransform.position;

        //判断不要将摄像机超出边界;
        if (birdPos.y>5f)//上界
        {
            birdPos.y = 5f;
        }

        if (birdPos.y<2.5f)
        {
            birdPos.y =2.5f;
        }

        //相机位置跟随 不断补偿偏移值;
       // gameObject.GetComponent<Transform>().position = birdTransform.position + offset;
        gameObject.GetComponent<Transform>().position = birdPos + offset;

    }
}

GameMannger

public class GameMannger : MonoBehaviour {
    
    
    //定义游戏的状态;
    public static int GAMESTATE_MENU = 0;
    public static int GAMESTATE_PLAYING = 1;
    public static int GAMESTATE_END = 2;
    //只有3个背景图,不断循环 进入背景2 的时候 把背景1移到背景3 中去

    public Transform firstBG;


    //每个管道口设置一个触发器,闯过一个得一分;
    
    //定义一个分数的变量;
    public int score=0;
    
    //定义一个游戏状态
    public int gameState = GAMESTATE_MENU;

    //定义一个鸟的游戏对象 并在初始化时赋值
    private GameObject bird;


    //单例模式

    public static GameMannger _intance;

    void Awake() {
        _intance = this;   //单例模式模板 得到的是gamemannger类型;
        //给鸟赋值;
        bird = GameObject.FindGameObjectWithTag("Player");
    }


    void Update() { 
    
        //判断当前的游戏状态;
        if (gameState==GAMESTATE_MENU)
        {
            //判断是否点击屏幕
            if (Input.GetMouseButtonDown(0))
            {
                //设置游戏的状态
                gameState = GAMESTATE_PLAYING;              
                //播放动画 和 是否能跳跃 对鸟设置重力
                //bird.GetComponent<Rigidbody>().useGravity = true;              
                ////添加X轴方向的力;
                //bird.GetComponent<Rigidbody>().velocity = new Vector3(1,0,0);
                //综上 我们可以封装成一个方法 在此调用方法时 发送一个方法名;
                bird.SendMessage("getLife");
            }
        }


        //判断游戏是结束状态,把结束界面显示出来;
        if (gameState == GAMESTATE_END)
        {
            GameMenu._instance.gameObject.SetActive(true);//参数设置为true;
            //把分数转递给结束的界面 显示最后得分
            GameMenu._instance.UpdateScore(score);
        }   
    }
}

GameMenu

using UnityEngine;
using System.Collections;
using UnityEngine.SceneManagement;
public class GameMenu : MonoBehaviour {
    //声明持有两个分数引用的变量;
    public GUIText bestScore;
    public GUIText nowScore;
    //声明持有重新开始的游戏贴图;
    public GUITexture startTexture;

    //单例模式
    public static GameMenu _instance;

    void Awake()
    {
        _instance = this;
        this.gameObject.SetActive(false);  //默认是不调用的;
    }



    //更新分数的方法 公开的 才可以调用
    public void UpdateScore(float currentScore)
    {
        //用来获取最高分数的关键词 piayerprefs;
        float highScore = PlayerPrefs.GetFloat("score", 0);//参数1:通过key关键词 score查找最高分数  参数2:默认是0;因为第一次没有最高分数,默认值设置为0;


        //判断一下 现在传过来的分数跟最高分数对比,更新下最高分;
        if (highScore < currentScore)
        {
            highScore = currentScore;
        }


        //用来保存最高分数的关键词 PlayerPrefs;
        PlayerPrefs.SetFloat("score", highScore);



        //将分数显示出来;
        bestScore.text = highScore.ToString();
        nowScore.text = currentScore.ToString();
        //这个方法会被GameMannger调用

        //判断结束界面之后重新开始;
        //首先判断鼠标点下和游戏处于结束状态
        if (Input.GetMouseButtonDown(0)&&GameMannger._intance.gameState==GameMannger.GAMESTATE_END)
        {
            //获取重新开始游戏贴图的位置 关键语句 GetScreenRect()
            Rect rect = startTexture.GetScreenRect();

            //再次判断点击的位置是否在区域范围内;
            //先获取鼠标的位置
            Vector3 mousePos=Input.mousePosition;

            //判断鼠标点击的范围
            if (mousePos.x>rect.x&&
                mousePos.x<(rect.x+rect.width)&&
                mousePos.y>rect.y&&
                mousePos.y<(rect.y+rect.height)
                )
            {
                ////改变游戏状态;
                //GameMannger._intance.gameState = GameMannger.GAMESTATE_PLAYING;
                ////隐藏本界面
                //this.gameObject.SetActive(false);  //默认是不调用的;
                //重新加载场景
                SceneManager.LoadScene(0);
            }
        }
    }
}

MoveTrigger

public class MoveTrigger : MonoBehaviour {
    //定义一个公开的背景
    public Transform currentBG;
    //定义持有两个管道的应用
    public Pipe pipe1;
    public Pipe pipe2;
    //触发事件 看谁触发了我,判断后 将背景1 移到背景2去

   public  void OnTriggerEnter(Collider coll) {

        if (coll.tag=="Player")
        {
            //第一步 得到放在游戏管理器的第一个bg的Transform;
         Transform firstBg=GameMannger._intance.firstBG;
            //第二步  移动; 改变位置;
         currentBG.transform.position = new Vector3(firstBg.position.x+10f,currentBG.transform.position.y,currentBG.transform.position.z);
            //第三部 把背景图更新为当前的位置;
         GameMannger._intance.firstBG = currentBG;            
            //第四步 随机生成管道的位置;
           //定义 持有管道的引用 调用起方法生成随机位置;
         pipe1.RandomGeneratePosition();
         pipe2.RandomGeneratePosition();
        }    
    }
}

Pipe

public class Pipe : MonoBehaviour { 
    void Start () { 
        //测试是否随机;
        RandomGeneratePosition();
    }
    /// <summary>
    /// 让Y轴的位置随机 随机范围是-0.1至-0.4;
    /// </summary>
    public void RandomGeneratePosition() {
        float pos_Y = Random.Range(-0.4f,-0.1f);  //参数1:最小值 参数2:最大值;
        //本地坐标
        gameObject.transform.localPosition = new Vector3(gameObject.transform.localPosition.x,pos_Y,gameObject.transform.position.z);    
    }

    /// <summary>
    /// 判断是否通过管道,加一分
    /// </summary>
    void OnTriggerExit(Collider coll) { //触犯3 个事件  OnTriggerEnter OnTriggerStay OnTriggerExit

        if (coll.tag=="Player")
        {
            //播放得分声音
            gameObject.GetComponent<AudioSource>().Play();

            //加分 调用单例模式静态的方法 的分数++
            GameMannger._intance.score++;
        }
    
    }

    /// <summary>
    /// ongui事件
    /// </summary>
    void OnGUI() { 
        //显示分数;
       // GUILayout.Label(GameMannger._intance.score.ToString());
        GUILayout.Label("Score:"+GameMannger._intance.score);
    }

}

PipeCollision

public class PipeCollision : MonoBehaviour {
    //定义两个 碰撞的声音 小鸟结束的声音 的变量
    public AudioSource hitMusic;
    public AudioSource dieMusic;

    /// <summary>
    /// 检测小鸟碰撞到管道,游戏结束 在结束前播放碰撞的声音
    /// </summary>
    void OnCollisionEnter(Collision coll)
    {

        if (coll.gameObject.tag == "Player")
        {
            //播放碰撞的声音
            //gameObject.GetComponent<AudioSource>().Play();
            hitMusic.Play();
            //播放小鸟结束的声音
            dieMusic.Play();
            //切换游戏状态
            GameMannger._intance.gameState = GameMannger.GAMESTATE_END;
        }

    }
}

守护森林.gif

相关文章

网友评论

      本文标题:Unity3D开发实战之守护森林

      本文链接:https://www.haomeiwen.com/subject/vkhmvttx.html