深入《羊了个羊》:从0到1的消除游戏开发

一、游戏简介

        《羊了个羊》是一款备受欢迎的消除类游戏。玩家需要通过交换相邻的方块,使三个或更多相同方块连成一线,从而将它们消除。消除方块可以获得分数,并在全球排行榜上与其他玩家竞争。


  •  设置项目结构

  • 首先,在文本编辑器中创建一个新项目文件夹,并在其中创建以下文件结构:


	game/ 

	├── index.html 

	├── img

	└── script.js

	└── font

  •         在HTML文件中,我们添加了一个canvas元素,用于渲染游戏界面。在JavaScript文件(script.js)中,我们将编写游戏的核心逻辑(没有图片和JS软件包私信我)

接下来,我们将在JavaScript文件中定义一些变量来控制游戏的状态和行为。

在HTML中,当您引用JavaScript文件或脚本时,通常使用<script>标签。例如:

<script src="path/to/your/script.js"></script>
  • keymap 用于存储键盘按键映射。
  • TOTAL 用于记录剩余未消的卡牌数量,初始化为待消总卡牌数。
  • DOMPOS 用于记录上一个入槽的dom元素的位置。
  • bgMisicclickVoicedisapearVoicewaterVoicehashVoicenoVoicefailVoicescreamVoiceapproveVoiceperspectiveVoiceperspectiveCloseVoice 是用于控制游戏音效的音频元素。
  • shaketimes 和 shakeSupport 用于控制手机震动效果。
  • 使用jQuery来简化DOM操作和事件处理。

HTML结构

  • 打开index.html文件,编写以下HTML代码:

