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

news2024/9/28 19:24:42

一、游戏简介

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


  •  设置项目结构

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


	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软件包私信博主)

 

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【数据结构与算法】之字符串系列-20240126

这里写目录标题 一、12. 整数转罗马数字二、43. 字符串相乘三、49. 字母异位词分组四、151. 反转字符串中的单词五、179. 最大数 一、12. 整数转罗马数字 中等 罗马数字包含以下七种字符&#xff1a; I&#xff0c; V&#xff0c; X&#xff0c; L&#xff0c;C&#xff0c;D …

前端vue集成echarts图形报表样例

文章目录 &#x1f412;个人主页&#x1f3c5;Vue项目常用组件模板仓库&#x1f4d6;前言&#xff1a;&#x1f415;1.在项目终端下载echarts依赖包&#x1f3e8;2.在main.js中导入echarts资源包并使用&#x1f380;3.在.vue文件中直接使用echarts&#xff0c;下面是一个样例&a…

计算机找不到x3daudio1_7.dll无法继续执行的5种解决方法

当我们在运行一款游戏时&#xff0c;遇到了“游戏找不到x3daudio1_7.dll”这样的错误提示&#xff0c;并因此无法继续执行游戏进程&#xff0c;这种情况具体是什么问题呢&#xff1f;我们可以深入解析一下。通常情况下&#xff0c;这种报错信息意味着系统缺失了一个关键的动态链…

144基于matlab的平面桁架结构的总体刚度矩阵计算

基于matlab的平面桁架结构的总体刚度矩阵计算&#xff0c;最后以图形形式显示出桁架结构&#xff0c;程序已调通&#xff0c;可直接运行。 144matlab 平面桁架 有限元分析 总体刚度 (xiaohongshu.com)

华为鸿蒙扩圈何时才会停息~

自从2023年华为秋季发布会上宣布鸿蒙Next不在兼容Android后&#xff0c;鸿蒙才开始扩圈行动&#xff0c;直到2024年1月18日鸿蒙千帆启航的仪式上宣布已有200鸿蒙原生态应用正在加速开发中&#xff0c;并且宣布启动了第二阶段的扩圈行动。 就1月25日就有多家银行和淘宝等支付平台…

Grafana loki配置, 无脑版

使用docker部署Grafana loki 1.创建 docker-compose.yml 文件 touch docker-compose.yml写入以下内容 vim touch docker-compose.yml version: "3"networks:loki:services:loki:image: grafana/loki:latestrestart: unless-stoppedports:- "3100:3100"vo…

1.24 C++ day1

思维导图 试编程 提示并输入一个字符串&#xff0c;统计该字符中大写、小写字母个数、数字个数、空格个数以及其他字符个数&#xff0c;要求使用C风格字符串完成 #include <iostream>using namespace std;int main() {string s;cout << "please enter a str…

设置模式之责任链模式

目录 1.概述 2.结构 3.实现 4.总结 1.概述 责任链模式&#xff08;Chain of Responsibility Pattern&#xff09;是一种行为性设计模式&#xff1b;它为请求创建了一个接收者对象的链&#xff0c;允许你将请求沿着处理者链进行发送。 收到请求后&#xff0c; 每个处理者均…

list的介绍及其模拟实现

今天我们了解list&#xff0c;list在python中是列表的意思 &#xff0c;但是在C中它是一个带头双向循环链表&#xff1a; list的介绍 list是可以在常数范围内在任意位置进行插入和删除的序列式容器&#xff0c;并且该容器可以前后双向迭代。list的底层是双向链表结构&#xf…

1.25学习总结

今天学习了二叉树&#xff0c;了解了二叉树的创建和遍历的过程 今天所了解的遍历过程主要分为三种&#xff0c;前序中序和后序&#xff0c;都是DFS的想法 前序遍历&#xff1a;先输出在遍历左节点和右节点&#xff08;输出->左->右&#xff09; 中序遍历&#xff1a;先…

