o0Game.js 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245
  1. var o0 = require('o0');
  2. var o0CC = require('o0CC');
  3. //for this game
  4. var GroupIndex = {
  5. Default : 0,
  6. Food : 1,
  7. Head : 2,
  8. Body : 3,
  9. PlayGround : 4,
  10. UI : 5,
  11. }
  12. class SnakeDirectionControl{
  13. constructor(script) {
  14. this.script = script;
  15. this.speed = 1;
  16. this.turningSpeed = 2;
  17. this.normalSpeedRate = 1;
  18. this.speedingSpeedRate = 3;
  19. this.targetSpeedRate = 1;
  20. this.targetVector = null;
  21. this.bodySpacingRate = 0.3;
  22. this.bodySpacing = 0;
  23. this.pulledScore = 0;
  24. this.pullScoreRate = 0.7;//the rate means remove 1 score from snake, and 0.5 score will come out to be food.
  25. this.speedingScoreCost = 0.02;//score cost per frame speeding
  26. this.minScore = 5;
  27. this.addScore(10);
  28. this.script.updateScale();
  29. this.updateBodySpacing();
  30. this.updateSpeed();
  31. this.setTargetVector(new o0.Vector2(1,0));
  32. }
  33. get node(){
  34. return this.script.node;
  35. }
  36. get radius(){
  37. return this.script.radius;
  38. }
  39. set radius(_radius){
  40. this.script.radius = _radius;
  41. }
  42. get bodyParentNode(){
  43. return this.script.bodyParentNode;
  44. }
  45. get foodParentNode(){
  46. return this.script.foodParentNode;
  47. }
  48. get body(){
  49. return this.script.body;
  50. }
  51. get head(){
  52. return this.script.head;
  53. }
  54. get score(){
  55. return this.script.score;
  56. }
  57. set score(_score){
  58. this.script.score = _score;
  59. }
  60. get pullScoreThreshold(){
  61. return Math.pow(this.body[0].scaleX * this.body[0].scaleY,1) * 1.5;
  62. }
  63. get targetBodyLength(){
  64. return this.score / Math.pow(this.body[0].scaleX * this.body[0].scaleY,1.5);
  65. }
  66. updateSpeed(){
  67. this.speed = 2 * Math.pow(this.body[0].scaleX * this.body[0].scaleY,1.0/3);
  68. }
  69. updateBodySpacing(){
  70. this.bodySpacing = this.radius*2 * this.bodySpacingRate * Math.sqrt(this.body[0].scaleX * this.body[0].scaleY);
  71. }
  72. setTargetSpeeding(bool){
  73. if(!bool)
  74. this.targetSpeedRate = this.normalSpeedRate;
  75. else
  76. this.targetSpeedRate = this.speedingSpeedRate;
  77. }
  78. setTargetVector(vector){
  79. this.targetVector = vector;
  80. }
  81. addScore(score) {
  82. this.score += score;
  83. this.script.updateScale();
  84. this.updateBodySpacing();
  85. this.updateSpeed();
  86. var targetBodyLength = Math.ceil(this.bodyLength);
  87. while(targetBodyLength > this.body.length){
  88. this.script.addBody();
  89. }
  90. }
  91. pullFood(score) {
  92. var newFood = o0CC.addScriptNode(this.foodParentNode,'Food',-100);
  93. var lastBody = this.body[this.body.length-1];
  94. var foodPosition = o0.randomInCircle2(lastBody,(this.radius-newFood.radius)*2);
  95. newFood.node.x = foodPosition.x;
  96. newFood.node.y = foodPosition.y;
  97. newFood.score = score;
  98. }
  99. pullScore(score){
  100. this.score -= score;
  101. this.script.updateScale();
  102. this.updateBodySpacing();
  103. this.updateSpeed();
  104. this.pulledScore += score * this.pullScoreRate;
  105. if(this.pulledScore >= this.pullScoreThreshold){
  106. this.pulledScore -= this.pullScoreThreshold;
  107. this.pullFood(this.pullScoreThreshold);
  108. }
  109. var targetBodyLength = Math.ceil(this.bodyLength);
  110. while(targetBodyLength < this.body.length && this.body.length > 1){
  111. this.script.removeBody();
  112. }
  113. }
  114. updateSnakeBody(){
  115. for(var i = 0, j = 1;j<this.body.length;++i, ++j){
  116. var targetVector = new o0.Vector2(this.body[i].x-this.body[j].x,this.body[i].y-this.body[j].y);
  117. var moveDistance = targetVector.length - this.bodySpacing;
  118. if(j==this.body.length-1)
  119. moveDistance += this.bodySpacing * (Math.ceil(this.bodyLength)-this.bodyLength)
  120. targetVector = targetVector.mod;
  121. this.body[j].rotation = o0CC.rotationFromVector(targetVector);
  122. if(moveDistance <= 0)
  123. continue;
  124. this.body[j].x += targetVector.x * moveDistance;
  125. this.body[j].y += targetVector.y * moveDistance;
  126. }
  127. }
  128. destroySnake(){
  129. this.node.active = false;//防止destory之前body再增长
  130. while(this.score >= 1){
  131. //cc.log("1");
  132. this.pullScore(1);
  133. }
  134. while(this.body.length > 1){
  135. //cc.log("2");
  136. this.script.removeBody();
  137. }
  138. //cc.log(this.score);
  139. this.node.destroy();
  140. //this.destroy();
  141. }
  142. // called every frame
  143. update (dt) {
  144. var speedRate;
  145. if(this.score <= this.minScore)
  146. speedRate = this.normalSpeedRate;
  147. else{
  148. speedRate = this.targetSpeedRate;
  149. if(speedRate != this.normalSpeedRate && speedRate == this.speedingSpeedRate)
  150. this.pullScore(this.speedingScoreCost);
  151. }
  152. for(var i = 0;i<speedRate;++i){
  153. //移动蛇头
  154. this.targetRotation = o0CC.rotationFromVector(this.targetVector);
  155. this.head.rotation = o0CC.nextRotation(this.head.rotation,this.targetRotation,this.turningSpeed);
  156. var moveVector = o0CC.vectorFromRotation(this.head.rotation);
  157. this.body[0].x += moveVector.x*this.speed;
  158. this.body[0].y += moveVector.y*this.speed;
  159. //////////////下面是移动蛇身
  160. this.updateSnakeBody();
  161. }
  162. }
  163. onCollisionEnter(other, self){
  164. if(other.node.active == false || this.node.active == false){//貌似能解决两蛇对撞导致卡死的bug
  165. return;
  166. }
  167. if(other.node.groupIndex == GroupIndex.Body){
  168. //cc.log("aaaaaaaaaaaaaaaaaaa");
  169. var selfBody = false;
  170. if(this.body.length > 1)
  171. for(var i = 1; i<this.body.length;++i){
  172. if(other.node == this.body[i]){
  173. selfBody = true;
  174. break;
  175. }
  176. }
  177. if(selfBody == false){
  178. //cc.log("dsadasd");
  179. this.destroySnake();
  180. }
  181. }
  182. if(other.node.groupIndex == GroupIndex.Food){
  183. this.addScore(other.score);
  184. other.node.destroy();
  185. //other.destroy();
  186. }
  187. }
  188. onCollisionExit(other,self){
  189. if(other.node.active == false || this.node.active == false){//貌似能解决两蛇对撞导致卡死的bug
  190. return;
  191. }
  192. if(other.node.groupIndex == GroupIndex.PlayGround){
  193. this.destroySnake();
  194. }
  195. }
  196. }
  197. class SnakeMouseControl extends SnakeDirectionControl{
  198. constructor(script) {
  199. super(script);
  200. //module.exports.snakeDirectionControl.prototype.getName.call(this,);
  201. var self = this;
  202. this.mouseLocation = new o0.Vector2(1,0);
  203. var listener = {
  204. event: cc.EventListener.MOUSE,
  205. onMouseDown: function (event) {
  206. self.setTargetSpeeding(true);
  207. },
  208. onMouseUp: function (event) {
  209. self.setTargetSpeeding(false);
  210. },
  211. onMouseMove: function (event) {
  212. self.mouseLocation = event.getLocation();
  213. },
  214. onMouseScroll: function (event) {
  215. }
  216. }
  217. cc.eventManager.addListener(listener, this.node);
  218. }
  219. update(dt) {
  220. var localLocation = this.node.parent.convertToNodeSpaceAR(this.mouseLocation);
  221. this.setTargetVector(new o0.Vector2(localLocation).mod);
  222. SnakeDirectionControl.prototype.update(dt);
  223. }
  224. }/** */
  225. module.exports = {
  226. GroupIndex,
  227. //SnakeDirectionControl,
  228. //SnakeMouseControl,
  229. };