o0ProjectRelease.js 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244
  1. var o0 = require('o0');
  2. module.exports = {
  3. SandbagAlgorithm: class{
  4. constructor() {
  5. this.stableAcc = new o0.Vector2(0,0);
  6. this.stableGyr = new o0.Vector2(0,0);
  7. this.stableCount = 0;
  8. this.stableCountMax = 3000;
  9. this.frameCapacity = 6;
  10. this.frame = [];
  11. this.frameLength = 5;
  12. this.frameOffset = 0;
  13. this.frameHitCapacity = 11;
  14. this.frameHit = [];//打击后的n帧
  15. for(var i = 0;i<this.frameCapacity;++i){
  16. var o = new Object();
  17. o.acc = new o0.Vector2(0,0);
  18. o.gyr = new o0.Vector2(0,0);
  19. o.time = new Date().getTime();
  20. o.timeGap = 20;
  21. o.accFixed = 0;
  22. o.accSlope = 0;
  23. o.pos = new o0.Vector2(0,0);
  24. o.predict = new o0.Vector2(0,0);
  25. o.shake = 0;
  26. o.shakeFixed = 0;
  27. o.shakeSlope = 0;
  28. o.hit = 0;
  29. this.frame.push(o);
  30. }
  31. }
  32. //这个函数不建议外部调用
  33. GetDirection(){
  34. var direction = new o0.Vector2(0,0);
  35. var directionDistance = 0.0;
  36. for (var fi = 0;fi < this.frameHit.length - 1;++fi) {
  37. for (var li = fi + 1;li < this.frameHit.length;++li) {
  38. var newDirection = this.frameHit[li].gyr - this.frameHit[fi].gyr;
  39. var newDirectionDistance = newDirection.length;
  40. if (directionDistance < newDirectionDistance) {
  41. directionDistance = newDirectionDistance;
  42. direction = newDirection.multiply(this.frameHit[this.frameHit.length -1].time - this.frameHit[0].time);
  43. }
  44. else {
  45. //cout << "false" << endl;
  46. }
  47. }
  48. }
  49. return direction;
  50. }
  51. // 输入俯视的平面坐标系下的xy轴坐标 的 加速计向量/陀螺仪向量。
  52. // timeGap 代表当前帧读取传感器与上一帧读取传感器 之间的时间差
  53. Update(accX, accY, gyrX,gyrY,timeGap,callback){
  54. var rawAcc = new o0.Vector2(accX,accY);
  55. var rawGyr = new o0.Vector2(gyrX,gyrY);
  56. let lastFrame = this.frame[(this.frameOffset + this.frameLength - 1) % this.frameCapacity];
  57. let last2Frame = this.frame[(this.frameOffset + this.frameLength - 2) % this.frameCapacity];
  58. let last3Frame = this.frame[(this.frameOffset + this.frameLength - 3) % this.frameCapacity];
  59. let last4Frame = this.frame[(this.frameOffset + this.frameLength - 4) % this.frameCapacity];
  60. let last5Frame = this.frame[(this.frameOffset + this.frameLength - 5) % this.frameCapacity];
  61. var newFrame = this.frame[(this.frameOffset + this.frameLength) % this.frameCapacity];
  62. newFrame.timeGap = timeGap;
  63. newFrame.acc = rawAcc.minus(this.stableAcc);
  64. newFrame.gyr = rawGyr.minus(this.stableGyr);
  65. if (this.stableCount < this.stableCountMax){
  66. this.stableCount += 1;
  67. }
  68. this.stableAcc = this.stableAcc.multiply((this.stableCount - 1.0) / this.stableCount).plus(rawAcc.multiply(1/this.stableCount));
  69. this.stableGyr = this.stableGyr.multiply((this.stableCount - 1.0) / this.stableCount).plus(rawGyr.multiply(1/this.stableCount));
  70. //////////////////////////////////////////////////////////////////////////////////
  71. newFrame.accFixed = newFrame.acc.length * 100;
  72. if(newFrame.accFixed < lastFrame.accFixed * 0.85){
  73. newFrame.accFixed = lastFrame.accFixed * 0.85;
  74. }
  75. lastFrame.accFixed = Math.max(lastFrame.accFixed, Math.min(newFrame.accFixed,last2Frame.accFixed), Math.min(newFrame.accFixed,last3Frame.accFixed));
  76. ///////////////////////////////////////////////////////////////////////
  77. //newFrame.pos = lastFrame.pos.plus(lastFrame.acc.plus(newFrame.acc).multiply(timeGap/60)).multiply(Math.max(1-timeGap/200,0));
  78. newFrame.pos = lastFrame.pos.plus(newFrame.acc.multiply(timeGap/30)).multiply(Math.max(1-timeGap/1000,0));
  79. ////////////////////////////////////////////
  80. newFrame.accSlope = Math.max(newFrame.accFixed-lastFrame.accFixed,0);
  81. var lastI = this.frame.length-1;
  82. var t2 = this.frame[lastI-1].timeGap;
  83. var t3 = this.frame[lastI].timeGap + t2;
  84. var t4 = newFrame.timeGap + t3;
  85. newFrame.predict = new o0.Vector2(
  86. new o0.QuadraticEquation(0,this.frame[lastI-2].pos.x,t2,this.frame[lastI-1].pos.x,t3,this.frame[lastI].pos.x).y(t4),
  87. new o0.QuadraticEquation(0,this.frame[lastI-2].pos.y,t2,this.frame[lastI-1].pos.y,t3,this.frame[lastI].pos.y).y(t4));/** */
  88. newFrame.shake = o0.distance2(newFrame.predict,newFrame.pos) * 100;
  89. if(isNaN(newFrame.shake)){
  90. newFrame.shake = 0.0;
  91. }
  92. newFrame.shakeFixed = lastFrame.shakeFixed * 0.85;
  93. if(newFrame.shake > newFrame.shakeFixed){
  94. newFrame.shakeFixed = newFrame.shake;
  95. }/* */
  96. lastFrame.shakeFixed = Math.max(lastFrame.shakeFixed, Math.min(newFrame.shakeFixed,last2Frame.shakeFixed), Math.min(newFrame.shakeFixed,last3Frame.shakeFixed));
  97. ////////////////////////////////////////////////////////////////
  98. newFrame.shakeSlope = Math.max(newFrame.shakeFixed-lastFrame.shakeFixed,0);
  99. ///////////////////////////////////////////////////////////////
  100. var direction = new o0.Vector2(0,0);
  101. if(lastFrame.hit==0
  102. && last2Frame.hit==0
  103. && last3Frame.hit==0
  104. && last4Frame.hit==0
  105. && last5Frame.hit==0
  106. && (newFrame.accSlope >= 15 || lastFrame.accSlope >= 20)
  107. && (newFrame.shakeSlope >= 20 || lastFrame.shakeSlope >= 40)){
  108. newFrame.hit = 1;
  109. if (this.frameHit.length < this.frameHitCapacity) {
  110. direction = this.GetDirection();
  111. }/**/
  112. this.frameHit = [];
  113. var o = new Object();
  114. o.time = 0;
  115. o.gyr = lastFrame.gyr;
  116. this.frameHit.push(o);
  117. }else{
  118. newFrame.hit = 0;
  119. }
  120. if (this.frameHit.length < this.frameHitCapacity) {
  121. var o = new Object();
  122. o.time = this.frameHit[this.frameHit.length - 1].time + newFrame.timeGap;
  123. o.gyr = newFrame.gyr;
  124. if (this.frameHit.length == this.frameHitCapacity) {
  125. direction = this.GetDirection();
  126. }
  127. }
  128. if ((this.frameOffset+=1) >= this.frameCapacity){
  129. this.frameOffset -= this.frameCapacity;
  130. }
  131. if(newFrame.hit != 0){
  132. console.log('hit:' + newFrame.hit);
  133. }
  134. if(direction.x != 0 || direction.y !=0){
  135. console.log(JSON.stringify(newFrame.hit) +" == " + JSON.stringify(direction));
  136. }
  137. return (newFrame.hit, direction);
  138. }
  139. test(){
  140. return "123123131";
  141. }
  142. getValue(hitValue, callback) {
  143. var direction = new o0.Vector2(0, 0);
  144. var directionDistance = 0;
  145. for (var fi = 1; fi < this.frameHit.length - 1; ++fi) {
  146. for (var li = fi + 1; li < this.frameHit.length; ++li) {
  147. let firstGyr = this.frameHit[fi].gyr;
  148. let lastGyr = this.frameHit[li].gyr;
  149. let newDirectionDistance = o0.distance2(firstGyr, lastGyr);
  150. if (directionDistance < newDirectionDistance) {
  151. directionDistance = newDirectionDistance;
  152. direction = lastGyr.minus(firstGyr);
  153. }
  154. }
  155. }
  156. let curAngle = new o0.Vector2(direction.x, direction.y).mod.angle(new o0.Vector2(0, 1));
  157. let directionPunch = "all",
  158. name = "击中",
  159. ename = "hit";
  160. let curAngleCeil = Math.ceil(curAngle);
  161. //已坐标 (0,1) 向量为参考
  162. if (direction.y < 0) {
  163. //相反方向击打
  164. //正方向
  165. if (curAngleCeil > 150) {
  166. directionPunch = "straightPunch";
  167. name = "负向的直拳";
  168. ename = "back-straight";
  169. } else if (direction.x > 0) {
  170. directionPunch = "rightPunch";
  171. name = "负向的右拳";
  172. ename = "back-right";
  173. } else if (direction.x < 0) {
  174. directionPunch = "leftPunch";
  175. name = "负向的左拳";
  176. ename = "back-left";
  177. }
  178. } else {
  179. // y 大于零 手柄正方向击打
  180. if (curAngleCeil < 30) {
  181. directionPunch = "straightPunch";
  182. name = "正向的直拳";
  183. ename = "front-straight";
  184. } else if (direction.x < 0) {
  185. directionPunch = "rightPunch";
  186. name = "正向的右拳";
  187. ename = "front-right";
  188. } else if (direction.x > 0) {
  189. directionPunch = "leftPunch";
  190. name = "正向的左拳";
  191. ename = "front-left";
  192. }
  193. }
  194. this.quitHitCount++;
  195. if (callback) {
  196. let temp = {
  197. type: 'hit',
  198. hit: hitValue / 5,
  199. hitCount: this.quitHitCount,
  200. direction: directionPunch,
  201. directionVect: {
  202. 'x': direction.x,
  203. 'y': direction.y
  204. },
  205. angle: curAngleCeil,
  206. name: name,
  207. ename: ename
  208. }
  209. callback(temp);
  210. }
  211. }
  212. }
  213. };