Browse Source

改成消消乐

liuyuqi-dellpc 9 months ago
parent
commit
753abae094
61 changed files with 1038 additions and 832 deletions
  1. 14 0
      .gitignore
  2. BIN
      audio/bgm.mp3
  3. BIN
      audio/boom.mp3
  4. BIN
      audio/clear.mp3
  5. BIN
      audio/swap.mp3
  6. BIN
      audio/yes.mp3
  7. 2 3
      game.js
  8. BIN
      images/1.png
  9. BIN
      images/2.png
  10. BIN
      images/3.png
  11. BIN
      images/4.png
  12. BIN
      images/5.png
  13. BIN
      images/6.png
  14. BIN
      images/Common.png
  15. BIN
      images/an.png
  16. BIN
      images/bg.jpg
  17. BIN
      images/boom.png
  18. BIN
      images/bullet.png
  19. BIN
      images/chicken.png
  20. BIN
      images/enemy.png
  21. BIN
      images/explosion1.png
  22. BIN
      images/explosion10.png
  23. BIN
      images/explosion11.png
  24. BIN
      images/explosion12.png
  25. BIN
      images/explosion13.png
  26. BIN
      images/explosion14.png
  27. BIN
      images/explosion15.png
  28. BIN
      images/explosion16.png
  29. BIN
      images/explosion17.png
  30. BIN
      images/explosion18.png
  31. BIN
      images/explosion19.png
  32. BIN
      images/explosion2.png
  33. BIN
      images/explosion3.png
  34. BIN
      images/explosion4.png
  35. BIN
      images/explosion5.png
  36. BIN
      images/explosion6.png
  37. BIN
      images/explosion7.png
  38. BIN
      images/explosion8.png
  39. BIN
      images/explosion9.png
  40. BIN
      images/hero.png
  41. BIN
      images/loginButton.png
  42. BIN
      images/play.png
  43. BIN
      images/sprit.png
  44. BIN
      images/sprit2.png
  45. BIN
      images/sprit3.png
  46. 494 0
      js/app.js
  47. 15 12
      js/base/animation.js
  48. 5 5
      js/base/pool.js
  49. 11 10
      js/base/sprite.js
  50. 7 26
      js/databus.js
  51. 1 1
      js/libs/symbol.js
  52. 351 327
      js/libs/weapp-adapter.js
  53. 0 176
      js/main.js
  54. 0 55
      js/npc/enemy.js
  55. 0 35
      js/player/bullet.js
  56. 0 119
      js/player/index.js
  57. 12 33
      js/runtime/background.js
  58. 42 0
      js/runtime/element.js
  59. 34 16
      js/runtime/gameinfo.js
  60. 26 0
      js/runtime/login.js
  61. 24 14
      js/runtime/music.js

+ 14 - 0
.gitignore

@@ -0,0 +1,14 @@
+# Windows
+[Dd]esktop.ini
+Thumbs.db
+$RECYCLE.BIN/
+
+# macOS
+.DS_Store
+.fseventsd
+.Spotlight-V100
+.TemporaryItems
+.Trashes
+
+# Node.js
+node_modules/

BIN
audio/bgm.mp3


BIN
audio/boom.mp3


BIN
audio/clear.mp3


BIN
audio/swap.mp3


BIN
audio/yes.mp3


+ 2 - 3
game.js

@@ -1,6 +1,5 @@
 import './js/libs/weapp-adapter'
 import './js/libs/symbol'
+import App from './js/app'
 
-import Main from './js/main'
-
-new Main()
+new App()

BIN
images/1.png


BIN
images/2.png


BIN
images/3.png


BIN
images/4.png


BIN
images/5.png


BIN
images/6.png


BIN
images/Common.png


BIN
images/an.png


BIN
images/bg.jpg


BIN
images/boom.png


BIN
images/bullet.png


BIN
images/chicken.png


BIN
images/enemy.png


BIN
images/explosion1.png


BIN
images/explosion10.png


BIN
images/explosion11.png


BIN
images/explosion12.png


BIN
images/explosion13.png


BIN
images/explosion14.png


BIN
images/explosion15.png


BIN
images/explosion16.png


BIN
images/explosion17.png


BIN
images/explosion18.png


BIN
images/explosion19.png


BIN
images/explosion2.png


BIN
images/explosion3.png


BIN
images/explosion4.png


BIN
images/explosion5.png


BIN
images/explosion6.png


BIN
images/explosion7.png


BIN
images/explosion8.png


BIN
images/explosion9.png


BIN
images/hero.png


BIN
images/loginButton.png


BIN
images/play.png


BIN
images/sprit.png


BIN
images/sprit2.png


BIN
images/sprit3.png


+ 494 - 0
js/app.js

