[unity]实现切水果游戏

来源:互联网 发布:php xpath 抓取内容 编辑:程序博客网 时间:2024/04/30 08:27

初学unity, 通过查阅资料以及自己的一些见解完成了自己做的第一款游戏.
现在把代码分享出来, 仅供参考,不足之处还请指正。

游戏中有三个场景,主要用到六个c#脚本:

脚本 作用 buttonClick.cs 控制游戏中所有的按钮 appearFruits.cs 控制所有水果出现 cutFruit.cs 判断水果被切以及产生其他对象 knife.cs 控制切水果的的刀痕轨迹 scoreManager.cs 控制分数面板的脚本 healthManager.cs 控制玩家的生命值

场景介绍:
StartScence:
StartPage
PlayScence:
PlayScence
OverScence:
OverScence


接下来开始逐个介绍脚本:

一. buttonClick.cs

该脚本需要控制游戏中所有的按钮,其中包括:
1. 场景跳转的按钮
2. 控制音乐播放的按钮

按钮通过NGUI的OnClick()函数触发的:

代码:

using UnityEngine;using System.Collections;public class ButtonClick : MonoBehaviour {    public Sprite png1, png2;    // 静音时的贴图,与播放时的贴图     private SpriteRenderer spr;    private bool flag;           //flag判断是否播放音乐    private AudioSource bgm;         void Start()    {        spr = GetComponent<SpriteRenderer>();        bgm = GetComponent<AudioSource>();        flag = true;    }    void OnClick()                   //通过按钮Gameobject的名字判断是哪个按钮被点击    {        if (name == "playScence")                 //play按钮切换到开始场景              Application.LoadLevel("play");        else if (name == "sound")       //音量按钮只需切换 SpriteRenderer组件中的贴图即可        {            if (flag)            {                spr.sprite = png2;                bgm.Stop();            }            else            {                bgm.Play();                spr.sprite = png1;            }            flag = !flag;        }        else if (name == "main")                           //回主界面按钮            Application.LoadLevel("StartScence");            else            Application.OpenURL("http://blog.csdn.net/axuan_k");    }}

play按钮用到的组件
图为play按钮用到的组件

二. appearFruits.cs

控制游戏中所有水果从游戏下方以抛物线的形式出现;
关键是要准备好需要用到的预制对象(各种水果) ,并添加到脚本上

代码:

using UnityEngine;using System.Collections;public class appearFruits : MonoBehaviour {    public GameObject[] fruits;           //水果预制对象数组                private static  float interval;       //出现水果的间隔时间    private float time;    void Start () {        interval = 0.9f;        InvokeRepeating("Create", interval, interval);         //重复隔interval时间出现一个水果    }    void Create()    {        float y = -5.75f;        float x = Random.Range(-6.5f, 6.5f);              //随机水果出现的x坐标        GameObject fruit = Instantiate(fruits[Random.Range(0, fruits.Length)]) as GameObject;   //实例化        fruit.transform.position = new Vector3(x, y, 0);        //根据x坐标决定 水果飞行的 带方向初始速度范围        float xSpeed = 0f;        if (x <= -3f)            xSpeed = Random.Range(2f, 4f);        else if (x < 3f)            xSpeed = Random.Range(-1f, 1f);        else            xSpeed = Random.Range(-4f, -2f);        fruit.GetComponent<Rigidbody2D>().velocity = new Vector2(xSpeed, 14f);           //通过Rigidbody2D组件给水果一个初始速度    }    /*    void Create()    {        GameObject obj = Instantiate(fruit[Random.Range(0, fruit.Length)], transform.position, Quaternion.AngleAxis(Random.Range(-30f, 30f), Vector3.back)) as GameObject;        Rigidbody2D rgd = obj.GetComponent<Rigidbody2D>();               //得到新生成苹果的rigidbody 来给它一个速度        rgd.velocity = Vector2.left * Random.Range(-10f, 10f);        Destroy(obj, 2f);    }    */}

三.cutFruit.cs

这个脚本需要添加到每一种水果的预制对象上面
处理的逻辑包括:
1. 判断水果是否被切中
2. 产生水果碎片 以及背景污渍
3. 出界面自动销毁
4. 向scoreManager.cs脚本中的函数传递切中加减分的信息

代码:

using UnityEngine;using System.Collections;public class CutFruit : MonoBehaviour {    public GameObject obj1, obj2;    //分开后的两边水果    public GameObject[] wz;          //几种污渍背景    private BoxCollider2D col;    private Vector2[] vec = { Vector2.left, Vector2.right };   //切后的半截往两个方向飞出    private GameObject scores;     //放置scoreManager.cs和healthManager.cs脚本的游戏对象    void Start()    {        col = GetComponent<BoxCollider2D>();        scores = GameObject.Find("score1");    }    private void CreateHalf(GameObject obj, int index)       //创建半个水果    {        obj = Instantiate(obj, transform.position, Quaternion.AngleAxis(Random.Range(-30f, 30f), Vector3.back)) as GameObject;        Rigidbody2D rgd = obj.GetComponent<Rigidbody2D>();        float v = Random.Range(2f, 4f);                        //随机飞出速度        rgd.velocity = vec[index] * v;        Destroy(obj, 2f);    }    private void Createwz()              //切开水果随机创建污渍    {        if (wz.Length == 0)              //仓鼠没有水果污渍            return;        GameObject obj = Instantiate(wz[Random.Range(0,wz.Length)], transform.position, Quaternion.AngleAxis(Random.Range(-30f, 30f), Vector3.back)) as GameObject;        Destroy(obj, 1f);    }    void Update () {        if (Input.GetMouseButton(0))        {            if (col.OverlapPoint(Camera.main.ScreenToWorldPoint(Input.mousePosition)))                //鼠标在当前水果2Dcollider内            {                if (name == "jpg0(Clone)")                //金苹果+20分                    scores.SendMessage("setScore", 20);                else if (name != "cs(Clone)")              //非仓鼠+1分                    scores.SendMessage("setScore", 1);                else                                     //切开仓鼠扣血                    scores.SendMessage("cutOne");                CreateHalf(obj1, 0);                CreateHalf(obj2, 1);                Createwz();                Destroy(this.gameObject);            }        }        else if (this.transform.position.y <= -6f)         //水果掉落到范围外扣分自动销毁        {            scores.SendMessage("setScore", -1);            Destroy(this.gameObject);        }    }}

水果对象的组件以及用到的prefab
图为各种需要用到的预制对象prefab以及组件component

四.knife.cs

打印出刀痕轨迹的脚本;
为了实现折线的刀痕, 这里我用到了LineRenderer组件, 每隔固定时间记录鼠标所在的坐标从而完成对刀痕的渲染

代码:

using UnityEngine;using System.Collections;public class knife : MonoBehaviour {    private LineRenderer myLinRenderer;     //该游戏对象的LineRenderer组件    private int count;           //LineRenderer中position的数量    private  static float timeInterval;     //每隔interval时间记录一次鼠标的坐标    private float time;    // Use this for initialization    void Start()    {        count = 0;        timeInterval = 0.3f;        myLinRenderer = GetComponent<LineRenderer>();       }    // Update is called once per frame    void addline()    {        Vector3 pos = Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y, 1));    //切换到世界坐标系        myLinRenderer.SetVertexCount(++count);                              myLinRenderer.SetPosition(count - 1, pos);        if(count==5)                                                 //清除刀痕 保证刀痕不能一直存在 无限延长            myLinRenderer.SetVertexCount(count = 0);    }    void Update()    {        if (Input.GetMouseButtonDown(0))      //当鼠标左键按下的时候记录第一个点        {            myLinRenderer.SetVertexCount(count = 0);               //先清除之前未清除的刀痕            GetComponent<AudioSource>().Play();            time = timeInterval;            addline();        }        else if (Input.GetMouseButton(0))          //鼠标按下时每隔interval秒记录一个点        {            time -= Time.deltaTime;            if (time <= 0)            {                addline();                time = timeInterval;            }        }        else if (Input.GetMouseButtonUp(0))           //松开鼠标记录linerenderer的最后一个点        {            addline();            time = timeInterval;                   //松开后interval秒清除刀痕        }        else        {            time -= Time.deltaTime;                //松开后interval秒清除刀痕            if (time <= 0)                myLinRenderer.SetVertexCount(count = 0);        }    }}

刀痕与组件
图为刀痕与组件

五. scoreManager.cs

准备好实例化数字需要的预制对象,再用一个贴图数组保存所有数字的贴图.
每收到一次分数变更消息, 销毁之前存在的分数, 逐个创建新的数字对象贴上对应的图片即可

代码:

using UnityEngine;using System.Collections;public class ScoreManager : MonoBehaviour{    public GameObject DObj;              //所有数字对应的  预制对象(tag需要手动添加并更改为score,方便下面销毁)    public Sprite[] Digits;           //每个数字对应的贴纸    private int score;    // Use this for initialization    void Start()    {        score = 0;        setScore(score);    }    void setScore(int newScore)    {        //先删除已存在的数字        GameObject[] objs = GameObject.FindGameObjectsWithTag("score");                      foreach (GameObject i in objs)            Destroy(i);        score += newScore;        score = score<0?0:score;            //保证不出现负分        string str = score.ToString();        int cnt = 0;        //逐个数字实例化预制对象        foreach(char ch in str)        {            GameObject dobj = Instantiate(DObj) as GameObject;            dobj.GetComponent<SpriteRenderer>().sprite = Digits[ch-'0'];            //贴上对应的贴图            dobj.transform.position =new Vector2(-4.8f+0.6f*cnt, 4.05f);            ++cnt;        }    }}

六. healthManager.cs

将已创建的游戏对象(代表血量的X)作为脚本的参数, 失去一条生命,修改对应位置上游戏对象贴图的颜色。

代码:

using UnityEngine;using System.Collections;public class healthManager : MonoBehaviour {    public SpriteRenderer[] spr;     private int count;    // Use this for initialization    void Start () {        count = 0;    }    // Update is called once per frame    void cutOne()    {        spr[count++].color = Color.red;        if (count == 5)            Application.LoadLevel("gameOver");        }}
1 0