微信小遊戲填坑指南

微信小遊戲

因爲工作需要,提前預研微信小遊戲的開發流程。做了如下一個簡單的demo項目,並且把實際項目中遇到的坑點都一一詳細列出,方便在今後的項目中可以進行查閱。

gitHub 項目源碼

小遊戲填坑指南

  • 微信小遊戲只允許在調試模式下使用window全局變量,在真機模式下使用window會導致報錯。

  • 如何在canvas繪製圖片

  let image = wx.createImage()
  image.src = './resources/background.png'
  // 資源加載完成回調
  image.onload = _ => {
    this.ctx.drawImage(
      image,
      0, 0,
      // 源圖片裁剪的寬高
      image.width,
      image.height,
      0, 0,
      // 屏幕投影寬高
      image.width,
      image.height
    )
  }

  • 單例模式應用
export default class Director {
  constructor () {
    console.log('Director 構造器初始化')
  }

  static getInstance () {
    if (!Director.instance) {
      Director.instance = new Director()
    }
    return Director.instance
  }
}


// other Class
import Director from './js/Director'

export default class Main {
  constructor () {
    // 獲取 Director 實例
    this.director = Director.getInstance()
  }
}


  • 實現全局狀態管理器

export default class DataStore {
  constructor () {
    this.map = new Map()
  }
  static getInstance () {
    if (!DataStore.instance) {
      DataStore.instance = new DataStore()
    }
    return DataStore.instance
  }
  put (key, value) {
    this.map.set(key, value)
    return this // 保證鏈式調用
  }
  get (key) {
    return this.map.get(key)
  }
  // 資源銷燬
  destory () {
    // for (let value of this.map.values()) {
    //   value = null
    // }
  }
}


  • super之前不可以調用this
export default class Background extends Sprite {
  constructor (image = null) {
    // this 不可以調用
    this.image = null 
    // this 不可以調用
    super(image,
      0, 0,
      image.width,
      image.height,
      0, 0,
      screenWidth,
      screenHeight
    )
  }
}

  • 子類中通過super,可以調用父類的方法
export default class Background extends Sprite {
  draw () {
    super.drawImage()
  }
}

  • 微信垃圾回收
wx.triggerGC()
  • 播放音樂
// 播放背景音樂
createBackgroundMusic () {
  const bgm = wx.createInnerAudioContext()
  bgm.autoplay = true // 自動播放
  bgm.loop = true // 循環播放
  bgm.src = 'audio/bgm.mp3'
}
  • 振動檢測
// 振動檢測
wx.vibrateShort({
  success () {
    console.log('success')
  },
  fail () {
    console.log('fail')
  },
  complete () {
    console.log('complete')
  }
})
  • 微信常用數據接口

// 獲取用戶授權信息
// https://developers.weixin.qq.com/miniprogram/dev/api/wx.getUserInfo.html
wx.getUserInfo(Object object)
// 用戶登錄
// https://developers.weixin.qq.com/miniprogram/dev/api/wx.login.html
wx.login(Object object)
  • 搭建簡易的websocket服務
// 服務端ws
const WebSocket = require('ws');
 
const wss = new WebSocket.Server({ port: 8080 });
// 建立連接
wss.on('connection', function connection(ws) {
  // 接受客戶端消息
  ws.on('message', function incoming(message) {
    console.log('received: %s', message);
  });
  // 發送消息
  ws.send('something');
});


// 客戶端ws
setConnect () {
  console.log('setConnect')
  wx.connectSocket({
    url: 'ws://127.0.0.1:8080',
    success () {
      console.log('建立成功')
    },
    complete () {
      console.log('建立完成')
    }
  })
}
  • 在webSocket中發送消息
wx.onSocketOpen(_ => {
  // 必須在onSocketOpen回調中發送
  wx.sendSocketMessage({
    data: '發送客戶端消息~~~~~~~~~~~',
    success () {
      console.log('發送成功')
    },
    complete () {
      console.log('發送完成')
    }
  })
  // 監聽服務端的消息
  wx.onSocketMessage(res => {
    console.log('這是接受服務端數據', res)
  })
})
  • 簡易碰撞檢測
  // 碰撞檢測
  checkCollision (point, range, image) {
    const offset = {
      top: -1,
      bottom: -1,
      left: -1,
      right: -1
    }
    if (point.y < range.top + image.height / 2) {
      // 超出上邊界
      offset.top = parseFloat((range.top + image.height / 2 - point.y) / image.height)
    } else if (point.y > range.bottom - image.height / 2) {
      // 超出下邊界
      offset.bottom = parseFloat((point.y - (range.bottom - image.height / 2)) / image.height)
    }
    if (point.x < range.left + image.width / 2) {
      // 超出左邊界
      offset.left = parseFloat((range.left + image.width / 2 - point.x) / image.width)
    } else if (point.x > range.right - image.width / 2) {
      // 超出右邊界
      offset.right = parseFloat((point.x - (range.right - image.width / 2)) / image.width)
    }
    return offset
  }
  • 簡易邊界檢測
  checkRange (point) {
    let infos = {
      valid: false,
      pos: -1, // 點擊區域無效
      point
    }
    const unitImage = this.dataStore.get('wrong')
    if (point.y >= this.topRange.top &&
        point.y <= this.topRange.bottom &&
        point.x >= this.topRange.left &&
        point.x <= this.topRange.right
    ) {
      console.log('點擊了上邊界')
      infos.pos = 0
      infos.valid = true
      infos.offset = this.checkCollision(point, this.topRange, unitImage)
    } else if (point.y >= this.bottomRange.top &&
      point.y <= this.bottomRange.bottom &&
      point.x >= this.bottomRange.left &&
      point.x <= this.bottomRange.right
    ) {
      console.log('點擊了下邊界')
      infos.pos = 1
      infos.valid = true
      infos.offset = this.checkCollision(point, this.bottomRange, unitImage)
    }
    return infos
  }
  • canvas 文字居中
// canvas 文字居中(動態計算文字長度)
const len = (this.score.toString().length - 1)
this.dataStore.ctx.font = `bold ${px(48)}px Arial`
this.dataStore.ctx.fillStyle = '#833823'
this.dataStore.ctx.fillText(
  this.score,
  px(pos.x - 10 * len), px(pos.y), 1000)
  • Promise.all 應用
  // 資源加載
  this.image = wx.createImage()
  this.progressbg = wx.createImage()
  this.progressbar = wx.createImage()
  this.image.src = 'resources/images/common/bg.png'
  this.progressbg.src = 'resources/images/common/progress-bar.png'
  this.progressbar.src = 'resources/images/common/progress.png'
  this.loaded = false
  const p1 = new Promise(resolve => {
    this.image.onload = _ => {
      resolve()
    }
  })
  const p2 = new Promise(resolve => {
    this.progressbg.onload = _ => {
      resolve()
    }
  })
  const p3 = new Promise(resolve => {
    this.progressbar.onload = _ => {
      resolve()
    }
  })
  Promise.all([p1, p2, p3]).then(_ => {
    console.log('loading頁加載完成')
    this.loaded = true
  })
  • 繪製矩形
// 繪製矩形
ctx.fillStyle = 'rgba(255,255,255,0.9)'
const width = px(300)
const height = px(200)
ctx.fillRect(this.screenWidth / 2 - width / 2, this.screenHeight / 2 - height / 2, width, height)
ctx.fill()
  • js 隨機數

Math.ceil();  //向上取整。

Math.floor();  //向下取整。

Math.round();  //四捨五入。

Math.random();  //0.0 ~ 1.0 之間的一個僞隨機數
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章