學習游戲制作記錄(各種水晶能力以及多晶體)8.1

1.實現創建水晶并且能與水晶進行交換位置的能力

創建好水晶的預制體,添加動畫控制器,傳入待機和爆炸的動畫

創建Crystal_Skill_Control腳本:

掛載在水晶預制體上

? ? private float crystalExstTime;//水晶存在時間

? ? public void SetupCrystal(float _crystalDuration)
{
crystalExstTime = _crystalDuration;
}

? ? private void Update()
{
crystalExstTime -= Time.deltaTime;

? ? ? ? if(crystalExstTime < 0 )
{
SelfDestroy();//超時自毀
}
}

? ? public void SelfDestroy() => Destroy(gameObject);

創建Crystal_Skill腳本:

掛載在技能管理器上,并在SkillManage腳本上初始化

? ? [SerializeField] private float crystalDuration;//傳入上面的控制腳本
[SerializeField] private GameObject crystalPrefab;//預制體
private GameObject currentCrystal;

? ? public override void UseSkill()
{
base.UseSkill();

? ? ? ? if(currentCrystal==null)//不存在則創建
{
currentCrystal =Instantiate(crystalPrefab,player.transform.position,Quaternion.identity);

? ? ? ? ? ? Crystal_Skill_Control newcrystalScript= currentCrystal.GetComponent<Crystal_Skill_Control>();

? ? ? ? ? ? newcrystalScript.SetupCrystal(crystalDuration);

? ? ? ? }
else//如果場上有水晶則傳送玩家并銷毀水晶
{
player.transform.position = currentCrystal.transform.position;

? ? ? ? ? ? Destroy(currentCrystal);
}
}

Player腳本:

? ? ? ? if(Input.GetKeyDown(KeyCode.F)) //update中
{
skill.crystal.CanbeUsed();
}

2.實現水晶爆炸和變大的功能

給水晶爆炸動畫選取中間一幀調用傷害函數,在結束添加幀事件調用自毀函數

動畫控制器添加觸發Explode

Crystal_Skill_Control腳本:

?private Animator anim ?=>GetComponent<Animator>();//獲取碰撞器和動畫器
private CircleCollider2D cd =>GetComponent<CircleCollider2D>();

private bool canExplode;//是否可以爆炸
private bool canMove;//是否可以移動
private bool canGrow=false;//是否可以變大

?private float moveSpeed;
private float growSpeed=5f;//增大速度

? ? public void SetupCrystal(float _crystalDuration,bool _canExplode,bool _canMove,float _moveSpeed)
{
crystalExstTime = _crystalDuration;
canExplode = _canExplode;
canMove = _canMove;
moveSpeed = _moveSpeed;

? ? }

? ? ? ? if(canGrow)//update()中
{
transform.localScale = Vector2.Lerp(transform.localScale,new Vector3(3,3),growSpeed*Time.deltaTime);//變大

? ? ? ? }

? ? public void AnimationExplodeEvent()//傷害事件
{
Collider2D[] collider2Ds = Physics2D.OverlapCircleAll(transform.position,cd.radius);//用碰撞器的半徑

? ? ? ? foreach (var hit in collider2Ds)
{
if (hit.GetComponent<Enemy>() != null)
{
hit.GetComponent<Enemy>().Damage();
}
}
}

? ? public ?void FinishCrystal()
{
if (canExplode)//如果可以爆炸
{
canGrow = true;//設置變大
anim.SetTrigger("Explode");//播放爆炸動畫
}
else
{
SelfDestroy();
}
}

Crystal_Skill腳本:

? ? [Header("Explode crystal")]
[SerializeField] private bool canExplode;


? ? [Header("Moving crystal")]
[SerializeField] private bool canMove;
[SerializeField] private float moveSpeed;

? ? ? ? else//修改
{
Vector2 playerPos= player.transform.position;

? ? ? ? ? ? player.transform.position = currentCrystal.transform.position;

? ? ? ? ? ? currentCrystal.transform.position = playerPos;//交換水晶與玩家

? ? ? ? ? ? currentCrystal.GetComponent<Crystal_Skill_Control>().FinishCrystal();
}

3.實現水晶的移動

Skill腳本:

