Bird.ts 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272
  1. import EventType from "./EventType";
  2. import Fruit from "./Fruit";
  3. const {ccclass, property} = cc._decorator;
  4. @ccclass
  5. export default class Bird extends cc.Component {
  6. //sprite frames
  7. @property({type:cc.SpriteFrame})
  8. spFlyingFrames1 = [];
  9. @property({type:cc.SpriteFrame})
  10. spFlyingFrames2 = [];
  11. @property({type:cc.SpriteFrame})
  12. arrowBlue = null;
  13. @property({type:cc.SpriteFrame})
  14. arrowPink = null;
  15. //audios
  16. @property({type:cc.AudioClip})
  17. wing = null;
  18. body:cc.Node;
  19. rigidBody:cc.RigidBody;
  20. scream:cc.Node;
  21. index:number;
  22. ai:boolean;
  23. arrow:cc.Node;
  24. spFlyingFrames:cc.SpriteFrame[];
  25. spBird:cc.Sprite;
  26. currentFlyingFrame: number = 0;
  27. currentAcc: number = 0;
  28. running:boolean = false;
  29. onGroundCount:number = 0;
  30. bouncing:boolean = false;
  31. withAttack:boolean = false;
  32. speed:number = 240;
  33. basicSpeed:number = 240;
  34. quickenSpeed:number = 1500;
  35. //quicken flag
  36. quickTimeCount:number = 0;
  37. quicking:boolean = false;
  38. quickenArmature:dragonBones.ArmatureDisplay;
  39. upDownSpeedScale: number = 1;
  40. aiAccuracy: number = 1;
  41. init(index:number) {
  42. this.index = index;
  43. if (this.index == 0) {
  44. this.spFlyingFrames = this.spFlyingFrames1;
  45. this.node.setPosition(0,80);
  46. } else {
  47. this.spFlyingFrames = this.spFlyingFrames2;
  48. this.node.setPosition(0,-160);
  49. }
  50. }
  51. isSelf():boolean {
  52. return this.index == window.myPlayerInfo.index;
  53. }
  54. onLoad() {
  55. this.body = this.node.getChildByName('Body');
  56. this.rigidBody = this.node.getComponent(cc.RigidBody);
  57. this.scream = this.body.getChildByName('Scream');
  58. this.spBird = this.body.getComponent(cc.Sprite);
  59. this.spBird.spriteFrame = this.spFlyingFrames[0];
  60. this.quickenArmature = this.body.getChildByName('Quicken').getComponent(dragonBones.ArmatureDisplay);
  61. this.quickenArmature.node.opacity = 0;
  62. this.upDownSpeedScale = window.appGame.device ? 0.5 : 1;
  63. this.aiAccuracy = window.appGame.device ? 0.7 : 1;
  64. if(this.isSelf()){
  65. let arrow = new cc.Node();
  66. if(window.myPlayerInfo.gender==2){
  67. arrow.addComponent(cc.Sprite).spriteFrame = this.arrowPink;
  68. }else{
  69. arrow.addComponent(cc.Sprite).spriteFrame = this.arrowBlue;
  70. }
  71. arrow.setAnchorPoint(0,0.5);
  72. arrow.scale = this.node.scale;
  73. arrow.angle = 90;
  74. this.node.parent.addChild(arrow);
  75. this.arrow = arrow;
  76. }
  77. this.schedule(this.updateFlyingFrame, 0.1);
  78. }
  79. update(dt:number) {
  80. if (this.arrow) {
  81. this.arrow.setPosition(this.node.x + 40 * this.node.scaleX, this.node.y + 125 * this.node.scaleY);
  82. }
  83. if (this.running) {
  84. this.rigidBody.gravityScale = 4 * this.upDownSpeedScale;
  85. if (this.onGroundCount == 0) {
  86. this.currentAcc -= dt * 300 * this.upDownSpeedScale;
  87. let nextAngle = this.currentAcc/3;
  88. if (nextAngle > -45) {
  89. this.body.angle = nextAngle;
  90. }
  91. }
  92. if (this.body.angle < 25) {
  93. this.withAttack = false;
  94. }
  95. if (this.quicking) {
  96. this.quickTimeCount += dt;
  97. if (this.quickTimeCount > 0.5) {
  98. this.quitQuicken();
  99. }
  100. }
  101. } else {
  102. this.withAttack = false;
  103. this.rigidBody.gravityScale = 0;
  104. this.rigidBody.linearVelocity = cc.v2(0,0);
  105. }
  106. if (this.onGroundCount > 0) {
  107. this.scream.active = true;
  108. } else {
  109. this.scream.active = false;
  110. }
  111. if (this.ai) {
  112. if (this.node.x < -(window.cameraNode.x + cc.winSize.width / 2 + 120)) {
  113. this.node.y = 0;
  114. } else if (this.node.x > (window.cameraNode.x + cc.winSize.width / 2 + 120)) {
  115. this.node.y = 0;
  116. this.rigidBody.linearVelocity = cc.v2(this.aiAccuracy * this.basicSpeed, 0);
  117. }
  118. }
  119. }
  120. flyUp(hitPower: number = 30) {
  121. if (hitPower > 45) {
  122. hitPower = 45;
  123. }
  124. if(!window.gm.isGameOver){
  125. this.running = true;
  126. }
  127. if(!this.running || this.bouncing) {
  128. return;
  129. }
  130. this.withAttack = true;
  131. this.currentAcc = 130;
  132. this.rigidBody.linearVelocity = cc.v2(this.speed, 300 + 300 * this.upDownSpeedScale * hitPower / 30);
  133. if (this.isSelf()) {
  134. cc.audioEngine.playEffect(this.wing, false);
  135. }
  136. }
  137. updateFlyingFrame() {
  138. if (!this.running || this.onGroundCount > 0) {
  139. return;
  140. }
  141. this.currentFlyingFrame++;
  142. if (this.currentFlyingFrame == this.spFlyingFrames.length) {
  143. this.currentFlyingFrame = 0;
  144. }
  145. this.spBird.spriteFrame = this.spFlyingFrames[this.currentFlyingFrame];
  146. }
  147. run() {
  148. this.running = true;
  149. }
  150. stop() {
  151. this.running = false;
  152. }
  153. quicken(strength:number) {
  154. this.quicking = true;
  155. this.quickTimeCount = 0;
  156. this.speed = this.basicSpeed + this.quickenSpeed * strength / (6 - strength);
  157. this.rigidBody.linearVelocity = cc.v2(this.speed, this.rigidBody.linearVelocity.y);
  158. this.quickenArmature.node.opacity = 255;
  159. this.quickenArmature.playAnimation('jiasu' + strength, 1);
  160. }
  161. quitQuicken() {
  162. this.quicking = false;
  163. this.quickTimeCount = 0;
  164. this.speed = this.basicSpeed;
  165. this.rigidBody.linearVelocity = cc.v2(this.speed, this.rigidBody.linearVelocity.y);
  166. this.quickenArmature.node.opacity = 0;
  167. }
  168. onCollisionEnter(otherCollider:cc.Collider){
  169. if(otherCollider.node.group==EventType.GROUP_BLOCK){
  170. if(otherCollider.tag==0||otherCollider.tag==1){
  171. this.onGroundCount++;
  172. this.currentAcc = 0;
  173. this.body.stopAllActions();
  174. this.body.runAction(cc.rotateTo(0.1,0).easing(cc.easeIn(1.5)));
  175. }
  176. else if(otherCollider.tag==2){
  177. if (this.isSelf()) {
  178. window.player.call('reachDestination',[this.index]);
  179. } else if (this.ai) {
  180. window.player.call('reachDestination',[this.index]);
  181. }
  182. }
  183. }else if(otherCollider.node.group==EventType.GROUP_BIRD){
  184. let otherBird = otherCollider.node.getComponent(Bird);
  185. if(!this.bouncing&&!otherBird.bouncing){
  186. //1.if under of other and with attack, can bounce other
  187. //2.if above of other and other with none attack, can bounce other
  188. if(this.withAttack&&this.node.y<otherBird.node.y
  189. ||this.body.angle<25&&!otherBird.withAttack&&this.node.y>otherBird.node.y){
  190. otherBird.bouncing = true;
  191. otherBird.rigidBody.linearVelocity = cc.v2(otherBird.rigidBody.linearVelocity.x,
  192. otherBird.rigidBody.linearVelocity.y + this.node.y<otherBird.node.y?900:-600);
  193. otherBird.scheduleOnce(()=>{
  194. otherBird.bouncing = false;
  195. },0.3);
  196. }
  197. }
  198. }else if(otherCollider.node.group==EventType.GROUP_FRUIT){
  199. if(this.isSelf()){
  200. window.player.call('eatFruit',[otherCollider.node.getComponent(Fruit).index]);
  201. }else if(this.ai){
  202. window.player.call('aiEatFruit',[otherCollider.node.getComponent(Fruit).index]);
  203. }
  204. }
  205. }
  206. onCollisionExit(otherCollider:cc.Collider){
  207. if(otherCollider.node.group==EventType.GROUP_BLOCK){
  208. if(otherCollider.tag==0||otherCollider.tag==1){
  209. this.onGroundCount--;
  210. this.body.stopAllActions();
  211. }
  212. }
  213. }
  214. setAI() {
  215. this.ai = true;
  216. this.flyUp();
  217. this.schedule(()=>{
  218. if(!window.gm.isGameOver){
  219. if (window.appGame.device) {
  220. if (window.gc.getBirdRelativeNextPipeStatus(this.node) < 0) {
  221. if (Math.random() < this.aiAccuracy) {
  222. this.flyUp();
  223. } else {
  224. // no do
  225. }
  226. } else {
  227. if (Math.random() < this.aiAccuracy) {
  228. // no do
  229. } else {
  230. this.flyUp();
  231. }
  232. }
  233. } else {
  234. if(window.gc.getBirdRelativeNextPipeStatus(this.node)<0){
  235. this.flyUp();
  236. }
  237. }
  238. }
  239. },0.3);
  240. }
  241. }