微信小程序
什么是微信小程序
微信小程序(weixinxiaochengxu),简称小程序,缩写XCX,英文名mini program,是一种不需要下载安装即可使用的应用,它实现了应用“触手可及”的梦想,用户扫一扫或搜一下即可打开应用。什么产品可以使用小程序
由于小程序不需要下载,占用内存小,用户体验优秀,一些使用频率低的应用可以使用小程序。微信小程序的开发准备
1.微信小程序开发API介绍文档链接
微信小程序开发API
2.微信注册账号(个人账号就可以开发)
3.小程序开发工具
开发工具下载地址以及介绍APPID注册地址
APPID注册
基本的项目结构介绍
1.三个全局文件
- app.js
程序启动时执行的文件,程序一旦启动就执行App()函数 - app.json
规定了显示的页面(.wxml 文件,类似于html),按照循序来显示,以及标题栏的样式等,如果别的页面没有定义json则用此文件 - app.wxss
页面布局样式,如果别的页面没有定义wxss则用此文件
2.一个文件夹包括一个完整页面信息
3.一个warning:项目路径必须是英文,但项目名称可以是中文
项目介绍
贪吃蛇小游戏,蛇可以根据手指指定的方向移动,吃到食物则累计加分,分数越高,长度越长,速度越快,直到碰壁或者得分超过3000,游戏停止。
用到的组件以及API
具体应用代码后续有说到
- canvas
- wx.getSystemInfo(OBJECT)
- wx.showToast(OBJECT)
- wx.showModal(OBJECT)
- wx.navigateBack(OBJECT)
步骤
- 1.画一个背景,背景色为鹅黄色
用组件画布画了一个背景,绑定事件bindtouchstart,bindtouchmove
<canvas canvas-id="snakeCanvas" style="width:100%; height:100%; background-color:#FFFFCC;" bindtouchstart="canvasStart" bindtouchmove="canvasMove"/>
实现绑定事件,确定手指滑动到的位置以及方向
// 手指开始位置
var startX = 0;
var startY = 0;
// 手指移动路径
var moveX = 0;
var moveY = 0;
// 差值
var X = 0;
var Y = 0;
canvasStart:function(e) {
//初始坐标
startX = e.touches[0].x;
startY = e.touches[0].y;
},
canvasMove:function(e) {
moveX = e.touches[0].x;
moveY = e.touches[0].y;
X = moveX - startX;
Y = moveY - startY;
if(Math.abs(X) > Math.abs(Y) && X>0) {
console.log("向右");
}else if(Math.abs(X) > Math.abs(Y) && Y<0) {
console.log("向左");
}else if(Math.abs(X) < Math.abs(Y) && Y>0) {
console.log("向下");
} else if (Math.abs(X) < Math.abs(Y) && Y < 0) {
console.log("向上");
}
}
函数测试结果:
- 2.绘制一个蛇头,并让蛇头根据手指移动的方向移动
需要的变量
//画布上下文
var context = null;
// 蛇头
var snakeHead = {
color: "#99FFCC",
x: 0,
y: 0,
w: snakeW,
h: snakeH
};
// 蛇头移动方向,默认向右
var snakeMoveDirection = "right";
修改canvasMove绑定事件:
逻辑:蛇头向上向下不允许直接切换,向左向右也不允许直接切换
canvasMove: function (e){
moveX = e.touches[0].x;
moveY = e.touches[0].y;
X = moveX - startX;
Y = moveY - startY;
if ( Math.abs(X) > Math.abs(Y) && X>0 && !(snakeMoveDirection == "left") ){
// 向右
snakeMoveDirection = "right";
console.log("向右");
} else if (Math.abs(X) > Math.abs(Y) && X<0 && !(snakeMoveDirection == "right") ){
// 向左
snakeMoveDirection = "left";
console.log("向左");
} else if (Math.abs(X) < Math.abs(Y) && Y>0 && !(snakeMoveDirection == "top") ){
// 向下
snakeMoveDirection = "bottom";
console.log("向下");
} else if (Math.abs(X) < Math.abs(Y) && Y<0 && !(snakeMoveDirection == "bottom") ){
// 向上
snakeMoveDirection = "top";
console.log("向上");
}
}
绘制蛇头,循环执行绘画使其移动
function beginGame(){
//获得画布上下文
context = wx.createContext();
// 绘制蛇头
function drawObj(obj) {
context.setFillStyle(obj.color);
context.beginPath();
context.rect(obj.x, obj.y, obj.w, obj.h);
context.closePath();
context.fill();
}
function beginDraw (){
//移动
switch(snakeMoveDirection){
case "left":
snakeHead.x -= snakeHead.w-14;
break;
case "right":
snakeHead.x += snakeHead.w - 14;
break;
case "top":
snakeHead.y -= snakeHead.w - 14;
break;
case "bottom":
snakeHead.y += snakeHead.w - 14;
break;
}
drawObj(snakeHead);
// 调用 wx.drawCanvas,通过 canvasId 指定在哪张画布上绘制,通过 actions 指定绘制行为
wx.drawCanvas({
canvasId: 'snakeCanvas',
actions: context.getActions() // 获取绘图动作数组
});
// 循环执行动画绘制
requestAnimationFrame(beginDraw);
}
beginDraw();
}
beginGame();
}
效果:
- 3.绘画蛇的身体
变量:
// 蛇身数组
var snakeBodys = [];
修改函数beginDraw
把蛇移动的频率改成moveSpeedLevel ,移动的长度改成蛇身长
蛇身的逻辑是这样的,蛇身的长度有一个控制范围,然后每次增加一个蛇身,这个蛇身保持当前蛇头的信息,当这个蛇头信息改变后,蛇身就是上一个蛇头,蛇身其实就是记录了一个蛇身长度的信息,所以要在蛇头改变以前记下来
//每moveSpeedLevel移动一次
if(++perform %moveSpeedLevel ==0){
// 添加蛇身
snakeBodys.push({
color: "#CCFFCC",
x: snakeHead.x,
y: snakeHead.y,
w: snakeW,
h: snakeH
});
// 只要长度大于5,移除蛇身
if (snakeBodys.length>5){
snakeBodys.shift();
}
//每次移动一个身体的长度
switch(snakeMoveDirection){
case "left":
snakeHead.x -= snakeHead.w;
break;
case "right":
snakeHead.x += snakeHead.w;
break;
case "top":
snakeHead.y -= snakeHead.h;
break;
case "bottom":
snakeHead.y += snakeHead.h;
break;
}
}
// 绘制蛇头
drawObj(snakeHead);
// 绘制蛇身体
for (var i=0; i<snakeBodys.length; i++) {
var snakeBody = snakeBodys[i];
drawObj(snakeBody);
}
效果:
- 4.绘制食物
变量:
// 手机屏幕宽/高
var windowW = 0;
var windowH = 0;
//食物的颜色
var mycolor = ["#FFCCFF", "#CCCCFF","#99CCFF"];
// 食物
var foods = [];
用到了微信的API来获取屏幕长度,因为每个手机屏幕大小不一样
wx.getSystemInfo({
success: function(res) {
// console.log(res.windowWidth);
// console.log(res.windowHeight);
windowW = res.windowWidth;
windowH = res.windowHeight;
}
})
创建一个食物对象
randomAB
function randomAB(A,B) {
return parseInt(Math.random()*(B-A)+A);
}
// 食物构造方法
function Food() {
this.color = mycolor[randomAB(0,3)];
this.x = randomAB(0, windowW-20);
this.y = randomAB(0, windowH-20);
var w = 15;
this.w = w;
this.h = w;
// 重置位置
this.reset = function (){
this.color = mycolor[randomAB(0, 3)];
this.x = randomAB(0, windowW);
this.y = randomAB(0, windowH);
var w = 15;
this.w = w;
this.h = w;
}
}
在初始化函数里创建食物
// 创建食物 25个
for (var i = 0; i<25; i++) {
var food = new Food();
foods.push(food);
}
在绘制函数beginDraw里:
// 绘制食物 25个
for (var i = 0; i<foods.length; i++) {
var food = foods[i];
drawObj(food);
}
效果:
- 5.实现游戏的加分,即碰到食物就加分,且蛇身加长,达到一定次数就给蛇加速
判断蛇头是否碰到食物
// 吃到食物函数
function eatFood(snakeHead, food){
var sL = snakeHead.x;
var sR = sL+snakeHead.w;
var sT = snakeHead.y;
var sB = sT+snakeHead.h;
var fL = food.x;
var fR = fL+food.w;
var fT = food.y;
var fB = fT+food.h;
if ( sR>fL && sB>fT && sL<fR && sT<fB && sL<fR ){
return true;
} else {
return false;
}
}
每加一次分用微信的API showToast 来提示,每吃到一个食物,就重置一个随机位置的食物
// 吃食物
if( eatFood(snakeHead, food) ){
// 食物重置
food.reset();
wx.showToast({
title: "+"+food.w+"分",
icon: 'succes',
duration: 500
})
score+=food.w;
// 吃到食物的次数
eatFoodCount++
if(eatFoodCount%speederPerFood==0){
// 每吃到speederPerFood次食物 蛇移动速度变快
moveSpeedLevel-=1;
if (moveSpeedLevel<=2){
moveSpeedLevel = 2;
}
shouldRemoveBody = false;
}
要实现蛇身的增加,那么移除蛇身的代码需要修改,如果此次吃到食物,那么不执行移除操作,那么蛇身长度增加
变量
// 是否变长/即移除蛇身
var shouldRemoveBody = true;
// 移除蛇身
if (snakeBodys.length>5){
if(shouldRemoveBody ){
snakeBodys.shift();
}
shouldRemoveBody = true;
}
- 6.设置游戏结束方式
游戏失败
一旦贪吃蛇的蛇头碰到了手机屏幕的边界,那么就提示用户游戏失败了
if(snakeHead.x>windowW || snakeHead.x<0 || snakeHead.y>windowH || snakeHead.y<0){
wx.showModal({
title: "总得分:"+score+"分-----蛇身总长:"+snakeBodys.length+"",
content: '游戏失败, 是否重新开始',
success: function(res) {
console.log(res)
if (res.confirm) {
beginGame();
} else {
initGame();
wx.navigateBack({
delta: 1
})
}
}
})
return;
}
游戏成功
分数达到3000以上就为成功,测试时设置为100
if (score >= 3000) {
wx.showModal({
title: "总得分:" + score + "分-----蛇身总长:" + snakeBodys.length + "",
content: '游戏成功,是否重新开始',
success: function (res) {
console.log(res)
if (res.confirm) {
beginGame();
} else {
initGame();
wx.navigateBack({
delta: 1
})
}
}
})
return;
}
- 7.增加开始提醒,在游戏开始时弹出对话框
写在onReady的函数里面,点击确定后才执行开始函数
wx.showModal({
title: '请开始游戏',
content: "每得15分,蛇身增长1 ",
success: function(res) {
if (res.confirm) {
beginGame();
} else {
initGame();
wx.navigateBack({
delta: 1
})
}
}
});