goods.ts 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. import { _decorator, Component, Vec3, RigidBody, CylinderCollider, BoxCollider, tween, Collider, ICollisionEvent, } from 'cc';
  2. import { AudioManager } from '../framework/audioManager';
  3. import { clientEvent } from '../framework/clientEvent';
  4. import { EffectManager } from '../framework/effectManager';
  5. import { playerData } from '../framework/playerData';
  6. import { poolManager } from '../framework/poolManager';
  7. import { gameConstants } from './gameConstants';
  8. import { gameManager } from './gameManager';
  9. const { ccclass, property } = _decorator;
  10. const v3_init = new Vec3();
  11. @ccclass('Goods')
  12. export class Goods extends Component {
  13. public goodsIndex: number = 0; // 当前物品判断帧数
  14. public uuidstr:string="";
  15. public addGold: number = -1; // 获得当前物品增加金币数
  16. public isPresent: boolean = false; // 当前是否为礼物
  17. /**
  18. * 初始化物品
  19. * @param id 当前判断帧数
  20. * @param addGold 当前物品增加金币数
  21. * @param pos 坐标
  22. * @param eul 旋转
  23. */
  24. public initGoods(isOnColliderEvent: boolean,id: number, uuidx: string, pos: Vec3, eul?: Vec3) {
  25. this.uuidstr=uuidx;
  26. this.goodsIndex = id;
  27. this.node.setPosition(pos);
  28. if (eul) {
  29. this.node.setRotationFromEuler(eul);
  30. }
  31. let collider;
  32. if (this.node.getComponent(RigidBody)) {
  33. this.node.getComponent(RigidBody)!.wakeUp();
  34. collider = this.node.getComponent(Collider);
  35. } else {
  36. if (this.node.name === gameConstants.GOLD_NAME) {
  37. collider = this.getComponent(Collider);
  38. } else {
  39. this._createRigidBody();
  40. collider = this._createPresentCollider();
  41. }
  42. }
  43. if (isOnColliderEvent) {
  44. collider!.on('onCollisionEnter', this._onCollisionEnter, this);
  45. }
  46. // }
  47. if (this.node.name === gameConstants.GOLD_NAME) {
  48. this.addGold = gameConstants.GOLD_ADD_GOLD_NUM;
  49. } else {
  50. this.isPresent = true;
  51. this.addGold = gameConstants.PRESENT_ADD_GOLD_NUM;
  52. if (pos.y === gameConstants.PRESENT_DROP_Y) {
  53. // 从上方掉落的礼物
  54. EffectManager.instance.playGetPresent(this.node);
  55. // 施加向上力
  56. if (this.node.getComponent(RigidBody)!) {
  57. this.node.getComponent(RigidBody)!.applyImpulse(new Vec3(0, 4, 0));
  58. }
  59. this.node.setScale(0, 0, 0);
  60. this.node.setRotationFromEuler(0, 0, 0);
  61. const randomNum = () => (Math.random() > 0.5 ? 1 : -1) * Math.random() * 80 + (Math.random() > 0.5 ? 100 : -100);
  62. tween(this.node)
  63. .to(0.3, {
  64. scale: new Vec3(1, 1, 1),
  65. })
  66. .start();
  67. tween(this.node)
  68. .to(1, {
  69. eulerAngles: new Vec3(randomNum(), randomNum(), randomNum()),
  70. })
  71. .start();
  72. }
  73. }
  74. }
  75. private _onCollisionEnter(e: ICollisionEvent) {
  76. // TODO:掉落到平台上的声音一次太多个
  77. const otherName = e.otherCollider.node.name;
  78. if (otherName === gameConstants.WALL_NAME
  79. || otherName === gameConstants.GOLD_NAME) return; // 碰到旁边的墙壁无效、金币
  80. if (otherName === gameConstants.WALL_NAME_PUSH) {
  81. const v3_pos = new Vec3();
  82. // 判断发生碰撞的另外一个物体的碰撞点
  83. if (e.contacts[0].isBodyA) {
  84. e.contacts[0].getWorldPointOnB(v3_pos);
  85. } else {
  86. e.contacts[0].getWorldPointOnA(v3_pos);
  87. }
  88. if (v3_pos.y > gameConstants.SOUND_PUSH_CHECK_Y) {
  89. AudioManager.instance.playSound(`${gameConstants.SOUND_NAME_LIST.DROP}2`);
  90. }
  91. } else if (otherName === gameConstants.WALL_NAME_DOWN_FLOOR) {
  92. this.node.getComponent(Collider)!.off('onCollisionEnter', this._onCollisionEnter, this);
  93. AudioManager.instance.playSound(`${gameConstants.SOUND_NAME_LIST.DROP}2`);
  94. }
  95. }
  96. /**
  97. * 创建刚体
  98. */
  99. private _createRigidBody() {
  100. const rigidBody = this.node.addComponent(RigidBody);
  101. rigidBody.type = RigidBody.Type.DYNAMIC;
  102. rigidBody.setGroup(gameConstants.GROUP_MASK_LIST.GOODS);
  103. rigidBody.setMask(gameConstants.GROUP_MASK_LIST.GOODS + gameConstants.GROUP_MASK_LIST.WALL);
  104. rigidBody.mass = 0.5;
  105. rigidBody.allowSleep = false;
  106. rigidBody.useGravity = true;
  107. // 防止快速穿透 开启后金币掉落效果不够好
  108. // https://docs.cocos.com/creator/3.3/manual/zh/physics/physics-ccd.html?h=cdd
  109. // rigidBody.useCCD = true;
  110. }
  111. /**
  112. * 创建金币碰撞体
  113. */
  114. private _createGoldCollider() {
  115. const collider = this.node.addComponent(CylinderCollider);
  116. // collider.isTrigger = false;
  117. collider.radius = gameConstants.GOLD_CYLINDER_RADIUS;
  118. collider.height = gameConstants.GOLD_CYLINDER_HEIGHT;
  119. collider.direction = CylinderCollider.Axis.Z_AXIS;
  120. v3_init.set(0, 0, 0);
  121. collider.center = v3_init;
  122. return collider;
  123. }
  124. /**
  125. * 创建礼物碰撞体
  126. */
  127. private _createPresentCollider() {
  128. const collider = this.node.addComponent(BoxCollider);
  129. const id = gameConstants.PRESENT_NAME_LIST.indexOf(this.node.name);
  130. const presentColliderData = gameConstants.INITSCENE_PRESENT_COLLIDER[id];
  131. v3_init.set(presentColliderData.size.x, presentColliderData.size.y, presentColliderData.size.z);
  132. collider.size = v3_init;
  133. v3_init.set(presentColliderData.center.x, presentColliderData.center.y, presentColliderData.center.z);
  134. collider.center = v3_init;
  135. return collider;
  136. }
  137. public getGoods() {
  138. //console.error("掉落物品>>>>:",this.uuidstr);
  139. //playerData.instance.updatePlayerInfo('gold', this.addGold);
  140. gameManager.Instance.DiaoLuoCallback(this);
  141. if (this.addGold === gameConstants.PRESENT_ADD_GOLD_NUM) {
  142. AudioManager.instance.playSound(gameConstants.SOUND_NAME_LIST.GETPRESENT);
  143. EffectManager.instance.playCelebrate();
  144. } else {
  145. AudioManager.instance.playSound(`${gameConstants.SOUND_NAME_LIST.GETGOLD}1`);
  146. }
  147. this.addGold = 0;
  148. //clientEvent.dispatchEvent(gameConstants.EVENT_LIST.GOLD_SHOW_UPDATE);
  149. }
  150. public putPoolGoods() {
  151. this.node.getComponent(Collider)!.off('onCollisionEnter', this._onCollisionEnter, this);
  152. this.node.getComponent(RigidBody)?.sleep();
  153. poolManager.instance.putNode(this.node);
  154. }
  155. }