上次代码有问题,只能在 IDE 下面预览,不能真机。因为真机小游戏中短少 window 对象。
解决办法就是,援用用微信的 weapp-adapter。
import './libs/weapp-adapter'
import './libs/symbol'
之后:
const context = canvas.getContext('2d')
并不需要 const canvas = wx.createCanvas()
了。
接下来,须要让精灵绘制图片。
所以,Sprite 的 draw 办法扭转一下:
draw(context) {
// context.fillStyle = '#1aad19'
// context.fillRect(this.x, this.y, 50, 50)
context.drawImage(this.img, this.x, this.y)
}
在构建函数中:
constructor(x = 0, y = 0, img, scale = 1) {
this.x = x
this.y = y
this.img = img
this.scale = scale
}
思考到 player 的 img 可能会变动,因而,设立一个 setImg 的办法:
setImg(img) {
this.img = img
this.width = img.width
this.height = img.height
}
可见精灵的尺寸是与图片无关的。很多游戏引擎能够通过 scale 来设置大小。因而,当初构建函数变为:
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)
}
}
当初,触动的地位刚好在精灵的两头。