js实现消灭星星(web简易版)


Posted in Javascript onMarch 24, 2020

昨天看视频之后,整理思路,自己完成了简易版消灭星星

思路:

模块1:初始化

  • 初始化总分数、当前分数、背景图、选择的星星分数
  • 初始化星星(生成二维数组,对二维数组的每一个对象设置样式(长、宽、背景图),生成二维数组个div元素节点插入到游戏面板中)

模块2:预判

判断:

 鼠标移动到某一个方块,判断上下左右是否有连接着的小方块(采用递归方法),然后将其存储到数组choose[],移到其他方块时,choose置为空

闪烁:

 将已选中的小方块设置样式(缩放)

显示选择分数:

 设置初始分数和递增分数,根据选中的块数算出选中的分数

模块3:点击

消失:

 点击已选中的小方块,将连着的所有小方块在二维数组的位置设置为空,清空choose数组

移动:

 下移:设置一个指针,指向最下面的行。每当行+1,若遇到不为空的方块,则pointer++,若遇到该列某行为空,则将pointer的行数设为i

  左移:最底部的一行若有一列为空,将右边的所有方块的列-1

判断:

 每次点击完成之后判断游戏是否结束

代码部分

html

html结构很简单

<!DOCTYPE html>
<html lang="en">
<head>
 <meta charset="UTF-8">
 <title>Title</title>
 <script src="./index.js"></script>
 <link rel="stylesheet" href="index.css" >
</head>
<body>
 <div id="pop_star">
 <div id="target_score">目标分数:2000</div>
 <div id="now_score">当前分数:0</div>
 <div id="select_score">0块 0分</div>
 </div>
</body>
</html>

CSS

css布局也很简单,相信不用我来说

* {
 margin: 0px;
 padding: 0px;
 }

html, body {
 height: 100%;
 width: 100%;
}

#pop_star {
 width: 500px;
 height: 100%;
 background: url("./pic/background.png");
 margin-left: auto;
 margin-right: auto;
 position: relative;
 background-size: cover;
 font-size: 0px;
}

#target_score {
 width: 100%;
 height: 50px;
 line-height: 50px;
 text-align: center;
 color: white;
 font-size: 20px;
 position: relative;
}

#now_score {
 width: 100%;
 height: 50px;
 line-height: 50px;
 text-align: center;
 color: white;
 font-size: 20px;
 position: relative;
}

#select_score {
 width: 100%;
 height: 50px;
 line-height: 50px;
 text-align: center;
 color: white;
 font-size: 20px;
 position: relative;
 opacity: 0;
}

JS

/*
 创建二维数组
 * 
 * 
 * */
