Unity版本捕鱼游戏设计与实现

经典的射击小游戏:捕鱼达人

灵魂画师上线:

这是比较直白的草图也叫灵魂图,中间大方框周围的小方框代表鱼的生成位置,鱼通过这七个点来生成,并且游向屏幕中央,

来让玩家看到这种效果:

而单纯的只给鱼向前游是不行的,那样看着会很机械,所以要模仿鱼的左右移动,也就是弧线移动。

弧线移动的实现方式也很简单,说白了就是让他边扭着身子边直线跑,这样就是弧线移动了。

把这两个运动分解成可以复用的两个脚本,一个直线移动,一个掌控自身的增量旋转。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

/*
作者:琦玉老师的二弟子
*/
namespace JumpAgent{

public class AutoMove : MonoBehaviour
{
        public float speed = 1f;
        public Vector3 Dir = Vector3.right;


        private void Update()
        {
            transform.Translate(Dir * speed * Time.deltaTime);
        }


    }//类

}//命名空间
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

/*
作者:琦玉老师的二弟子
*/
namespace JumpAgent{

public class AutoRotate : MonoBehaviour
{
        public float speed = 10f;

        private void Update()
        {
            transform.Rotate(Vector3.forward, speed * Time.deltaTime);
        }


    }//类

}//命名空间

有了这两个脚本就能开始生成鱼了:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

/*
作者:琦玉老师的二弟子
*/
namespace JumpAgent
{

    public class FishMaker : MonoBehaviour
    {
        public Transform[] genPositions;//鱼的生成位置
        public GameObject[] fishPrefabs;//所有鱼的预制体
        public Transform fishHolder;//收纳鱼的clone,防止散乱

        private void Start()
        {
            InvokeRepeating("MakeFish", 0, 0.1f);
        }

        void MakeFish()
        {
            //在什么位置生成什么鱼
            int genPosIndex = Random.Range(0, genPositions.Length);
            int fishPreIndex = Random.Range(0, fishPrefabs.Length);
            //获取鱼的最大生成数量和最大速度
            int maxNum = fishPrefabs[fishPreIndex].GetComponent<FishAttribute>().maxNuml;
            int maxSpeed = fishPrefabs[fishPreIndex].GetComponent<FishAttribute>().maxSpeed;
            //决定鱼的生成数量和速度
            int num = Random.Range((maxNum / 2) + 1, maxNum);
            int speed = Random.Range(maxSpeed / 2, maxSpeed);
            //鱼的行为轨迹,0代表直线,1代表弧线
            int moveType = Random.Range(0, 2);
            //直走的倾斜角
            int angOffset;
            //转弯速度
            int angSpeed;

            if (moveType == 0)
            {
                //直线鱼
                angOffset = Random.Range(-22, 22);
                StartCoroutine(GreatLineFish(genPosIndex, fishPreIndex, num, speed, angOffset));
            }
            else
            {
                //弧线
                angSpeed = Random.Range(8, 13);
                int direct= Random.Range(0, 2);
                if (direct==0)
                {
                    StartCoroutine(GreatcurveFish(genPosIndex, fishPreIndex, num, speed, angSpeed));
                }
                else
                {
                    StartCoroutine(GreatcurveFish(genPosIndex, fishPreIndex, num, speed, angSpeed));
                }
            }
        }
        IEnumerator GreatLineFish(int genPosIndex, int fishPreIndex, int num, int speed, int angOffset)
        {
            for (int i = 0; i < num; i++)
            {
                GameObject fish = GameObject.Instantiate(fishPrefabs[fishPreIndex]);
                fish.transform.SetParent(fishHolder, false);
                fish.transform.localPosition = genPositions[genPosIndex].localPosition;
                fish.transform.localRotation = genPositions[genPosIndex].localRotation;
                fish.transform.Rotate(0, 0, angOffset);
                fish.GetComponent<SpriteRenderer>().sortingOrder += i;
                fish.AddComponent<AutoMove>().speed = speed;
                yield return new WaitForSeconds(0.5f);
            }
        }
        IEnumerator GreatcurveFish(int genPosIndex, int fishPreIndex, int num, int speed, int angSpeed)
        {
            for (int i = 0; i < num; i++)
            {
                GameObject fish = GameObject.Instantiate(fishPrefabs[fishPreIndex]);
                fish.transform.SetParent(fishHolder, false);
                fish.transform.localPosition = genPositions[genPosIndex].localPosition;
                fish.transform.localRotation = genPositions[genPosIndex].localRotation;
                fish.GetComponent<SpriteRenderer>().sortingOrder += i;
                fish.AddComponent<AutoRotate>().speed = angSpeed;//添加旋转组件
                fish.AddComponent<AutoMove>().speed = speed;//添加移动组件
                yield return new WaitForSeconds(0.5f);
            }
        }

    }//类

}//命名空间

 

再然后是:炮台,子弹,网

首先,炮台会跟随我们的手指的输入坐标来进行转动,然后,是炮台的伤害,炮台的伤害根据我们所选择的伤害来执行,也就是操作一个int类型的伤害数组,然后可以把这个伤害数组里面的元素平均分组,然后每到一个分组里就给我们的换一个炮台(隐藏和显示)。

其次,我们的炮台发射子弹是要钱的,根据不同的金额,对鱼造成不同的伤害,当时并不是直接通过子弹对其造成伤害,是炮台放出去子弹,子弹碰到鱼,然后在子弹处生成网子,在把子弹应该造成的伤害赋值给网子,网子存在一定时间,然后由网子再和鱼做碰撞检测,每个enter进去的鱼都会收到网子发送给鱼的伤害,也就是说每次鱼碰到网子生命值都会减少,直到鱼死亡。

