微信隐藏应用代码代码小游戏有哪些?


博客简介
本篇博客介绍的是微信小游戏贪吃蛇的案例,详细的开发过程,并且提供代码压缩包下载。
案例简介
布局
构建对象
响应事件
蛇头对象的移动
蛇身的移动
食物刷新
绘制得分
碰撞检验
开始界面和结束界面
前后台的切换
添加音频
源码下载https://download.csdn.net/download/weixin_44307065/12151658
微信小游戏贪吃蛇
案例简介
作者学习微信小程序时偶然想到贪吃蛇游戏,画布绘制了一番,突发了做贪吃蛇的想法。由于还没有正式开始学习小游戏,并且只是想要简单的做出这个程序来,就没有去用游戏引擎,深究小游戏中的细节。游戏基于canvas以及响应事件,效果如下。(由于微信审核小城序名称的限制,将其命名为贪吃毛毛虫)
布局
整个小游戏界面的布局很简单,包括小蛇,食物,以及纯色背景,插入的文字得分组成。
构建对象
按照布局中的元素,我们构建蛇头对象,蛇身对象,食物三个对象,并且添加相应的位置,颜色,大小属性:
//蛇头对象
var snakeHead = {
x: 100,
y: 100,
r: 15,
deg: 0,
snakeDirection: "right",
color: '#CD5C5C',
drawHead: function () {
//画出嘴脸this.
ctx.save();
ctx.translate(this.x, this.y);
ctx.rotate(this.deg);//旋转
ctx.beginPath();
ctx.moveTo(0, 0);
ctx.arc(0, 0, this.r, Math.PI / 7, -Math.PI / 7, false);
ctx.fillStyle = this.color;
ctx.fill();
ctx.beginPath();
ctx.arc(0, -this.r / 2, 2, Math.PI * 2, 0, true);
ctx.fillStyle = 'black';
ctx.fill();
ctx.restore();
}
}
//蛇身数组
var snakeBody = [];
//食物数组
var foods = [];
//创建食物对象
//food构造函数
function Food() {
this.x = parseInt(Math.random() * windowWidth);
this.y = parseInt(Math.random() * windowHeight);
this.r = parseInt(Math.random() * 10 + 10);
this.color = "rgb(" + parseInt(Math.random() * 255) + "," + parseInt(Math.random() * 255) + "," + parseInt(Math.random() * 255) + ")";
//重新随机位置和颜色
this.reset = function () {
this.x = parseInt(Math.random() * windowWidth);
this.y = parseInt(Math.random() * windowHeight);
this.r = parseInt(Math.random() * 10 + 10);
this.color = "rgb(" + parseInt(Math.random() * 255) + "," + parseInt(Math.random() * 255) + "," + parseInt(Math.random() * 255) + ")";
}
}
//创建食物对象数组
function makeFoods() {
for (var i = 0; i < 15; i++) {
//push20个食物对象
foods.push(new Food());
}
}
事件监听
在正式开始绘制之前,我们要确定snake的移动方向,这就需要我们根据玩家手指滑动的方向来确定当前是上滑动还是下滑动还是左滑动或是右滑动?我们可以这样来设置监听:
onTouchStart获取当前触摸点x,y坐标
onTouchMove获取当前触摸点x坐标
onTouchEnd发生时将方向改为相应的上下左右
wx.onTouchEnd(function (res) {
snakeHead.snakeDirection = direction;
})
wx.onTouchMove(function (res) {
moveX = res.changedTouches[0].clientX // 重新判断当前触摸点x坐标
moveY = res.changedTouches[0].clientY // 重新判断当前触摸点y坐标
dx = moveX - startX;
dy = moveY - startY;
if (Math.abs(dx) > Math.abs(dy)) {
if (dx > 0) direction = "right";
else if (dx < 0) direction = "left";
}
else if (Math.abs(dx) < Math.abs(dy)) {
if (dy > 0) direction = "buttom";
else if (dy < 0) direction = "top";
}
})
wx.onTouchStart(function (res) {
startX = res.changedTouches[0].clientX // 重新判断当前触摸点x坐标
startY = res.changedTouches[0].clientY // 重新判断当前触摸点y坐标
})
蛇头对象的移动
整个snake对象想要动起来我们就必须给snake定义一个animation函数,一帧一帧的移动位置。
蛇头对象在每一帧开始时根据方向来移动一个距离
function animation() {
//开始绘制
//判定方向
switch (snakeHead.snakeDirection) {
case 'top': snakeHead.y -= 1.8 * snakeHead.r; snakeHead.deg = -Math.PI / 2; break;
case 'buttom': snakeHead.y += 1.8 * snakeHead.r; snakeHead.deg = Math.PI / 2; break;
case 'left': snakeHead.x -= 1.8 * snakeHead.r; snakeHead.deg = Math.PI; break;
case 'right': snakeHead.x += 1.8 * snakeHead.r; snakeHead.deg = 0; break;
}
ctx.save();
ctx.clearRect(0, 0, windowWidth, windowHeight);
ctx.fillStyle ="#8A2BE2";
ctx.fillRect(0, 0, windowWidth, windowHeight);
//绘制蛇头
snakeHead.drawHead();
}
蛇身的移动
蛇身对象的移动我们可以这样考虑:
蛇身是一个对象数组
整个蛇第i节下一帧的位置就是他的上一个节点(i-1)的位置
添加新的一节在蛇头的位置
移除最后一节蛇身
这样一来蛇头向前移动,就像蛇头的位置添加一个新的蛇身节点,移除最后一节
function animation() {
//添加新的身体
snakeBody.push({
x: snakeHead.x,
y: snakeHead.y,
r: snakeHead.r,
color: "#708090"
});
//判定方向
switch (snakeHead.snakeDirection) {
case 'top': snakeHead.y -= 1.8 * snakeHead.r; snakeHead.deg = -Math.PI / 2; break;
case 'buttom': snakeHead.y += 1.8 * snakeHead.r; snakeHead.deg = Math.PI / 2; break;
case 'left': snakeHead.x -= 1.8 * snakeHead.r; snakeHead.deg = Math.PI; break;
case 'right': snakeHead.x += 1.8 * snakeHead.r; snakeHead.deg = 0; break;
}
//绘制身体
//没有碰撞食物则移除最后一节身体(下标为0,cover掉)
//否则不做移除,长度增加,改isCollision为false表示未碰撞
//绘制身体数组
for(var i=0;i<snakeBody.length;i++)
{
draw(snakeBody[i]);
}
//绘制蛇头
snakeHead.drawHead();
//绘制得分
ctx.save();
}
食物刷新
食物的刷新很简单,食物对象是一个数组,我们在每一帧发生时将食物根据当前位置绘制在画布上:
初始化时生成15个食物对象,随机位置,大小和颜色
在每一帧发生时根据食物当前位置绘制在画布上
//创建食物对象
//food构造函数
function Food() {
this.x = parseInt(Math.random() * windowWidth);
this.y = parseInt(Math.random() * windowHeight);
this.r = parseInt(Math.random() * 10 + 10);
this.color = "rgb(" + parseInt(Math.random() * 255) + "," + parseInt(Math.random() * 255) + "," + parseInt(Math.random() * 255) + ")";
//重新随机位置和颜色
this.reset = function () {
this.x = parseInt(Math.random() * windowWidth);
this.y = parseInt(Math.random() * windowHeight);
this.r = parseInt(Math.random() * 10 + 10);
this.color = "rgb(" + parseInt(Math.random() * 255) + "," + parseInt(Math.random() * 255) + "," + parseInt(Math.random() * 255) + ")";
}
}
//创建食物对象数组
function makeFoods() {
for (var i = 0; i < 15; i++) {
//push20个食物对象
foods.push(new Food());
}
}
//获取屏幕宽高并且初始化食物对象,蛇身对象
function window() {
wx.getSystemInfo({
success(res) {
windowWidth = res.windowWidth;
windowHeight = res.windowHeight;
canvas.width = windowWidth;
canvas.height = windowHeight;
}
});
makeFoods();//初始化20个食物
//绘制食物
for (var i = 0; i < foods.length; i++) {
draw(foods[i]);
}
snakeBody.push({
x: snakeHead.x,
y: snakeHead.y,
r: snakeHead.r,
color: "#708090"
});
}
function animation() {
//添加新的身体
snakeBody.push({
x: snakeHead.x,
y: snakeHead.y,
r: snakeHead.r,
color: "#708090"
});
//判定方向
switch (snakeHead.snakeDirection) {
case 'top': snakeHead.y -= 1.8 * snakeHead.r; snakeHead.deg = -Math.PI / 2; break;
case 'buttom': snakeHead.y += 1.8 * snakeHead.r; snakeHead.deg = Math.PI / 2; break;
case 'left': snakeHead.x -= 1.8 * snakeHead.r; snakeHead.deg = Math.PI; break;
case 'right': snakeHead.x += 1.8 * snakeHead.r; snakeHead.deg = 0; break;
}
//开始绘制
//绘制食物
ctx.save();
ctx.clearRect(0, 0, windowWidth, windowHeight);
ctx.fillStyle ="#8A2BE2";
ctx.fillRect(0, 0, windowWidth, windowHeight);
for (var i = 0; i < foods.length; i++) {
draw(foods[i]);
}
//绘制身体
//绘制身体数组
for(var i=0;i<snakeBody.length;i++)
{
draw(snakeBody[i]);
}
//绘制蛇头
snakeHead.drawHead();
}
碰撞检验
在蛇和食物可以顺利的刷新移动后,我们要给蛇设置碰撞检验,包括蛇和墙壁的检验,蛇和食物的检验
(1)检验触壁
检验小蛇和墙壁的触碰很简单,只要在animation函数中判断当前蛇头的位置是否在屏幕范围内,如果不在范围内说明触壁,游戏结束
//判定是否触壁
function JudgeStared(){
if(snakeHead.x<0
snakeHead.x>windowWidth
snakeHead.y<0
snakeHead.y>windowHeight) started=false;
}
(2)检验碰撞食物
检验碰撞食物很简单,遍历整个食物数组,判断蛇头圆心和食物圆心的位置关系,如果距离大于半径和说明碰撞。需要注意的是碰撞后的连锁反应,蛇身增长,食物要随机刷新到另外一个位置,要点如下:
判断碰撞:(R+r)^2 <= (x1-x2)^2 + (y1-y2)^2
蛇身增长:如果碰撞,那么我们不移除蛇尾
碰撞随机刷新到另外一个位置
分数point++
设置变量iscollison来记录当前的碰撞状态
//动画函数
function animation() {
//添加新的身体
snakeBody.push({
x: snakeHead.x,
y: snakeHead.y,
r: snakeHead.r,
color: "#708090"
});
//边界
if (snakeHead.x > windowWidth) snakeHead.snakeDirection = "left";
if (snakeHead.x <= 0) snakeHead.snakeDirection = "right";
if (snakeHead.y <= 0) snakeHead.snakeDirection = "buttom";
if (snakeHead.y > windowHeight) snakeHead.snakeDirection = "top";
//判定方向
switch (snakeHead.snakeDirection) {
case 'top': snakeHead.y -= 1.8 * snakeHead.r; snakeHead.deg = -Math.PI / 2; break;
case 'buttom': snakeHead.y += 1.8 * snakeHead.r; snakeHead.deg = Math.PI / 2; break;
case 'left': snakeHead.x -= 1.8 * snakeHead.r; snakeHead.deg = Math.PI; break;
case 'right': snakeHead.x += 1.8 * snakeHead.r; snakeHead.deg = 0; break;
}
//判定是否触壁
JudgeStared();
//检验碰撞,移动食物
for (var i = 0; i < foods.length; i++) {
isCollision = collision(snakeHead, foods[i]);
//碰撞则重新绘制
//发生碰撞
if (isCollision) {
foods[i].reset();
break;
}
}
//开始绘制
//绘制食物
ctx.save();
ctx.clearRect(0, 0, windowWidth, windowHeight);
ctx.fillStyle ="#8A2BE2";
ctx.fillRect(0, 0, windowWidth, windowHeight);
for (var i = 0; i < foods.length; i++) {
draw(foods[i]);
}
//绘制身体
//没有碰撞食物则移除最后一节身体(下标为0,cover掉)
//否则不做移除,长度增加,改isCollision为false表示未碰撞
if (!isCollision) {
snakeBody.shift();
}
else {
isCollision=false;
}
//绘制身体数组
for(var i=0;i<snakeBody.length;i++)
{
draw(snakeBody[i]);
}
//绘制蛇头
snakeHead.drawHead();
}
碰撞函数collision:
//碰撞函数,返回bolean值
function collision(obj1, obj2) {
var r1 = obj1.r, r2 = obj2.r;
var dis = (obj1.x - obj2.x) * (obj1.x - obj2.x) + (obj1.y - obj2.y) * (obj1.y - obj2.y)
if (dis < (r1 + r2) * (r1 + r2))
{
audioEat.stop();
audioEat.play();
point++;
return true;
}
else return false;
}
绘制得分
得分绘制十分简单,插入ctx.fillText(‘当前得分:’ + point, 135, 220)即可
//绘制得分
ctx.save();
ctx.fillStyle ='#B0C4DE';
ctx.font = "normal 20px 幼圆";
ctx.fillText('当前得分:' + point, 135, 220);
ctx.restore();
if(!started) end();
开始界面和结束界面
现在我们的游戏大体上已经准备好了,但是直接进入游戏未免有些枯燥,我们需要一个开始界面和结束界面,当点击这个界面的时候游戏开始:
设置两个函数end和start分别表示结束界面和开始界面
绘制这个开始或者结束界面
给界面设置监听
当点击屏幕时游戏开始,调用定时器,当碰撞到墙壁时清除定时器
由于开始之后 wx.onTouchStart(function (res))仍然在执行,我们不能一直让监听执行调用定时器,所以我们用started记录当前游戏开始或结束的状态,仅仅在started=false时,可以调用定时器,在started=true时能够清除定时器
function end()
{
clearInterval(timer);//清除定时器
audioDie.play();//死亡语音
audioBackground.stop();//背景音乐
ctx.save();
ctx.drawImage(imageStart, 0, 0, canvas.width, canvas.height);
ctx.beginPath();
ctx.fillStyle = "#8A2BE2";
ctx.fillRect(windowWidth * 5 / 7, 0, windowWidth * 2 / 7, windowHeight * 1 / 10);
ctx.arc(canvas.width / 2, canvas.height / 2, 120, 0, Math.PI * 2, false);
ctx.fillStyle = "#6495ED";
ctx.fill();
ctx.fillStyle = '#FF7F50';
ctx.font = "normal 20px 幼圆";
ctx.fillText('.游戏结束.', canvas.width / 2 - 50, canvas.height / 2 - 25);
ctx.fillText('您的得分是'+point+"分", canvas.width / 2 - 60, canvas.height / 2);
ctx.fillText('->点击屏幕重新开始<-', canvas.width / 2 - 100, canvas.height / 2 + 25);
ctx.restore();
//重置参数
point=0;
snakeHead.x=100;
snakeHead.y=100;
snakeHead.snakeDirection="right";
direction='right';
started=false;
snakeBody.length=0;
wx.onTouchStart(function (res) {
if (!started) {
start();
}
})
}
function start()
{
imageStart.onload = function () {
ctx.clearRect(0,0,windowWidth,windowHeight);
ctx.drawImage(imageStart, 0,0,canvas.width, canvas.height);
ctx.beginPath();
ctx.fillStyle ="#8A2BE2";
ctx.fillRect(windowWidth * 5 / 7, 0, windowWidth * 2 / 7, windowHeight * 1 / 10);
ctx.arc(canvas.width/2,canvas.height/2,120,0,Math.PI*2,false);
ctx.fillStyle ="#6495ED";
ctx.fill();
ctx.fillStyle = '#FF7F50';
ctx.font = "normal 20px 幼圆";
ctx.fillText('<贪吃小虫>', canvas.width / 2-50, canvas.height / 2-30);
ctx.fillText('->点击屏幕开始<-', canvas.width / 2 - 75, canvas.height / 2+20);
audioBackground.loop = true;
audioBackground.play();
//调用定时器
wx.onTouchStart(function (res) {
if (!started) {
audioStart.play();
started = true;
timer = setInterval(animation, 500);
ctx.clearRect(0, 0, windowWidth, windowHeight);
}
})
}
前台后台的切换
游戏界面有了,但是当切到后台时怎么办?从后台调到前台有如何处理?我们可以这样设置
设置stopped记录当前的路由的来源
当stopped=true表示程序来自后台
stopped=false表示直接打开程序
在start函数中添加stopped状态,如果stopped=true直接调用定时器
function start()
{
imageStart.onload = function () {
ctx.clearRect(0,0,windowWidth,windowHeight);
ctx.drawImage(imageStart, 0,0,canvas.width, canvas.height);
ctx.beginPath();
ctx.fillStyle ="#8A2BE2";
ctx.fillRect(windowWidth * 5 / 7, 0, windowWidth * 2 / 7, windowHeight * 1 / 10);
ctx.arc(canvas.width/2,canvas.height/2,120,0,Math.PI*2,false);
ctx.fillStyle ="#6495ED";
ctx.fill();
ctx.fillStyle = '#FF7F50';
ctx.font = "normal 20px 幼圆";
ctx.fillText('<贪吃小虫>', canvas.width / 2-50, canvas.height / 2-30);
ctx.fillText('->点击屏幕开始<-', canvas.width / 2 - 75, canvas.height / 2+20);
audioBackground.loop = true;
audioBackground.play();
//调用定时器
if(stopped)//来源后台
{
audioStart.play();
started = true;
stopped=false;
timer = setInterval(animation, 500);
ctx.clearRect(0, 0, windowWidth, windowHeight);
}
else
{
wx.onTouchStart(function (res) {
if (!started) {
audioStart.play();
started = true;
timer = setInterval(animation, 500);
ctx.clearRect(0, 0, windowWidth, windowHeight);
}
})
}
}
}
wx.onShow(function () {
start();
})
wx.onHide(function(){
clearInterval(timer);//清除定时器,暂停
started=false;//停止运行
stopped=true;//切后台
})
wx.showShareMenu({
withShareTicket: true
})
添加音频
此小游戏有4个音频,音频的设置往往能有不错的效果,要点如下
背景音频audioBackground:在小游戏运行在前台的调用
获取食物音频audioEat:在碰撞函数collision中调用
开始音频audioStart:在游戏开始时调用
结束音频audioDie:在游戏结束时调用
var audioBackground = wx.createInnerAudioContext();//背景音乐
audioBackground.src ="audio/background.mp3";
var audioEat = wx.createInnerAudioContext();//吃的声音
audioEat.src = "audio/eat.mp3";
var audioDie = wx.createInnerAudioContext();//死亡声音
audioDie.src = "audio/end.mp3";
var audioStart = wx.createInnerAudioContext();//死亡声音
audioStart.src = "audio/start.mp3";
展示
最后整个小游戏就完成了,展示如下
微信小游戏贪吃蛇

微信13个隐藏代码朋友们喜欢微信表情包,但你知道微信有十几个隐藏表情包吗?那么如何使用这些隐藏表情包呢?经常使用表情包的用户可以记一下,然后与大家分享。这些隐藏的表情包每一个都具有独特的形态,让我们感受一个新的时刻。作为隐藏的表情包当我们使用时一定会震惊到自己的朋友,快来展现给喜欢的朋友吧,记得要下载。
微信13个隐藏代码满屏表情:
1、鸡腿雨口令:加个鸡腿
2、亲吻雨口令:么么哒、XOXO
3、星星雨口令:miss u、想你了
4、蛋糕雨口令:birthday、生日快乐
春节期间有效:
火苗:红红火火
爆竹:新年快乐
黄色的星星:吉星高照,福星高照
桔子:大吉大利,吉祥如意,万事如意,万事大吉
鱼:年年有余,年年有鱼
苹果:一路平安,平平安安
钱袋:恭喜发财,招财进宝
马头:马年快乐,马到成功,马到功成,马年进步,马年快乐
红心:点个赞
雪人:下雪了,炸鸡和啤酒(有的版本是下雪花)《来自星星的你》
元宵节/情人节期间有效:
玫瑰花:love you,情人节快乐,情人节快乐,七夕
钻戒:嫁给我吧
爆竹:元宵节快乐
KISS:muah
春运期间有效:
火车:train,回家,火车,春运
高考期间:
肌肉雨:高考加油
飘桃花:桃花运/花开富贵/在一起
砸西瓜:西瓜
掉圣诞树:圣诞快乐
掉康乃馨:母亲节快乐
掉南瓜:万圣节快乐
掉彩蛋:感恩节快乐

我要回帖

更多关于 隐藏应用代码 的文章

 

随机推荐