? ? protected virtual Transform FindClosetEnemy(Transform _checkTransform)//這是之前寫克隆攻擊時用到的代碼,現將它放在skill上,用于找到指定組件附近最近的敵人
{
Collider2D[] collider2Ds = Physics2D.OverlapCircleAll(_checkTransform.position, 25);
float closestEnemyDistance = Mathf.Infinity;
Transform closestEnemy = null;
foreach (var hit in collider2Ds)
{

? ? ? ? ? ? if (hit.GetComponent<Enemy>() != null)
{
float distanceToEnemy = Vector2.Distance(_checkTransform.position, hit.transform.position);

? ? ? ? ? ? ? ? if (distanceToEnemy < closestEnemyDistance)
{
closestEnemyDistance = distanceToEnemy;
closestEnemy = hit.transform;
}
}
}

? ? ? ? return closestEnemy;
}

自行修改克隆攻擊腳本中的一些代碼

Crystal_Skill_Control腳本:

private Transform closestTarget;//最近的敵人目標

? ? ? ? if (canMoveToEnemy)
{
transform.position =Vector2.MoveTowards(transform.position,closestTarget.position,moveSpeed*Time.deltaTime);//移動

? ? ? ? ? ? if(Vector2.Distance(transform.position,closestTarget.position)<1f )//距離小于1時自毀
{
FinishCrystal();
canMoveToEnemy = false;
}
}

Crystal_Skill腳本:

? ? ? ? if(currentCrystal==null)
{
currentCrystal =Instantiate(crystalPrefab,player.transform.position,Quaternion.identity);

? ? ? ? ? ? Crystal_Skill_Control newcrystalScript= currentCrystal.GetComponent<Crystal_Skill_Control>();

? ? ? ? ? ? newcrystalScript.SetupCrystal(crystalDuration,canExplode,canMoveToEnemy,moveSpeed,FindClosetEnemy(currentCrystal.transform));//傳入上面函數返回的最近敵人

? ? ? ? }
else
{
if (canMoveToEnemy)//水晶移動時不可以換位
{
return;
}

? ? ? ? ? ? Vector2 playerPos= player.transform.position;

? ? ? ? ? ? player.transform.position = currentCrystal.transform.position;

? ? ? ? ? ? currentCrystal.transform.position = playerPos;

? ? ? ? ? ? currentCrystal.GetComponent<Crystal_Skill_Control>().FinishCrystal();
}

4.實現多晶體

玩家可以擁有多個晶體并且可以一次性使用它們

Crystal_Skill腳本:


? ? [Header("Multi Stacking crystal")]
[SerializeField] private bool canMultiStack;//是否可以使用多晶體
[SerializeField] private int?amountofCrystal;//晶體數量
[SerializeField] private float MultiCrystalCooldown;//冷卻時間
[SerializeField] private List<GameObject> crystalLeft=new List<GameObject>();//預備儲存晶體的列表

? ? ? ? if(canMultiCrystal())//update中
{
return;
}

?private bool canMultiCrystal()//是否能夠發射多晶體
{
if(canMultiStack)
{
if(crystalLeft.Count>0)//如果列表里有晶體
{
cooldown = 0;//可以連發
GameObject crystaclToSpawn = crystalLeft[crystalLeft.Count-1];//取最后一個晶體
GameObject newCrystal =Instantiate(crystaclToSpawn,player.transform.position,Quaternion.identity);//生成

? ? ? ? ? ? ?crystalLeft.Remove(crystaclToSpawn);//從列表中移除
Crystal_Skill_Control newcrystalScript = newCrystal.GetComponent<Crystal_Skill_Control>();

? ? ? ? ? ? ?newcrystalScript.SetupCrystal(crystalDuration, canExplode, canMoveToEnemy, moveSpeed, FindClosetEnemy(newCrystal.transform));

? ? ? ? ? ? ?if(crystalLeft.Count<=0)//無晶體重新填裝
{
cooldown = MultiCrystalCooldown;//設置冷卻
RefillCrystal();
}


? ? ? ? ? ? ?return true;
}
}
return false;
}

? ? public void RefillCrystal()//填裝晶體
{
for(int i = 0;i<amountofCrystal;i++)
{
crystalLeft.Add(crystalPrefab);
}
}

5.實現發射晶體的時間窗口

即當玩家只發射一顆晶體時,經過一定時間后也會進入冷卻并重新填裝晶體

Crystal_Skill腳本:

[SerializeField] private float useTimeWindow;//延遲窗口時間

? ? public void RefillCrystal()
{
int ?amountToAdd=amountofCrystal-crystalLeft.Count;//確保填裝數等于設定的數
for(int i = 0;i<amountToAdd;i++)
{
crystalLeft.Add(crystalPrefab);
}
}

? ? private void ResetAbility()//重置
{
if (coolDownTime > 0)//如果已經在冷卻則返回
return;

? ? ? ? cooldown = MultiCrystalCooldown;
RefillCrystal();
}

