感觉又是在发小白文,没办法,我还在不断学习中。前端进阶计划再一次因为学习难度,项目经验而告吹。
好在,我在缓慢进步~
文章内容来源我网络上看到别人用js和css3写的仙剑记忆力翻牌游戏,感觉自己可以学到些什么。所以就有了一天一夜的奋斗成果,写的过程,感觉好坎坷,又是查看canvas的API,又是设置相关变量,又得摸索坑爹费脑的游戏逻辑!
说实话,人家那个玩的挺爽,想过很炫。换成我做得,不说了,去把他的网页考下来参考参考。
说下游戏相关:鼠标点击事件(根据卡牌显示大小,确定鼠标有效点击区域,触发点击事件)
canvas绘图(将座标分好的图片加载进去)
计时器(使用浏览器运动API---requestAnimationFrame)我压根不知道如何停止这货
游戏卡牌匹配有bug,性能也不咋滴,直接上代码
html页面代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta content=”width=device-width; initial-scale=1.0; maximum-scale=1.0; user-scalable=0″ name=”viewport” />
<meta content=”yes” name=”apple-mobile-web-app-capable” />
<meta content=”black” name=”apple-mobile-web-app-status-bar-style” />
<meta content=”telephone=no” name=”format-detection” />
<title>js版仙剑翻牌记忆力游戏</title>
<link rel="stylesheet" type="text/css" href="css/memory.css">
<script type="text/javascript" src="js/memory.js"></script>
</head>
<body>
<header id="memory">
<canvas id="show"></canvas>
<audio id="astart" loop='loop'>
<source id="as1" type="audio/ogg" src="music/start.ogg">
<source id="as2" type="audio/mpeg" src="music/start.mp3">
</audio>
<audio id="afail" >
<source id="af1" type="audio/ogg" src="music/fail.ogg">
<source id="af2" type="audio/mpeg" src="music/fail.mp3">
</audio>
<audio id="asucess">
<source id="asu1" type="audio/ogg" src="music/success.ogg">
<source id="asu2" type="audio/mpeg" src="music/success.mp3">
</audio>
<audio id="aclear">
<source id="ac" type="audio/ogg" src="music/clear.ogg">
<source id="ac2" type="audio/mpeg" src="music/clear.mp3">
</audio>
</header>
</body>
</html>
css代码:可以忽略
body{margin:0;padding:0;background: url(../images/gamebg.jpg) no-repeat;}
header{width: 1000px;height: 600px;position: relative;top:0;left: 50%;margin-left: -575px;}
#show{background: #000;position: absolute;top:50%;left: 0;margin-top: -267px;}
js代码:有bug,大家看着解决吧
var canvas;
var audio;
window.requestAnimFrame=(function(){
return window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||window.oRequestAnimationFrame||window.msRequestAnimationFrame||function( /* function FrameRequestCallback */ callback, /* DOMElement Element */ element) {
return window.setTimeout(callback, 1000 / 60);
};
})();//自动执行函数
window.οnlοad=function(){
canvas=document.getElementById('show');//画布canvas
astart=document.getElementById('astart');//音乐
afail=document.getElementById('afail');//音乐
asucess=document.getElementById('asucess');//音乐
aclear=document.getElementById('aclear');//音乐
canvas.width=1150;
canvas.height=600;//画布宽高
Card.init();
game();
astart.play();
}
//游戏刷新函数
function game(){
Card.draw();
requestAnimFrame(game);
}
//牌对象类
var Card={
x:[],
y:[],//图片位置数组
boardArr:[],//牌数组
arr:[],
num:8,//初始化为8
first:-1,//是否全部开牌
ctx:null,//画笔
pic:null,//卡牌正面
bg:new Image(),//背面
tbg:new Image(),//剩余时间
fail:new Image(),
sucess:new Image(),
img:null,
k:null,//下一次打开的图片
l:null,//上一次点击打开的图片
click:true,//防止多次点击
lookNum:10,//记忆时间
playerTime:60,//游戏时间
count:0,//游戏成功判断
flag:0,//0:正在运行 1:失败 2:成功
//初始化
init:function(){
this.ctx=canvas.getContext('2d');
this.fail.src='./images/fail.png';
this.sucess.src='./images/success.png';
this.bg.src='./images/cardbg.jpg';//牌反面图片地址
this.tbg.src='./images/sword.png';//游戏时间背景图片
var rom=Math.floor(Math.random()*(10-this.num));
for(var i=rom+1;i<this.num+rom+1;i++){
this.pic=new Image();
this.pic.src='./images/card'+i+'.jpg';//卡牌正面
this.boardArr.push({ca:this.pic,bg:this.bg,key:i,open:false});//图片对象插入数组
}
// 二维数组深度复制
this.extend(this.arr,this.boardArr);
this.boardArr=this.arr.concat(this.boardArr);
//数组元素随机排列
this.boardArr=this.shuffle(this.boardArr);
this.boardArr.push({tbg:this.tbg});//游戏时间背景图片
this.boardArr.push({fail:this.fail});//游戏失败图片
this.boardArr.push({sucess:this.sucess});//游戏成功图片
//图片显示位置
for(var m=0;m<8;m++){
for(var n=1;n<3;n++){
this.x.push(m*142);
this.y.push(n*199);
}
}
//游戏时间图片的位置
this.x.push(550);
this.y.push(0);
//游戏失败图片
this.x.push(350);
this.y.push(250);
//成功图片
this.x.push(350);
this.y.push(250);
this.isSame();
// 为了避免与界面刷新定期器时间干扰,将时间倒计时定时器独立出来
var timer=setInterval(function(){
Card.lookNum--;
if(Card.lookNum<=0){
Card.playerTime--;
if(Card.playerTime<=0){
this.flag=1;
clearInterval(timer);
}
}
},1000);
},
//随机洗牌函数
shuffle:function(arr){
var len = arr.length;
for(var i = 0; i < len - 1; i++){
var idx = Math.floor(Math.random() * (len - i));
var temp = arr[idx];
arr[idx] = arr[len - i - 1];
arr[len - i -1] = temp;
}
return arr;
},
//画图
draw:function(){
for(var i in this.boardArr){//起始图片展示
if(Card.first==-1){
Card.img=Card.boardArr[i].ca;
if(Card.lookNum<=0){ Card.first=0; return}
}
if(!this.boardArr[i].open&&Card.first==0){
this.img=this.boardArr[i].bg;
if(Card.playerTime<=0){
this.boardArr[i].open=false;
i==this.boardArr[i].length-2;
Card.flag=1;
Card.click=false;
}
}else{
this.img=this.boardArr[i].ca;
}
if(i<this.boardArr.length-3){
this.ctx.drawImage(this.img,this.x[i],this.y[i]);//画出图片
}else{
if(i==this.boardArr.length-3&&Card.playerTime>0&&this.flag==0){
this.img=this.boardArr[this.boardArr.length-3].tbg;
this.ctx.drawImage(this.img,this.x[i],this.y[i]);//画出图片
}
if(i==this.boardArr.length-2&&Card.playerTime<=0&&this.flag==1){
astart.pause();
aclear.pause();
afail.play();//失败
this.img=this.boardArr[this.boardArr.length-2].fail;
this.ctx.drawImage(this.img,this.x[i],this.y[i]);//画出图片
}
if(i==this.boardArr.length-1&&Card.playerTime>0&&this.flag==2){
this.img=this.boardArr[this.boardArr.length-1].sucess;
this.ctx.drawImage(this.img,this.x[i],this.y[i]);//画出图片
astart.pause();
aclear.pause();
asucess.play();//成功
}
this.fontText();
}
}
},
//判断是否相同
isSame:function(){
//鼠标点击
if(Card.flag==0){
window.addEventListener('click',function(e){
if(Card.click){
Card.click=false;
if(e.offSetX||e.layerX){//兼容性写法
//三元运算符
mx=e.offSetX==undefined?e.layerX:e.offSetX;
my=e.offSetY==undefined?e.layerY:e.layerY;
}
for(var i in Card.boardArr){
if(parseFloat(mx)<=1150&&parseFloat(mx)>=0&&parseFloat(my)>=199&&parseFloat(my)<=600){
if(parseFloat(mx)>=parseFloat(Card.x[i])&&parseFloat(mx)<=parseFloat(Card.x[i])+142&&parseFloat(my)>=parseFloat(Card.y[i])&&parseFloat(my)<=parseFloat(Card.y[i])+199){
// 可以旋转打开
if(!Card.boardArr[i].open){
if(Card.k==null){
Card.k=i;
this.img=Card.boardArr[i].ca;
Card.boardArr[i].open=true;
Card.click=true;
return;
}
else if(Card.boardArr[i].key==Card.boardArr[Card.k].key){//相同图片显示
if(i==Card.k){return}
this.img=Card.boardArr[i].ca;
Card.boardArr[i].open=true;
Card.k=null;//上一张图片标志
Card.click=true;
Card.count++;
astart.pause();
aclear.play();
if(Card.count==Card.num){Card.flag=2;}//成功
}else{//不同图片都不显示
this.img=Card.boardArr[i].ca;
Card.boardArr[i].open=true;
Card.l=i;
setTimeout(function(){
if(!Card.k){return}
this.img=Card.boardArr[Card.l].bg;
this.img=Card.boardArr[Card.k].bg;
Card.boardArr[Card.k].open=false;
Card.boardArr[Card.l].open=false;
Card.k=null;//上一张图片标志情况
Card.l=null;
Card.click=true;
},800);
if(Card.count!=Card.num){Card.flag=1;}//失败
}
}else{//点击同一张图片
Card.click=true;
}
}
}
}
}
});
}
},
getType:function(o){
var _t;
return ((_t = typeof(o)) == "object" ? o==null && "null" || Object.prototype.toString.call(o).slice(8,-1):_t).toLowerCase();
},
extend:function(destination,source){
for(var p in source)
{
if(Card.getType(source[p])=="array"||Card.getType(source[p])=="object")
{
destination[p]=Card.getType(source[p])=="array"?[]:{};
arguments.callee(destination[p],source[p]);
}
else
{
destination[p]=source[p];
}
}
},
fontText:function(){
this.ctx.fillStyle="#000";//白色为例子;
this.ctx.fillRect(735,40,180,22);
this.ctx.beginPath();
this.ctx.font='20px Courier 微软雅黑';
this.ctx.fillStyle='red';
if(this.lookNum<=0){this.ctx.fillText('游戏剩余时间 '+this.playerTime,740,60);return;}
this.ctx.fillText('记忆时间倒计时 '+this.lookNum,740,60);
this.ctx.closePath();
}
}
代码比较混乱,不管怎么说都耗费了我接近20小时的时间,虽然不咋滴,也很小白,但我相信,只要我坚持,技术会好的,经验会有的,面包也会很多的。