试验性质的一个微信小程序,用canvas做的一个类似flappy-bird的小游戏。 包含一些基本的功能:躲避障碍物、计分、排行榜等等。后端的工程也一并上传了,在java目录中,很简单的一个SpringMVC工程。 游戏原型见这里。
使用说明直接git clone下来,用微信开发者工具导入即可。 导入的时候,最好填上appid,原因下方说明。 注意事项- 小程序目前还在公测状态,个人可以去公众平台上申请,但无法认证,最终的程序也无法发布。不过对于demo而言,有appid,能在手机上预览就可以了。
- 如果不填写appid,小程序无法在手机上预览,只能在开发者工具里使用。
- 小程序要求后端接口都是https的(必须事先在公众平台上配置好),对个人而言搞https证书实在太麻烦了。有两个办法绕过去:不填写appid,就不会有https的限制,但这样就不能在手机上预览;或者使用代理,将针对https://xxx的请求都代理到http://localhost:8080。我的做法是使用神器Charles的SSL Proxy和Map Remote功能,实现对https请求的代理。
- 我尽量使用ES6的写法,但微信对ES6的支持还不太完善。
[mw_shl_code=html,true]/**
* 某个可以在canvas中绘制的图形
*/
class Component {
// 构造函数
constructor(config) {
this.ctx = config.context; // canvas对应的context
this.type = config.type; // 组件类型,要么是文字,要么是矩形,其实对于不同的组件类型,用继承更好
this.text = config.text; // 如果是文字型组件,要显示的文字是啥?
this.fontSize = config.fontSize || 25; // 文字的大小,单位是像素
this.width = config.width || 10; // 宽度,宽度和长度只对矩形有用
this.height = config.height || 10; // 长度
this.x = config.x || 0; // x坐标
this.y = config.y || 0; // y坐标
this.xSpeed = config.xSpeed || 0; // 在x轴上的速度
this.ySpeed = config.ySpeed || 0; // 在y轴上的速度
this.color = config.color || '#CD853F'; // 颜色
this.xAcc = config.xAcc || 0; // 在x轴上的加速度
this.yAcc = config.yAcc || 0; // 在y轴上的加速度
this.canvasHeight = config.canvasHeight || 400; // canvas的高度
}
// 在canvas上绘制图形
update() {
// 微信的canvas API真是难用,跟标准的完全不一样
this.ctx.setFillStyle(this.color);
this.ctx.setStrokeStyle(this.color);
if (this.type == "text") {
this.ctx.setFontSize(this.fontSize);
this.ctx.fillText(this.text, this.x, this.y);
} else if (this.type == "bird") {
this.ctx.drawImage("../../images/bird.png", this.x, this.y, this.width, this.height);
} else {
this.ctx.rect(this.x, this.y, this.width, this.height);
this.ctx.fill();
}
}
// 计算组件新的位置,每一帧都要重新计算一次
newPos() {
// console.log('xSpeed=%d, ySpeed=%d, xAcc=%d, yAcc=%d', this.xSpeed, this.ySpeed, this.xAcc, this.yAcc);
// 首先计算新的速度
this.xSpeed += this.xAcc;
this.ySpeed += this.yAcc;
// 计算新的位置
this.x += this.xSpeed;
this.y += this.ySpeed;
// 检测是否碰到了canvas边缘
this.hitBoundary();
}
// 检测组件是否碰到了canvas边缘
hitBoundary() {
// 其实只检测了y轴的边界
if (this.y < 0) {
this.y = 0;
this.ySpeed = 0;
if (this.yAcc < 0) {
this.yAcc = 0;
}
}
let bottom = this.y + this.height;
if (bottom > this.canvasHeight) {
// 这里其实可能有个bug,就是假设组件的高度一定不会超过canvas的高度
this.y = this.canvasHeight - this.height;
this.ySpeed = 0;
if (this.yAcc > 0) {
this.yAcc = 0;
}
}
}
// 检测是否撞到了障碍物
crashWith(otherobj) {
let myleft = this.x;
let myright = this.x + (this.width);
let mytop = this.y;
let mybottom = this.y + (this.height);
let otherleft = otherobj.x;
let otherright = otherobj.x + (otherobj.width);
let othertop = otherobj.y;
let otherbottom = otherobj.y + (otherobj.height);
let crash = true;
// 因为自己的角色是只鸟,形状不规则,碰撞检测很难搞,偷个懒
if (this.type == 'bird') {
myleft += 5;
myright -= 5;
mytop += 5;
mybottom -= 5;
}
if ((mybottom < othertop) || (mytop > otherbottom) || (myright < otherleft) || (myleft > otherright)) {
crash = false;
}
return crash;
}
// ES6的set/get是个很让人费解的设计,跟java bean中的setter/getter不是一个概念
// 在我看来更多的是弥补js对象没有private变量的不足
// 当然不用这种蛋疼的写法也可以,我只是想试试新特性
set newYAcc(acc) {
this.yAcc = acc;
}
}
export default Component;[/mw_shl_code]
|