2024传薪文化盛大启航 年度论坛暨新春年会圆满举办

2024年1月20日下午, 由创人文/传薪文化理事会与长三角美好生活创新联盟主办,由传薪文化、九鲲文化承办的“文脉传万象薪”传薪&美创联2024甲辰年度论坛暨新春年会,在上海成功举办。来自学界、文化、经济和艺术等领域的社会精英人士170余人齐聚一堂,从历史和传承中汲取营养,…

elementplus 中 DatePicker 日期选择器样式修改无效

问题 遇到一个需求需要修改 DatePicker 日期选择器的样式&#xff0c;在添加了 scoped 属性的 style 标签&#xff0c;并且使用了 deep 样式穿透的情况下并不能修改其样式。 原因 DatePicker 日期选择器弹出面板默认挂载在 body 上&#xff0c;所以在组件中添加了 scoped 属…

MFC扩展库BCGControlBar Pro v34.0 - 图形管理器功能升级

BCGControlBar库拥有500多个经过全面设计、测试和充分记录的MFC扩展类。 我们的组件可以轻松地集成到您的应用程序中&#xff0c;并为您节省数百个开发和调试时间。 BCGControlBar专业版 v34.0已正式发布了&#xff0c;该版本包括新的主题任务对话框、图像效果、旋转圆形刻度、…

【操作系统】实验六 分析源代码

&#x1f57a;作者&#xff1a; 主页 我的专栏C语言从0到1探秘C数据结构从0到1探秘Linux &#x1f618;欢迎关注&#xff1a;&#x1f44d;点赞&#x1f64c;收藏✍️留言 &#x1f3c7;码字不易&#xff0c;你的&#x1f44d;点赞&#x1f64c;收藏❤️关注对我真的很重要&…

Python爬虫 l 中国农药信息网的农药登记数据

一、爬取目标 二、完整源码 #""""""""""""""""""""""""""""""""""""""…

Docker网络及资源控制

目录 1.Docker网络 Docker网络实现原理 Docker的网络模式 host模式 container模式 none模式 bridge模式 自定义网络 2.资源控制 CPU资源控制 设置CPU使用率上限 设置CPU资源占用比 设置容器绑定指定的CPU 对内存使用的限制 对磁盘IO配额控制&#xff08;blkio&a…

泰迪科技最新大数据法律监督模型解决方案

大数据法律监督平台是基于监督数据整合管理平台、监督模型构建平台、内置模型库以及法律监督线索管理平台打造的一套服务于检察机关法律监督工作的专业化系统。通过数据采集、融合、挖掘、建模、展现等一系列能力&#xff0c;辅助检察官从纷繁复杂的数据中&#xff0c;开展多维…

手拉手JavaFX UI控件与springboot3+FX桌面开发

目录 javaFx文本 javaFX颜色 字体 Label标签 Button按钮 //按钮单击事件 鼠标、键盘事件 //(鼠标)双击事件 //键盘事件 单选按钮RadioButton 快捷键、键盘事件 CheckBox复选框 ChoiceBox选择框 Text文本 TextField(输入框)、TextArea文本域 //过滤 (传入一个参数&a…

【嵌入式学习】C++QT-Day1-C++基础

思维导图&&笔记 见我的博客&#xff1a;https://lingjun.life/wiki/EmbeddedNote/19Cpp 作业&#xff1a; 提示并输入一个字符串&#xff0c;统计该字符中大写、小写字母个数、数字个数、空格个数以及其他字符个数 要求使用C风格字符串完成 #include <iostream&…

【K8S】Service使用NodePort对外暴露应用

一、背景介绍 Pod是有生命周期的&#xff0c;当一个工作节点(node)销毁时&#xff0c;节点上运行的pods也会被销毁。ReplicationController会动态地在其他节点上创建Pod来保持应用程序的运行&#xff0c;每一个Pod都有一个独立的IP地址&#xff0c;甚至是同一个节点上的Pod。可…