2D游戏——2021年6月2日

介绍

本篇博文,我们介绍2种新的机关——冰锥。根据设计,冰锥有大冰锥和小冰锥2种,下面我们来依次介绍。

小冰锥

在冰属性地图中,在地图上方会生成若干冰锥,当玩家进入一定区域后,冰锥会落下,对玩家造成伤害。一定时间后,冰锥会重新生成。
为满足小冰锥的功能,我们还需要一个冰锥管理器。因为冰锥掉落后会在一定时间后重新生成,所以我们需要一个管理器来控制冰锥的生成。那么冰锥管理器有2个主要方法,一个是让冰锥掉落(可以写在update中),一个是让冰锥重新生成。小冰锥仍然需要对象池去生成。

冰锥管理器代码

/**
 * @Description: SmallIceConeManager为小冰锥管理器,在一定范围内随机生成小冰锥
 * @Author: CuteRed

 *     
*/

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

public class SmallIceConeManager : Mechanism
{
    [Header("生成参数")]
    public int generateNumber = 3;
    private int flowNum = 0;
    private Vector2 generatePosition = new Vector2(0, 0);

    [Header("时间参数")]
    public float flowIntervalTime = 1.0f;
    private float passTime = 0.0f;

    private Collider2D coll;
    private SmallIceCone[] cones;

    private PoolManager poolManager;

    protected override void Start()
    {
        base.Start();

        poolManager = GameObject.Find("PoolManager").GetComponent<PoolManager>();
        if (poolManager == null)
        {
            Debug.LogError("在" + gameObject.name + "中,找不到PoolManager");
        }

        coll = GetComponent<Collider2D>();
        if (coll == null)
        {
            Debug.LogError("在" + gameObject.name + "中,获取collider失败");
        }

        cones = new SmallIceCone[generateNumber];

        //生成冰锥
        GenerateIceCone();

        enabled = false;
    }

    // Update is called once per frame
    void Update()
    {
        //计时
        passTime += Time.deltaTime;
        if (passTime > flowIntervalTime)
        {
            cones[flowNum].Trigger(TiggerType.Other);
            flowNum++;
            passTime = 0.0f;
        }

        //检测是否冰锥都掉落
        if (flowNum == generateNumber)
        {
            //掉落数置为0
            flowNum = 0;
            //cones.Clear();

            //生成新冰锥
            GenerateIceCone();

            enabled = false;
            isTriggered = false;
        }
    }

    public override void Trigger(TiggerType triggerType)
    {
        if (TriggerDetect())
        {
            isTriggered = true;
            enabled = true;
        }
    }

    protected override bool TriggerDetect()
    {
        return !isTriggered;
    }

    /// <summary>
    /// 在指定范围内随机生成冰锥
    /// </summary>
    private void GenerateIceCone()
    {
        for (int i = 0; i < generateNumber; i++)
        {
            Debug.Log(i);
            GameObject cone = poolManager.GetGameObject(SmallIceCone.SMALL_ICE_CONE);
            SmallIceCone a = cone.GetComponent<SmallIceCone>();

            //随机生成位置
            float x = Random.Range(coll.bounds.min.x, coll.bounds.max.x);
            float y = Random.Range(coll.bounds.min.y, coll.bounds.max.y);
            generatePosition.x = x;
            generatePosition.y = y;
            a.SetPosition(generatePosition);

            //加入列表
            cones[i] = a;
        }
    }
}

小冰锥设计

关于小冰锥,它有下落和生成2种方法。小冰锥掉落在地面上时,会消失,为了模拟消失,我们可以让它变为透明的。一定时间后,会重新生成,这里可以使用协程。

/**
 * @Description: SmallIceCone为小冰锥,由冰锥管理器管理,掉落地面后消失
 * @Author: CuteRed

 *     
*/

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

public class SmallIceCone : Mechanism
{
    public const string SMALL_ICE_CONE = "SmallIceCone";

    private Collider2D coll;
    private CanFight canFight;
    private SpriteRenderer spriteRenderer;

    [Header("颜色参数")]
    private Color originalColor;
    private Color transparentColor;

    [Header("运动参数")]
    public float originalFlowSpeed = 3.0f;
    private float speed;
    private Vector3 direction = Vector3.down;
    private Vector3 startPosition;

    [Header("伤害参数")]
    public int damage = 2;
    private List<LayerMask> layers = new List<LayerMask>();

    [Header("时间参数")]
    public float generateTime = 2.0f;

    private LayerMask ground;


    protected override void Start()
    {
        base.Start();

        

        speed = originalFlowSpeed;

        startPosition = transform.position;

        ground = LayerMask.GetMask("Platform");

        spriteRenderer = GetComponent<SpriteRenderer>();
        if (spriteRenderer == null)
        {
            Debug.LogError("在" + gameObject.name + "中,找不到spriteRenderer");
        }

        //颜色初始化
        originalColor = spriteRenderer.color;
        transparentColor = spriteRenderer.color;
        transparentColor.a = 0.0f;

        //碰撞体初始化
        coll = GetComponent<Collider2D>();
        if (coll == null)
        {
            Debug.LogError("在" + gameObject.name + "中,找不到collider");
        }

        //初始化目标层级
        layers.Add(LayerMask.NameToLayer("Player"));
        layers.Add(LayerMask.NameToLayer("Enemy"));

        //初始化canFight
        canFight = GetComponent<CanFight>();
        if (canFight == null)
        {
            Debug.LogError("在" + gameObject.name + "中,找不到canFight");
        }
        string[] targetLayer = new string[2];
        targetLayer[0] = "Player";
        targetLayer[1] = "Enemy";
        canFight.Initiailize(targetLayer);

        enabled = false;
    }

