上次代码有问题,只能在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.srcplayer_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) }}
当初,触动的地位刚好在精灵的两头。