Roman 96843244ae 任务:流程化游戏
*.编写黑块逻辑
(*.具有状态in、all、out
(1.当被呼出,执行呼出事件
((1.分type执行“入”的Tween动画
((2.入动画结束后,修改自身状态至all
((3.等待一定的加载时间后,修改自身状态为out,并开始出动画
((4.出动画结束后,找到“开幕演出”游戏物体,找到它的Stage并触发
((5.完成善后工作,将块移回原来的位置
(2.start时,检查场景内是否有其他转场块。若有,删除自己

1.制作转场
(1.触发转移
(2.关闭操作地图
(4.令玩家一直向右移动
(3.呼出黑块
(4.等待、直到黑块进入全覆盖状态
(5.根据字典经行场景转移
(6.黑块内部协程级时结束后,揭开黑幕
(7.揭开动画结束后
(8.找到“开幕演出”游戏物体,找到它的Stage并触发

3.流程化游戏
(1.将各个场景简单连接

4.修改各场景开幕演出,使开幕演出时修改玩家位置至指定位置

5.制作和替换美术素材,增加部分动画
(1.制作地藏石像动画

*优化和修复
1.修复佛教前置关陷阱小怪抽动的问题
2.修复佛教前置关掉怪陷阱下落太慢的问题

建议:
1.给普通关卡和村也加上类似Boos的全局shader,目前从关卡间过度的时候能够看出明显的区别
2.建议给地藏敲钟攻击的灰尘加上渐隐,目前是瞬间消失的,十分违和
3.建议给普通的炸弹也加上拖尾,很酷
4.以撒发怒时变红太快了,消散得也太快了
5.以撒鬼魂的粒子也建议加上淡入和淡出

*.至此,已经基本完成了游戏的流程化,已经能够顺利地连成一条线了,并且可以在关卡失败的时候在当前场景重生
*.接下来就是填充剧情和美化场景,明天应该能把数据库互动做好

下班
2021-12-23 01:19:03 +08:00

230 lines
7.5 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using DG.Tweening;
using Sirenix.OdinInspector;
/// <summary>
/// 撞钟类,控制地藏头上的钟
/// </summary>
public class Bell : MonoBehaviour
{
// _____ _ _ _
// | __ \ | | | (_)
// | |__) | _| |__ | |_ ___
// | ___/ | | | '_ \| | |/ __|
// | | | |_| | |_) | | | (__
// |_| \__,_|_.__/|_|_|\___|
/// <summary>
/// 攻击前置动作钟上浮多少距离
/// </summary>
[Header("攻击前置动作钟上浮多少距离")]
public float upDistance;
/// <summary>
/// 攻击将会持续多长时间
/// </summary>
[Header("攻击将会持续多长时间")]
public float atkTime;
/// <summary>
/// 主人也就是地藏Boss
/// </summary>
[HideInInspector]
public DiZang owner;
/// <summary>
/// 钟飞上去将要花费多少时间(降下来也是这个值)
/// </summary>
[Header("钟飞上去将要花费多少时间(降下来也是这个值)")]
public float upTime;
/// <summary>
/// 干扰多长时间能造成伤害和击飞?
/// </summary>
[Header("干扰多长时间能造成伤害和击飞?")]
public float annoyingToHitTime;
[Header("声波Shader")]
public BellShader bellShader;
[Header("声波受击粒子")]
public GameObject particleObj;
// _____ _ _
// | __ \ (_) | |
// | |__) | __ ___ ____ _| |_ ___
// | ___/ '__| \ \ / / _` | __/ _ \
// | | | | | |\ V / (_| | || __/
// |_| |_| |_| \_/ \__,_|\__\___|
/// <summary>
/// 当前正在攻击吗
/// </summary>
[SerializeField][Button][ReadOnly][Header("当前正在攻击吗(不包括钟上下过程))")]
private bool isAtking = false;
private MyPlayer player;
/// <summary>
/// 浮动动画,用来重启浮动动画解决Tween的一些局限性问题
/// </summary>
public Tweener floatTweener;
private float annoyingToHitTimeLeft;
/// <summary>
/// 此时是否在干扰玩家
/// </summary>
[SerializeField]
private bool isAnnoyingPlayer;
/// <summary>
/// 钟的初始位置
/// </summary>
private Vector3 startPositon;
// _____ _ _ ____ _
// / ____| | | | _ \ | |
// | | __ _| | | |_) | __ _ ___| | __
// | | / _` | | | _ < / _` |/ __| |/ /
// | |___| (_| | | | |_) | (_| | (__| <
// \_____\__,_|_|_|____/ \__,_|\___|_|\_\
void Start(){
annoyingToHitTimeLeft = annoyingToHitTime;
startPositon = transform.position;
//启动浮动动画
RestartFloat();
}
void Update(){
//如果钟正在攻击
if(isAtking)
{
bellShader.isBell = true;
particleObj.SetActive(true);
if(!player.isAnnoying){
player.OnInAnnoying();
}
//创建一条从钟射向玩家的射线
Ray2D ray = new Ray2D(
(Vector2)transform.position,
(Vector2)(player.transform.position - transform.position)
);
Debug.DrawRay(ray.origin,ray.direction * 1500,Color.red);
//获取射线的碰撞结果
RaycastHit2D hit2D;
hit2D = Physics2D.Raycast(ray.origin,ray.direction);
if(hit2D){
Debug.Log(hit2D.collider.name);
}
//如果射线击中玩家并且玩家未处于被攻击状态,说明刚被击中,触发玩家的被干扰事件
if(hit2D.collider.TryGetComponent<MyPlayer>(out MyPlayer trash) ){
// player.OnInAnnoying();
isAnnoyingPlayer = true;
}
//如果没有击中玩家,但是玩家处于被攻击状态,说明玩家脱离了攻击,触发玩家解除干扰事件
else if(!hit2D.collider.TryGetComponent<MyPlayer>(out MyPlayer trash1)){
//player.OnOutAnnoying();
isAnnoyingPlayer = false;
annoyingToHitTimeLeft = annoyingToHitTime;
}
}
if(isAnnoyingPlayer){
annoyingToHitTimeLeft -= Time.deltaTime;
if(annoyingToHitTimeLeft <= 0){
//告诉玩家,你被攻击了
player.OnBeHit(owner.ATK,
((transform.position.x -
player.transform.position.x)
> 0) ? 1 : -1);//通过自身位置和玩家位置的比较来返回玩家本次的受击方向
//恢复CD
annoyingToHitTimeLeft = annoyingToHitTime;
}
}
}
// _ _ _
// | \ | | | |
// | \| | ___ _ __ _ __ ___ __ _| |
// | . ` |/ _ \| '__| '_ ` _ \ / _` | |
// | |\ | (_) | | | | | | | | (_| | |
// |_| \_|\___/|_| |_| |_| |_|\__,_|_|
/// <summary>
/// 介于Tweener的特性经常需要重新创建钟浮动的动画
/// </summary>
private void RestartFloat(){
if(floatTweener != null){
floatTweener.Kill();
}
Tweener tweener = transform.DOShakePosition(5f,0.3f,1,90,false,false);
tweener.SetLoops(-1);
tweener.SetEase(Ease.InQuad);
floatTweener = tweener;
}
// ______ _
// | ____| | |
// | |____ _____ _ __ | |_
// | __\ \ / / _ \ '_ \| __|
// | |___\ V / __/ | | | |_
// |______\_/ \___|_| |_|\__|
/// <summary>
/// 从主人那里得到攻击指令后触发
/// </summary>
public void ATK(MyPlayer player){
//指定一下攻击目标
this.player = player;
//创建和执行上浮动画
Tweener tweener = transform.DOLocalMoveY(
transform.position.y + upDistance,
upTime
);
//创建并加入上浮动画结束事件
TweenCallback action = () => {
//标记自己开始攻击
isAtking = true;
//重启浮动动画
RestartFloat();
//等待攻击结束
StartCoroutine(WaitAndTurnDownThebutton());
};
tweener.OnComplete(action);
}
/// <summary>
/// 上浮动画结束的时候触发
/// </summary>
/// <returns></returns>
private IEnumerator WaitAndTurnDownThebutton(){
//等待攻击时长结束
yield return new WaitForSeconds(atkTime);
//标记攻击结束
isAtking = false;
//触发自身攻击结束功能
ATKEnd();
}
/// <summary>
/// 攻击结束的时候触发
/// </summary>
private void ATKEnd()
{
bellShader.isBell = false;
bellShader.Remake = true;
particleObj.SetActive(false);
//如果玩家仍处于被干扰状态,解除干扰
if(player.isAnnoying) player.OnOutAnnoying();
annoyingToHitTimeLeft = annoyingToHitTime;
isAnnoyingPlayer = false;
//创建动画让钟回去
Tweener tweener =
//transform.DOMoveY(transform.position.y - upDistance,upTime);
transform.DOMove(startPositon,upTime);
//创建和添加结束事件
TweenCallback action = () => {
//重启浮动动画
RestartFloat();
//告诉主人,攻击结束,开始下一个轮回
owner.ATKEnd();
};
tweener.OnComplete(action);
}
}