[unity]实现切水果游戏

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/AXuan_K/article/details/53589252

初学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");    
    }
}

猜你喜欢

转载自blog.csdn.net/AXuan_K/article/details/53589252