var table ;
var suqareWidth = 50 ; //一个星星/方块边长
var boardWidth = 10 ; //横竖方块个数
var squareSet = [];//小方块的集合,二维数组
var choose = [];//有相邻的小方块,将其放到这个数组
var timer = null ;
var baseScore = 5 ;
var stepScore = 10 ;
var totalScore = 0 ;
var targetScore = 1500;
var flag = true ;
var tempSquare = null;//在处理鼠标动作过程中,动作被屏蔽,导致事件处理完成,有不连贯现象
function createSquare(value , row , col){
 //创建小方块节点
 var blocks = document.createElement('div');
 //设置样式
 blocks.style.width = suqareWidth + 'px';
 blocks.style.height = suqareWidth + 'px';
 blocks.style.display = 'inline-block';
 blocks.style.boxSizing = 'border-box';
 blocks.style.position = 'absolute';
 blocks.style.borderRadius = "12px";
 //小方块的行和列,小方块的num.jpg
 blocks.num = value ;
 blocks.row = row ;
 blocks.col = col ;
 return blocks;
}
function refresh(){
 for(var i = 0 ; i < squareSet.length ; i ++){
 for (var j = 0 ; j < squareSet[i].length ; j++) {
 //严谨判断
 if (squareSet[i][j] == null) {
 continue;
 }
 //将二维数组里面的小方块对应面板的行和列显示
 squareSet[i][j].row = i;
  squareSet[i][j].col = j;
  //列*方块长度
  squareSet[i][j].style.transition = "left 0.3s, bottom 0.3s";
 squareSet[i][j].style.left = squareSet[i][j].col * suqareWidth + 'px';
 squareSet[i][j].style.bottom = squareSet[i][j].row * suqareWidth + 'px';
 //背景图
 squareSet[i][j].style.backgroundImage = "url('img/" + squareSet[i][j].num + ".png')";
 squareSet[i][j].style.backgroundSize = 'cover';
 squareSet[i][j].style.transform = 'scale(0.95)';//是图片缩小至原来的0.95倍
 }
 }
}
function checkLinked(square , arr){
 //严谨判断
 if(square == null){
 return;
 }
 //添加小方块到arr
 arr.push(square);
 /*
 判断位于该小方块左边的小方格是否能被收录进选择数组
 1.小方格不能是最左边的
 2.小方格左边必须有小方块
 3.小方块左边的要和该小方块颜色相同
 4.该小方块左边没有被收录到数组中去
 5.递归
 * 
 * */
 //向左
 if(square.col > 0 && squareSet[square.row][square.col - 1]
 && squareSet[square.row][square.col - 1].num == square.num 
 && arr.indexOf(squareSet[square.row][square.col - 1]) == -1){
 checkLinked(squareSet[square.row][square.col - 1] , arr);
 }
 //向右
 if(square.col < boardWidth - 1 && squareSet[square.row][square.col + 1]
 && squareSet[square.row][square.col + 1].num == square.num 
 && arr.indexOf(squareSet[square.row][square.col + 1]) == -1){
 checkLinked(squareSet[square.row][square.col + 1] , arr);
 }
 //向上
 if(square.row < boardWidth - 1 && squareSet[square.row + 1][square.col ]
 && squareSet[square.row + 1][square.col].num == square.num 
 && arr.indexOf(squareSet[square.row + 1][square.col ]) == -1){
 checkLinked(squareSet[square.row + 1][square.col] , arr);
 }
 //向上
 if(square.row > 0 && squareSet[square.row - 1][square.col]
 && squareSet[square.row - 1][square.col].num == square.num 
 && arr.indexOf(squareSet[square.row - 1][square.col]) == -1){
 checkLinked(squareSet[square.row - 1][square.col] , arr);
 }
}
//让选中的小方块闪烁
function flicker(arr){
 var num = 0 ;
 //设置计时器,让其一之闪烁
 timer = setInterval(function(){
 for (var i = 0 ; i < arr.length ; i++) {
 //设置缩放样式
 arr[i].style.border = "3px solid #BFEFFF";
 arr[i].style.transform = "scale("+(0.9 + 0.05 *Math.pow(-1 , num))+")";
 }
 //小方块闪烁完成之后num++,使其再次缩放
 num++;
 },300);
}
function back(){
 //若计时器还存在,清楚计数器
 if(timer != null){
 clearInterval(timer);
 }
 //返回原样式
 for(var i = 0 ; i < squareSet.length ; i++){
 for(var j = 0 ; j < squareSet[i].length ; j++){
 //严谨判断
 if (squareSet[i][j] == null) {
 continue;
 }
 squareSet[i][j].style.border = "0px solid #BFEFFF";
 squareSet[i][j].style.transform = "scale(0.95)";
 }
 }
 
}
//选中分数
function selectScore(){
 var socre = 0 ;
 //遍历choose
 for(var i = 0 ; i < choose.length ; i++){
 socre += baseScore + stepScore * i ;
 }
 //严谨判断
 if (socre <= 0) {
 return ;
 }
 //设置select_score的样式
 var select_score = document.getElementById('select_score');
 select_score.innerHTML = choose.length + "块" + socre + "分";
 select_score.style.transition = null ;
 //设置透明度,让其突然显示
 select_score.style.opacity = 1 ;
 //让其逐渐消失
 setTimeout(function(){
 select_score.style.transition = 'opacity 1s';
 select_score.style.opacity = 0;
 },1000);
 
}
//鼠标移动到该小方块时,闪烁
function mouseOver(obj){
 //当鼠标在移动到该方块突然移动到其他位置时
 if(!flag){
 tempSquare = obj;
 return ;
 }
 //当鼠标移开选中的方块之后,让其回到原来的样式
 back();
 //选择相邻相同的小方格
 //传一个数组
 choose = [];
 checkLinked(obj , choose);//obj是当前鼠标移到的小方块,choose是存储响铃小方块的数组
 if (choose.length <= 1) {
 choose = [] ;
 return;
 }
 //将选中的设置样式,让其闪烁
 flicker(choose);
 //显示所选中的小方块的分数
 selectScore();
}
function move(){
 /*
 1.设置一个指针,开始的时候指针指向最下面一行
 2.此时指针和j是否一样,一样都++。
 3.若改行该列该列有小方块,均++,反之j++,pointer不变,循环判断该条件
 3.当j移动到该列某行的小方块,该小方块存在,则将j指向的小方块的位置设置为指针指向的那一个小方块的位置
 * */
 //向下移动
 for (var i = 0 ; i < boardWidth ; i ++) {
 var pointer = 0;//pointer指向小方块,当遇到null的时候停止,等待上面的小方块落到这里来
 for (var j = 0 ; j < boardWidth ; j ++) {
  if (squareSet[j][i] != null) {
  if (j != pointer) {
   squareSet[pointer][i] = squareSet[j][i];
   squareSet[j][i].row = pointer;
   squareSet[j][i] = null;
  }
  pointer ++;
  }
 }
 }
 //横向移动
 for (var i = 0 ; i < squareSet[0].length ; ) {
 if (squareSet[0][i] == null) {
  for (var j = 0 ; j < boardWidth ; j ++) {
  squareSet[j].splice(i, 1);
  }
  continue;
 }
 i ++;
 }
 refresh();
}
function isFinish(){
 for (var i = 0 ; i < squareSet.length ; i++) {
 for (var j = 0 ; j < squareSet[i].length ; j++) {
 //判断周围是否还有可消除的方块
 var temp = [];
 checkLinked(squareSet[i][j] , temp);
 if(temp.length > 1){
 return false ;
 }
 }
 }
 return true;
}
function init(){
 //获取面板
 table = document.getElementById('pop_star');
 //创建二维数组
 for(var i = 0 ; i < boardWidth ; i++){
 squareSet[i] = new Array();
 for(var j = 0 ; j < boardWidth; j++){
 //创建小方块
 var square = createSquare(Math.floor(Math.random() * 5), i, j);
 //鼠标移动到该方块
 square.onmouseover = function(){
 mouseOver(this);
 }
 //点击小方块时的操作
 square.onclick = function(){
 //小方块在被点击的时候其他操作不能影响他的执行
 if(choose.length == 0 || !flag ){
 return ;
 }
 flag = false;
 tempSquare = null ;
 /*
 1.增加当前分数
 2.小方块消失
 3.向下或想做移动
 4.判断游戏是否结束
 */ 
 var socre = 0 ;
 //遍历choose
 for(var i = 0 ; i < choose.length ; i++){
 socre += baseScore + stepScore * i ;
 }
 totalScore += socre ;//总分数
 //改变样式
 document.getElementById('now_score').innerHTML = '当前分数:' + totalScore;
 //小方块消失
 /*
 1.从二维数组里面移除选择了的小方块
 2.在面板上移除div,不然div会一直占着格子
 * */
 for(var i = 0 ; i < choose.length ; i++){
 //立即函数,立即出发该函数,否则的话,不会执行
 (function(i){
 setTimeout(function(){
 //将二维数组的某一值设置为空,后面的会向前移
 squareSet[choose[i].row][choose[i].col] = null ;
 //移除div
 table.removeChild(choose[i]);
 },i * 100);
 })(i);
 }
 //移动
 setTimeout(function(){
 move();
 setTimeout(function(){
 var finished = isFinish();
 if(finished){
 if (totalScore >= targetScore) {
 alert('闯关成功');
 } else{
 alert('闯关失败');
 }
 }else{//还可以继续
 choose = [] ;
 flag = true;
 mouseOver(tempSquare);
 }
 } , 300 + choose.length * 150);
 },choose.length * 100);
 }
 //将小方块放进二维数组
 squareSet[i][j] = square;
 //将创建好的小方块插入到面板中
 table.appendChild(square);
 }
 }
 //显示小星星,刷新整个面板
 
 refresh();
}
//页面加载完成之后,初始化所有操作
window.onload = function(){
 init();
}