@@ -0,0 +1,494 @@
+import Element from './runtime/element'
+const screenWidth = window.innerWidth
+const screenHeight = window.innerHeight
+import BackGround from './runtime/background'
+import Login from './runtime/login'
+import GameInfo from './runtime/gameinfo'
+import Music from './runtime/music'
+let ctx = canvas.getContext('2d')
+const scalx = screenWidth / 375
+const scaly = screenHeight / 667
+const numberY = 6; //行
+const numberX = 6; //
+const imgW = 47.5 * scalx;
+const imgH = 46.5 * scaly;
+const ceilX = 45 * scalx;
+const ceilY = 128 * scaly;
+const fixedW = 95;
+const animal = [0, 1, 2, 3, 4]; //元素种类
+const BG_IMG_SRC = 'images/bg.jpg'
+const BG_IMG_SRC2 = 'images/play.png'
+let minute = 0; //控制动画速度
+
+export default class App {
+  constructor() {
+    this.aniId = 0
+    this.boxData = []; // 消消乐数据
+    this.startCoordinates = [0, 0]; // 开始的坐标位置
+    this.endCoordinates = [0, 0]; // 结束的坐标位置
+    this.clickbox = []; // 点击的方块位置
+    this.click = 0;
+    this.isSwaping = false;
+    this.isClear = false;
+    this.boxArray = {}
+    this.speed = 0;
+    this.anB = 0;
+    this.maxx = 0;
+    this.repeat = false;
+    this.score = {
+      num: 0,
+      animal: 0
+    }
+    this.hoverImage = {
+      animal: 0,
+      x: 0,
+      y: 0
+    };
+    this.hoverSpeed = 0;
+    this.timer = 0;
+    this.fill = false;
+    this.w = 0;
+    this.draw = false;
+    this.restart();
+
+
+  }
+
+  restart() {
+    this.login = new Login()
+    this.bindLoop = this.loop.bind(this)
+    this.bg = new BackGround(ctx, BG_IMG_SRC);
+    this.bg2 = new BackGround(ctx, BG_IMG_SRC2);
+    this.ele = new Element(ctx);
+    this.gameinfo = new GameInfo(ctx);
+    this.bindLoop = this.loop.bind(this);
+    this.music = new Music();
+    canvas.removeEventListener(
+      'touchstart',
+      this.touchHandler
+    )
+
+
+    this.aniId = window.requestAnimationFrame(
+      this.bindLoop,
+      canvas
+    )
+
+  }
+  step1() {
+    ctx.clearRect(0, 0, canvas.width, canvas.height)
+    this.bg.render(ctx);
+    this.login.render(ctx);
+    this.touchHandler = this.touchEventHandler.bind(this)
+    canvas.addEventListener('touchstart', this.touchHandler)
+  }
+  touchEventHandler(e) {
+    e.preventDefault()
+    let x = e.touches[0].clientX
+    let y = e.touches[0].clientY
+
+    let area = this.login.btnArea
+
+    if (x >= area.startX &&
+      x <= area.endX &&
+      y >= area.startY &&
+      y <= area.endY) {
+      this.secenceChange()
+    }
+
+  }
+  secenceChange() {
+    canvas.removeEventListener(
+      'touchstart',
+      this.touchHandler
+    )
+    this.boxArray = {}
+    window.cancelAnimationFrame(this.aniId);
+    console.log(this.aniId)
+    this.up = this.update.bind(this)
+    this.bgupdate()
+    this.aniId = window.requestAnimationFrame(this.up, canvas)
+    this.music.secen2()
+
+
+  }
+
+  initEvent() {
+    canvas.addEventListener('touchstart', this.touchHandlerStart.bind(this))
+    canvas.addEventListener('touchmove', this.touchHanderMove.bind(this))
+    canvas.addEventListener('touchend', this.touchEnd.bind(this))
+
+  }
+  touchHandlerStart(e) {
+    if (this.fill) {
+      return;
+    }
+    e.preventDefault()
+    this.isSwaping = false
+    this.repeat = false;
+    this.boxArray = {}
+    let x = e.touches[0].clientX - ceilX
+    let y = e.touches[0].clientY - ceilY
+    this.draw = false
+    if (x > 0 && y > 0 && x < (imgW * numberX + ceilX) && y < imgH * numberY + ceilY) {
+      this.startCoordinates = [x, y];
+      this.clickbox[0] = Math.ceil(x / imgW) - 1
+      this.clickbox[1] = Math.ceil(y / imgH) - 1
+      let col = this.clickbox[1]
+      let row = this.clickbox[0]
+      this.hoverImage = {
+        animal: this.boxData[row][col].animal,
+        x: row,
+        y: col
+      }
+      console.log("start1")
+      setTimeout(() => {
+        this.hover();
+        this.date1 = new Date();
+      }, 0);
+
+
+    }
+
+
+    //点击重玩区域
+    this.againPalyArea(e)
+
+
+
+  }
+  hover() {
+    this.bgupdate();
+    this.boxData.forEach((item, x) => {
+      item.forEach((it, y) => {
+        this.ele.render(ctx, it['animal'] * fixedW, 0, imgW * x + ceilX, imgH * y + ceilY);
+      })
+    })
+    this.ele.renderHover(ctx, this.hoverImage.animal * 95, 0, imgW * this.hoverImage.x + ceilX, imgH * this.hoverImage.y + ceilY);
+
+  }
+
+
+
+  againPalyArea(e) {
+    let x = [],
+      y = [];
+    x[0] = 214 * scalx;
+    x[1] = 214 * scalx + 100 * scalx;
+    y[0] = screenHeight - 107 * scaly;
+    y[1] = screenHeight - 36 * scaly;
+    //点击重玩区域
+    if (e.touches[0].clientX > x[0] && e.touches[0].clientY > y[0] && e.touches[0].clientX < x[1] && e.touches[0].clientY < y[1]) {
+      this.secenceChange()
+    }
+
+  }
+  //交换
+  touchHanderMove(e) {
+    this.date2 = new Date();
+    console.log((this.date2 - this.date1) * 3600 / 24 * 60 * 60, "start2")
+    e.preventDefault()
+    let x = e.touches[0].clientX - ceilX
+    let y = e.touches[0].clientY - ceilY
+    this.endCoordinates = [x, y];
+    //点击 交换区域
+    if (x > 0 && y > 0 && x < (ceilX + imgW * numberX) && y < ceilY + imgH * numberY) {
+      this.swap() //交换位置
+      this.isReapet();
+
+
+      if (this.repeat) {
+
+        this.isSwaping = true;
+        if (this.draw) return
+        this.music.playswapAudio()
+        this.drawBlock();
+
+
+      }
+
+    }
+
+  }
+
+  touchEnd(e) {
+    window.requestAnimationFrame(() => {
+      if (this.isSwaping) {
+        this.clear();
+        this.down();
+        this.fillBlock();
+
+      }
+
+    }, canvas)
+
+  }
+  //
+  drawBlock() {
+    this.bgupdate();
+    this.draw = true;
+
+    this.boxData.forEach((item, x) => {
+      item.forEach((it, y) => {
+        this.ele.render(ctx, it['animal'] * fixedW, 0, imgW * x + ceilX, imgH * y + ceilY);
+      })
+    })
+
+  }
+
+
+  //swap 二二交换
+  swap() {
+    const moveX = this.endCoordinates[0] - this.startCoordinates[0];
+    const moveY = this.endCoordinates[1] - this.startCoordinates[1];
+    const col = this.clickbox[0]; //y
+    const row = this.clickbox[1]; //x
+    if (Math.abs(moveX) > Math.abs(moveY) && moveX > 0) { // 从左到右
+      let tmp = this.boxData[col + 1][row];
+      this.boxData[col + 1][row] = this.boxData[col][row];
+      this.boxData[col][row] = tmp;
+    } else if (Math.abs(moveX) > Math.abs(moveY) && moveX < 0) { // 从右到左
+      let tmp = this.boxData[col - 1][row]
+      this.boxData[col - 1][row] = this.boxData[col][row];
+      this.boxData[col][row] = tmp;
+
+
+
+    } else if (Math.abs(moveY) > Math.abs(moveX) && moveY > 0) { // 从上到下
+      let tmp = this.boxData[col][row + 1]
+      this.boxData[col][row + 1] = this.boxData[col][row];
+      this.boxData[col][row] = tmp;
+
+    } else if (Math.abs(moveY) > Math.abs(moveX) && moveY < 0) { // 从下到上
+      let tmp = this.boxData[col][row - 1]
+      this.boxData[col][row - 1] = this.boxData[col][row];
+      this.boxData[col][row] = tmp;
+    }
+
+
+
+
+  }
+  bgupdate() {
+    ctx.clearRect(0, 0, screenWidth, screenHeight);
+    this.bg2.render(ctx, 0, 0, 2, 2);
+    this.gameinfo.renderGameScore(ctx)
+  }
+
+  downgame() {
+    this.bgupdate();
+
+    this.boxData.forEach((item, x) => {
+      item.forEach((it, y) => {
+        if (this.boxData[x][y]['match'] > 0) {
+          //  this.ele.render(ctx,it['animal']*fixedW,0,imgW*x+ceilX,imgH*y+ceilY,true);
+          if (this.score.animal == it['animal']) {
+            this.score.num++;
+          }
+          let key = x + '' + y
+          this.boxArray[key] = {
+            x: imgW * x + ceilX,
+            y: ceilY + imgH * y,
+            animal: animal[Math.floor(Math.random() * 5)],
+            match: 0
+          }
+          this.maxx = this.max(y, this.maxx)
+
+
+
+        } else {
+          this.ele.render(ctx, it['animal'] * fixedW, 0, imgW * x + ceilX, imgH * y + ceilY);
+        }
+      })
+    })
+    this.gameinfo.renderImage(ctx, this.score.num)
+    console.log(this.score.num, "xxxxxxxxxxx")
+  }
+  //隐藏要消灭的元素
+  clear() {
+
+    this.bgupdate();
+    this.boxData.forEach((item, x) => {
+      item.forEach((it, y) => {
+        if (this.boxData[x][y]['match'] > 0) {
+          this.ele.render(ctx, it['animal'] * fixedW, 0, imgW * x + ceilX, imgH * y + ceilY, true);
+
+        } else {
+          this.ele.render(ctx, it['animal'] * fixedW, 0, imgW * x + ceilX, imgH * y + ceilY);
+        }
+      })
+    })
+
+
+
+
+  }
+  //检测是否重复
+  isReapet() {
+    this.boxData.forEach((item, x) => {
+      item.forEach((it, y) => {
+        let vb = x + 2 < numberX && this.boxData[x][y]['animal'] == this.boxData[x + 1][y]['animal'] && this.boxData[x + 1][y]['animal'] == this.boxData[x + 2][y]['animal'];
+        let vy = y + 2 < numberY && this.boxData[x][y]['animal'] == this.boxData[x][y + 2]['animal'] && this.boxData[x][y + 1]['animal'] == this.boxData[x][y + 2]['animal'];
+        if (vb) {
+          ++this.boxData[x][y].match;
+          ++this.boxData[x + 1][y].match;
+          ++this.boxData[x + 2][y].match;
+
+        }
+        if (vy) {
+          ++this.boxData[x][y].match;
+          ++this.boxData[x][y + 1].match;
+          ++this.boxData[x][y + 2].match;
+
+        }
+        if (vb || vy) {
+          this.repeat = true;
+        }
+
+      })
+    })
+
+  }
+  //方块下落
+  down() {
+    for (let x = numberY - 1; x > -1; x--) { //行
+      for (let y = 0; y < numberX; y++) { //列
+        if (this.boxData[y][x].match) {
+          for (let k = x - 1; k > -1; k--) {
+            if (this.boxData[y][k].match == 0) {
+              let temp = this.boxData[y][k];
+              this.boxData[y][k] = this.boxData[y][x]
+              this.boxData[y][x] = temp;
+              break;
+
+            }
+
+          }
+
+        }
+      }
+
+    }
+    this.downgame();
+
+
+
+  }
+
+  fillBlock() {
+    this.fill = true;
+
+    for (let key in this.boxArray) {
+
+      this.ele.renderBoom(ctx, this.speed * 93, 0, this.boxArray[key].x, this.boxArray[key].y);
+      if (this.isauto) {
+        this.music.playisAudio()
+      } else {
+        this.music.playclearAudio()
+      }
+      this.ele.render(ctx, this.boxArray[key]['animal'] * fixedW, 0, this.boxArray[key].x, minute - parseInt((this.maxx + 1) * imgH) + this.boxArray[key].y)
+
+    }
+    this.loopBlock();
+
+  }
+  max(a, b) {
+    return a > b ? a : b
+  }
+
+  loopBlock() {
+    this.anB = window.requestAnimationFrame(() => {
+      minute += 4;
+
+      if (minute < parseInt((this.maxx + 1) * imgH)) {
+        this.clear()
+          ++this.speed
+
+        this.fillBlock()
+      } else {
+        window.cancelAnimationFrame(this.anB);
+        this.clear()
+        for (let key in this.boxArray) {
+          console.log(key, "key11")
+          let ma = this.boxArray[key]['animal'] * fixedW
+          this.ele.render(ctx, ma, 0, this.boxArray[key].x, this.boxArray[key].y)
+          let x = key.substring(0, 1);
+          let y = key.substring(1, 2);
+          this.boxData[x][y]['animal'] = this.boxArray[key]['animal']
+          this.boxData[x][y]['match'] = this.boxArray[key]['match']
+        }
+        minute = 0;
+        this.isauto = false
+        this.speed = 0;
+        this.repeat = false;
+        this.isReapet()
+        console.log(this.boxData, this.repeat, "下落")
+        if (this.repeat) {
+          this.boxArray = {}
+          setTimeout(() => {
+            this.clear()
+            this.down()
+            this.isauto = true;
+            this.fillBlock()
+          }, 1000)
+
+        } else {
+          this.fill = false
+        }
+
+      }
+
+
+
+    }, canvas)
+
+
+  }
+  touchHanderEnd(e) {
+    e.preventDefault();
+    canvas.removeEventListener('touchstart', this.touchHandlerStart.bind(this))
+    canvas.removeEventListener('touchmove', this.touchHanderMove.bind(this))
+
+  }
+
+
+  update() {
+    this.enemyGenerate();
+    this.initEvent();
+    this.gameinfo.renderImage(ctx, this.score.num)
+  }
+  loop() {
+    this.step1();
+    this.aniId = window.requestAnimationFrame(this.bindLoop, canvas)
+  }
+  /**
+   * 随机方块生成逻辑
+   * 帧数取模定义成生成的频率
+   * 左边和左边的左边
+   * 下边和下边的下边
+   */
+  enemyGenerate() {
+    this.boxData = [];
+    for (let i = 0; i < numberX; i++) {
+      for (let j = 0; j < numberY; j++) {
+        if (j == 0) this.boxData[i] = new Array(numberY)
+        this.boxData[i][j] = {
+          animal: animal[Math.floor(Math.random() * 5)],
+          match: 0
+        }
+        while (i > 1 && this.boxData[i][j]['animal'] == this.boxData[i - 2][j]['animal'] || j > 1 && this.boxData[i][j]['animal'] == this.boxData[i][j - 2]['animal']) this.boxData[i][j]['animal'] = animal[Math.floor(Math.random() * 4)]
+
+
+      }
+    }
+
+    this.boxData.forEach((item, x) => {
+      item.forEach((it, y) => {
+        this.ele.render(ctx, it['animal'] * fixedW, 0, imgW * x + ceilX, imgH * y + ceilY);
+      })
+
+    })
+
+  }
+
+}

