123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218 |
- import { _decorator, Collider, Enum, Node, RigidBody, SkeletalAnimation, Vec3 } from 'cc';
- import { BaseExp } from '../core/base/BaseExp';
- import { PoolManager } from '../core/manager/PoolManager';
- import { userIns } from '../data/UserData';
- import { autoBind } from '../extend/AutoBind';
- import { Logger } from '../extend/Logger';
- import { ResUtil } from '../utils/ResUtil';
- import { Game } from './Game';
- import { Enemy, EPartType } from './Enemy';
- import { audioMgr } from '../core/manager/AudioManager';
- import { Constants } from '../data/Constants';
- import MsgHints from '../utils/MsgHints';
- const { ccclass, property } = _decorator;
- /**
- * 战场障碍物类型
- */
- export enum ObstacleType {
- /** 沙袋堆 */
- SANDBAG_PILE = "沙袋堆",
- /** 油桶 */
- OIL_BARREL = "油桶",
- /** 军车 */
- MILITARY_TRUCK = "军车",
- /** 小沙袋 */
- SMALL_SANDBAG = "小沙袋"
- }
- /**
- * 杂物建筑物类
- */
- @ccclass('Sundries')
- export class Sundries extends BaseExp {
- @property({ type: Enum(ObstacleType), tooltip: "SANDBAG_PILE: 沙袋堆 OIL_BARREL: 油桶 MILITARY_TRUCK: 军车 SMALL_SANDBAG: 小沙袋 ", displayName: "障碍物类型"})
- public obstacleType: ObstacleType = ObstacleType.SANDBAG_PILE;
- @autoBind({type: SkeletalAnimation,tooltip: "杂物动画节点"})
- public skeletal: SkeletalAnimation = null!;
- //杂物信息数据
- public data: any = null;
- //杂物是否被打报废
- private isDead: boolean = false;
- //杂物当前的总血量
- private totalHp: number = 0;
- //杂物身上的Collider
- public collider: Collider = null!;
-
- start() {
- this.collider = this.node.getComponent(Collider);
- if(this.collider){
- this.collider["args"] = [EPartType.sundries,this];
- }
- //根据障碍物类型设置总血量
- let sundrie_id: number = -1;
- switch (this.obstacleType) {
- case ObstacleType.SANDBAG_PILE:
- sundrie_id = 11001;
- break;
- case ObstacleType.OIL_BARREL:
- sundrie_id = 11002;
- break;
- case ObstacleType.MILITARY_TRUCK:
- sundrie_id = 11003;
- break;
- case ObstacleType.SMALL_SANDBAG:
- sundrie_id = 11004;
- break;
- }
- if(sundrie_id !== -1){
- const data: any = userIns.sundriesTable.find(e=>e.id == sundrie_id);
- this.data = data;
- this.totalHp = data.hp;
- }else{
- Logger.log('未找到对应的杂物信息');
- }
- }
- /**
- * 杂物被打掉血
- * @param hp 血
- * @param pData 玩家数据
- */
- public subHP(hp: number, pData:any){
- if(Game.I.isPause
- ||this.isDead
- ||hp == null
- ||this.totalHp <= 0){
- return;
- }
- MsgHints.show(`${this.node.name} HP:`+hp)
- this.totalHp -= hp;
- //杂物打打死报废
- if(this.totalHp <= 0
- && !this.isDead){
- this.isDead = true;
- this.scrap();
- }
- }
-
- /**
- * 杂物被打报废
- */
- public scrap(){
- switch (this.obstacleType) {
- case ObstacleType.SANDBAG_PILE:{//沙袋堆
- if(this.skeletal)return;
- //沙袋掀开的动画
- this.skeletal.play('take');
- this.scheduleOnce(this.recycle.bind(this), 1.5);
- }
- break;
- case ObstacleType.OIL_BARREL:{//油桶
- //油漆桶爆炸动画
- audioMgr.playOneShot(Constants.audios.Oildrum_explosion);
- //爆炸后生成爆炸特效 粒子路径、自动回收时间、外部设置回调
- ResUtil.playParticle(
- `effects/Prefabs/OilBoom`,
- 4,
- (particle) => {
- particle.position = new Vec3(0.1,0.1, 0.1);
- particle.children.forEach((c) => {
- c.position = new Vec3(0.1, 0.1, 0.1);
- });
- particle.parent = Game.I.map.node;
- particle.worldPosition = this.node.worldPosition.clone();
- particle.active = true;
- this.recycle();
- //爆炸后生成爆炸伤害
- this.explosionDamage();
- }
- );
- }
- break;
- case ObstacleType.MILITARY_TRUCK:{//军车
- //加载报废的军车
- ResUtil.loadRes(`enemy/sundries/scrap_car`, this.node)
- .then((military: Node | null) => {
- if(!military)return;
- military.active = true;
- military.parent = Game.I.map.node;
- military.worldPosition = this.node.worldPosition.clone();
- //回收原有的军车
- this.recycle();
- //播放爆炸过后的浓烟
- ResUtil.playParticle(
- `effects/Prefabs/HeavySmoke`,
- 4,
- (particle) => {
- particle.parent = Game.I.map.node;
- particle.worldPosition = this.node.worldPosition.clone();
- particle.active = true;
- particle.scale = new Vec3(0.5, 0.5, 0.5);
- //爆炸后生成爆炸伤害
- this.explosionDamage();
- }
- );
- });
- }
- break;
- case ObstacleType.SMALL_SANDBAG:{//小沙袋
- //获取刚体组件
- const rigidBody = this.node.getComponent(RigidBody);
- if (!rigidBody) return;
- //计算抛射方向
- const startPos = this.node.worldPosition.clone();
- const playerPos = Game.I.player.node.worldPosition.clone();
- const direction = startPos.subtract(playerPos).normalize();
- //随机抛射参数 水平力1500-2500N
- const horizontalForce = 1500 + Math.random() * 1000;
- //垂直力800-1500N
- const verticalForce = 800 + Math.random() * 700;
- //旋转扭矩50-150
- const torqueForce = 50 + Math.random() * 100;
- //施加作用力
- rigidBody.applyForce(new Vec3(
- direction.x * horizontalForce,
- verticalForce,
- direction.z * horizontalForce
- ));
- //施加旋转扭矩
- rigidBody.applyTorque(new Vec3(0, torqueForce, 0));
- }
- break;
- }
- }
- /**
- * 爆炸物产生爆炸伤害
- * @returns
- */
- public explosionDamage(){
- //爆炸半径
- const eRadius: number = this.data.explosion_radius;
- const allEnemys = Game.I.buildEnemys.allEnemys.filter(e=>!e.isDead);
- if(allEnemys.length <= 0)return;
- //爆炸伤害
- const damage: number = this.data.explosion_injury;
- allEnemys.forEach((e: Enemy) => {
- const ePos: Vec3 = e.node.worldPosition;
- const sPos: Vec3 = this.node.worldPosition;
- const distance = ePos.clone().subtract(sPos).length();
- if(distance <= eRadius) {
- e.subHP(damage, this.data);
- }
- })
- }
- /**
- * 杂物回收
- */
- public recycle(){
- if(this.node.parent){
- this.isDead = true;
- PoolManager.putNode(this.node);
- }
- }
- }
|