塔防游戏 Day2
1. 创建炮塔选择的 UI
使用 UI -> Toggle 。注意指定同一 group。
2. 创建炮台的数据类
[System.Serializable] // 序列化
public class TurretData{
public GameObject turretPrefab; // 炮塔模型
public int cost; // 建造炮塔花费
public GameObject turretUpgradedPrefab; // 升级炮塔模型
public int costUpgraded; // 升级花费
public TurretType type; // 炮台类型
} public enum TurretType // 炮塔类型
{
LaserTurret,
MissileTurret,
StandardTurret
}
3. 监听炮塔选择的事件
在 Inspector 中指定 On Value Changed 触发函数。

public void onLaserSelected(bool isOn) // 当监听变量发生变化时触发
{
if (isOn)
{
selectedTurretData = laserTurretData;
}
} public void onMissileSelected(bool isOn)
{
if (isOn)
{
selectedTurretData = missileTurretData;
}
} public void onStandardSelected(bool isOn)
{
if (isOn)
{
selectedTurretData = standardTurretData;
}
}
4. 鼠标点击创建炮塔
void Update()
{
if (Input.GetMouseButtonDown()) // 监测鼠标左键点击
{
if (!EventSystem.current.IsPointerOverGameObject()) // 鼠标没有点击 UI 图标
{
// 有鼠标所在位置发射射线
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit hit; // 存储射线碰撞物
bool isCollider = Physics.Raycast(ray, out hit, , LayerMask.GetMask("MapCube"));
if (isCollider)
{
MapCube mapCube = hit.collider.GetComponent<MapCube>(); // 获取点击方块
// 当前已选择炮台且方块上没有放置炮台
if (selectedTurretData != null && mapCube.turretGo == null)
{
if (money > selectedTurretData.cost) // 钱够用
{
ChangeMoney(-selectedTurretData.cost);
mapCube.BuildTurret(selectedTurretData.turretPrefab);
}
else
{
// 钱不够,则触发动画
moneyAnimator.SetTrigger("Flicker");
}
}
else if (mapCube.turretGo != null)
{
// TODO 升级处理
}
}
}
}
}
// 建造炮塔
public void BuildTurret(GameObject turretPrefab)
{
// 实例化炮塔模型
turretGo = GameObject.Instantiate(turretPrefab, transform.position, Quaternion.identity);
// 产生建造特效
GameObject effect = GameObject.Instantiate(buildEffect, transform.position, Quaternion.identity);
Destroy(effect, ); // 一秒后销毁特效
}
5. 检测炮塔附近的敌人
public class Turret : MonoBehaviour {
// 存储炮塔攻击范围内的敌人
public List<GameObject> enemys = new List<GameObject>();
void OnTriggerEnter(Collider col)
{
if (col.tag == "Enemy") // 敌人进入
{
enemys.Add(col.gameObject);
}
}
void OnTriggerExit(Collider col)
{
if (col.tag == "Enemy") // 敌人离开
{
enemys.Remove(col.gameObject);
}
}
public float attackRateTime = ; // 攻击频率
private float timer = ; // 记录时间
public GameObject bulletPrefab; // 子弹模型
public Transform firePosition; // 子弹生成位置
public Transform head; // 炮塔头部位置
void Start()
{
timer = attackRateTime; // 有敌人立刻攻击
}
void Update()
{
if (enemys.Count > )
{
if (enemys[] != null)
{
// 炮塔头部转向敌人位置
Vector3 targetPosition = enemys[].transform.position;
targetPosition.y = head.position.y; // 要注意高度相同
head.LookAt(targetPosition);
}
timer += Time.deltaTime;
if (timer >= attackRateTime) // 攻击
{
timer -= attackRateTime;
Attack();
}
}
}
void Attack()
{
if (enemys[] == null) // 若第一个敌人为空
{
updateEnemys(); // 更新攻击范围内敌人
}
if (enemys.Count > )
{
// 实例化子弹
GameObject bullet = GameObject.Instantiate(bulletPrefab, firePosition.position, firePosition.rotation);
bullet.GetComponent<Bullet>().setTarget(enemys[].transform);
}
else
{
timer = attackRateTime;
}
}
// 去除已经死亡的敌人
void updateEnemys()
{
List<int> emptyIndex = new List<int>();
for (int i = ; i < enemys.Count; ++i)
{
if (enemys[i] == null)
{
emptyIndex.Add(i);
}
}
for (int i = ; i < emptyIndex.Count; ++i)
{
enemys.RemoveAt(emptyIndex[i] - i);
}
}
}
6. 敌人添加血条设计
使用 UI -> Slider
hpSlider.value = (float)hp / totalHp; // 更新血条

