上次代碼有問題,只能在IDE上面預覽,不能真機。由於真機小遊戲中缺乏window對象。
解決方法就是,引用用微信的weapp-adapter。canvas
import './libs/weapp-adapter' import './libs/symbol'
以後:微信
const context = canvas.getContext('2d')
並不須要const canvas = wx.createCanvas()
了。app
接下來,須要讓精靈繪製圖片。異步
因此,Sprite的draw方法改變一下:函數
draw(context) { // context.fillStyle = '#1aad19' // context.fillRect(this.x, this.y, 50, 50) context.drawImage(this.img, this.x, this.y) }
在構建函數中:this
constructor(x = 0, y = 0, img, scale = 1) { this.x = x this.y = y this.img = img this.scale = scale }
考慮到player的img可能會變化,所以,設立一個setImg的方法:spa
setImg(img) { this.img = img this.width = img.width this.height = img.height }
可見精靈的尺寸是與圖片有關的。不少遊戲引擎能夠經過scale來設置大小。所以,如今構建函數變爲:code
constructor(x = 0, y = 0, img, scale = 1) { this.x = x this.y = y this.scale = scale this.setImg(img) }
相應地,在game.js中,初始化player就變成了:對象
const player = new Sprite(0, 0, player_img, 0.5)
player_img是哪兒來的?遊戲
代碼以下:
const player_img = wx.createImage() player_img.src = item.src player_img.onload = function () { const player = new Sprite(0, 0, player_img, 0.5) }
由於是直接用Sprite new出來的,所以以前Player.js沒用了,刪掉就好。
因爲精靈須要改變位置,所以添加一個方法:
setPosition(x, y) { this.x = x this.y = y }
因爲加載圖片是異步的,若是圖片不少,那麼一個個寫明顯不合適。所以,寫一個資源載入類/codetyphon/resloader.js:
export default class ResLoader { constructor() { this.list = [] this.res = {} this.load_num = 0 } add(name, src) { this.list.push({ name: name, src: src }) } on_load_finish(fun) { const _self = this this.list.map(item => { console.log(item.src) const image = wx.createImage() image.src = item.src image.onload = function () { console.log(item.name + ' load') _self.res[item.name] = this _self.load_num += 1; } }) const id = setInterval(() => { if(_self.load_num==_self.list.length){ clearInterval(id) fun(_self.res) } }, 100) } }
在 codetyphon/index.js 中:
import Sprite from './sprite' import ResLoader from './resloader' export { ResLoader, Sprite }
在 game.js 中:
import './libs/weapp-adapter' import './libs/symbol' import { ResLoader, Sprite } from './codetyphon/index' const context = canvas.getContext('2d') const { windowWidth, windowHeight } = wx.getSystemInfoSync() const loader = new ResLoader() loader.add('player', 'images/player.png') loader.on_load_finish((res) => { const player = new Sprite(0, 0, res['player'], 0.5) player.setPosition(windowWidth / 2, windowHeight - player.height) const step = (timestamp) => { context.clearRect(0, 0, windowWidth, windowHeight) player.update() player.draw(context) window.requestAnimationFrame(step); } window.requestAnimationFrame(step); wx.onTouchMove(function (res) { const x = res.changedTouches[0].clientX const y = res.changedTouches[0].clientY player.setPosition(x, y) }) })
這個時候,就能夠經過觸屏去移動player了。
可是仔細看能夠發現,觸動時,是精靈的左上角,而不是中間。
所以,Sprite的draw方法改成:
context.drawImage(this.img, this.x - this.width / 2, this.y - this.height / 2, this.width, this.height)
如今,Sprite所有代碼爲:
export default class Sprite { constructor(x = 0, y = 0, img, scale = 1) { this.x = x this.y = y this.scale = scale this.setImg(img) } setImg(img) { this.img = img this.width = img.width * this.scale this.height = img.height * this.scale } setPosition(x, y) { this.x = x this.y = y } update() { } draw(context) { context.drawImage(this.img, this.x - this.width / 2, this.y - this.height / 2, this.width, this.height) } }
如今,觸動的位置恰好在精靈的中間。