<!-- CSDN:GT开发算法工程师 Git:GAOSIR369-->
<!DOCTYPE html>
<meta name="viewport" content="width=device-width,	initial-scale=1.0,maximun-scale=1.0,user-scalable=no">
<link rel="icon" href="img/bt.jpeg" />
<html>
	<head>
		<meta charset="utf-8" />
		<title>原了个原(gss)</title>
		<style>
			@font-face {
				font-family: 'myfont';
				src: url('font/myfont.woff2') format('woff2'),
					 url('font/myfont.woff') format('woff');
				font-weight: normal;
				font-style: normal;
			
			}
			html{
				font-size: 62.5%;/*10PX 100%为16px*/
				height:100%;
				width: 100%;
				font-family: 'myfont';
			}
			body{
				font-size:1.6rem ;
				height:100%;
				width: 100%;
				margin:0;
			}
			body::after{
				position:absolute;
				top:0;
				left: 0;
				right: 0;
				bottom: 0;
				background: url(img/background.jpg);
				content: " ";
				opacity: 0.35;
				z-index: -1;
			}
			.left{
				float: left;
				width:30%;
			}
			.right{
				float:right;
				width:70%;
			}
			header{
				height:10%;
				width: 100%;
				display: flex;
				justify-content: center;
				align-items: center;
				font-size: 2.5rem;
				background:linear-gradient(180deg, #988e6e, #fefdfd);
			}
			footer{
				box-sizing:border-box;
				height:15%;
				width: 100%;
				display: flex;
				justify-content: center;
				align-items: flex-end;
				position: relative;
				padding:10px 10px;
			}
			.content{
				height:75%;
				width: 100%;
				display: flex;
				justify-content: center;
				align-items: baseline;
				box-sizing: border-box;
			}
			.borad{
				width: 85%;
				height: 80%;
				float: left;
				z-index: 100;
				position: relative;
				z-index: 1001;
			}
			.foot-box{
				background-color: #734A3D;
				border-radius: 10px;
				box-shadow: 10px -10px 10px rgba(0,0,0,0.3);
				display: flex;
				justify-content: left;
				align-items: center;
				transition: all 0.5s;
				background: url(./img/bg.png);
				padding:0 3px;
				border: 1px solid #afa657;
				box-sizing: border-box;
				position: fixed;
				bottom: 38px;
				left:5px;
				right:5px;
				max-width:700px;
			}
			.marks{
				position: absolute;
				top:0;
				bottom:0;
				left:0;
				right:0;
				z-index: 999;
				border-radius: 10px;
				display: flex;
				justify-content: left;
				align-items: center;
				padding:0 3px;
				box-sizing: border-box;
			}
			.foot-item,.item{
				background: linear-gradient(45deg, #919948, #d7cbba);
				/* float: left; */
				border-radius: 6px;
				margin: 2px;
				z-index: 1000;
				border: 1px solid rgb(199 180 174 / 0%);
				display: inline-flex;
				justify-content: center;
				align-items: center;
				transition: all 200ms;
				font-size: 1.4rem;
				height:35px;
				width:35px;
				position: relative;
				box-shadow: 2px -2px 2px #7c786a;
				/* 防止inline导致的位置变化 */
				vertical-align:middle;
				cursor:pointer;
			}
			.foot-item{
				background: #ffffff40;
				box-shadow:none;
			}
			.item .block{
				display: none;
				/* width:100%; */
				/* height:100%; */
				transition: transform 0.5s ease-in-out;
			}
			.foot-mark{
				position: relative;
				float: left;
				z-index: 1999;
				margin: 2px;
				border: 1px solid #afa65700;
			}
			.foot-mark>img{
				position: absolute;
				bottom: -24px;
				right:-12px;
				width: 18px;
				height:30px;
				transform: rotateX(180deg);
			}
			.layer{
				position: absolute;
				top: 0;
				bottom: 0;
				left: 0;
				right: 0;
				margin: auto;
				box-sizing: border-box;
				display: table;
				flex-wrap: wrap;
				align-items: center;
				justify-content: center;
			}
			button{
				position: absolute;
				padding: 10px 30px;
				border: none;
				border-radius: 4px;
				font-family: 'myfont';
				font-size: 2rem;
				color: #a6e7ef;
				background: linear-gradient(45deg, #2a2727, transparent);
			}
			.myLevel{
				position: absolute;
				    padding: 8px 30px;
				    border: none;
				    border-radius: 4px;
				    font-family: 'myfont';
				    font-size: 1.7rem;
				    color: #a6e7ef;
				    background: linear-gradient(194deg, #b77b22, transparent);
				    top: 0;
				    height: .8rem;
				    display: flex;
				    justify-content: center;
				    align-items: center;
			}
			.mask{
				position: fixed;
				top:0;
				bottom:0;
				left:0;
				right:0;
				background:#b3ab92a3;
				z-index: 20000;
				display: flex;
				justify-content: center;
				align-items: center;
				font-size:5rem;
				opacity: 1;
			}
			.pause{
				display: none;
				position: fixed;
				top:0;
				bottom:0;
				left:0;
				right:0;
				background:#b3ab92eb;
				z-index: 1000;
			}
			.overlayer{
				border: 1px solid #939ea7;
				background: #c7b4ae;
				color: #9d8787;
				box-shadow:2px -2px 1px #ff00001f;
			}
			.removeBottomLay{
				z-index:-1;
				opacity:0;
			}
			.options{
				position: absolute;
				top: -40px;
				width: 45px;
				box-shadow: -3px -3px 2px #00bcd4;
				height: 45px;
				border-radius: 50%;
				border: 1px solid #00bcd4;
				display: flex;
				justify-content: center;
				align-items: center;
				color: #5f6f76;
				z-index: 100000;
				right:5px;
				cursor:pointer;
				transform: rotateZ(3deg);
			}
			.look{
				position: absolute;
				top: -40px;
				width: 45px;
				box-shadow: -3px -3px 2px #00bcd4;
				height: 45px;
				border-radius: 50%;
				border: 1px solid #00bcd4;
				display: flex;
				justify-content: center;
				align-items: center;
				color: #5f6f76;
				z-index: 100000;
				left:5px;
				cursor:pointer;
				transform: rotateZ(3deg);
			}
			.music{
				position: fixed;
				top: 10px;
				left: 10px;
				color: antiquewhite;
				font-size: 2.2rem;
				display: flex;
				justify-content: center;
				align-items: center;
				cursor:pointer;
			}
			.music img{
				height:3rem;
			}
		</style>
	</head>
	<!-- CSDN:GT开发算法工程师 Git:GAOSIR369-->
	<body>
		<audio style="display:none; height: 0" id="bg-music" preload="auto" src="vender/bg.wav" loop="loop"></audio>
		<audio style="display:none; height: 0" id="di" preload="auto" src="vender/di.wav"></audio>
		<audio style="display:none; height: 0" id="dong" preload="auto" src="vender/dong.wav"></audio>
		<audio style="display:none; height: 0" id="water" preload="auto" src="vender/water.wav"></audio>
		<audio style="display:none; height: 0" id="hash" preload="auto" src="vender/hash.wav"></audio>
		<audio style="display:none; height: 0" id="no" preload="auto" src="vender/no.wav"></audio>
		<audio style="display:none; height: 0" id="fail" preload="auto" src="vender/fail.wav"></audio>
		<audio style="display:none; height: 0" id="scream" preload="auto" src="vender/scream.wav"></audio>
		<audio style="display:none; height: 0" id="approve" preload="auto" src="vender/approve.wav"></audio>
		<audio style="display:none; height: 0" id="perspective" preload="auto" src="vender/perspective.wav"></audio>
		<audio style="display:none; height: 0" id="perspectiveClose" preload="auto" src="vender/perspectiveClose.wav"></audio>
		<header>
			第<text class="level"></text>关
			<div class="music">
				<img src="img/jy.jpg">
			</div>
			<div class="myLevel" style=";">跳最高<text class="myLevelnum" style="color: aquamarine;">1</text>关纪录开始</div>
		</header>
		<div class="mask">
			<text style="display: none; margin-bottom: 200px;color: #4e5221;">游戏结束</text>
			<text style="display: none; margin-bottom: 200px;color: #4e5221;">恭喜通关!</text>
			<button class="again" style="display: none;">再来一把</button>
			<button class="nextLevel" style="display: none;">下一关</button>
		</div>
		<div class="pause"></div>
		<div class="content">
			<div id="bg"> </div>
			<div class="borad">
			</div>
		</div>
		<footer>
			<div class="foot-box">
				<div class="marks">
					<div class="options"><img style="height: 36px;transform: rotateZ(352deg );" src="img/reorder.svg"> 剩<text class="tooltimes">0</text></div>
					<div class="look"><img style="height: 25px;transform: rotateZ(352deg );" src="img/eye.svg"> 剩<text class="looktimes">0</text></div>
					<img src="img/mark.svg" style="position: absolute;width: 18px;height:30px;transform: rotateX(180deg);bottom: -13px;left:-3px;">
					<span class="foot-mark"><img src="img/mark.svg"></span>
					<span class="foot-mark"><img src="img/mark.svg"></span>
					<span class="foot-mark"><img src="img/mark.svg"></span>
					<span class="foot-mark"><img src="img/mark.svg"></span>
					<span class="foot-mark"><img src="img/mark.svg"></span>
					<span class="foot-mark"><img src="img/mark.svg"></span>
					<span class="foot-mark"><img src="img/mark.svg"></span>
				</div>
				<span class="foot-item"></span>
				<span class="foot-item"></span>
				<span class="foot-item"></span>
				<span class="foot-item"></span>
				<span class="foot-item"></span>
				<span class="foot-item"></span>
				<span class="foot-item"></span>
			</div>
		</footer>
	</body>
	<script type="text/javascript" src="js/jquery1.10.min.js" ></script>
	<script type="application/javascript" src="js/fastclick.js" ></script>
	<script type="application/javascript" src="js/explode.js" ></script>
	<script>
		//本地缓存
		var STORAGE = window.localStorage;
	    var BOARD=[];
		//延迟安全控制参数,1允许入槽,0不允许
		var HANDLE=1;
		var LEVEL=1;
		var FISTREND=0;
		var TOOLTIMES=1;
		var LOOKTIMES=0;
		var row=0,col=0;
		
		//图层参数
		var lAYOFFSETFACTOR={}
		//
		//偏移参数
		const OFFSETFACTOR={
			0:[0,0,0,0],
			1:[-1,1,-1,1],
			2:[1,-1,-1,1]
		}
		//
		var resouceBase={
			0:{pic:"img/1.png",leftNum:0},
			1:{pic:"img/2.png",leftNum:0},
			2:{pic:"img/3.png",leftNum:0},
			3:{pic:"img/ys.png",leftNum:0},
			4:{pic:"img/4.png",leftNum:0},
			5:{pic:"img/wq.png",leftNum:0},
		}
		var resouceExtends={
			6:{pic:"img/5.png",leftNum:0},
			7:{pic:"img/6.png",leftNum:0},
			8:{pic:"img/7.png",leftNum:0},
			9:{pic:"img/8.png",leftNum:0},
			10:{pic:"img/9.png",leftNum:0},
			11:{pic:"img/10.png",leftNum:0},
		}
		var keymap={}
		//记录剩余未消的卡牌,为0时游戏通关,需要初始化为待消总卡牌,有重置卡牌,返回操作时,需要改动此值
		var TOTAL=0;
		//指针记录上一个入槽的dom
		var DOMPOS;
		var bgMisic=document.getElementById('bg-music');
		var clickVoice=document.getElementById('di');
		clickVoice.volume = 1;
		var disapearVoice=document.getElementById('dong');
		disapearVoice.volume = 1;
		var waterVoice=document.getElementById('water');
		waterVoice.volume = 1;
		var hashVoice=document.getElementById('hash');
		hashVoice.volume = 1;
		var noVoice=document.getElementById('no');
		noVoice.volume = 1;
		var failVoice=document.getElementById('fail');
		failVoice.volume = 1;
		var screamVoice=document.getElementById('scream');
		screamVoice.volume = 1;
		var approveVoice=document.getElementById('approve');
		approveVoice.volume = 1;
		var perspectiveVoice=document.getElementById('perspective');
		perspectiveVoice.volume = 1;
		var perspectiveCloseVoice=document.getElementById('perspectiveClose');
		perspectiveCloseVoice.volume = 1;
		
		
		var shaketimes;
		var shakeSupport=false;
		setTimeout(function(){
		    navigator.vibrate = navigator.vibrate || navigator.webkitVibrate || navigator.mozVibrate || navigator.msVibrate;
		    if(navigator.vibrate) {
				// shakeSupport=true;
		    }
		},1000)
		
		
		$(function(){
			//加载fastclick,解决ios手机端延迟问题
			FastClick.attach(document.body);
			$(".tooltimes").html(TOOLTIMES);
			$(".looktimes").html(LOOKTIMES);
			$(".mask").fadeOut('fast');
			$(window).resize(resizeFootBox);
			resizeFootBox();
			FISTREND=1;
			if(STORAGE.getItem("maxLevel")){
				try{
					!isNaN(parseInt(STORAGE.getItem("maxLevel")))?"":STORAGE.setItem("maxLevel",1);
				}catch(e){
					STORAGE.setItem("maxLevel",1);
				}
			}else{
				STORAGE.setItem("maxLevel",1);
			}
			var myLevel=parseInt(STORAGE.getItem("maxLevel"));
			$(".myLevelnum").html(myLevel);

			$(document).on('click', ".item",function(){
				if(!isOverLayer(this)) return false;
				clickVoice.play();
				if(shakeSupport){
					navigator.vibrate(500);
				}
				//停止上一个模块的动画和队列中的动画
				if(DOMPOS){
					DOMPOS.stop(true,true);
					$(".foot-item .block").css("display","");
				}
				if(HANDLE==0) return;
				HANDLE=0;
				$(this).addClass("removeBottomLay");
				var $dom=$(".foot-item").not(":has('.block')").eq(0);
				var same=$(".foot-item").find(".block[data-type='"+$(this).children().attr("data-type")+"']");
				if(same.length>0){
					$dom.insertAfter(same.eq(same.length-1).parent());
				}
				var top=$dom.offset().top;
				var left=$dom.offset().left;
				var nowtop=$(this).offset().top;
				var nowleft=$(this).offset().left;
				var that=this;
				DOMPOS=$(this).children().clone().hide();
				DOMPOS.appendTo($dom);
				TOTAL--;
				if($(".foot-item").has(".block").length>=7) {
						if(!tribleDisapear($(this).children())){
								gameOver();
						} 
				}
				if(TOTAL<=0){
					approveLevel(myLevel);
				}
				HANDLE=1;
				$(this).children().css("top",nowtop+"px").css("left",nowleft+"px").css("position","fixed");
				$(this).children().animate({top:top+"px",left:left+"px"},200,'swing',function(){
					$(this).remove();
					$dom.find(".block").show();
					tribleDisapear(this);
					checkAllLayer();
				})
			})
			$(document).on('click', ".again", function(){
				BOARD=[];
				HANDLE=1;
				FISTREND=0;
				TOOLTIMES=1;
				LOOKTIMES=0;
				lAYOFFSETFACTOR={};
				DOMPOS=null;
				$(".foot-item .block").remove();
				$(".layer").remove();
				resizeFootBox();
				$(".mask,.mask text,.mask button ").fadeOut();
			});
			$(document).on('click', ".myLevel",function(){
				LEVEL=myLevel;
				BOARD=[];
				HANDLE=1;
				FISTREND=0;
				TOOLTIMES=1;
				LOOKTIMES=0;
				lAYOFFSETFACTOR={};
				DOMPOS=null;
				$(".foot-item .block").remove();
				$(".layer").remove();
				resizeFootBox();
				clearInterval(shaketimes);
			})
			$(document).on('click', ".nextLevel", function(){
				BOARD=[];
				HANDLE=1;
				LEVEL++;
				FISTREND=0;
				TOOLTIMES=1;
				LOOKTIMES=0;
				lAYOFFSETFACTOR={};
				DOMPOS=null;
				$(".foot-item .block").remove();
				$(".layer").remove();
				resizeFootBox();
				$(".mask,.mask text,.mask button ").fadeOut();
			});
			$(document).on('click', ".music",function(){
				waterVoice.play();
				if(bgMisic.paused){ 
					$(this).css("opacity",1);
					bgMisic.play(); 
					return;
				}else{
					$(this).css("opacity",0.3);
					bgMisic.pause(); 
				}
			})
			$(document).on('click', ".options",function(){
				dislocate();
			})
			$(document).on('click', ".look",function(){
				perspective();
			})
			
			audioAutoPlay(bgMisic); 
			audioAutoPlay(hashVoice);
		})
		function audioAutoPlay(audio){  
			var play = function(){  
					audio.play();  
					document.removeEventListener("touchstart",play, false);  
				};  
			audio.play();  
			document.addEventListener("WeixinJSBridgeReady", function () {  
				play();  
			}, false);  
			document.addEventListener('YixinJSBridgeReady', function() {  
				play();  
			}, false);  
			document.addEventListener("touchstart",play, false);  
			//禁用下拉
			document.addEventListener('touchmove', function(e) {e.preventDefault();}, { passive: false });
		}  
		//响应式初始化,手机、电脑、ipad三端支持
		function resizeFootBox() {
			$(".level").html(LEVEL);
			if(LEVEL<=4){
				keymap=JSON.parse(JSON.stringify(resouceBase));
			}
			else if(LEVEL>4&&LEVEL<=9){
				keymap=JSON.parse(JSON.stringify(resouceBase));
				keys = Object.keys(resouceExtends);
				for(i=4;i<LEVEL&&i<(4+keys.length);++i){
					keymap[keys[i-4]]=resouceExtends[keys[i-4]];
				}
			}else if(9<LEVEL&&LEVEL<=16){
				keymap=JSON.parse(JSON.stringify(resouceBase));
			}else if(LEVEL>16){
				keymap=JSON.parse(JSON.stringify(resouceBase));
				keys = Object.keys(resouceExtends);
				for(i=4;i<LEVEL&&i<(4+keys.length);++i){
					keymap[keys[i-4]]=resouceExtends[keys[i-4]];
				}
			}
			var availableWidth=$(".foot-box").innerWidth();
			//根据屏幕计算行列
			var itemWidth=availableWidth/7-6+2+4;
			//是否初次渲染
			if(FISTREND==0){
				var row=Math.ceil(availableWidth*0.85/itemWidth);
				var col=Math.ceil($(window).height()*0.75*0.7/itemWidth); 
				iniMatrix(row,col);
				initialBoard();
			}
			$(".foot-box").css("height",availableWidth/7+15+"px");
			$(".foot-item,.item,.foot-mark,.block").css("width",availableWidth/7-6+"px")
							.css("height",availableWidth/7-6+"px");
			$(".block").css("height",(availableWidth/7-6)*0.8+"px")
							.css("max-width",(availableWidth/7-6)*0.8+"px")
							.css("width","auto");
			$(".content").css("padding-top",itemWidth+"px")
			if($(window).width()>=770){
				$(".foot-box").css("left",($(window).width()/2-$(".foot-box").width()/2)+"px");
			}else{
				$(".foot-box").css("left","5px");
			}
			layerOffsetCal();
		}
		
		//矩阵初始化
		function iniMatrix(row,col){
			if(row*col==1&&row>0) return false;
			var matrix=[];
			for(i=row-1;i>=0;--i){
				matrix[i]=[];
				for(j=col-1;j>=0;--j){
					matrix[i][j]=Math.round(Math.random()*(Object.keys(keymap).length-1));
				}
			}
			BOARD.push(matrix);
			iniMatrix(row==1?1:row-1,col==1?1:col-1);
		}
		//初始化棋盘
		function initialBoard(){
			if(LEVEL<=3){
				TOOLTIMES=3;
				BOARD = BOARD.reverse();
			}else if(3<LEVEL&&LEVEL<=6){
				TOOLTIMES=5;
			}else if(6<LEVEL&&LEVEL<=9){
				TOOLTIMES=5-(LEVEL-6);
				TOOLTIMES<1?TOOLTIMES=1:TOOLTIMES=TOOLTIMES;
			}else if(9<LEVEL&&LEVEL<=12){
				TOOLTIMES=6;
			}else{
				TOOLTIMES=6-(LEVEL-8);
				TOOLTIMES<1?TOOLTIMES=1:TOOLTIMES=TOOLTIMES;
			}
			if(LEVEL>8){
				LOOKTIMES=3;
				$(".looktimes").html(LOOKTIMES);
			}
			var html="";
			var namespace="lay";
			var idcount=0;
			for(i=0;i<BOARD.length;++i){
				//层数遍历
				lAYOFFSETFACTOR[namespace+i]=OFFSETFACTOR[i%3];
				if(LEVEL<=6){
					if(i==3) break;
				}
				html+='<div class="layer lay'+i+'">';
				for(s=0;s<BOARD[i].length;++s){
					for(k=0;k<BOARD[i][s].length;++k){
						html+='<span  id="'+idcount+'" class="item overlayer"><img data-type="'+BOARD[i][s][k]+'" class="block" src="'+keymap[BOARD[i][s][k]].pic+'"></span>';
						keymap[BOARD[i][s][k]].leftNum++;
						idcount++;
					}
				}
				html+='</div>';	
			}
			html+='<div class="layer lay'+BOARD.length+'">';
			for(key in keymap){
				if(keymap[key].leftNum%3!=0){
					var count=3-(keymap[key].leftNum%3);
					for(i=0;i<count;++i){
						html+='<span  id="'+idcount+'" class="item overlayer"><img data-type="'+key+'" class="block" src="'+keymap[key].pic+'"></span>';
						idcount++;
						keymap[key].leftNum++;
					}
				}
			}
			html+='</div>';	
			$(".borad").append(html);
			if(LEVEL>9){
				for(i=9;i<=LEVEL;++i){
					$(".item").eq(Math.floor(Math.random()*idcount)).find(".block").attr("src","img/weizhi.svg");
					$(".item").eq(Math.floor(Math.random()*idcount)).find(".block").attr("src","img/weizhi.svg");
				}
			}
			TOTAL=$(".item .block").length-$(".removeBottomLay .block").length;
		}
		//图层初始化偏移计算
		function layerOffsetCal(){
			var xs=($(".foot-box").width()/7-6)/3;
			for(key in lAYOFFSETFACTOR){
				$("."+key).css("top",lAYOFFSETFACTOR[key][0]*xs+"px")
						  .css("left",lAYOFFSETFACTOR[key][1]*xs+"px")
						  .css("bottom",lAYOFFSETFACTOR[key][2]*xs+"px")
						  .css("right",lAYOFFSETFACTOR[key][3]*xs+"px")
			}
			dislocate();
		}
		//碰撞单点计算,防渲染不及时
		function isOverLayer(element) {
		  var left=$(element).offset().left;
		  var top=$(element).offset().top;
		  var width=$(element).width();
		  var height=$(element).height();
		  var el=[document.elementFromPoint(left+2, top+2),
		   document.elementFromPoint(left+width-2, top+2),
		   document.elementFromPoint(left+width-2, top+height-2),
		   document.elementFromPoint(left+2, top+height-2)]
		   for(i=0;i<el.length;++i){
				if($(el[i]).hasClass("block")){
					el[i]=$(el[i]).parent();
				}
			   if(element.id!=$(el[i]).attr("id")) return false;
		   }
		  return true;
		}
		//碰撞动态计算
		function checkAllLayer(){
			$(".item").each(function(){
				$(this).find(".block").slideDown("normal").css("display","inline-block");
				if($(this).hasClass("overlayer")){
					if(isOverLayer(this)){
						$(this).removeClass("overlayer");
						$(this).find(".block").css("opacity","1");
					}else{
						$(this).addClass("overlayer");
						$(this).find(".block").css("opacity","0.3");
					}
				}
			})
		}
		//三个一样消除检验
		function tribleDisapear(ele){
			var count=$(".foot-item .block[data-type='"+$(ele).attr("data-type")+"']").length;
			if(count>=3){
				disapearVoice.play();
				aniWorking=true;
				$(".foot-item .block[data-type='"+$(ele).attr("data-type")+"']:lt(3)").hide("explode", {pieces: 6 }, 180 ,function(){
					$(this).parent().empty().insertAfter($(".foot-item:last-child"));
					aniWorking=false;
				});
				return true;
			}
			return false;
		}
		function dislocate(){
			if(HANDLE==0) return;
			if(TOOLTIMES<=0){
				noVoice.play();
				return;
			} 
			hashVoice.play();
			TOOLTIMES--;
			$(".tooltimes").html(TOOLTIMES);
			$(".pause").fadeIn(200);
			setTimeout(function(){
				$(".pause").fadeOut(200);
				HANDLE=1;
				checkAllLayer();
			},2200);
			
			HANDLE=0;
			var $dom=$(".item").has(".block");
			var directorArray=["top","left"];
			var distanceFactorArray=[0.8,1.5,-1.2,-0.5,0.7,1.3];
			var toparray=[];
			var leftarray=[];
			//前一个移动会对后一个影响,需要数组记录全部位置
			$dom.each(function(e){
				toparray.push($(this).offset().top);
				leftarray.push($(this).offset().left);
			})
			$dom.each(function(e){
				$(this).css("top",toparray[e]-2+"px")//2为border
				.css("left",leftarray[e]-2+"px")
				.css("position","fixed")
				$(this).addClass("overlayer");
				$(this).find(".block").css("opacity","0");
			})
			$dom.each(function(e){
				var width=$(this).width();
				for(i=0;i<3;++i){
					var director=directorArray[Math.floor(Math.random()*2)];
					var param=$(this).offset()[director];
					var distanceFactor=distanceFactorArray[Math.floor(Math.random()*6)]*width*2;
					$(this).animate({[director]:param+distanceFactor+"px"},350)
					$(this).animate({[director]:param-distanceFactor+"px"},150)
				}
				$(this).animate({"top":toparray[e]-2+"px","left":leftarray[e]-2+"px"},200)
			})
			exchange();
			if(LEVEL<parseInt(STORAGE.getItem("maxLevel"))){
				if(!shaketimes){
					shaketimes=setInterval(function(){
						$(".myLevel").shake(2, 20, 200);
					},5000);
				}
			}else{
				clearInterval(shaketimes);
			}
		}
		
		function perspective(){
			if(HANDLE==0) return;
			if(LOOKTIMES<=0){
				noVoice.play();
				return;
			} 
			HANDLE=0;
			perspectiveVoice.play();
			LOOKTIMES--;
			$(".looktimes").html(LOOKTIMES);
			$(".block[src='img/weizhi.svg']").each(function(){
				$(this).css("transform","rotateY(90deg)")
				.attr("src",keymap[$(this).attr("data-type")].pic)
				.css("transform","rotateY(720deg)").addClass("wenhao")
			})
			setTimeout(function(){
				perspectiveCloseVoice.play();
				$(".wenhao").css("transform","rotateY(-90deg)")
				.attr("src","img/weizhi.svg")
				.css("transform","rotateY(-720deg)").removeClass("wenhao")
				HANDLE=1;
			},3000)
		}
		
		function gameOver(){
			if(shakeSupport){
				navigator.vibrate(500);
			}
			Math.round(Math.random()*2)==1?failVoice.play():screamVoice.play();
			$(".mask").fadeIn(200,function(){
				$(this).find("text").eq(0).slideDown(2000);
				$(this).find("button").eq(0).fadeIn(2000);
			});
			return;
		}
		
		function approveLevel(myLevel){
			if(myLevel<(parseInt(LEVEL)+1)){
				var level=parseInt(LEVEL)+1;
				STORAGE.setItem("maxLevel",level);
			}
			$(".myLevelnum").html(STORAGE.getItem("maxLevel"));
			$(".mask").fadeIn(200,function(){
				approveVoice.play();
				$(this).find("text").eq(1).slideDown(1000);
				$(this).find("button").eq(1).fadeIn(1000);
			});
		}
		
		function exchange(){
			var allblock=$(".item").has(".block");
			for(i=0;i<allblock.length;++i){
				var dom1=allblock.eq(Math.floor(Math.random()*allblock.length));
				var dom2=allblock.eq(Math.floor(Math.random()*allblock.length));
				dom1.find('.block').appendTo(dom2);
				dom2.find('.block').eq(0).appendTo(dom1);
			}
		}
		
		jQuery.fn.shake = function (intShakes , intDistance , intDuration) {
			this.each(function () {
				var jqNode = $(this);
				var left=jqNode.offset().left;
				var top=jqNode.offset().top;
				for (var x = 1; x <= intShakes; x++) {
					jqNode.animate({ left: left+(intDistance * -1)}, (((intDuration / intShakes) / 4)))
					.animate({ left: left+intDistance }, ((intDuration / intShakes) / 2))
					.animate({ left: left }, (((intDuration / intShakes) / 4)));
				}
			});
			return this;
		}

</script>
</html>
<!-- CSDN:GT开发算法工程师 Git:GAOSIR369-->
<!-- 以下所发布项目的唯一作者。
CSDN:GT开发算法工程师
Gitee:GAOSIR369

本人保留所有权利和责任,并对该项目的准确性和完整性负责。
未经我的明确书面同意,任何人不得以任何形式复制、分发、展示、发布或使用此项目中的任何内容,包括但不限于文本、图像、音频和视频。
任何未经授权的使用都将被视为侵犯我的知识产权,并可能引起法律责任。
我保留在任何时候更改或撤销此免责声明的权利,而无需事先通知任何人,我希望这个声明符合您的需求。
————————————————————————————————————————————————————————————————————————————————————————————————I reserve all rights and responsibilities, and am responsible for the accuracy and completeness of this project.
Without my explicit written consent, no one is allowed to copy, distribute, display, publish or use any content in this project in any form, including but not limited to text, images, audio, and video.
Any unauthorized use will be considered an infringement of my intellectual property rights and may result in legal liability.
I reserve the right to change or revoke this disclaimer at any time without prior notice to anyone, and I hope this statement meets your needs.——2192251291@qq.com -->

效果展示:

  • 初始化棋盘

  • 游戏界面 

 

 


  •         通过掌握这些技术,读者可以轻松地创建自己的消除类游戏,并添加更多有趣的功能来吸引玩家。本文提供了一个实用的开发指南,旨在帮助读者从零开始构建类似“羊了个羊”的消除游戏。
  •         总之,本文详细介绍了如何使用HTML和JavaScript开发一个类似于“羊了个羊”的消除游戏。通过理解代码结构和逻辑,以及掌握关键技术,读者可以轻松地创建自己的游戏项目,并进一步探索游戏开发的乐趣。
  • (没有图片和JS软件包私信博主)

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/348012.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【博客搭建记录贴】day4_Hexo基本操作,添加草稿并发布

目录 1.将项目导入到开发环境1.1 先把项目导入到IDEA中1.2 确认IDEA中服务器启动正常 2.Hexo基本操作: 添加草稿并发布2.1 生成一个草稿文件2.2 在页面上查看草稿3.3 将草稿正式发布 1.将项目导入到开发环境 我本地已经安装了 IntelliJ IDEA&#xff08;版本&#xff1a;社区版…

【modelsim使用】数据显示设置

本文介绍modelsim使用中数据的显示设置&#xff0c;定点小数的显示、模拟波形的显示、数据截位查看、信号颜色和行高设置的操作。 文章目录 定点小数显示模拟波形的显示选取信号的某几位组合查看信号颜色与行高设置 定点小数显示 使用modelsim进行仿真时&#xff0c;涉及到定点…

【GitHub项目推荐--一款美观的开源社区系统】【转载】

推荐一款开源社区系统&#xff0c;该系统基于主流的 Java Web 技术栈&#xff0c;如果你是一名 Java 新手掌握了基本 JavaEE 框架知识&#xff0c;可以拿本项目作为练手项目。 开源社区系统功能还算完善包含发布帖子、发布评论、私信、系统通知、点赞、关注、搜索、用户设置、…

【MySQL】内外连接

内外连接 一、内连接二、外连接1、左外连接2、右外连接 表的连接分为内连和外连。 一、内连接 内连接实际上就是利用where子句对两种表形成的笛卡儿积进行筛选。只不过为了让sql的可读性更好&#xff0c;我们使用其他的关键字进行内连接。 语法&#xff1a; SELECT ... FRO…

BGP路由协议通告原则

1仅将自己最优的路由发给BGP邻居 一般情况下,如果BGP Speaker学到去往同一网段的路由多于一条时,只会选择一条最优的路由给自己使用,即用来发布给邻居,同时上送给IP路由表。但是,由于路由器也会选择最优的路由给自己使用,所以BGP Speaker本身选择的最优的路由也不一定被…

简单模拟实现一个线程池

废话不多说之间上代码 import java.util.ArrayList; import java.util.List; import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.BlockingQueue;public class MyThreadPoolExecutor {private List<Thread> listnew ArrayList<>();pri…

Linux 离线安装Docker(脚本自动安装)

文章目录 1. 准备docker离线包2. 准备docker.service 系统配置文件3. 准备安装脚本和卸载脚本4. 安装5、docker存储 前言 关于服务器不能联网的情况&#xff0c;这样就没法用yum安装软件&#xff0c;docker也是如此&#xff1b;或者由于CentOS系统采用Yum 安装过程中很慢&#…

SpringBootAdmin邮件通知

在上一篇中我们学习到了 Admin Service Clustering 分布式缓存配置 &#xff0c;这一篇我们来学习&#xff0c;客户端离线&#xff0c;出现故障的时候&#xff0c;我们这么能及时知道呢&#xff0c;发现邮件通知也许是最简单的方式了&#xff01; 邮件通知 邮件通知将作为使用…

​在 Linux ​中管理用户

在 Linux 系统中&#xff0c;用户是系统资源的主要使用者&#xff0c;每个用户都有一个唯一的标识符&#xff08;用户ID&#xff09;。为了更好地组织和管理用户&#xff0c;Linux 还引入了用户组的概念。用户组是用户的集合&#xff0c;有助于更有效地分配权限和资源。 用户是…

LabVIEW工业机器人系统

介绍了ABB工业机器人与LabVIEW之间进行数据交互的解决方案。通过使用TCP/IP协议的socket通信&#xff0c;实现了机器人坐标数据的读取&#xff0c;为人机交互提供了一个更便捷、更高效的新思路。 系统主要由ABB工业机器人、基于TCP/IP协议的通信接口和LabVIEW软件组成。工业机…

Excel:将截面数据转换成面板数据

原始截面数据如下&#xff1a; 步骤&#xff1a;数据——自表格/区域 点击确定&#xff0c;出现下图&#xff1a; 然后&#xff0c;在这个界面选择&#xff1a;“转换”——“逆透视列”下选择逆透视其他列。会出现面板数据形式。 然后&#xff0c;点击“主页”——关闭并上载即…

day16打卡

day16打卡 104. 二叉树的最大深度 递归法时间复杂度&#xff1a;O(N)&#xff0c;空间复杂度&#xff1a;O(N) class Solution { public:int maxDepth(TreeNode* root) {if(root nullptr) return 0;return 1 max(maxDepth(root->left), maxDepth(root->right));} };…

Android Settings 显示电池点亮百分比

如题&#xff0c;Android 原生 Settings 里有个 电池电量百分比 的选项&#xff0c;打开后电池电量百分比会显示在状态栏。 基于 Android 13 &#xff0c; 代码在 ./packages/apps/Settings/src/com/android/settings/display/BatteryPercentagePreferenceController.java &am…

springboot125汽车资讯网站

简介 【毕设源码推荐 javaweb 项目】基于springbootvue 的125汽车资讯网站 适用于计算机类毕业设计&#xff0c;课程设计参考与学习用途。仅供学习参考&#xff0c; 不得用于商业或者非法用途&#xff0c;否则&#xff0c;一切后果请用户自负。 看运行截图看 第五章 第四章 获…

[AIGC 大数据基础] 浅谈hdfs

HDFS介绍 什么是HDFS&#xff1f; HDFS&#xff08;Hadoop Distributed File System&#xff09;是Apache Hadoop生态系统的一部分&#xff0c;是一个分布式文件系统。它被设计用于存储和处理大规模数据集&#xff0c;并且能够容错、高可靠和高性能地处理文件。 HDFS是为了支…

逻辑回归中的损失函数梯度下降

一、引言 逻辑回归中的损失函数通常采用的是交叉熵损失函数&#xff08;cross-entropy loss function&#xff09;。在逻辑回归中&#xff0c;我们通常使用sigmoid函数将线性模型的输出转换为概率值&#xff0c;然后将这些概率值与实际标签进行比较&#xff0c;从而计算损失。 …

创建第一个 Spring 项目(IDEA社区版)

文章目录 创建 Spring 项目创建一个普通的 Maven 项目添加 Spring 依赖IDEA更换国内源 运行第一个 Spring 项目新建启动类存储 Bean 对象将Bean注册到Spring 获取并使用 Bean 对象 创建 Spring 项目 创建一个普通的 Maven 项目 首先创建一个普通的 Maven 项目 添加 Spring 依…

web项目开发的基本过程

一、背景 web项目开发基本过程一般由需求分析&#xff0c;概要设计&#xff0c;详细设计&#xff0c;数据库设计&#xff0c;编码&#xff0c;测试&#xff0c;发布上线这几个过程。这就是经典的瀑布模型。但是随着系统的复杂度越来越高&#xff0c;团队人员技术栈分工越来越小…

《WebKit技术内幕》学习之十三(3):移动WebKit

3 其他机制 3.1 新渲染机制 为了移动领域更好的用户体验&#xff0c;渲染机制所做的改进主要是提升渲染性能来增加响应的速度&#xff0c;甚至不惜牺牲一些跟规范定义的行为不一致的地方。在这一小节中主要介绍三个方面的技术&#xff0c;其一是Tiled Backing Store&#x…

Wpf 使用 Prism 实战开发Day14

备忘录接口增删&#xff08;CURD&#xff09;改查实现 一.添加备忘录控制器&#xff08;MemoController&#xff09; 备忘录控制器&#xff08;MemoController&#xff09;和待办事项控制器 &#xff08;ToDoController&#xff09;功能实现差不多一样。基本套路就是&#xff1…