import { _decorator, Vec3,Node, geometry, PhysicsSystem, PhysicsRayResult} from 'cc'; import { PoolManager } from '../../core/manager/PoolManager'; import { Game } from '../../game/Game'; import { BulletBase } from '../base/BulletBase'; import { GunBase } from '../base/GunBase'; import { Sundries } from '../../game/Sundries'; import { Enemy } from '../../game/Enemy'; import { GameEnums } from '../../data/GameEnums'; import { GunAttribute, userIns } from '../../data/UserData'; const { ccclass, property } = _decorator; //玩家所用子弹 连狙子弹 @ccclass('Bullet3') export class Bullet3 extends BulletBase { //是否必死 必死的子弹不会回收 要自己控制 private isRemoveDead: boolean = false; //射击方向的位置 private vector: Vec3 = null; //计算子弹停留时间 private time: number = 0.6; /** * 初始化一个子弹 * @param gun 属于哪把枪 * @param isRemoveDead 是否不受控制的子弹自己管理 */ public init(gun:GunBase,isRemoveDead:boolean = true){ this.gunBase = gun; this.isDead = false; this.isRemoveDead = isRemoveDead; } /** * 设置子弹开始位置和射击方向 * @param v 射向的方向 */ public setBulletVector(v: Vec3){ this.time = this.getBulletTime(); const bulletSpeed = this.gunBase.data.bulletSpeed / 3; this.vector = v.clone().multiplyScalar(bulletSpeed); this.node.forward = v; } /** * 射击速度发生改变 */ public speedChange() { const bulletSpeed = this.gunBase.data.bulletSpeed; if(this.vector) { this.vector = this.vector.normalize().multiplyScalar(bulletSpeed); } } /** * 实时帧更新 */ public update(deltaTime: number) { if(Game.I.isGameOver || Game.I.isPause) { this.isDead = true; PoolManager.putNode(this.node); return; } if(this.vector) { const moveDelta = this.vector.clone().multiplyScalar(deltaTime); this.node.worldPosition = this.node.worldPosition.add(moveDelta); //开始检测射击 this.scheduleOnce(this.rayPreCheck,this.time); } } /** * 检测射击 * @param b * @param len 检测 */ private rayPreCheck() { let screenPos: Vec3 = this.stabilityGetBulletPos(180); //射线检测 const r = geometry.Ray.create(); Game.I.camera.screenPointToRay(screenPos.x, screenPos.y, r); const hasHit = PhysicsSystem.instance.raycast(r, 0xffffffff, 100000, true); const raycastResults:PhysicsRayResult[] = PhysicsSystem.instance.raycastResults; if(hasHit && raycastResults.length > 0){ const gunPos = this.gunBase.node.worldPosition; raycastResults.sort((a, b) => { const aDist = Vec3.distance(a.hitPoint, gunPos); const bDist = Vec3.distance(b.hitPoint, gunPos); return aDist - bDist; }); //先查找 要检测的物体 对象上带args参数的就是优先检测的 let targetResult: PhysicsRayResult | null = null; for (const result of raycastResults) { if (result.collider["args"]) { targetResult = result; break; } } targetResult = targetResult ?? raycastResults[0]; this.addHitImpact(targetResult); const args:any = targetResult.collider["args"]; if(args){ let [type,cls] = args; let attack: number = this.gunBase.data.attack; if(cls instanceof Enemy){ const e: Enemy = cls as Enemy; //爆头击杀 let isHeadShot:boolean = false; if(type == GameEnums.enemyPartType.head){ Game.I.player.headShotNum += 1; attack = Game.I.player.pData.headshotDmgMul * attack; isHeadShot = true; } //打到了盾兵上的盾 if(type == GameEnums.enemyPartType.shield && e.shieldHp > 0){ e.shieldHp -= attack; return; } e.isShotHead = isHeadShot; //坦克是单独的碰撞体 if(e.isTank()){ if(type == GameEnums.enemyPartType.tank){ e.subHP(attack,this.gunBase.data); } }else{ e.raycastResults = targetResult; e.subHP(attack,this.gunBase.data); } }else if(cls instanceof Sundries){ const sundrie: Sundries = cls as Sundries; sundrie.subHP(attack,this.gunBase.data,Game.I.player.node); } } //自动回收了子弹 this.autoRecycle(); } } }