main.js 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439
  1. import Player from './player/index'
  2. import Enemy from './npc/enemy'
  3. import BackGround from './runtime/background'
  4. import GameInfo from './runtime/gameinfo'
  5. import Music from './runtime/music'
  6. import Sdk from './runtime/sdk'
  7. import DataBus from './databus'
  8. import huoSdk from '../libs/huosdk-1.0.3'
  9. let ctx = canvas.getContext('2d')
  10. let databus = new DataBus()
  11. let qrCanvas = wx.createCanvas()
  12. qrCanvas.width = window.innerWidth
  13. qrCanvas.height = window.innerHeight
  14. /**
  15. * 游戏主函数
  16. */
  17. export default class Main {
  18. constructor() {
  19. // 维护当前requestAnimationFrame的id
  20. this.aniId = 0
  21. this.restart()
  22. this.sdk = new Sdk()
  23. let opts = wx.getLaunchOptionsSync()
  24. huoSdk.init({
  25. debug: true,
  26. app_id: 81234695,
  27. mp_id: 'wx57ee4c500a48fb52'
  28. // app_id: 81234700,
  29. // mp_id: 'wx1f44257e9b7b36a1'
  30. }).then(res => {
  31. console.log('init', res)
  32. huoSdk.login({
  33. data: {
  34. state: opts.query.state || opts.query.scene
  35. }
  36. }).then(res => {
  37. console.log('login', res)
  38. if (res.data.nickname !== undefined) {
  39. wx.showToast({
  40. title: '登录成功'
  41. })
  42. this.sdk.loginBtn.text = res.data.nickname
  43. }
  44. huoSdk.updateRole({
  45. data: {
  46. 'role-event': 'offline',
  47. 'role-server_id': '11',
  48. 'role-server_name': '测试11区',
  49. 'role-role_id': '1000005',
  50. 'role-role_name': 'cx_test',
  51. 'role-role_level': 150,
  52. 'role-role_vip': 7,
  53. 'role-onlineTime': 0,
  54. 'role-scene': '背包',
  55. 'role-axis': '(999,999,999)',
  56. 'role-scene': '打开礼包'
  57. }
  58. }).then(res => {
  59. // do something
  60. }, err => {
  61. console.log('updateRole', err)
  62. })
  63. huoSdk.getShareInfo({
  64. data: {
  65. path: ''
  66. }
  67. }).then(res => {
  68. wx.onShareAppMessage(function () {
  69. return {
  70. title: res.data.title,
  71. imageUrl: res.data.image,
  72. query: `state=${res.data.state}`
  73. }
  74. })
  75. wx.showShareMenu()
  76. }, err => {
  77. console.log('getShareInfo', err)
  78. })
  79. }, err => {
  80. console.log('login', err)
  81. })
  82. huoSdk.reportAdClick({
  83. data: {
  84. click_id: opts.gdt_vid || opts.query.gdt_vid,
  85. url: '/'
  86. }
  87. }).then(res => {
  88. console.log(res)
  89. })
  90. // 敏感词检测
  91. huoSdk.checkMsg({
  92. data: {
  93. content: '特3456书yuuo莞6543李zxcz蒜7782法fgnv级'
  94. }
  95. }).then(res => {
  96. console.log(res)
  97. }, err => {
  98. console.log(err)
  99. })
  100. // 敏感图片检测
  101. wx.chooseImage({
  102. count: 1,
  103. success: res => {
  104. huoSdk.checkImg({
  105. data: {
  106. filePath: res.tempFilePaths[0]
  107. }
  108. }).then(res => {
  109. console.log(res)
  110. }, err => {
  111. console.log(err)
  112. })
  113. }
  114. })
  115. }, err => {
  116. console.log('init', err)
  117. })
  118. // huoSdk.midasPayQuery({
  119. // data: {
  120. // 'order-order_id': 'g1541505495627000074'
  121. // }
  122. // }).then(res => {
  123. // }, err => {
  124. // })
  125. wx.onShow(opts => {
  126. huoSdk.removeOffScreen()
  127. let orderId = wx.getStorageSync('orderId')
  128. if (opts.scene === 1038 && orderId) {
  129. huoSdk.mpPayQuery({
  130. data: {
  131. 'order-order_id': orderId
  132. }
  133. }).then(res => {
  134. wx.showModal({
  135. content: res.data.status === 2 ? '充值成功' : '充值失败',
  136. showCancel: false
  137. })
  138. })
  139. wx.removeStorageSync('orderId')
  140. }
  141. })
  142. }
  143. restart() {
  144. databus.reset()
  145. canvas.removeEventListener(
  146. 'touchstart',
  147. this.touchHandler
  148. )
  149. this.bg = new BackGround(ctx)
  150. this.player = new Player(ctx)
  151. this.gameinfo = new GameInfo()
  152. this.music = new Music()
  153. this.bindLoop = this.loop.bind(this)
  154. this.hasEventBind = false
  155. // 清除上一局的动画
  156. window.cancelAnimationFrame(this.aniId);
  157. this.aniId = window.requestAnimationFrame(
  158. this.bindLoop,
  159. canvas
  160. )
  161. }
  162. /**
  163. * 随着帧数变化的敌机生成逻辑
  164. * 帧数取模定义成生成的频率
  165. */
  166. enemyGenerate() {
  167. if (databus.frame % 30 === 0) {
  168. let enemy = databus.pool.getItemByClass('enemy', Enemy)
  169. enemy.init(6)
  170. databus.enemys.push(enemy)
  171. }
  172. }
  173. // 全局碰撞检测
  174. collisionDetection() {
  175. let that = this
  176. databus.bullets.forEach((bullet) => {
  177. for (let i = 0, il = databus.enemys.length; i < il; i++) {
  178. let enemy = databus.enemys[i]
  179. if (!enemy.isPlaying && enemy.isCollideWith(bullet)) {
  180. enemy.playAnimation()
  181. that.music.playExplosion()
  182. bullet.visible = false
  183. databus.score += 1
  184. break
  185. }
  186. }
  187. })
  188. for (let i = 0, il = databus.enemys.length; i < il; i++) {
  189. let enemy = databus.enemys[i]
  190. if (this.player.isCollideWith(enemy)) {
  191. databus.gameOver = true
  192. break
  193. }
  194. }
  195. }
  196. // 游戏结束后的触摸事件处理逻辑
  197. touchEventHandler(e) {
  198. e.preventDefault()
  199. let x = e.touches[0].clientX
  200. let y = e.touches[0].clientY
  201. let area = this.gameinfo.btnArea
  202. if (x >= area.startX
  203. && x <= area.endX
  204. && y >= area.startY
  205. && y <= area.endY)
  206. this.restart()
  207. }
  208. // 支付事件
  209. sdkEventHandler (e) {
  210. e.preventDefault()
  211. let { clientX: x, clientY: y } = e.touches[0]
  212. let { payBtn, paying, balanceBtn, getBalance, navigatorBtn, hasNavigator } = this.sdk
  213. if (x >= payBtn.startX && x <= payBtn.endX && y >= payBtn.startY && y <= payBtn.endY && !paying) {
  214. this.sdk.paying = true
  215. setTimeout(() => {
  216. this.sdk.paying = false
  217. }, 1000)
  218. huoSdk.checkPay({
  219. data: {
  220. 'order-currency': 'CNY',
  221. 'order-cp_order_id': '10001',
  222. 'order-product_price': 1,
  223. 'order-product_id': '1000000001',
  224. 'order-product_cnt': 10,
  225. 'order-product_name': '金币',
  226. 'order-product_desc': '金币',
  227. 'order-ext': '',
  228. 'role-event': '',
  229. 'role-server_id': '11',
  230. 'role-server_name': '测试11服',
  231. 'role-combat_num': 99,
  232. 'role-role_id': '',
  233. 'role-role_name': '',
  234. 'role-role_level': 0,
  235. 'role-role_vip': 0
  236. },
  237. canvas,
  238. offscreen: qrCanvas
  239. }).then(res => {
  240. console.log('pay', res)
  241. wx.setStorageSync('orderId', res.data.order_id)
  242. // if (res.data.mp_id && res.data.path) {
  243. // wx.showLoading({
  244. // mask: true,
  245. // title: '跳转中'
  246. // })
  247. // wx.navigateToMiniProgram({
  248. // appId: res.data.mp_id,
  249. // path: res.data.path,
  250. // complete: function (res) {
  251. // wx.hideLoading()
  252. // }
  253. // })
  254. // }
  255. this.sdk.paying = false
  256. }, err => {
  257. console.log('pay', err)
  258. this.sdk.paying = false
  259. })
  260. }
  261. // if (x >= balanceBtn.startX && x <= balanceBtn.endX && y >= balanceBtn.startY && y <= balanceBtn.endY && !getBalance) {
  262. // this.sdk.getBalance = true
  263. // setTimeout(() => {
  264. // this.sdk.getBalance = false
  265. // }, 1000)
  266. // huoSdk.midasPayQuery().then(res => {
  267. // console.log('balance', res)
  268. // this.sdk.getBalance = false
  269. // }, err => {
  270. // console.log('balance', err)
  271. // this.sdk.getBalance = false
  272. // })
  273. // }
  274. // if (x >= navigatorBtn.startX && x <= navigatorBtn.endX && y >= navigatorBtn.startY && y <= navigatorBtn.endY && !hasNavigator) {
  275. // this.sdk.hasNavigator = true
  276. // setTimeout(() => {
  277. // this.sdk.hasNavigator = false
  278. // }, 1000)
  279. // wx.showLoading({
  280. // mask: true,
  281. // title: '跳转中'
  282. // })
  283. // huoSdk.preOrder({
  284. // data: {
  285. // 'order-currency': 'CNY',
  286. // 'order-cp_order_id': '10001',
  287. // 'order-product_price': 1,
  288. // 'order-product_id': '1000000001',
  289. // 'order-product_cnt': 10,
  290. // 'order-product_name': '金币',
  291. // 'order-product_desc': '金币',
  292. // 'order-ext': '',
  293. // 'role-event': '',
  294. // 'role-server_id': '',
  295. // 'role-server_name': '',
  296. // 'role-role_id': '',
  297. // 'role-role_name': '',
  298. // 'role-role_level': 0,
  299. // 'role-role_vip': 0
  300. // }
  301. // }).then(res => {
  302. // console.log('pre order', res)
  303. // wx.navigateToMiniProgram({
  304. // appId: 'wx3535cdf616ef205a',
  305. // path: `pages/pay/index?orderId=${res.data.order_id}`,
  306. // extraData: {
  307. // mem_id: wx.getStorageSync('userInfo').mem_id,
  308. // price: 200
  309. // },
  310. // complete: function (res) {
  311. // wx.hideLoading()
  312. // }
  313. // })
  314. // }, err => {
  315. // console.log('pre order', err)
  316. // })
  317. // }
  318. }
  319. /**
  320. * canvas重绘函数
  321. * 每一帧重新绘制所有的需要展示的元素
  322. */
  323. render() {
  324. ctx.clearRect(0, 0, canvas.width, canvas.height)
  325. this.bg.render(ctx)
  326. // 展示支付按钮
  327. this.sdk.renderBtn(ctx)
  328. canvas.addEventListener('touchstart', this.sdkEventHandler.bind(this))
  329. databus.bullets
  330. .concat(databus.enemys)
  331. .forEach((item) => {
  332. item.drawToCanvas(ctx)
  333. })
  334. this.player.drawToCanvas(ctx)
  335. databus.animations.forEach((ani) => {
  336. if (ani.isPlaying) {
  337. ani.aniRender(ctx)
  338. }
  339. })
  340. this.gameinfo.renderGameScore(ctx, databus.score)
  341. // 游戏结束停止帧循环
  342. if (databus.gameOver) {
  343. this.gameinfo.renderGameOver(ctx, databus.score)
  344. if (!this.hasEventBind) {
  345. this.hasEventBind = true
  346. this.touchHandler = this.touchEventHandler.bind(this)
  347. canvas.addEventListener('touchstart', this.touchHandler)
  348. }
  349. }
  350. ctx.drawImage(qrCanvas, 0, 0)
  351. }
  352. // 游戏逻辑更新主函数
  353. update() {
  354. if (databus.gameOver)
  355. return;
  356. this.bg.update()
  357. databus.bullets
  358. .concat(databus.enemys)
  359. .forEach((item) => {
  360. item.update()
  361. })
  362. this.enemyGenerate()
  363. this.collisionDetection()
  364. if (databus.frame % 20 === 0) {
  365. this.player.shoot()
  366. this.music.playShoot()
  367. }
  368. }
  369. // 实现游戏帧循环
  370. loop() {
  371. databus.frame++
  372. this.update()
  373. this.render()
  374. this.aniId = window.requestAnimationFrame(
  375. this.bindLoop,
  376. canvas
  377. )
  378. }
  379. }