+ 15 - 12
js/base/animation.js

@@ -1,7 +1,7 @@
-import Sprite from './sprite'
+import Sprite  from './sprite'
 import DataBus from '../databus'
 
-const databus = new DataBus()
+let databus = new DataBus()
 
 const __ = {
   timer: Symbol('timer'),
@@ -48,7 +48,7 @@ export default class Animation extends Sprite {
    */
   initFrames(imgList) {
     imgList.forEach((imgSrc) => {
-      const img = new Image()
+      let img = new Image()
       img.src = imgSrc
 
       this.imgList.push(img)
@@ -63,7 +63,7 @@ export default class Animation extends Sprite {
       this.imgList[this.index],
       this.x,
       this.y,
-      this.width * 1.2,
+      this.width  * 1.2,
       this.height * 1.2
     )
   }
@@ -71,14 +71,14 @@ export default class Animation extends Sprite {
   // 播放预定的帧动画
   playAnimation(index = 0, loop = false) {
     // 动画播放的时候精灵图不再展示,播放帧动画的具体帧
-    this.visible = false
+    this.visible   = false
 
     this.isPlaying = true
-    this.loop = loop
+    this.loop      = loop
 
-    this.index = index
+    this.index     = index
 
-    if (this.interval > 0 && this.count) {
+    if ( this.interval > 0 && this.count ) {
       this[__.timer] = setInterval(
         this.frameLoop.bind(this),
         this.interval
@@ -90,17 +90,20 @@ export default class Animation extends Sprite {
   stop() {
     this.isPlaying = false
 
-    if (this[__.timer]) clearInterval(this[__.timer])
+    if ( this[__.timer] )
+      clearInterval(this[__.timer])
   }
 
   // 帧遍历
   frameLoop() {
     this.index++
 
-    if (this.index > this.count - 1) {
-      if (this.loop) {
+    if ( this.index > this.count - 1 ) {
+      if ( this.loop ) {
         this.index = 0
-      } else {
+      }
+
+      else {
         this.index--
         this.stop()
       }

+ 5 - 5
js/base/pool.js

@@ -18,7 +18,7 @@ export default class Pool {
    * 获取对应的对象池
    */
   getPoolBySign(name) {
-    return this[__.poolDic][name] || (this[__.poolDic][name] = [])
+    return this[__.poolDic][name] || ( this[__.poolDic][name] = [] )
   }
 
   /**
@@ -26,11 +26,11 @@ export default class Pool {
    * 对象池为空创建新的类,否则从对象池中取
    */
   getItemByClass(name, className) {
-    const pool = this.getPoolBySign(name)
+    let pool = this.getPoolBySign(name)
 
-    const result = (pool.length
-      ? pool.shift()
-      : new className())
+    let result = (  pool.length
+                  ? pool.shift()
+                  : new className()  )
 
     return result
   }

+ 11 - 10
js/base/sprite.js

@@ -2,11 +2,10 @@
  * 游戏基础的精灵类
  */
 export default class Sprite {
-  constructor(imgSrc = '', width = 0, height = 0, x = 0, y = 0) {
-    this.img = new Image()
+  constructor(imgSrc = '', width=  0, height = 0, x = 0, y = 0) {
+    this.img     = new Image()
     this.img.src = imgSrc
-
-    this.width = width
+    this.width  = width
     this.height = height
 
     this.x = x
@@ -19,7 +18,8 @@ export default class Sprite {
    * 将精灵图绘制在canvas上
    */
   drawToCanvas(ctx) {
-    if (!this.visible) return
+    if ( !this.visible )
+      return
 
     ctx.drawImage(
       this.img,
@@ -36,14 +36,15 @@ export default class Sprite {
    * @param{Sprite} sp: Sptite的实例
    */
   isCollideWith(sp) {
-    const spX = sp.x + sp.width / 2
-    const spY = sp.y + sp.height / 2
+    let spX = sp.x + sp.width / 2
+    let spY = sp.y + sp.height / 2
 
-    if (!this.visible || !sp.visible) return false
+    if ( !this.visible || !sp.visible )
+      return false
 
-    return !!(spX >= this.x
+    return !!(   spX >= this.x
               && spX <= this.x + this.width
               && spY >= this.y
-              && spY <= this.y + this.height)
+              && spY <= this.y + this.height  )
   }
 }

+ 7 - 26
js/databus.js

@@ -7,7 +7,8 @@ let instance
  */
 export default class DataBus {
   constructor() {
-    if (instance) return instance
+    if ( instance )
+      return instance
 
     instance = this
 
@@ -17,35 +18,15 @@ export default class DataBus {
   }
 
   reset() {
-    this.frame = 0
-    this.score = 0
-    this.bullets = []
-    this.enemys = []
-    this.animations = []
-    this.gameOver = false
-  }
-
-  /**
-   * 回收敌人,进入对象池
-   * 此后不进入帧循环
-   */
-  removeEnemey(enemy) {
-    const temp = this.enemys.shift()
 
-    temp.visible = false
+    this.score  = 0
+    this.animations = []
+    this.gameOver   = false
+    this.box    = []
 
-    this.pool.recover('enemy', enemy)
+    
   }
 
-  /**
-   * 回收子弹,进入对象池
-   * 此后不进入帧循环
-   */
-  removeBullets(bullet) {
-    const temp = this.bullets.shift()
 
-    temp.visible = false
 
-    this.pool.recover('bullet', bullet)
-  }
 }

+ 1 - 1
js/libs/symbol.js

@@ -3,7 +3,7 @@
  * 方便模拟私有变量
  */
 
-let Symbol = window.Symbol
+let Symbol  = window.Symbol
 let idCounter = 0
 
 if (!Symbol) {

File diff suppressed because it is too large
+ 351 - 327
js/libs/weapp-adapter.js


+ 0 - 176
js/main.js

@@ -1,176 +0,0 @@
-import Player from './player/index'
-import Enemy from './npc/enemy'
-import BackGround from './runtime/background'
-import GameInfo from './runtime/gameinfo'
-import Music from './runtime/music'
-import DataBus from './databus'
-
-const ctx = canvas.getContext('2d')
-const databus = new DataBus()
-
-/**
- * 游戏主函数
- */
-export default class Main {
-  constructor() {
-    // 维护当前requestAnimationFrame的id
-    this.aniId = 0
-
-    this.restart()
-  }
-
-  restart() {
-    databus.reset()
-
-    canvas.removeEventListener(
-      'touchstart',
-      this.touchHandler
-    )
-
-    this.bg = new BackGround(ctx)
-    this.player = new Player(ctx)
-    this.gameinfo = new GameInfo()
-    this.music = new Music()
-
-    this.bindLoop = this.loop.bind(this)
-    this.hasEventBind = false
-
-    // 清除上一局的动画
-    window.cancelAnimationFrame(this.aniId)
-
-    this.aniId = window.requestAnimationFrame(
-      this.bindLoop,
-      canvas
-    )
-  }
-
-  /**
-   * 随着帧数变化的敌机生成逻辑
-   * 帧数取模定义成生成的频率
-   */
-  enemyGenerate() {
-    if (databus.frame % 30 === 0) {
-      const enemy = databus.pool.getItemByClass('enemy', Enemy)
-      enemy.init(6)
-      databus.enemys.push(enemy)
-    }
-  }
-
-  // 全局碰撞检测
-  collisionDetection() {
-    const that = this
-
-    databus.bullets.forEach((bullet) => {
-      for (let i = 0, il = databus.enemys.length; i < il; i++) {
-        const enemy = databus.enemys[i]
-
-        if (!enemy.isPlaying && enemy.isCollideWith(bullet)) {
-          enemy.playAnimation()
-          that.music.playExplosion()
-
-          bullet.visible = false
-          databus.score += 1
-
-          break
-        }
-      }
-    })
-
-    for (let i = 0, il = databus.enemys.length; i < il; i++) {
-      const enemy = databus.enemys[i]
-
-      if (this.player.isCollideWith(enemy)) {
-        databus.gameOver = true
-
-        break
-      }
-    }
-  }
-
-  // 游戏结束后的触摸事件处理逻辑
-  touchEventHandler(e) {
-    e.preventDefault()
-
-    const x = e.touches[0].clientX
-    const y = e.touches[0].clientY
-
-    const area = this.gameinfo.btnArea
-
-    if (x >= area.startX
-        && x <= area.endX
-        && y >= area.startY
-        && y <= area.endY) this.restart()
-  }
-
-  /**
-   * canvas重绘函数
-   * 每一帧重新绘制所有的需要展示的元素
-   */
-  render() {
-    ctx.clearRect(0, 0, canvas.width, canvas.height)
-
-    this.bg.render(ctx)
-
-    databus.bullets
-      .concat(databus.enemys)
-      .forEach((item) => {
-        item.drawToCanvas(ctx)
-      })
-
-    this.player.drawToCanvas(ctx)
-
-    databus.animations.forEach((ani) => {
-      if (ani.isPlaying) {
-        ani.aniRender(ctx)
-      }
-    })
-
-    this.gameinfo.renderGameScore(ctx, databus.score)
-
-    // 游戏结束停止帧循环
-    if (databus.gameOver) {
-      this.gameinfo.renderGameOver(ctx, databus.score)
-
-      if (!this.hasEventBind) {
-        this.hasEventBind = true
-        this.touchHandler = this.touchEventHandler.bind(this)
-        canvas.addEventListener('touchstart', this.touchHandler)
-      }
-    }
-  }
-
-  // 游戏逻辑更新主函数
-  update() {
-    if (databus.gameOver) return
-
-    this.bg.update()
-
-    databus.bullets
-      .concat(databus.enemys)
-      .forEach((item) => {
-        item.update()
-      })
-
-    this.enemyGenerate()
-
-    this.collisionDetection()
-
-    if (databus.frame % 20 === 0) {
-      this.player.shoot()
-      this.music.playShoot()
-    }
-  }
-
-  // 实现游戏帧循环
-  loop() {
-    databus.frame++
-
-    this.update()
-    this.render()
-
-    this.aniId = window.requestAnimationFrame(
-      this.bindLoop,
-      canvas
-    )
-  }
-}

+ 0 - 55
js/npc/enemy.js

@@ -1,55 +0,0 @@
-import Animation from '../base/animation'
-import DataBus from '../databus'
-
-const ENEMY_IMG_SRC = 'images/enemy.png'
-const ENEMY_WIDTH = 60
-const ENEMY_HEIGHT = 60
-
-const __ = {
-  speed: Symbol('speed')
-}
-
-const databus = new DataBus()
-
-function rnd(start, end) {
-  return Math.floor(Math.random() * (end - start) + start)
-}
-
-export default class Enemy extends Animation {
-  constructor() {
-    super(ENEMY_IMG_SRC, ENEMY_WIDTH, ENEMY_HEIGHT)
-
-    this.initExplosionAnimation()
-  }
-
-  init(speed) {
-    this.x = rnd(0, window.innerWidth - ENEMY_WIDTH)
-    this.y = -this.height
-
-    this[__.speed] = speed
-
-    this.visible = true
-  }
-
-  // 预定义爆炸的帧动画
-  initExplosionAnimation() {
-    const frames = []
-
-    const EXPLO_IMG_PREFIX = 'images/explosion'
-    const EXPLO_FRAME_COUNT = 19
-
-    for (let i = 0; i < EXPLO_FRAME_COUNT; i++) {
-      frames.push(`${EXPLO_IMG_PREFIX + (i + 1)}.png`)
-    }
-
-    this.initFrames(frames)
-  }
-
-  // 每一帧更新子弹位置
-  update() {
-    this.y += this[__.speed]
-
-    // 对象回收
-    if (this.y > window.innerHeight + this.height) databus.removeEnemey(this)
-  }
-}

+ 0 - 35
js/player/bullet.js

@@ -1,35 +0,0 @@
-import Sprite from '../base/sprite'
-import DataBus from '../databus'
-
-const BULLET_IMG_SRC = 'images/bullet.png'
-const BULLET_WIDTH = 16
-const BULLET_HEIGHT = 30
-
-const __ = {
-  speed: Symbol('speed')
-}
-
-const databus = new DataBus()
-
-export default class Bullet extends Sprite {
-  constructor() {
-    super(BULLET_IMG_SRC, BULLET_WIDTH, BULLET_HEIGHT)
-  }
-
-  init(x, y, speed) {
-    this.x = x
-    this.y = y
-
-    this[__.speed] = speed
-
-    this.visible = true
-  }
-
-  // 每一帧更新子弹位置
-  update() {
-    this.y -= this[__.speed]
-
-    // 超出屏幕外回收自身
-    if (this.y < -this.height) databus.removeBullets(this)
-  }
-}

+ 0 - 119
js/player/index.js

@@ -1,119 +0,0 @@
-import Sprite from '../base/sprite'
-import Bullet from './bullet'
-import DataBus from '../databus'
-
-const screenWidth = window.innerWidth
-const screenHeight = window.innerHeight
-
-// 玩家相关常量设置
-const PLAYER_IMG_SRC = 'images/hero.png'
-const PLAYER_WIDTH = 80
-const PLAYER_HEIGHT = 80
-
-const databus = new DataBus()
-
-export default class Player extends Sprite {
-  constructor() {
-    super(PLAYER_IMG_SRC, PLAYER_WIDTH, PLAYER_HEIGHT)
-
-    // 玩家默认处于屏幕底部居中位置
-    this.x = screenWidth / 2 - this.width / 2
-    this.y = screenHeight - this.height - 30
-
-    // 用于在手指移动的时候标识手指是否已经在飞机上了
-    this.touched = false
-
-    this.bullets = []
-
-    // 初始化事件监听
-    this.initEvent()
-  }
-
-  /**
-   * 当手指触摸屏幕的时候
-   * 判断手指是否在飞机上
-   * @param {Number} x: 手指的X轴坐标
-   * @param {Number} y: 手指的Y轴坐标
-   * @return {Boolean}: 用于标识手指是否在飞机上的布尔值
-   */
-  checkIsFingerOnAir(x, y) {
-    const deviation = 30
-
-    return !!(x >= this.x - deviation
-              && y >= this.y - deviation
-              && x <= this.x + this.width + deviation
-              && y <= this.y + this.height + deviation)
-  }
-
-  /**
-   * 根据手指的位置设置飞机的位置
-   * 保证手指处于飞机中间
-   * 同时限定飞机的活动范围限制在屏幕中
-   */
-  setAirPosAcrossFingerPosZ(x, y) {
-    let disX = x - this.width / 2
-    let disY = y - this.height / 2
-
-    if (disX < 0) disX = 0
-
-    else if (disX > screenWidth - this.width) disX = screenWidth - this.width
-
-    if (disY <= 0) disY = 0
-
-    else if (disY > screenHeight - this.height) disY = screenHeight - this.height
-
-    this.x = disX
-    this.y = disY
-  }
-
-  /**
-   * 玩家响应手指的触摸事件
-   * 改变战机的位置
-   */
-  initEvent() {
-    canvas.addEventListener('touchstart', ((e) => {
-      e.preventDefault()
-
-      const x = e.touches[0].clientX
-      const y = e.touches[0].clientY
-
-      //
-      if (this.checkIsFingerOnAir(x, y)) {
-        this.touched = true
-
-        this.setAirPosAcrossFingerPosZ(x, y)
-      }
-    }))
-
-    canvas.addEventListener('touchmove', ((e) => {
-      e.preventDefault()
-
-      const x = e.touches[0].clientX
-      const y = e.touches[0].clientY
-
-      if (this.touched) this.setAirPosAcrossFingerPosZ(x, y)
-    }))
-
-    canvas.addEventListener('touchend', ((e) => {
-      e.preventDefault()
-
-      this.touched = false
-    }))
-  }
-
-  /**
-   * 玩家射击操作
-   * 射击时机由外部决定
-   */
-  shoot() {
-    const bullet = databus.pool.getItemByClass('bullet', Bullet)
-
-    bullet.init(
-      this.x + this.width / 2 - bullet.width / 2,
-      this.y - 10,
-      10
-    )
-
-    databus.bullets.push(bullet)
-  }
-}

+ 12 - 33
js/runtime/background.js

@@ -1,60 +1,39 @@
 import Sprite from '../base/sprite'
 
-const screenWidth = window.innerWidth
+const screenWidth  = window.innerWidth
 const screenHeight = window.innerHeight
+const BG_WIDTH     = 375
+const BG_HEIGHT    =  667
 
-const BG_IMG_SRC = 'images/bg.jpg'
-const BG_WIDTH = 512
-const BG_HEIGHT = 512
 
 /**
  * 游戏背景类
  * 提供update和render函数实现无限滚动的背景功能
  */
 export default class BackGround extends Sprite {
-  constructor(ctx) {
+  constructor(ctx,BG_IMG_SRC) {
     super(BG_IMG_SRC, BG_WIDTH, BG_HEIGHT)
-
-    this.top = 0
-
     this.render(ctx)
   }
 
-  update() {
-    this.top += 2
-
-    if (this.top >= screenHeight) this.top = 0
-  }
 
   /**
-   * 背景图重绘函数
-   * 绘制两张图片,两张图片大小和屏幕一致
-   * 第一张漏出高度为top部分,其余的隐藏在屏幕上面
-   * 第二张补全除了top高度之外的部分,其余的隐藏在屏幕下面
+   
    */
-  render(ctx) {
+  render(ctx,sx=0,sy=0,scalX=1,scalY=1) {
+  
     ctx.drawImage(
       this.img,
+      sx,
+      sy,
+      this.width*scalX,
+      this.height*scalY,
       0,
       0,
-      this.width,
-      this.height,
-      0,
-      -screenHeight + this.top,
       screenWidth,
       screenHeight
     )
 
-    ctx.drawImage(
-      this.img,
-      0,
-      0,
-      this.width,
-      this.height,
-      0,
-      this.top,
-      screenWidth,
-      screenHeight
-    )
+ 
   }
 }

+ 42 - 0
js/runtime/element.js

@@ -0,0 +1,42 @@
+
+let atlas = new Image()
+atlas.src = 'images/sprit.png'
+let atlas2 = new Image()
+atlas2.src = 'images/sprit3.png'
+let atlas3 = new Image()
+atlas3.src = 'images/boom.png'
+const screenWidth  = window.innerWidth
+const scalX = (47/375)*screenWidth
+const scalY = scalX
+export default class Element   {
+  
+    render(ctx,x,y,screenX,screenY,hide) {
+        if(hide) return
+        ctx.drawImage(
+            atlas,
+            x, y, 95, 93 ,screenX,screenY,scalX,scalY
+          )
+    
+
+      }
+    renderHover(ctx,x,y,screenX,screenY,hide) {
+     
+        if(hide) return
+        ctx.drawImage(
+            atlas2,
+            x, y, 95, 93 ,screenX,screenY,scalX,scalY
+          )
+    
+          
+      }
+     renderBoom(ctx,x,y,screenX,screenY,hide) {
+     
+        if(hide) return
+        ctx.drawImage(
+            atlas3,
+            x, y+5, 95, 82 ,screenX,screenY,scalX,scalY
+          )
+    
+          
+      }
+}

+ 34 - 16
js/runtime/gameinfo.js

@@ -1,26 +1,43 @@
-const screenWidth = window.innerWidth
+const screenWidth  = window.innerWidth
 const screenHeight = window.innerHeight
-
-const atlas = new Image()
-atlas.src = 'images/Common.png'
-
+import Element from './element'
+let atlas = new Image()
+atlas.src = 'images/bg.jpg'
+const scalx = canvas.width/375
+const scaly=canvas.height/ 667
 export default class GameInfo {
   renderGameScore(ctx, score) {
-    ctx.fillStyle = '#ffffff'
-    ctx.font = '20px Arial'
-
+    this.info = new Element(ctx);
+    ctx.font      = "15px Arial bold"
+    ctx.strokeStyle = '#fff';  
+    ctx.strokeText('第:'+1+'关',10*scalx,15*scaly)  
+    ctx.fillStyle = "#ffcf00"
     ctx.fillText(
-      score,
-      10,
-      30
+      '第:'+1+'关',
+      10*scalx,
+      15*scaly
     )
+      
+  
+  }
+
+  renderImage(ctx,score) {
+    this.info.render(ctx,0,0,148*scalx,5*scaly);
+  
+    ctx.font      = "16px Arial bold"
+    ctx.strokeStyle = '#eee';  
+    ctx.strokeText(score,183*scalx,50*scaly)  
+    ctx.fillStyle = "#ffcf00"
+    ctx.fillText(score,183*scalx,50*scaly)
+  
+
   }
 
   renderGameOver(ctx, score) {
     ctx.drawImage(atlas, 0, 0, 119, 108, screenWidth / 2 - 150, screenHeight / 2 - 100, 300, 300)
 
-    ctx.fillStyle = '#ffffff'
-    ctx.font = '20px Arial'
+    ctx.fillStyle = "#ffffff"
+    ctx.font    = "20px Arial"
 
     ctx.fillText(
       '游戏结束',
@@ -29,7 +46,7 @@ export default class GameInfo {
     )
 
     ctx.fillText(
-      `得分: ${score}`,
+      '得分: ' + score,
       screenWidth / 2 - 40,
       screenHeight / 2 - 100 + 130
     )
@@ -55,8 +72,9 @@ export default class GameInfo {
     this.btnArea = {
       startX: screenWidth / 2 - 40,
       startY: screenHeight / 2 - 100 + 180,
-      endX: screenWidth / 2 + 50,
-      endY: screenHeight / 2 - 100 + 255
+      endX  : screenWidth / 2  + 50,
+      endY  : screenHeight / 2 - 100 + 255
     }
   }
 }
+

+ 26 - 0
js/runtime/login.js

@@ -0,0 +1,26 @@
+
+const screenWidth  = window.innerWidth
+const screenHeight = window.innerHeight
+let atlas = new Image()
+atlas.src = 'images/loginButton.png'
+export default class Login  {
+    btnArea = {
+        startX: screenWidth/2-60,
+        startY:screenHeight-60,
+        endX  : screenWidth/2-60+138,
+        endY  : screenHeight-60+67
+    }
+    render(ctx) {
+        ctx.drawImage(
+            atlas,
+            0, 0, 138, 67,screenWidth/2-60,screenHeight-60,120, 40
+          )
+            /**
+     * 重新开始按钮区域
+     * 方便简易判断按钮点击
+     */
+     
+
+      }
+
+}

+ 24 - 14
js/runtime/music.js

@@ -5,34 +5,44 @@ let instance
  */
 export default class Music {
   constructor() {
-    if (instance) return instance
+    if ( instance )
+      return instance
 
     instance = this
 
     this.bgmAudio = new Audio()
     this.bgmAudio.loop = true
-    this.bgmAudio.src = 'audio/bgm.mp3'
+    this.bgmAudio.src  = 'audio/bgm.mp3'
 
-    this.shootAudio = new Audio()
-    this.shootAudio.src = 'audio/bullet.mp3'
+    this.swapAudio     = new Audio()
+    this.swapAudio.src = 'audio/swap.mp3'
 
-    this.boomAudio = new Audio()
-    this.boomAudio.src = 'audio/boom.mp3'
-
-    this.playBgm()
+    this.clearAudio     = new Audio()
+    this.clearAudio.src = 'audio/clear.mp3'
+    this.isAudio     = new Audio()
+    this.isAudio.src = 'audio/yes.mp3'
+     this.playBgm()
   }
 
   playBgm() {
     this.bgmAudio.play()
+  
+  }
+  secen2() {
+
+    this.bgmAudio.pause()
+   
+   
   }
 
-  playShoot() {
-    this.shootAudio.currentTime = 0
-    this.shootAudio.play()
+  playswapAudio() {
+    this.swapAudio.play()
   }
 
-  playExplosion() {
-    this.boomAudio.currentTime = 0
-    this.boomAudio.play()
+  playclearAudio() {
+    this.clearAudio.play()
+  }
+  playisAudio() {
+    this.isAudio.play()
   }
 }

Some files were not shown because too many files changed in this diff