?if(crystalLeft.Count>0)
{
if(amountofCrystal==crystalLeft.Count)//當發射出第一顆時延遲調用
{
Invoke("ResetAbility", useTimeWindow);
}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/91500.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/91500.shtml
英文地址,請注明出處:http://en.pswp.cn/web/91500.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

在vscode 如何運行a.nut 程序(Squirrel語言)

在 VS Code 中運行 Squirrel 語言編寫的 .nut 程序&#xff0c;需要先配置 Squirrel 運行環境并安裝相關插件&#xff0c;具體步驟如下&#xff1a; 一、安裝 Squirrel 解釋器 Squirrel 程序需要通過其官方解釋器 squirrel 或 sq 執行&#xff0c;首先需要安裝解釋器&#xf…

【數據結構】生活中的數據結構:從吃飯與編程看棧與隊列思維

生活中的數據結構&#xff1a;從吃飯與編程看棧與隊列思維 在軟件開發的世界里&#xff0c;棧&#xff08;Stack&#xff09;和隊列&#xff08;Queue&#xff09;是兩種基礎的數據結構&#xff0c;它們以不同的順序管理數據&#xff1a;棧遵循后進先出&#xff08;LIFO&#x…

牛客——接頭密匙

題目鏈接&#xff1a;牛客--接頭密匙 該題是一個很顯然的前綴樹問題&#xff0c;只需要構建a中所有數組對應的前綴樹&#xff0c;之后求b所處前綴個數即可。關于前綴樹的構建&#xff0c;可以觀看左老師算法講解045的視頻&#xff0c;簡單來講就是用特殊字符將實際數據隔開&…

【Linux基礎知識系列】第六十三篇 - 文件編輯器基礎:vim

在 Linux 系統中&#xff0c;文本編輯器是系統管理員和開發人員不可或缺的工具。vim 是一個功能強大的文本編輯器&#xff0c;廣泛應用于 Linux 系統中。它支持多種編輯模式&#xff0c;提供了豐富的文本編輯功能&#xff0c;適用于編寫代碼、配置文件和文檔。掌握 vim 的基本使…

音頻驅動的視覺特效:粒子、動畫與Shader的融合技術

音頻驅動視覺效果的實現與應用1. 引言在互動媒體、游戲和數字藝術領域&#xff0c;音頻數據實時控制視覺元素已成為核心技術&#xff0c;它能創造沉浸式體驗&#xff0c;增強用戶參與感。例如&#xff0c;音樂會可視化或VR游戲中&#xff0c;音頻信號驅動粒子流動、動畫變化和S…

機器學習環境配置

【終極指南】吃透機器學習環境配置&#xff1a;從Conda、CUDA到Docker容器化 大家好&#xff01;在機器學習的旅程中&#xff0c;一個穩定、可復現的環境是成功的基石。 第一部分&#xff1a;核心理念——為何環境配置如此重要&#xff1f; 任何機器學習模型的運行&#xff0c;…

【14】大恒相機SDK C#開發 ——Bitmap.UnlockBits()什么意思?有什么用?bmpData.Scan0;什么意思?有什么用?

文章目錄1 Bitmap.UnlockBits()2 bmpData.Scan01 Bitmap.UnlockBits() 在 C# 中&#xff0c;Bitmap.UnlockBits() 方法的作用是解鎖通過 Bitmap.LockBits() 方法鎖定的位圖數據&#xff0c;并釋放相關的位圖數據結構。 當你使用 Bitmap.LockBits() 方法鎖定位圖數據時&#x…

什么是doris

文章目錄簡介使用場景Apache Doris 主要應用于以下場景&#xff1a;實時數據分析&#xff1a;湖倉融合分析&#xff1a;半結構化數據分析&#xff1a;Apache Doris 的核心特性詳細請看官方文檔&#xff1a; Apache Doris介紹簡介 Apache Doris 是一款基于 MPP 架構的高性能、實…

python+pyside6的簡易畫板

十分簡單的一個畫板程序&#xff0c;用QLabel控件作為畫布&#xff0c;在畫布上可以畫出直線、矩形、填充矩形、園&#xff0c;橢園、隨手畫、文本等內容。將原先發布的畫板程序中的畫文本方法修改成了原位創建一編輯框&#xff0c;編輯框失去焦點后&#xff0c;即將文本畫在畫…

【數據可視化-76】從釋永信被查,探索少林寺客流量深度分析:Python + Pyecharts 炫酷大屏可視化(含完整數據和代碼)

&#x1f9d1; 博主簡介&#xff1a;曾任某智慧城市類企業算法總監&#xff0c;目前在美國市場的物流公司從事高級算法工程師一職&#xff0c;深耕人工智能領域&#xff0c;精通python數據挖掘、可視化、機器學習等&#xff0c;發表過AI相關的專利并多次在AI類比賽中獲獎。CSDN…

WPF TreeView自帶自定義滾動條

放在TreeView.Resources中&#xff1a;<Style TargetType"ScrollBar"><Setter Property"Stylus.IsPressAndHoldEnabled" Value"false"/><Setter Property"Stylus.IsFlicksEnabled" Value"false"/><Set…

MongoDB 詳細用法與 Java 集成完整指南

MongoDB 詳細用法與 Java 集成完整指南 目錄 MongoDB 基礎概念MongoDB 安裝與配置MongoDB Shell 基本操作Java 環境準備Java MongoDB 驅動集成連接配置基本 CRUD 操作高級查詢操作索引操作聚合管道事務處理Spring Boot 集成最佳實踐 1. MongoDB 基礎概念 1.1 核心概念對比 …

【Flutter3.8x】flutter從入門到實戰基礎教程(四):自定義實現一個自增的StatefulWidget組件

fluttet中實現一個自定義的StatefulWidget組件&#xff0c;可以在數據變化后&#xff0c;把最新的頁面效果展示給客戶 實現效果實現代碼 pages文件夾下新加一個counter_page.dart文件 class CounterPage extends StatefulWidget {const CounterPage({super.key});overrideState…

[AI8051U入門第十三步]W5500實現MQTT通信

前言 學習目標: 1、學習MQTT協議 2、了解MQTT數據幀格式 3、自己編寫MQTT程序 4、調試MQTT程序一、MQTT協議介紹 MQTT(Message Queuing Telemetry Transport) 是一種輕量級的 發布/訂閱(Pub/Sub) 消息傳輸協議,專為 低帶寬、高延遲或不可靠網絡 環境設計,廣泛應用于 物…

四、基于SpringBoot,MVC后端開發筆記

整合第三方技術&#xff1a; 1、整合Junit (1)名稱&#xff1a;SpringBootTest (2)類型&#xff1b;測試類注解 (3)位置&#xff1a;測試類定義上方 (4)作用&#xff1a;設置Junit加載的SpringBoot啟動類 (5)相關屬性&#xff1a;classes&#xff1a;設置SpringBoot啟動類 2、整…

深入講講異步FIFO

一、異步 FIFO 的基本概念1.1 定義與核心作用異步 FIFO&#xff08;Asynchronous FIFO&#xff09;是一種讀寫時鐘完全獨立的先進先出&#xff08;First-In-First-Out&#xff09;數據緩沖器&#xff0c;主要用于跨時鐘域數據傳輸場景。在數字系統中&#xff0c;當兩個模塊工作…

linux81 shell通配符:[list],‘‘ ``““

shell 文件處理工具 grep 別名顯示顏色 grep --colorauto ‘root’ passwd alias grep‘grep --colorauto’ vim /etc/bashrc alias grep‘grep --colorauto’ source /etc/bashrc [rootsamba tmp]# grep --colorauto root 2.txt root:x:0:0:root:/root:/bin/bash operator:x:1…

CMake、CMakeLists.txt 基礎語法

前言 代碼變成可執行文件&#xff0c;叫做編譯&#xff08;compile&#xff09;&#xff1b;先編譯這個&#xff0c;還是先編譯那個&#xff08;即編譯的安排&#xff09;&#xff0c;叫做構建&#xff08;build&#xff09;。CMake是最常用的構建工具&#xff0c;誕生于1977年…

《文明5》錯誤代碼0xc0000142修復方法

只要是錯誤代碼為0xc0000142&#xff1f;不管是哪種錯誤&#xff0c;都是一樣的。 修復方法有很多&#xff0c;我先推薦個人認為比較好用的修復方法 方式一&#xff1a;第三方軟件修復&#xff1a; 地址在這里獲取&#xff1a;修復軟件點這里 添加圖片注釋&#xff0c;不超過 …

【Java面試題】緩存穿透

什么是緩存穿透 緩存穿透是指當秒殺請求在Redis中未命中緩存時&#xff0c;系統會轉而查詢數據庫。若數據庫中也不存在該數據&#xff0c;大量此類請求將直接沖擊數據庫&#xff0c;造成數據庫負載激增。解決方案 緩存空值 當我們查詢數據庫發現數據庫當中也不存在該數據時&…