html5+canvas+純原生javascript+audio開發仙劍記憶力翻牌遊戲

感覺又是在發小白文,沒辦法,我還在不斷學習中。前端進階計劃再一次因爲學習難度,項目經驗而告吹。

好在,我在緩慢進步~

文章內容來源我網絡上看到別人用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小時的時間,雖然不咋滴,也很小白,但我相信,只要我堅持,技術會好的,經驗會有的,麪包也會很多的。


完整代碼下載

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章