上次代码有问题,只能在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) } }
如今,触动的位置恰好在精灵的中间。