7.
塔防游戏 Day2的更多相关文章
- Cocos2d-x3.x塔防游戏(保卫萝卜)从零开始(三)
一.前提: 完成前一篇的内容. 具体参考:Cocos2d-x3.x塔防游戏(保卫萝卜)从零开始(二)篇 二.本篇目标: l 说说游戏中各种角色的动作.属性以及重构思路 l 进行代码重构让色狼大叔和 ...
- Cocos2d-x3.x塔防游戏(保卫萝卜)从零开始(二)
一.前提: 完成前一篇的内容. 具体参考:Cocos2d-x3.x塔防游戏(保卫萝卜)从零开始(一)篇 二.本篇目标: l 说说关于cocos2dx手机分辨率适配 l 对前一篇完成的塔防游戏原型进 ...
- Cocos2d-x3.x塔防游戏(保卫萝卜)从零开始(一)
一.前提: 完成Hello Game项目的创建编译. 具体参考:Cocos2dx.3x_Hello Game项目创建篇 二.本篇目标: l 说说关于塔防游戏的想法和思路 l 实现一个简单的塔防游戏 ...
- 三国塔防游戏android源码
三国塔防游戏源码,这个游戏源码比较完整的,因为上传有20M限制,把代码工程包分开了,主文件是TFGame,其他res大家按照安卓包加进去就行,欢迎下载并交流 ,大家可以参考一下吧.<ignore ...
- HTML5塔防游戏——《三国塔防》 - Yorhom's Game Box
h3{ font-size:20px; } HTML5塔防游戏--<三国塔防> 游戏介绍: <三国塔防>是一款基于HTML5和Javascript的2D塔防游戏.游戏中除了塔防 ...
- HTML5另类塔防游戏 -《三国战线》公布
关于本作 游戏介绍 本游戏是一款另类塔防游戏.本作以三国这段历史为题材,提供了从颍川之战到官渡之战.官渡之战到夷陵之战.夷陵之战到五丈原之战等15个关卡.在每一个关卡中,你会控制一名三国武将与出现的敌 ...
- [译]终极塔防——运用HTML5从头创建一个塔防游戏
翻译共享一篇CodeProject的高星力作,原文地址:http://www.codeproject.com/Articles/737238/Ultimate-Tower-Defense 下载演示项目 ...
- 使用Unity创建塔防游戏(Part2)
How to Create a Tower Defense Game in Unity – Part 2 原文地址:https://www.raywenderlich.com/107529/unity ...
- 使用Unity创建塔防游戏(Part1)
How to Create a Tower Defense Game in Unity - Part1 原文作者:Barbara Reichart 文章原译:http://www.cnblogs.co ...
随机推荐
- 跳转后全屏,兼容大部分浏览器JavaScript
<!DOCTYPE html> <html> <head> <title>测试</title> </head> <body ...
- erl_0014 《硝烟中的erlang》 读书笔记001 “绪论”
1.大家听说Erlang,往往是因为其对高并发的良好支持.其实,Erlang的核心特征是容错,从某种程度上讲,并发只是容错这个约束下的一个副产品.容错是Erlang语言的DNA,也是和其他所有编程语言 ...
- JS实现浏览器打印、打印预览
1.JS实现打印的方式方式一:window.print()window.print();会弹出打印对话框,打印的是window.document.body.innerHTML中的内容,下面是从网上摘到 ...
- JavaScript中字符串截取函数slice()、substring()、substr()
在js中字符截取函数有常用的三个slice().substring().substr()了,下面我来给大家介绍slice().substring().substr()函数在字符截取时的一些用法与区别吧 ...
- vim初探
https://github.com/spf13/spf13-vim 安装了此博主的开源项目. :vsp ——竖分屏 :sp ——横分屏
- jdk1.8新特性之接口default方法
众所周知,default是java的关键字之一,使用场景是配合switch关键字用于条件分支的默认项.但自从java的jdk1.8横空出世以后,它就被赋予了另一项很酷的能力——在接口中定义非抽象方法. ...
- 老齐python-基础6(循环 if while for)
1.条件语句if 依据某个条件,满足这个条件后执行下面的内容 >>> if bool(conj): #语法 do something >>> a = 8 >& ...
- AT命令控制上网 PDP
1. AT+CGATT=1 (Attach or detach from GPRS service, GPRS 附着状态) 说的简单点,这一步就是让SGSN (服务GPRS节点,你可以把它理解成与基站 ...
- 电脑桌面文件图标经常显示异常&&右键桌面文件属性不显示
桌面图标经常失效,但文件可以正常点开使用. 右键桌面文件的属性,电脑无反应. 解决方法 ① cmd-sfc/scannow 此方法无效 ② 点击上图的运行疑难解答,最终找到问题,重启后解决! PS 型 ...
- Linux Shell read命令
linux read 用法 1.基本读取 read命令接收标准输入(键盘)的输入,或其他文件描述符的输入(后面在说).得到输入后,read命令将数据放入一个标准变量中.下面是 read命令 的最简单形 ...