其实这里还有优化的就是闯关部分,大致的思路就是,游戏每过一关增加目标分数,当游戏结束时,闯关失败,目标分数恢复初始值。

大家有什么不懂,可以在评论区评论。

jq进阶版的源码详情见我github,网址

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
newxtree.js代码
Mar 13 Javascript
jQuery弹出层插件简化版代码下载
Oct 16 Javascript
HTML代码中标签的全部属性 中文注释说明
Mar 26 Javascript
JS中toFixed()方法引起的问题如何解决
Nov 20 Javascript
jQuery 中国省市两级联动选择附图
May 14 Javascript
javascript中bind函数的作用实例介绍
Sep 28 Javascript
JQuery动态添加和删除表格行的方法
Mar 09 Javascript
微信小程序 触控事件详细介绍
Oct 17 Javascript
node.js中实现kindEditor图片上传功能的方法教程
Apr 26 Javascript
详解React-Native解决键盘遮挡问题(Keyboard遮挡问题)
Jul 13 Javascript
vue中设置height:100%无效的问题及解决方法
Jul 27 Javascript
vue中使用protobuf的过程记录
Oct 26 Javascript
JavaScript实现移动端带transition动画的轮播效果
Mar 24 #Javascript
javascript实现滚动条效果
Mar 24 #Javascript
Webpack中SplitChunksPlugin 配置参数详解
Mar 24 #Javascript
JS实现点星星消除小游戏
Mar 24 #Javascript
js实现小星星游戏
Mar 23 #Javascript
JS Array.from()将伪数组转换成数组的方法示例
Mar 23 #Javascript
Vue+elementUI实现多图片上传与回显功能(含回显后继续上传或删除)
Mar 23 #Javascript
You might like
php+oracle 分页类
2006/10/09 PHP
PHP中的正规表达式(一)
2006/10/09 PHP
PHP 事务处理数据实现代码
2010/05/13 PHP
解析在PHP中使用mysqli扩展库对mysql的操作
2013/07/03 PHP
php url路由入门实例
2014/04/23 PHP
ThinkPHP3.1新特性之内容解析输出详解
2014/06/19 PHP
php+curl 发送图片处理代码分享
2015/07/09 PHP
jQuery提交表单ajax查询实例代码
2012/10/07 Javascript
javaScript让文本框内的最后一个文字的后面获得焦点实现代码
2013/01/06 Javascript
同时使用n个window onload加载实例介绍
2013/04/25 Javascript
Jquery在指定DIV加载HTML示例代码
2014/02/17 Javascript
javascript简单实现命名空间效果
2014/03/06 Javascript
jQuery中:image选择器用法实例
2015/01/03 Javascript
jQuery延迟加载图片插件Lazy Load使用指南
2015/03/25 Javascript
JavaScript与ActionScript3两者的同性与差异性
2016/09/22 Javascript
[原创]javascript typeof id==='string'?document.getElementById(id):id解释
2016/11/02 Javascript
angularjs中ng-attr的用法详解
2016/12/31 Javascript
详解jQuery中ajax.load()方法
2017/01/25 Javascript
JavaScript数据结构之二叉树的查找算法示例
2017/04/13 Javascript
js和jquery中获取非行间样式
2017/05/05 jQuery
nodejs multer实现文件上传与下载
2017/05/10 NodeJs
基于JavaScript实现表格滚动分页
2017/11/22 Javascript
使用vue2.6实现抖音【时间轮盘】屏保效果附源码
2019/04/24 Javascript
js实现简单分页导航栏效果
2019/06/28 Javascript
vue实现行列转换的一种方法
2019/08/06 Javascript
简单了解Vue + ElementUI后台管理模板
2020/04/07 Javascript
Vue自定义多选组件使用详解
2020/09/08 Javascript
[01:14]DOTA2 7.22版本新增神杖效果展示(智力英雄篇)
2019/05/29 DOTA
Python中http请求方法库汇总
2016/01/06 Python
python3实现从kafka获取数据,并解析为json格式,写入到mysql中
2019/12/23 Python
python集合删除多种方法详解
2020/02/10 Python
Python3利用openpyxl读写Excel文件的方法实例
2021/02/03 Python
亮剑精神演讲稿
2014/05/23 职场文书
幼儿园中班教师个人工作总结
2015/02/06 职场文书
通讯稿格式及范文
2015/07/22 职场文书
利用javaScript处理常用事件详解
2021/04/14 Javascript