小游戏触摸事件
我们知道, HTML Canvas 中可以通过 <canvas>
元素的 addEventListener()
和 removeEventListener()
添加各种事件,包括鼠标单击,鼠标双击,鼠标移动等
详细的内容可以访问我们的 Canvas 事件 和 Canvas 鼠标/手指按下和松开事件
但是在移动设备上,其实就只有三种事件:手指触碰屏幕 、手指在屏幕上移动 和 手指离开屏幕
它们分别对应着 touchstart()
、 touchmove()
和 touchend()
事件
微信小游戏中的触摸事件
微信小游戏参照 DOM 中的 TouchEvent
提供了以下监听触摸事件的 API
事件 | 说明 |
---|---|
wx.onTouchStart() | 监听触摸开始事件 |
wx.onTouchMove() | 监听触摸移动事件 |
wx.onTouchEnd() | 监听触摸结束事件 |
wx.onTouchCancel() | 监听触点失效事件 |
四个方法的的原型都一样
都是使用一个函数 function(e){}
作为回调函数
wx.onTouchStart (function callback(e){}) wx.onTouchMove (function callback(e){}) wx.onTouchEnd (function callback(e){}) wx.onTouchCancel(function callback(e){})
回调函数 callback(e)
回调函数 callback(e){}
中的参数 e
是一个对象,包括以下属性
参数 | 类型 | 说明 |
---|---|---|
touches | array<array<Touch>> | 当前所有触摸点的列表 |
changedTouches | array<array<Touch>> | 触发此次事件的触摸点列表 |
timeStamp | number | 事件触发时的时间戳 |
touches
和 changedTouches
对象都是一个类型为 Touch
对象的二维数组
触点对象 Touch
Touch
对象表示在触控设备上的触摸点。通常是指手指或者触控笔在触屏设备或者触摸板上的操作
Touch
对象有以下属性
属性 | 类型 | 说明 |
---|---|---|
identifier | number | Touch 对象的唯一标识符,只读属性 一次触摸动作在平面上移动的整个过程中, 该标识符不变 可以根据它来判断跟踪的是否是同一次触摸过程 |
screenX | number | 触点相对于屏幕左边沿的 X 坐标 |
screenY | number | 触点相对于屏幕上边沿的 Y 坐标 |
取消触摸事件
微信小游戏也同时提供了以下事件用于取消触摸动作
事件 | 说明 |
---|---|
wx.offTouchStart() | 取消监听触摸开始事件 |
wx.offTouchMove() | 取消监听触摸移动事件 |
wx.offTouchEnd() | 取消监听触摸结束事件 |
wx.ffTouchCancel() | 取消监听触点失效事件 |
四个方法的的原型都一样
都是使用监听时传递的回调函数名 callback
作为参数
wx.onTouchStart (callback) wx.onTouchMove (callback) wx.onTouchEnd (callback) wx.onTouchCancel(callback)
范例
我们写一个范例用来监听用户的触摸事件
game.js
var c = wx.createCanvas(); var ctx = c.getContext('2d'); // 用来保存开始触摸和结束触摸的点 var touches = {x1:null,y1:null,x2:null,y2:null}; function reset() { ctx.save(); ctx.fillStyle = '#fff'; ctx.fillRect(0,0,c.width,c.height); ctx.fillStyle = "orange" ctx.textAlign = "center" // 居中对齐 ctx.textBaseline = "middle" //垂直居中绘制 ctx.font = "32px Arial" // 字体大小 44 像素 ctx.fillText("www.twle.cn", c.width / 2, (c.height - 20)); ctx.strokeStyle = "#000"; ctx.strokeText("简单教程,简单编程", c.width / 2, (c.height - 75)) ctx.restore(); } // 绘制文本 function drawText(ctx,text) { ctx.save(); ctx.font = "14px Arial" // 字体大小 44 像素 ctx.fillText(text, 10,25); ctx.restore(); } // 渲染 Canvas function render() { reset(); if ( touches.x1 == touches.x2 && touches.y1 == touches.y2 ) { return; } if ( touches.x1 == null || touches.x2 == null) { return; } ctx.fillStyle = 'green'; ctx.fillRect(touches.x1,touches.y1,touches.x2 - touches.x1,touches.y2 - touches.y1); } // 触摸开始事件 wx.onTouchStart(function(e){ var x = e.touches[0].clientX var y = e.touches[0].clientY touches.x1 = x; touches.y1 = y; touches.x2 = null; touches.y2 = null; render(); drawText(ctx,"用户开始触摸,触摸点为(" + x + "," + y + ")"); }) // 在屏幕上移动 wx.onTouchMove(function(e){ var x = e.touches[0].clientX var y = e.touches[0].clientY touches.x2 = x; touches.y2 = y; render(); drawText(ctx,"用户在手指在屏幕上滑动"); }) // 手指离开屏幕 wx.onTouchEnd(function(e){ var x = e.touches[0].clientX var y = e.touches[0].clientY touches.x2 = x; touches.y2 = y; render(); drawText(ctx,"用户手指离开屏幕"); }) reset();
在微信中运行效果如下
范例 2 : 小游戏:控制小球移动
我们在写一个范例,使用手势来控制小球移动方向
game.js
var c = wx.createCanvas(); var ctx = c.getContext('2d'); var tt = null; // 用于保存定时器 // 用来判断是否在游戏中 // 0 表示未开始 // 1 表示游戏进行中 // 2 表示游戏已经结束 var ingame = 0; // 用来保存开始触摸点 var lasted = { x: null, y: null }; // 小球 var ball = { x: 10, y: 10, vx: 50 / 60, vy: 50 / 30, radius: 10, color: 'black', draw: function () { ctx.beginPath(); ctx.arc(this.x, this.y, this.radius, 0, Math.PI * 2, true); ctx.closePath(); ctx.fillStyle = this.color; ctx.fill(); } }; function resetball() { ball.x = 10; ball.y = 10; ball.vx = 50 / 60; ball.vy = 50 / 30; } function reset() { ctx.save(); ctx.fillStyle = '#fff'; ctx.fillRect(0, 0, c.width, c.height); ctx.fillStyle = "orange" ctx.textAlign = "center" // 居中对齐 ctx.textBaseline = "middle" //垂直居中绘制 ctx.font = "32px Arial" // 字体大小 44 像素 ctx.fillText("www.twle.cn", c.width / 2, (c.height - 20)); ctx.strokeStyle = "#000"; ctx.strokeText("简单教程,简单编程", c.width / 2, (c.height - 75)) ctx.restore(); if (ingame == 0) { drawTip("请点击屏幕开始任意位置开始"); } } function drawTip(text) { ctx.save(); ctx.font = "22px Arial" // 字体大小 44 像素 ctx.fillStyle = '#333333'; ctx.textAlign = "center" // 居中对齐 ctx.textBaseline = "middle" //垂直居中绘制 ctx.fillText(text, c.width / 2, c.height / 2); ctx.restore(); } function animate_it() { reset(); ball.draw(); ball.x += ball.vx; ball.y += ball.vy; ball.vx = ball.vx * 1.001; ball.vy = ball.vy * 1.001; if (ball.x <= 0 || ball.y <= 0 || ball.x > c.width || ball.y > c.height) { ingame = 2; drawTip("你失败了....,请点击画面重新开始"); cancelAnimationFrame(tt); return; } requestAnimationFrame(animate_it); } // 绘制文本 function drawText(ctx, text) { ctx.save(); ctx.font = "14px Arial" // 字体大小 44 像素 ctx.fillText(text, 10, 25); ctx.restore(); } // 触摸开始事件 wx.onTouchStart(function (e) { if (ingame == 0 || ingame == 2) { return; } lasted.x = e.touches[0].clientX lasted.y = e.touches[0].clientY }) // 手指离开屏幕 wx.onTouchEnd(function (e) { if (ingame == 0 || ingame == 2) { ingame = 1; resetball(); tt = requestAnimationFrame(animate_it); return; } var x = e.touches[0].clientX var y = e.touches[0].clientY var x0 = x - lasted.x; var y0 = y - lasted.y; // 左右滑动 if (Math.abs(x0) > Math.abs(y0)) { ball.vx = (x0 > 0 ? Math.abs(ball.vx) : - Math.abs(ball.vx)); } else { // 上下滑动 ball.vy = (y0 > 0 ? Math.abs(ball.vy) : - Math.abs(ball.vy)); } lasted.x = null; lasted.y = null; }) reset();
大家还可以对这个小游戏做一些改动,比如
-
绘制边界,就是不使用屏幕边界,而是使用自己绘制的边界
-
加入另一个小球,变成一个小球吃小球的游戏,吃了自己会变大,然后速度会提高