game.js 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231
  1. import * as PIXI from "pixi.js";
  2. import "pixi-plugin-bump";
  3. const { Application, Sprite, Container, TextStyle, Text } = PIXI;
  4. const { resources } = PIXI.loader;
  5. import { loaderRes } from "./util";
  6. import GroundData from "./groudData";
  7. const GAME_STATE_ON = "游戏开始";
  8. const GAME_STATE_OVER = "游戏失败";
  9. class Game {
  10. constructor(wrapper) {
  11. this.gameState = GAME_STATE_ON;
  12. this.wrapper = wrapper;
  13. this.roleJump = false; //跳起状态
  14. this.fallingDown = false; //下坠状态
  15. this.decibel = 0; //分贝总和
  16. this.init();
  17. }
  18. //底部小游戏
  19. init() {
  20. this.app = new Application({
  21. width: 750,
  22. height: 532,
  23. backgroundColor: "0xdd4a68"
  24. });
  25. this.wrapper.appendChild(this.app.view);
  26. this.bump = new PIXI.extras.Bump();
  27. loaderRes([`/60064.png`, `/ground.png`], this.loadedSource, this);
  28. }
  29. loadedSource() {
  30. this.initGround();
  31. this.initRole();
  32. this.initGameOver();
  33. this.gameState = GAME_STATE_ON;
  34. // make the stage interactive...
  35. // this.app.view.addEventListener("touchstart", this.jump.bind(this));
  36. }
  37. //创建角色
  38. initRole() {
  39. this.role = new Sprite(resources["/60064.png"].texture);
  40. this.role.x = 375;
  41. this.role.y = this.groundData[0].y;
  42. this.role._vy = 4;
  43. this.role.anchor.x = 0.5;
  44. this.role.anchor.y = 1;
  45. this.role.scale.x = -1;
  46. this.app.stage.addChild(this.role);
  47. this.app.ticker.add(this.jumpLoop, this);
  48. }
  49. // 创建地面容器
  50. initGround() {
  51. this.groundArr = [];
  52. this.groundData = new GroundData({
  53. stageHeight: 532,
  54. groundNum: 100,
  55. gaps: [100, 200],
  56. widths: [60, 500],
  57. heights: [100, 150]
  58. });
  59. this.groundContainer = new Container();
  60. this.groundContainer._vx = 2;
  61. this.app.stage.addChild(this.groundContainer);
  62. this.groundData.forEach(this.createGround.bind(this));
  63. this.groundWalk();
  64. }
  65. //生成黑色地面
  66. createGround({ width, height, x, y }) {
  67. const ground = new Sprite(resources["/ground.png"].texture);
  68. ground.x = x;
  69. ground.y = y;
  70. ground.width = width;
  71. ground.height = height;
  72. this.groundArr.push(ground);
  73. this.groundContainer.addChild(ground);
  74. }
  75. walkLoop() {
  76. this.groundContainer.x -= this.groundContainer._vx;
  77. let rolePosX = Math.abs(this.groundContainer.x - 375); //人物所在位置
  78. let rolePosY = this.role.y;
  79. if (rolePosY >= 532) {
  80. console.log("掉坑里挂了");
  81. this.gameOver();
  82. return;
  83. }
  84. let index = this.groundData.findIndex(
  85. ground =>
  86. rolePosX >= ground.x && rolePosX <= ground.x + ground.width
  87. );
  88. if (index >= 0) {
  89. /**
  90. * 人物下方的方块下标
  91. * 判断是否和方块有碰撞
  92. */
  93. let ground = this.groundArr[index];
  94. if (ground.y <= rolePosY) {
  95. let collision = this.bump.hit(
  96. this.role,
  97. ground,
  98. true,
  99. true,
  100. true
  101. );
  102. console.log("collision", collision);
  103. if (collision) {
  104. switch (collision) {
  105. case "bottom":
  106. console.log("站上了");
  107. this.standGround();
  108. break;
  109. default:
  110. console.log("撞上了");
  111. this.gameOver();
  112. break;
  113. }
  114. }
  115. }
  116. } else {
  117. /**
  118. * 掉坑里了
  119. * 如果不是跳起状态,默认下坠
  120. * */
  121. console.log("在坑里的范围内");
  122. if (!this.roleJump && !this.fallingDown) {
  123. this.fallDown();
  124. }
  125. }
  126. }
  127. standGround() {
  128. this.app.ticker.remove(this.downLoop, this);
  129. this.roleJump = false;
  130. this.fallingDown = false;
  131. }
  132. initGameOver() {
  133. this.gameOverContainer = new Container();
  134. this.gameOverContainer.interactive = true;
  135. let style = new TextStyle({
  136. fontFamily: "Arial",
  137. fontSize: 36,
  138. fill: "white",
  139. stroke: "#ff3300",
  140. strokeThickness: 4,
  141. dropShadow: true,
  142. dropShadowColor: "#000000",
  143. dropShadowBlur: 4,
  144. dropShadowAngle: Math.PI / 6,
  145. dropShadowDistance: 6
  146. });
  147. this.gameoverText = new Text(`${GAME_STATE_OVER} 重新开始`, style);
  148. this.gameoverText.interactive = true;
  149. this.gameoverText.buttonMode = true;
  150. this.gameOverContainer.addChild(this.gameoverText);
  151. this.gameoverText.on("pointerdown", this.restartGame, this);
  152. this.gameOverContainer.visible = false;
  153. this.gameOverContainer.x = 375 - this.gameOverContainer.width / 2;
  154. this.gameOverContainer.y = 220;
  155. this.app.stage.addChild(this.gameOverContainer);
  156. }
  157. gameOver() {
  158. this.roleJump = false;
  159. this.fallingDown = false;
  160. this.app.ticker.remove(this.fallDownLoop, this);
  161. this.gameOverContainer.visible = true;
  162. this.gameState = GAME_STATE_OVER;
  163. this.app.ticker.stop();
  164. }
  165. restartGame() {
  166. console.log("restartGame");
  167. this.gameState = GAME_STATE_ON;
  168. this.groundContainer.x = 0;
  169. this.role.y = this.groundData[0].y;
  170. this.gameOverContainer.visible = false;
  171. this.decibel = 0;
  172. this.app.ticker.start();
  173. }
  174. groundWalk() {
  175. this.app.ticker.add(this.walkLoop, this);
  176. }
  177. groundStop() {
  178. this.app.ticker.remove(this.walkLoop, this);
  179. }
  180. // 跳起,有一个最高值
  181. jump(decibel) {
  182. if (this.gameState === GAME_STATE_OVER) return;
  183. if (this.decibel >= 80) return;
  184. this.decibel += decibel;
  185. this.roleJump = true;
  186. this.fallingDown = false;
  187. this.app.ticker.remove(this.fallDownLoop, this);
  188. this.app.ticker.remove(this.downLoop, this);
  189. }
  190. jumpLoop() {
  191. if (this.decibel > 0) {
  192. let distance = Math.min(this.role._vy, this.decibel);
  193. this.role.y -= distance;
  194. this.decibel -= distance;
  195. console.log("distance,decibel", distance, this.decibel);
  196. if (this.decibel === 0) {
  197. this.app.ticker.add(this.downLoop, this);
  198. }
  199. }
  200. }
  201. downLoop() {
  202. this.roleJump = true;
  203. this.role.y += this.role._vy;
  204. }
  205. fallDownLoop() {
  206. this.role.y += this.role._vy;
  207. }
  208. fallDown() {
  209. this.fallingDown = true;
  210. this.app.ticker.add(this.fallDownLoop, this);
  211. }
  212. }
  213. export default Game;