123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493 |
- import { utils } from "../../common-plugin/Scripts/Utils";
- import { cocosz } from "../Framework/CocosZ";
- import Constant, { PanelName, ZindexLayer } from "../Framework/Constant";
- import Bullet from "./bullet";
- import GameDate from "./gameDate";
- import { gameMgr } from "./gameMgr";
- import Person from "./person";
- import { SkillType, upgradeMgr } from "./UpgradeMgr";
- import Weapon from "./weapon";
- // @ts-ignore
- const i18n = require('LanguageData');
- const { ccclass, property } = cc._decorator;
- @ccclass
- export default class Player extends Person {
- onLoad() {
- this.isPlayer = true;
- this.id = 1;
- gameMgr.playerTs = this;
- if (this.hpSpr) {
- this.hpSpr.color = cc.Color.GREEN;
- }
- if (this.atkBar) {
- this.atkBar.node.children[1].color = cc.Color.YELLOW;
- }
- this.rig = this.node.getComponent(cc.RigidBody);
- if (this.rig) { this.rig.linearDamping = 0.2; }
- this.playerMess = this.node.getChildByName("playerMess");
- this.hpNumNode = this.playerMess.getChildByName("hpNum");
- // 光环
- this.ghAniNode = this.node.getChildByName("gh");
- // 烟尘
- this.ycAniNode = this.node.getChildByName("yc");
- // 相机跟随
- gameMgr.followNode = this.node;
- // 防止玩家和僵尸碰撞
- if (cocosz.gameMode == 6) {
- if (this.rig && this.rig.isValid) {
- this.rig.enabledContactListener = true;
- }
- }
- }
- start() {
- super.start();
- this.setProperty();
- this.node.zIndex = ZindexLayer.zindex_player;
- if (this.ghAniNode && this.ghAniNode.isValid) {
- this.ghAniNode.setParent(this.node.parent);
- this.ghAniNode.zIndex = ZindexLayer.zinedx_gh;
- this.updateGhAni();
- }
- if (this.ycAniNode && this.ycAniNode.isValid) {
- this.ycAniNode.setParent(this.node.parent);
- this.ycAniNode.zIndex = ZindexLayer.zinedx_footYc;
- this.updateYcAni();
- }
- // 血条
- if (this.hpSpr) {
- this.hpSpr.color = cc.Color.GREEN;
- }
- }
- lateUpdate(dt) {
- this.curTime++;
- if (cocosz.isPause || this.isDeath || gameMgr.isWin || gameMgr.isFail) {
- this.rig.linearVelocity = cc.v2(0, 0);
- return;
- };
- if (this.curTime % 15 == 0) {
- this.updateAni();
- this.creatFootPrint();
- }
- this.updateAtk();
- this.updatePerson();
- this.udpateRBody(this.moveDir);
- this.updateMess();
- this.updateGhAni();
- this.updateYcAni();
- if (this.atkTarget && this.atkTarget.isValid) {
- this.atkEnemy();
- }
- }
- recoverEffect() {
- let node = cc.instantiate(gameMgr.itemEffect[0]);
- node.parent = this.node;
- }
- lastTime: number = 0;
- checkTarget() {
- if (Number(new Date()) - this.lastTime < 500) return;
- this.lastTime = Number(new Date());
- let num = this.atkList.indexOf(this.atkTarget);
- if (num >= 0) {
- if (num == this.atkList.length - 1) {
- num = 0;
- }
- else {
- num += 1;
- }
- this.atkTarget = this.atkList[num];
- }
- else {
- this.atkTarget = this.atkList[0];
- }
- }
- lastAtkTime: number = 0;
- atkBulletNum: number = 1;
- atkEnemy() {
- if (!this.curWeapon || !this.curWeapon.isValid || this.isAtk) return;
- if (this.curWeapon && this.curWeapon.isRangeWeapon) {
- // 是否有子弹
- if (this.curWeapon._isReload || this.curWeapon.curBullet <= 0) {
- return;
- } else {
- if (cocosz.gameMode == 6 && this.curWeapon.curBullet == 1) {
- cc.game.emit(Constant.E_GAME_LOGIC, { type: Constant.E_Bullet_Last, node: this.node });
- }
- this.curWeapon.curBullet--;
- }
- // 抖动效果
- let t = (this.atkSpeed > 0.1 ? 0.1 : this.atkSpeed) / 3;
- cc.tween(this.rangedWeapon.children[0])
- .by(t, { x: -20, angle: 20 })
- .by(t, { x: 20, angle: -20 })
- .start();
- // 攻击效果
- let pos = this.startPosNode.getPosition();
- if (this.curWeapon.atkEffect) {
- let effect = cc.instantiate(this.curWeapon.atkEffect);
- if (this.curWeapon.weaponNum == 9 || this.curWeapon.weaponNum == 15) {
- this.node.parent.addChild(effect, ZindexLayer.zindex_effect_fire, "effect");
- effect.setPosition(this.startPosNode.parent.convertToWorldSpaceAR(pos).sub(cc.v2(cc.winSize.width / 2, cc.winSize.height / 2)));
- if (this.body.scaleX > 0) {
- effect.angle = this.rangedWeapon.angle;
- }
- else {
- effect.angle = 180 - this.rangedWeapon.angle;
- }
- }
- else {
- this.curWeapon.node.addChild(effect, 1, "effect");
- effect.setPosition(pos);
- }
- // 升级开火特效
- // if (this.curWeapon.can_effect_hit && this.curWeapon && this.curWeapon.weaponLevel > 0) {
- // let effect_fire = cc.instantiate(gameMgr.effect_fire);
- // effect_fire.parent = effect.parent;
- // effect_fire.setPosition(effect.position);
- // effect_fire.angle = effect.angle;
- // // 颜色
- // let arr = ["", "y", "p", "r"];
- // let spAni = effect_fire.children[0].getComponent(sp.Skeleton);
- // spAni && spAni.setSkin(arr[this.curWeapon.weaponLevel]);
- // }
- }
- }
- else {
- gameMgr.shakeEffect(2, 1, false);//屏幕晃动
- let ani = this.meleeWeapon.getComponent(cc.Animation);
- ani && ani.isValid && ani.play("atk_dao");
- this.scheduleOnce(() => {
- ani && ani.isValid && ani.play("daiji_dao");
- }, 0.18)
- }
- // 生成子弹
- let dir;
- if (this.atkDir && !this.atkDir.equals(cc.Vec2.ZERO)) {
- dir = this.atkDir;
- } else if (this.moveDir && !this.moveDir.equals(cc.Vec2.ZERO)) {
- dir = this.moveDir;
- } else {
- dir = this.body.scaleX > 0 ? cc.Vec2.RIGHT : cc.Vec2.RIGHT.negSelf();
- }
- if (this.atkBulletNum > 1) {
- for (let i = 0; i < this.atkBulletNum; i++) {
- let angle = ((this.atkBulletNum - 1) / 2 - i) * 15;
- let new_dir: cc.Vec2 = dir.rotate(cc.misc.degreesToRadians(angle));
- this.createBullet(new_dir);
- }
- } else {
- this.createBullet(dir);
- }
- // 攻击表情
- let t = this.atkSpeed > 0.1 ? 0.1 : this.atkSpeed;
- cc.tween(this.head_atk)
- .set({ opacity: 255 })
- .delay(t)
- .set({ opacity: 0 })
- .start();
- this.isAtk = true;
- if (this.curWeapon.isRangeWeapon && this.curWeapon.curBullet <= 0) {
- cc.tween(this.node)
- .delay(this.curWeapon.reload)
- .call(() => {
- this.isAtk = false;
- })
- .start();
- } else {
- cc.tween(this.node)
- .delay(this.atkSpeed)
- .call(() => {
- this.isAtk = false;
- })
- .start();
- }
- // 攻击音效
- let name = Weapon.WeaponName[this.curWeapon.weaponNum - 1];
- if (GameDate.Weapon[name] && GameDate.Weapon[name].music) {
- gameMgr.playEffect("shot_" + GameDate.Weapon[name].music, this.node);
- } else {
- gameMgr.playEffect(`shot_${Weapon.WeaponName[this.curWeapon.weaponNum - 1]}`, this.node);
- }
- }
- createBullet(dir: cc.Vec2) {
- let bullet = cc.instantiate(this.curWeapon.bullet);
- if (this.curWeapon.isRangeWeapon) {
- bullet.parent = this.node.parent;
- let fromPos = bullet.parent.convertToNodeSpaceAR(this.startPosNode.convertToWorldSpaceAR(cc.Vec2.ZERO));
- bullet.setPosition(fromPos);
- bullet.angle = -cc.v2(dir).signAngle(cc.v2(1, 0)) / Math.PI * 180;
- if (this.curWeapon.weaponNum == 2) {
- bullet.angle += (5 - Math.random() * 10);
- }
- if (this.curWeapon.flySpeed > 0) {
- let pos1 = bullet.getPosition();
- let pos2 = pos1.add(dir.mul(this.curWeapon.atkRangeNum));
- cc.tween(bullet)
- .to(pos2.sub(pos1).mag() / this.curWeapon.flySpeed, { position: cc.v3(pos2) })
- .call(() => {
- let ts = bullet.getComponent(Bullet);
- if (ts.boomEffect) {
- let boom = cc.instantiate(ts.boomEffect)
- boom.parent = ts.node.parent;
- boom.setPosition(ts.node.getPosition());
- let curBullet = boom.getComponent(Bullet);
- curBullet.atk = ts.atk;
- curBullet.atker = ts.atker;
- curBullet.id = ts.id;
- gameMgr.playEffect("explo", boom);
- if (ts.hitEffect) {
- let pos = bullet.getPosition();
- let node = cc.instantiate(ts.hitEffect);
- node.parent = bullet.parent;
- node.setPosition(pos);
- node.zIndex = ZindexLayer.zindex_effect_hit;
- }
- }
- bullet.destroy()
- })
- .start();
- // 弹壳
- if (this.curWeapon.shellCall) {
- let shellCase = cc.instantiate(this.curWeapon.shellCall);
- shellCase.setParent(gameMgr.map);
- shellCase.setPosition(this.node.position);
- shellCase.scaleX = this.body.scale;
- }
- } else {
- cc.tween(bullet).delay(0.4).call(() => {
- bullet.destroy()
- }).start();
- }
- let ts = bullet.getComponent(Bullet);
- ts.id = this.id;
- ts.atker = this.node;
- ts.atk = (this.atkNum + this.personAtk) * this.atkRate;
- ts.dir = dir;
- }
- else {
- this.node.addChild(bullet, -1);
- bullet.color = this.curWeapon.bulletCollor;
- if (this.atkDir.x < 0) {
- bullet.scaleX *= -1 / this.node.scaleX;
- }
- else {
- bullet.scaleX /= this.node.scaleX;
- }
- bullet.scaleY /= this.node.scaleY;
- cc.tween(bullet).delay(0.2).call(() => { bullet.destroy() }).start();
- let ts = bullet.getComponent(Bullet);
- ts.id = this.id;
- ts.atker = this.node;
- ts.atk = (this.atkNum + this.personAtk) * this.atkRate;
- ts.dir = dir;
- }
- }
- hart(atkNum: number, from: cc.Node, dir: cc.Vec2 = null, isAudio: boolean = true) {
- if (cocosz.isPause || this.isDeath || this.isAvoidInjury) return;
- if (cocosz.gameMode == 6 && upgradeMgr) {
- // 移动过程中15%的概率免伤
- if (upgradeMgr.isHaveSkill(SkillType.护甲靴子) && this.moveDir.mag() > 0 && Math.random() < 0.4) {
- // gameMgr.showRoleTip(this.node, "闪避", cc.Color.YELLOW);
- return;
- }
- else if (upgradeMgr.isHaveSkill(SkillType.神圣守护) && upgradeMgr.hudun && upgradeMgr.hudun.active) {
- upgradeMgr.updateHudun();
- // gameMgr.showRoleTip(this.node, "免伤", cc.Color.YELLOW);
- return;
- }
- }
- // 防止dir过大
- if (dir && dir.mag() > 3) dir.normalizeSelf().mulSelf(3);
- // 减伤
- atkNum = (1 - this.damageReduction) * atkNum;
- // 护盾
- if (this.Shiled > 0) {
- this.Shiled -= atkNum;
- if (this.Shiled < 0) {
- atkNum = -this.Shiled;
- this.Shiled = 0;
- } else {
- return;
- }
- }
- // 数字
- if (cocosz.gameMode != 6) {
- gameMgr.showRoleTip(this.node, Math.min(this.HP, atkNum).toFixed(0));
- }
- this.HP -= atkNum;
- // 受伤音效
- if (isAudio) {
- if (from) {
- let ts = from.getComponent(Person);
- if (ts && ts.curWeapon && ts.curWeapon.isRangeWeapon) {
- gameMgr.playEffect("hurt_range", this.node);
- } else {
- gameMgr.playEffect("hurt_melee", this.node);
- }
- } else {
- gameMgr.playEffect("hurt", this.node);
- }
- }
- // 屏幕闪红
- if (cocosz.gameMode == 6) {
- cc.tween(gameMgr.red)
- .to(0.5, { opacity: 255 }, { easing: "sineOut" })
- .to(0.5, { opacity: 0 }, { easing: "sineIn" })
- .start();
- }
- // 震动
- cocosz.vibrate("long");
- if (this.HP <= 0) {
- if (cocosz.gameMode == 6) cocosz.audioMgr.playEffect("GameOver");
- this.death();
- if (from) {
- let ts = from.getComponent(Person);
- ts.killNum++;
- ts.curKillNum++;
- // 更新最佳成绩
- if (ts.curKillNum > ts.maxNum) {
- ts.maxNum = ts.curKillNum;
- }
- this.killer = ts;
- this.curKillNum = 0;
- }
- // 倒飞
- if (dir) {
- let p1 = this.node.getPosition();
- let pTo = p1.add(dir.normalizeSelf().mulSelf(200));
- let p2 = cc.v2((p1.x + pTo.x) / 2, p1.y + 200);
- cc.tween(this.node)
- .bezierTo(0.3, p1, p2, pTo)
- .start();
- }
- // 死亡事件
- if (cocosz.gameMode == 6) {
- cc.game.emit(Constant.E_GAME_LOGIC, { type: Constant.E_Player_Death })
- }
- } else {
- // 受伤事件
- if (cocosz.gameMode == 6) {
- this.avoidInjury(2);
- cc.game.emit(Constant.E_GAME_LOGIC, { type: Constant.E_Player_Hart })
- }
- // 效果
- if (!this.isAttackedEffect) {
- this.isAttackedEffect = true;
- // 后退
- if (this.rig.type == cc.RigidBodyType.Dynamic && dir) {
- // 控制
- this.canMove = false;
- this.scheduleOnce(() => { this.canMove = true; }, 0.1);
- // 后退
- let div = dir.mulSelf(400 * dir.mag()).addSelf(this.rig.linearVelocity);
- if (div.mag() > 500) {
- div.normalizeSelf().mulSelf(500);
- }
- this.rig.linearVelocity = div;
- }
- // 晃头
- cc.tween(this.head)
- .call(() => { this.head_hart.opacity = 255; })
- .to(0.05, { angle: 15 })
- .to(0.05, { angle: -15 })
- .to(0.05, { angle: 15 })
- .to(0.05, { angle: 0 })
- .call(() => { this.head_hart.opacity = 0; })
- .start();
- // 人物变色
- let spArr = this.body.getComponentsInChildren(cc.Sprite);
- cc.tween(this.body)
- .call(() => { spArr.forEach((v, i) => { v.isValid && v.setMaterial(0, this.mat_attacked) }) })
- .delay(0.1)
- .call(() => { spArr.forEach((v, i) => { v.isValid && v.setMaterial(0, this.mat_common) }) })
- .delay(0.1)
- .union()
- .repeat(cocosz.gameMode == 6 ? 5 : 2)
- .call(() => { this.isAttackedEffect = false; })
- .start();
- }
- }
- }
- creatFootPrint() {
- if (this.node.opacity == 0) return;
- let pos = this.node.getPosition();
- if (pos.sub(this.lastPos).mag() < 5) return;
- this.lastPos = cc.v2(pos);
- this.footNum++;
- // 脚步音效
- if (this.isPlayer && this.footNum % 3 == 0) {
- gameMgr.playEffect("footsteps", this.node);
- }
- // 脚印(雪地)
- if (gameMgr.map.name == "map2") {
- let node = new cc.Node();
- node.addComponent(cc.Sprite).spriteFrame = gameMgr.jiaoyin;
- cc.tween(node).delay(0.5).to(0.5, { opacity: 0 }).call(() => { node.destroy() }).start();
- node.parent = this.node.parent;
- node.zIndex = ZindexLayer.zinedx_footPrint;
- if (this.moveDir.mag() > 0) node.angle = 360 - cc.v2(this.moveDir).signAngle(cc.v2(1, 0)) / Math.PI * 180;
- pos.y -= 100 * this.node.scale;
- let pos2 = cc.v2(20, 0).rotate(node.angle / 180 * Math.PI).rotate(this.footNum % 2 == 0 ? Math.PI / 2 : -Math.PI / 2)
- pos.addSelf(pos2);
- node.setPosition(pos);
- }
- }
- // 0:检测碰撞;1:检测子弹;2:检测在层级下,3:检测在层级上
- onCollisionEnter(other: cc.Collider, self: cc.Collider) {
- if (self.tag == 0) {
- // 敌人
- if (other.tag == 1) {
- let ts = other.node.getComponent(Person);
- if (ts && ts.id != this.id) {
- this.atkList.push(other.node);
- if (!cc.isValid(this.atkTarget) && other.node.isValid) {
- this.atkTarget = other.node;
- }
- }
- }
- }
- }
- onCollisionExit(other: cc.Collider, self: cc.Collider) {
- if (self.tag == 0) {
- let num = this.atkList.indexOf(other.node)
- if (other.tag == 1 && num >= 0) {
- this.atkList.splice(num, 1);
- if (this.atkList.length == 0) {
- this.atkTarget = null;
- }
- else {
- if (!cc.isValid(this.atkTarget) || other.node.uuid == this.atkTarget.uuid) {
- this.atkTarget = this.atkList[0];
- }
- }
- }
- }
- }
- // 每次将要处理碰撞体接触逻辑时被调用
- onPreSolve(contact: cc.PhysicsContact, selfCollider: cc.PhysicsCollider, otherCollider: cc.PhysicsCollider) {
- if (otherCollider.node.group == "zombie") {
- contact.disabled = true;
- }
- }
- }
|