import { _decorator, Component, Sprite, SpriteFrame, UITransform, v3, Vec3, sp, Quat } from 'cc'; import { DataSystem } from '../core/data/DataSystem'; import { ResourceLoader } from '../core/resourceManager/ResourceLoader'; import { ConfigData } from '../data/ConfigData'; import { BattleData, BattleState } from './BattleData'; import { BulletData } from './BulletData'; import { Monster } from './Monster'; const { ccclass, property } = _decorator; @ccclass('Bullet') export class Bullet extends Component { @property({ type: Sprite, tooltip: "子弹资源" }) bulletSprite: Sprite; @property({ type: sp.Skeleton, tooltip: "受击特效" }) hitEffect: sp.Skeleton; @property({ type: [sp.SkeletonData], tooltip: "受击特效集合" }) hitArray: Array = []; @property({ type: [SpriteFrame], tooltip: "子弹精灵集合" }) bulletSprites: Array = []; private _battle: BattleData; private data: BulletData; private target: Monster; private config: any; private beenHit = false; private get battle(): BattleData { if (!this._battle) { this._battle = DataSystem.getData(BattleData); } return this._battle; } async start() { this.config = DataSystem.getData(ConfigData)["skill"]; } update(dt: number) { if (this.target && this.target.node && this.battle.battleState == BattleState.inBattle) { if (!this.beenHit) { this.move(); this.look(); this.checkHit(); } } else { this.node.destroy(); } } public async setData(data: BulletData) { this.data = data; if (this.data) { // this.hitEffect = this.node.addComponent(sp.Skeleton); let spData = this.hitArray[this.data.hit_res - 1]; this.hitEffect.skeletonData = spData; this.target = DataSystem.getData(BattleData)._monsters[this.data.target]; this.bulletSprite.spriteFrame = this.bulletSprites[data.res - 1]; let direction = this.battle.slots.get(data.from)._direction; let offset = direction == 1 ? -this.battle.slots.get(data.from).node.getComponent(UITransform).width / 2 : this.battle.slots.get(data.from).node.getComponent(UITransform).width / 2; this.node.scale = this.battle.slots.get(data.from).node.scale; this.node.setPosition(v3(this.battle.slots.get(data.from).node.position).add(v3(offset, 0, 0))); this.bulletSprite.node.scale.multiplyScalar(this.data.isLeader ? 1 : 0.8); } } /**子弹转向 */ private look(): void { let radian = 0; let node = this.target.node; let tran = this.target.node.getComponent(UITransform); if (this.node.scale.x < 0) { radian = Math.atan2((node.position.y + tran.height / 2) - this.node.position.y, node.position.x - this.node.position.x); } else { radian = Math.PI - Math.atan2(this.target.node.position.y - this.node.position.y, this.target.node.position.x - this.node.position.x); if (radian > Math.PI) { radian -= Math.PI * 2; } radian = -radian; } let distance = Vec3.distance(this.node.position, v3(this.target.node.position.clone().add(v3(0, this.target.getComponent(UITransform).height * this.target.node.scale.y / 20, 0)))); if (distance > 150 || this.node.rotation.z == 0) {//位置接近时,停止转向 this.node.setRotationFromEuler(v3(0, 0, 180 / Math.PI * radian)); } else { this.node.setRotation(this.node.rotation); } } /**子弹移动 */ private move(): void { let node = this.target.node; let tran = this.target.node.getComponent(UITransform); let angle = Math.atan2((node.position.y + tran.height * node.scale.y / 2) - this.node.position.y, node.position.x - this.node.position.x); this.node.position.add(v3(Math.cos(angle) * this.data.speed, Math.sin(angle) * this.data.speed, 0)); } /**检查是否击中 */ private checkHit() { let targetPosition = this.target.node.position.clone(); targetPosition.y += this.target.getComponent(UITransform).height * this.target.node.scale.y / 2; let distance = Vec3.distance(this.node.position, targetPosition); if (distance <= 10) { this.hit(); } } /**击中 */ private async hit() { this.beenHit = true; let node = this.target.node; let tran = this.target.node.getComponent(UITransform); this.node.position = v3(node.position.x, node.position.y + tran.height * node.scale.y / 2, node.position.z); this.bulletSprite.node.active = false; this.node.setRotationFromEuler(v3(0, 0, 0)); this.hitEffect.addAnimation(0, "animation", false); this.hitEffect.setCompleteListener(() => { let config = this.config[this.data.skillID]["attType"]; let type = parseInt(config.split(":")[0]); if (type == 1) { DataSystem.getData(BattleData)._hitMonster.push(this.data); } else { this.pushRangeMonsterToHit(); } this.node.destroy(); }); } /**将攻击范围内的敌人放入受击容器 */ private pushRangeMonsterToHit(): void { let node = this.target.node; let config = this.config[this.data.skillID]["attType"]; let range = parseInt(config.split(":")[1].split(",")[0]); let maxCount = parseInt(config.split(":")[1].split(",")[1]); let monsters = DataSystem.getData(BattleData)._monsters; let result = []; for (let i = 0; i < monsters.length; i++) { if (Vec3.distance(node.position, monsters[i].node.position) <= range) { if (result.length < maxCount - 1) { result.push(i); } } } DataSystem.getData(BattleData)._hitMonster.push(this.data); for (let j = 0; j < result.length; j++) { DataSystem.getData(BattleData)._hitMonster.push(this.data); } } }