    private void Update()
    {
        //下落
        transform.position += direction * speed * Time.deltaTime;
        speed += 1.0f;

        //检测碰到地图
        RaycastHit2D hit;
        hit = Physics2D.Raycast(transform.position, direction, 0.2f, ground);
        if (hit && speed > 0.0f)
        {
            //消失
            spriteRenderer.color = transparentColor;

            //速度置为0
            speed = 0.0f;
            StartCoroutine(nameof(FlowToFloor));
        }
    }

    /// <summary>
    /// 设置生成位置
    /// </summary>
    /// <param name="startPosition">生成位置</param>
    public void SetPosition(Vector2 startPosition)
    {
        transform.position = startPosition;
    }

    public override void Trigger(TiggerType triggerType)
    {
        if (TriggerDetect())
        {
            //触发
            isTriggered = true;

            //恢复速度
            speed = originalFlowSpeed;

            //开启脚本
            enabled = true;
        }
    }

    protected override bool TriggerDetect()
    {
        return !isTriggered;
    }

    /// <summary>
    /// 落到地板上,被对象池收回
    /// </summary>
    private IEnumerator FlowToFloor()
    {

        yield return new WaitForSeconds(generateTime);

        //消失
        //gameObject.SetActive(false);

        //等待重新生成
        Generate();
    }

    private void OnTriggerEnter2D(Collider2D collision)
    {
        //层级检测
        if (speed > 0 && layers.Contains(collision.gameObject.layer))
        {
            //检测是否可以被攻击
            CanBeFighted beFought;
            if (collision.TryGetComponent<CanBeFighted>(out beFought))
            {
                canFight.Attack(beFought, damage);
                Debug.Log(gameObject.name + "攻击到了" + beFought.gameObject.name);
            }
        }
    }

    /// <summary>
    /// 重新生成
    /// </summary>
    /// <returns></returns>
    private void Generate()
    {
        enabled = false;

        transform.position = startPosition;

        //恢复颜色
        spriteRenderer.color = originalColor;
        //gameObject.SetActive(true);
        isTriggered = false;
    }
}

效果

在这里插入图片描述

大冰锥

大冰锥与小冰锥的不同为,大冰锥掉落后不会消失,而是会变成一种地形,玩家可以踩在上面。而且大冰锥掉落后不可重新生成。
那么大冰锥有2个方法,掉落(可以写在update种)和变为地形,造成伤害的代码可以写在OnTriggerEnter2D中。

代码

/**
 * @Description: LargeIceCone为大冰锥类,掉落会变成地形,碰到敌人或玩家会造成伤害
 * @Author: CuteRed

 *     
*/

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

public class LargeIceCone : Mechanism
{
    private Collider2D coll;
    private CanFight canFight;

    [Header("运动参数")]
    public float flowSpeed = 3.0f;
    private Vector3 direction = Vector3.down;

    [Header("伤害参数")]
    public int damage = 2;
    private List<LayerMask> layers = new List<LayerMask>();

    private LayerMask ground;

    protected override void Start()
    {
        base.Start();

        ground = LayerMask.GetMask("Platform");

        coll = GetComponent<Collider2D>();
        if (coll == null)
        {
            Debug.LogError("在" + gameObject.name + "中,找不到collider");
        }

        //初始化目标层级
        layers.Add(LayerMask.NameToLayer("Player"));
        layers.Add(LayerMask.NameToLayer("Enemy"));

        //初始化canFight
        canFight = GetComponent<CanFight>();
        if (canFight == null)
        {
            Debug.LogError("在" + gameObject.name + "中,找不到canFight");
        }
        string[] targetLayer = new string[2];
        targetLayer[0] = "Player";
        targetLayer[1] = "Enemy";
        canFight.Initiailize(targetLayer);

        enabled = false;
    }

    private void Update()
    {
        //下落
        transform.position += direction * flowSpeed * Time.deltaTime;
        flowSpeed += 1.0f;

        //检测碰到地图
        RaycastHit2D hit;
        hit = Physics2D.Raycast(transform.position, direction, 1.0f, ground);
        if (hit)
        {
            StartCoroutine(nameof(FlowToFloor));
            flowSpeed = 0.0f;
        }
    }

    public override void Trigger(TiggerType triggerType)
    {
        if (TriggerDetect())
        {
            //触发
            isTriggered = true;

            //开启脚本
            enabled = true;
        }
    }

    protected override bool TriggerDetect()
    {
        return !isTriggered;
    }

    /// <summary>
    /// 落到地板上
    /// </summary>
    private IEnumerator FlowToFloor()
    {
        yield return new WaitForSeconds(2.0f);

        gameObject.layer = LayerMask.NameToLayer("Platform");
        coll.isTrigger = false;
    }

    private void OnTriggerEnter2D(Collider2D collision)
    {
        //层级检测
        if (flowSpeed > 0 && layers.Contains(collision.gameObject.layer))
        {
            //检测是否可以被攻击
            CanBeFighted beFought;
            if (collision.TryGetComponent<CanBeFighted>(out beFought))
            {
                canFight.Attack(beFought, damage);
                beFought.BeatBack(transform, 1.0f, 10.0f);
                Debug.Log(gameObject.name + "攻击到了" + beFought.gameObject.name);
            }
        }
    }
}

效果

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值