再根据每只鱼的死亡,去更新相应的UI数据即可。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;

/*
作者:琦玉老师的二弟子
*/
namespace JumpAgent
{

    public class GameController : MonoBehaviour
    {

        public static GameController _instance;

        private void Awake()
        {
            _instance = this;
        }

        public GameObject Waterwave;
        public GameObject bg;
        public Sprite[] BGSprite;
        public Text oneShootCostText;
        public Text goldText;
        public Text lvText;
        public Text lvNameText;
        public Text smallCuttondownText;
        public Text bigCuttondownText;
        public Button bigCountdownButton;
        public Button BackButton;
        public Button SettingButton;
        public GameObject[] BulletPrefabs;
        public GameObject[] Guns;
        public Slider ExpSlider;
        private int[] ShootCost = { 5, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 200, 300, 400, 500, 600, 700, 800, 900, 1000 };
        private string[] lvName = { "坚韧黑铁", "倔强青铜", "不屈白银", "荣耀黄金", "华贵铂金", "永恒钻石","璀璨星耀","最强王者","荣耀王者","巅峰王者"};
        public Text ShootCostText;
        private int CostIndex = 0;
        public Transform bulletHorder;

       
        public int lv = 0;
        public int exp=0;
        public int gold = 500;
        private const float bigCountdown = 240f;
        private const float smallCountdown = 60f;
        private float bigTimer= bigCountdown;
        private float smallTimer= smallCountdown;
        /// <summary>
        /// 更新UI
        /// </summary>
        public void UpdateUI()
        {

            bigTimer -= Time.deltaTime;
            smallTimer -= Time.deltaTime;
            if (smallTimer <= 0)
            {
                smallTimer = smallCountdown;
                gold += 100;
            }
            if (bigTimer<=0&& bigCountdownButton.gameObject.activeSelf==false)
            {
                bigCuttondownText.gameObject.SetActive(false);
                bigCountdownButton.gameObject.SetActive(true);
            }

            while (exp>=1000+200*lv)
            {                
                lv++;
                if (lv%10==0)//每十级生成一次大浪花,并且更新一次背景
                {
                    GameObject.Instantiate(Waterwave);
                    bg.gameObject.GetComponent<Image>().sprite = BGSprite[Random.Range(0, BGSprite.Length)];
                }
               exp= exp - (1000 + 200 * lv);
            }

            goldText.text = "$" + gold;
            lvText.text = lv.ToString();
            if (lv/10<=9)
            {
                lvNameText.text = lvName[lv / 10];
            }
            else
            {
                lvNameText.text = lvName[9];
            }

            smallCuttondownText.text = (int)smallTimer / 10 + "   " + (int)smallTimer % 10;
            bigCuttondownText.text = (int)bigTimer + "s";
            ExpSlider.value = ((float)exp) / (1000 + 200 * lv);            
        }

        /// <summary>
        /// 开火
        /// </summary>
        public void Fire()
        {
            if (Input.GetMouseButton(0) && EventSystem.current.IsPointerOverGameObject() == false)
            {
                //这里当没钱打子弹的时候给一个提示
                if (gold- ShootCost[CostIndex]>=0)
                {
                    goldText.color = Color.yellow;
                    gold -= ShootCost[CostIndex];
                }
                else
                {
                    goldText.color = Color.red;
                    return;
                }

                GameObject bullet = GameObject.Instantiate(BulletPrefabs[Random.Range(0, BulletPrefabs.Length)]);
                bullet.transform.SetParent(bulletHorder, false);
                bullet.transform.position = Guns[CostIndex / 4].transform.Find("FirePosition").position;
                bullet.transform.rotation = Guns[CostIndex / 4].transform.Find("FirePosition").rotation;

                bullet.GetComponent<BulletAttribute>().damage = ShootCost[CostIndex];
                bullet.AddComponent<AutoMove>().Dir = Vector3.up;
                bullet.GetComponent<AutoMove>().speed = 10f;
                bullet.AddComponent<AutoDestory>().DestoryTime = 3f;

            }
        }
        /// <summary>
        /// 右上角大奖金点击
        /// </summary>
        public void OnBigCountdownButtonDown()
        {
            gold += 500;
            bigCountdownButton.gameObject.SetActive(false);
            bigCuttondownText.gameObject.SetActive(true);
            bigTimer = bigCountdown;
        }

        //换枪操作--------------------------
        public void OnRDButtonClick()
        {
            Guns[CostIndex / 4].SetActive(false);
            CostIndex++;
            CostIndex = (CostIndex > ShootCost.Length - 1) ? 0 : CostIndex;
            ShootCostText.text = "$" + ShootCost[CostIndex];
            Guns[CostIndex / 4].SetActive(true);
        }
        public void OnLDButtonClick()
        {
            Guns[CostIndex / 4].SetActive(false);
            CostIndex--;
            CostIndex = (CostIndex < 0) ? ShootCost.Length - 1 : CostIndex;
            ShootCostText.text = "$" + ShootCost[CostIndex];
            Guns[CostIndex / 4].SetActive(true);
        }
        void hualun()
        {
            if (Input.GetAxis("Mouse ScrollWheel") > 0)
            {
                OnRDButtonClick();
            }
            if (Input.GetAxis("Mouse ScrollWheel") < 0)
            {
                OnLDButtonClick();
            }
        }
        //---------------------------------

        private void Update()
        {
            hualun();
            Fire();
            UpdateUI();
        }


    }//类

}//命名空间

其实这个游戏和打飞机的原理基本一样,不同的是模拟了下捕鱼的动作之类的。

最后是我去除了限制炮台发射速度的效果,因为这样比较爽:

 

 

 

  • 1
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值