H5W3
当前位置:H5W3 > JavaScript > 小程序 > 正文

【微信小游戏开发】小游戏触摸事件

我们知道, 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 事件触发时的时间戳

toucheschangedTouches 对象都是一个类型为 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();

大家还可以对这个小游戏做一些改动,比如

  1. 绘制边界,就是不使用屏幕边界,而是使用自己绘制的边界

  2. 加入另一个小球,变成一个小球吃小球的游戏,吃了自己会变大,然后速度会提高

本文地址:H5W3 » 【微信小游戏开发】小游戏触摸事件