首先看一下html的布局方式在index.html文件中:
首页 web前端 js教程 原生JavaScript实现连连看游戏(附源码)_javascript技巧

原生JavaScript实现连连看游戏(附源码)_javascript技巧

May 16, 2016 pm 05:17 PM
原生js

向大家推荐一款原生JavaScript版连连看游戏,源码下载,首页如下图所示:
原生JavaScript实现连连看游戏(附源码)_javascript技巧 
首先看一下html的布局方式在index.html文件中:

复制代码 代码如下:





连连看











分 数


0


时 间


0













css文件夹下的index.css文件如下:
复制代码 代码如下:

body {
font-size : 16px;
font-weight : bold;
color : grey;
}
#whole {
border : 1px double #999999;
border-width : 5px;
width : 800px;
height : 505px;
position : relative;
}
#gamePanel {
margin: 1px 1px 1px 1px;
width : 602px;
height : 502px;
background : url(../img/background.gif) repeat;
position : absolute;
}
#pieces {
margin-top : 35px;
border : 1px solid #999999;
width : 546px;
height : 434px;
position: relative;
}
#pieces .piece {
width : 32px;
height : 36px;
position : relative;
cursor : pointer;
float : left;
}
#pieces .track {
width : 32px;
height : 36px;
position : relative;
float : left;
}
#pieces .track2 {
width : 32px;
height : 36px;
position : relative;
float : left;
background : red;
}
#gameLogo {
margin-top : 60px;
border : 1px solid #999999;
left : 607px;
width : 187px;
height : 73px;
background : url(../img/logo.gif);
position: absolute;
}
#scorePanel {
border : 1px solid #999999;
left : 607px;
top : 200px;
width : 187px;
height : 30px;
position : absolute;
}
#score {
border : 1px solid #999999;
left : 607px;
top : 240px;
width : 187px;
height : 30px;
position : absolute;
}
#timePanel {
border : 1px solid #999999;
left : 607px;
top : 300px;
width : 187px;
height : 30px;
position : absolute;
}
#time {
border : 1px solid #999999;
left : 607px;
top : 340px;
width : 187px;
height : 30px;
position : absolute;
}
#button {
border : 1px solid #999999;
left : 607px;
top : 400px;
width : 187px;
height : 30px;
position : absolute;
}

下面让我们来看一下最核心的js部分实现代码,js部分分为三个源文件即game.js、map.js、piece.js每一个源文件对应一个类,其中本游戏通过game类来操纵map和图片piece对象:
game.js代码如下:
复制代码 代码如下:

// 游戏控制类
var Game = {
// 游戏背景
gamePanel : null,
// 分数
score : 0,
// 时间
time : 0,
// 图片映射表
pieceMap : null,
// 图片列表
pieceList : [],
// 图片列表不包含图片
pieceImgList : [],
// 图片随机数列表
randomList : [],
// 轨迹列表
trackList : [],
// 游戏是否开始
isGameBigin : false,
// 游戏是否结束
isGameOver : false,
// 游戏是否重置
isGameReset : false,
// 图片元素是否第一次点击
isFirstClick : true,
// 开始游戏
start : function() {
document.getElementById("start").disabled = true;
document.getElementById("reset").disabled = false;
if (this.isGameReset) {
this.isGameOver = false;
this.startTime();
return;
} else if (this.isGameBegin) {
return;
} else {
this.init();
return;
}
},
reset : function() {
document.getElementById("start").disabled = false;
document.getElementById("reset").disabled = true;
this.clear();
this.initPieces();
this.initImgPieces();
this.time = 0;
document.getElementById("time").innerHTML = 0;
this.score = 0;
document.getElementById("score").innerHTML = 0;
this.isGameReset = true;
this.isGameBegin = true;
},
// 初始化
init : function() {
if (this.isGameBegin) {
return;
}
this.pieceMap = new Map();
var _this = this;
this.time = 0;
this.startTime();
this.gamePanel = document.getElementById("pieces");
this.initPieces();
this.initImgPieces();
this.isGameBegin = true;
},
// 将随机生成的150张图片添加进画布
initPieces : function() {
var _this = this;
this.initRandomList();
// 打乱随机列表排序
this.messRandomList();
for (var i = 0; i var piece = new Piece(this);
this.pieceList.push(piece);
var x = (i%17);
var y = Math.floor(i/17);
this.pieceMap.put(x+","+y, piece);
piece.setPosition(x, y);
this.gamePanel.appendChild(piece.dom);
if (x == 0 || x == 16 || y == 0 || y == 11) {
piece.track = document.createElement("div");
piece.track.className = "track";
piece.dom.appendChild(piece.track);
piece.isTracked = true;
continue;
} else {
if (x == 1 || x == 15 || y == 1 || y == 10) {
piece.setAtEdge(true);
}
this.pieceImgList.push(piece);
}
}
},
// 初始化图片
initImgPieces : function() {
for (var i = 0; i this.pieceImgList[i].initImg();
this.pieceImgList[i].img.src = "img/pieces/"+this.randomList[i]+".gif"
this.pieceImgList[i].setImgSrc(this.pieceImgList[i].img.src);
// 执行图片点击事件
this.pieceImgList[i].onClick();
}
},
// 初始化随机表
initRandomList : function() {
// 获取随机数列,成双出现
for (var i = 0; i var random = parseInt(Math.random()*22*10000, 10);
var number = random%23;
this.randomList.push(number);
this.randomList.push(number);
}
},
// 打乱随机表
messRandomList : function() {
for (var i = 0; i var random = parseInt(Math.random()*15*10000, 10);
var number = random%150;
var temp;
temp = this.randomList[i];
this.randomList[i] = this.randomList[number];
this.randomList[number] = temp;
}
},
// 开始计时
startTime : function() {
var _this = this;
if (this.isGameOver) {
return;
} else {
this.time ++;
document.getElementById("time").innerHTML = this.time;
this.isGameBegin = true;
setTimeout(function() {_this.startTime();}, 1000);
}
},
// 清除
clear : function() {
for (var i = 0; i this.gamePanel.removeChild(this.pieceList[i].dom);
}
this.pieceList = [];
this.randomList = [];
this.pieceImgList = [];
this.isGameOver = true;
this.isGameBegin = false;
}
}
window.onload = function() {
document.getElementById("start").disabled = false;
document.getElementById("reset").disabled = true;
}
// 游戏开始入口
function Start() {
Game.start();
}
// 游戏重置入口
function Reset() {
Game.reset();
}

自定义的js版映射结构map.js源文件如下:
复制代码 代码如下:

var Map = function(){
this.data = [];
}
Map.prototype = {
put : function(key, value) {
this.data[key] = value;
},
get : function(key) {
return this.data[key];
},
remove : function(key) {
this.data[key] = null;
},
isEmpty : function() {
return this.data.length == 0;
},
size : function() {
return this.data.length;
}
}

图片类piece.js源文件如下:
复制代码 代码如下:

var Piece = function(game) {
// 游戏对象
this.game = game;
// 是否为边缘元素
this.isEdge = false;
// 是否挨着边缘元素
this.atEdge = false;
// 图片dom元素
this.dom = null;
// 图片元素
this.img = null;
// 图片元素来源
this.src = null;
// 轨迹元素
this.track = null;
// 是否可以作为轨迹
this.isTracked = false;
// 选中标记元素
this.selected = null;
// 图片横向排列
this.x = 0;
// 图片纵向排列
this.y = 0;
// 图片闪烁Id
this.flashId = null;
// 图片是否点击
this.onClicked = false;
// 闪烁次数
this.flashCount = 0;
this.init();
}
Piece.prototype = {
// 初始化
init : function() {
this.dom = document.createElement("div");
this.dom.className = "piece";
this.selected = document.createElement("img");
},
// 初始化图片
initImg : function() {
this.img = document.createElement("img");
this.dom.appendChild(this.img);
},
// 满足算法后初始化track元素
initTrack : function() {
if (this.flashId != null) {
// 停止闪烁
this.stopFlash();
}
//alert("initTrack middle");
if (this.track != null) {
return;
}
this.onClicked = false;
this.dom.removeChild(this.img);
this.track = document.createElement("div");
this.track.className = "track";
this.dom.appendChild(this.track);
},
// 位图片设置来源
setImgSrc : function(src) {
this.src = src;
},
// 为图片设置二维排列位置
setPosition : function(x, y) {
this.x = x;
this.y = y;
},
// 为图片设置选中元素
setSelected : function() {
if (this.flashCount ++ % 2 == 0) {
//this.dom.removeChild(this.img);
//this.selected.src = "img/selected.gif";
//this.dom.appendChild(this.selected);
this.img.src = "img/pieces/flash.gif";
} else {
//if (this.selected != null) {
// this.dom.removeChild(this.selected);
//}
this.img.src = this.src;
//this.dom.appendChild(this.img);
}
},
// 设置是否为边缘元素
setEdge : function(isEdge) {
this.isEdge = isEdge;
},
// 设置是否挨着边缘元素
setAtEdge : function(atEdge) {
this.atEdge = atEdge;
},
// 开始闪烁
flash : function() {
var _this = this;
this.flashId = setInterval(function() {_this.setSelected();}, 500);
},
// 停止闪烁
stopFlash : function() {
clearInterval(this.flashId);
if (this.flashCount % 2 == 1) {
//if (this.selected != null) {
// this.dom.removeChild(this.selected);
//}
this.img.src = this.src;
//this.dom.appendChild(this.img);
}
},
// 对象被选择的内部函数
onClick : function() {
if (this.onClicked) {
return;
}
var _this = this;
this.img.onclick = function() {
if (!document.getElementById("start").disabled) {
return;
}
if (_this.onClicked) {
return;
}
if (_this.checkPiece()) {
return;
}
_this.flash();
_this.onClicked = true;
};
},
// 检查是否有被点击的图片
checkPiece : function() {
for (var i = 0; i if (this.game.pieceList[i].onClicked && !this.game.pieceList[i].equal(this)) {
if (this.game.pieceList[i].equalImage(this)) {
//alert("The same Image");
this.searchTrack(this.game.pieceList[i]);
} else {
this.game.pieceList[i].stopFlash();
this.game.pieceList[i].onClicked = false;
this.onClicked = false;
return false;
}
return true;
} else {
continue;
}
}
return false;
},
// 是否为同一个对象
equal : function(piece) {
return (this.x == piece.x && this.y == piece.y);
},
// 是否为同一个图片
equalImage : function(piece) {
return this.src == piece.src;
},
// 搜寻路径
searchTrack : function(piece) {
if (this.isNear(piece)) {
this.linkTrack(piece);
return;
}
if (this.isReach(piece) || this.isReach2(piece)) {
this.linkTrack(piece);
return;
}
},
// 是否相邻
isNear : function(piece) {
var a = (Math.abs(piece.x - this.x) == 1) && (piece.y == this.y)
|| (Math.abs(piece.y - this.y) == 1) && (piece.x == this.x);
return a;
},
// 直线
isStraightReach : function(piece) {
//alert("isStraightReach");
if (this.isNear(piece)) {
return true;
}
var a = false;
var b = false;
// 沿y轴方向搜索
if (this.x == piece.x) {
//alert("!!!!!!!!!!!");
for (var i = this.min(this.y, piece.y) + 1; i //alert("this.x == piece.x: " + piece.x + "," + i);
if (this.game.pieceMap.get(piece.x + "," + i).isPass()) {
a = true;
this.game.trackList.push(this.game.pieceMap.get(piece.x + "," + i));
continue;
} else {
a = false;
this.game.trackList = [];
return a;
}
}
}
// 沿x轴方向搜索
if (this.y == piece.y) {
//alert("!!!!!!!!!!!");
for (var i = this.min(this.x, piece.x) + 1; i //alert("this.y == piece.y: " + i + "," + piece.y);
if (this.game.pieceMap.get(i + "," + piece.y).isPass()) {
b = true;
this.game.trackList.push(this.game.pieceMap.get(i + "," + piece.y));
continue;
} else {
b = false
this.game.trackList = [];
return b;
}
}
}
return a || b;
},
// 拐一次弯搜索
isReach1 : function(piece) {
//alert("isReach1");
var corner_1 = this.game.pieceMap.get(this.x + "," + piece.y);
var corner_2 = this.game.pieceMap.get(piece.x + "," + this.y);
var _this = this;
if ((_this.isStraightReach(corner_1))
&& (corner_1.isStraightReach(piece))
&& corner_1.isPass()) {
//alert("corner_1: " + this.x + "," + piece.y);
this.game.trackList.push(corner_1);
return true;
}
if ((_this.isStraightReach(corner_2))
&& (corner_2.isStraightReach(piece))
&& corner_2.isPass()) {
//alert("corner_2: " + piece.x + "," + this.y);
this.game.trackList.push(corner_2);
return true;
}
return false;
},
// 直接或拐一次弯搜索
isReach : function(piece) {
var a = this.isStraightReach(piece);
var b = this.isReach1(piece);
return a || b;
},
// 拐两次弯搜索
isReach2 : function(piece) {
// 沿x轴正向搜索
for (var i = this.x + 1; i if (!this.game.pieceMap.get(i + "," + this.y).isPass()) {
this.game.trackList = [];
break;
} else if (this.game.pieceMap.get(i + "," + this.y).isReach(piece)
&& this.game.pieceMap.get(i + "," + this.y).isPass()) {
this.game.trackList.push(this.game.pieceMap.get(i + "," + this.y));
return true;
}
}
// 沿x轴搜索
for (var i = this.x - 1; i >= 0; i --) {
if (!this.game.pieceMap.get(i + "," + this.y).isPass()) {
this.game.trackList = [];
break;
} else if (this.game.pieceMap.get(i + "," + this.y).isReach(piece)
&& this.game.pieceMap.get(i + "," + this.y).isPass()) {
this.game.trackList.push(this.game.pieceMap.get(i + "," + this.y));
return true;
}
}
// 沿y轴搜索
for (var i = this.y - 1; i >= 0; i --) {
if (!this.game.pieceMap.get(this.x + "," + i).isPass()) {
this.game.trackList = [];
break;
} else if (this.game.pieceMap.get(this.x + "," + i).isReach(piece)
&& this.game.pieceMap.get(this.x + "," + i).isPass()) {
this.game.trackList.push(this.game.pieceMap.get(this.x + "," + i));
return true;
}
}
// 沿y轴正向搜索
for (var i = this.y + 1; i if (!this.game.pieceMap.get(this.x + "," + i).isPass()) {
this.game.trackList = [];
break;
} else if (this.game.pieceMap.get(this.x + "," + i).isReach(piece)
&& this.game.pieceMap.get(this.x + "," + i).isPass()) {
this.game.trackList.push(this.game.pieceMap.get(this.x + "," + i));
return true;
}
}
return false;
},
// 路径连接
linkTrack : function(piece) {
this.initTrack();
piece.initTrack();
this.changeScore();
this.showTrack(piece);
},
// 显示足迹
showTrack : function(piece) {
this.game.trackList.push(piece);
this.track.className = "track2";
for (var i = 0; i //alert(i);
this.game.trackList[i].track.className = "track2";
}
var _this = this;
setTimeout(function() {_this.hideTrack()}, 500);
},
// 隐匿足迹
hideTrack : function() {
for (var i = 0; i this.game.trackList[i].track.className = "track";
}
this.game.trackList = [];
this.track.className = "track";
this.isTracked = true;
},
// 分数增加
changeScore : function() {
this.game.score += 100;
document.getElementById("score").innerHTML = this.game.score;
},
min : function(a, b) {
if (a return a;
} else {
return b;
}
},
max : function(a, b) {
if (a > b) {
return a;
} else {
return b;
}
},
// 判断是否通过
isPass : function() {
return this.track != null;
}
}

以上是源文件的代码,具体的实现代码请关注CSDN中zhangjinpeng66下载。下面讲一下连连看游戏最核心的部分,js实现搜索路径。
js实现搜索路径算法首先最简单的是判断两个图片能否直线到达函数代码如下:
复制代码 代码如下:

// 直线
isStraightReach : function(piece) {
//alert("isStraightReach");
if (this.isNear(piece)) {
return true;
}
var a = false;
var b = false;
// 沿y轴方向搜索
if (this.x == piece.x) {
//alert("!!!!!!!!!!!");
for (var i = this.min(this.y, piece.y) + 1; i //alert("this.x == piece.x: " + piece.x + "," + i);
if (this.game.pieceMap.get(piece.x + "," + i).isPass()) {
a = true;
this.game.trackList.push(this.game.pieceMap.get(piece.x + "," + i));
continue;
} else {
a = false;
this.game.trackList = [];
return a;
}
}
}
// 沿x轴方向搜索
if (this.y == piece.y) {
//alert("!!!!!!!!!!!");
for (var i = this.min(this.x, piece.x) + 1; i //alert("this.y == piece.y: " + i + "," + piece.y);
if (this.game.pieceMap.get(i + "," + piece.y).isPass()) {
b = true;
this.game.trackList.push(this.game.pieceMap.get(i + "," + piece.y));
continue;
} else {
b = false
this.game.trackList = [];
return b;
}
}
}
return a || b;
},

该函数实现了连连看判断两图片是否符合连接条件的最简单的一步,然后是拐一次弯搜索。
复制代码 代码如下:

// 拐一次弯搜索
isReach1 : function(piece) {
//alert("isReach1");
var corner_1 = this.game.pieceMap.get(this.x + "," + piece.y);
var corner_2 = this.game.pieceMap.get(piece.x + "," + this.y);
var _this = this;
if ((_this.isStraightReach(corner_1))
&& (corner_1.isStraightReach(piece))
&& corner_1.isPass()) {
//alert("corner_1: " + this.x + "," + piece.y);
this.game.trackList.push(corner_1);
return true;
}
if ((_this.isStraightReach(corner_2))
&& (corner_2.isStraightReach(piece))
&& corner_2.isPass()) {
//alert("corner_2: " + piece.x + "," + this.y);
this.game.trackList.push(corner_2);
return true;
}
return false;
},

在拐一次弯搜索的函数中调用了直接搜索的函数,同样最复杂的拐两次弯搜索也会调用拐一次弯搜索的函数。
复制代码 代码如下:

// 拐两次弯搜索
isReach2 : function(piece) {
// 沿x轴正向搜索
for (var i = this.x + 1; i if (!this.game.pieceMap.get(i + "," + this.y).isPass()) {
this.game.trackList = [];
break;
} else if (this.game.pieceMap.get(i + "," + this.y).isReach(piece)
&& this.game.pieceMap.get(i + "," + this.y).isPass()) {
this.game.trackList.push(this.game.pieceMap.get(i + "," + this.y));
return true;
}
}
// 沿x轴搜索
for (var i = this.x - 1; i >= 0; i --) {
if (!this.game.pieceMap.get(i + "," + this.y).isPass()) {
this.game.trackList = [];
break;
} else if (this.game.pieceMap.get(i + "," + this.y).isReach(piece)
&& this.game.pieceMap.get(i + "," + this.y).isPass()) {
this.game.trackList.push(this.game.pieceMap.get(i + "," + this.y));
return true;
}
}
// 沿y轴搜索
for (var i = this.y - 1; i >= 0; i --) {
if (!this.game.pieceMap.get(this.x + "," + i).isPass()) {
this.game.trackList = [];
break;
} else if (this.game.pieceMap.get(this.x + "," + i).isReach(piece)
&& this.game.pieceMap.get(this.x + "," + i).isPass()) {
this.game.trackList.push(this.game.pieceMap.get(this.x + "," + i));
return true;
}
}
// 沿y轴正向搜索
for (var i = this.y + 1; i if (!this.game.pieceMap.get(this.x + "," + i).isPass()) {
this.game.trackList = [];
break;
} else if (this.game.pieceMap.get(this.x + "," + i).isReach(piece)
&& this.game.pieceMap.get(this.x + "," + i).isPass()) {
this.game.trackList.push(this.game.pieceMap.get(this.x + "," + i));
return true;
}
}
return false;
},

该函数以点击的图片为中心分别沿x轴,y轴展开搜索。
以上是本游戏代码的全部内容。具体游戏源码请到CSDN中zhangjinpeng66的资源里下载。
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

Video Face Swap

Video Face Swap

使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

前端热敏纸小票打印遇到乱码问题怎么办? 前端热敏纸小票打印遇到乱码问题怎么办? Apr 04, 2025 pm 02:42 PM

前端热敏纸小票打印的常见问题与解决方案在前端开发中,小票打印是一个常见的需求。然而,很多开发者在实...

谁得到更多的Python或JavaScript? 谁得到更多的Python或JavaScript? Apr 04, 2025 am 12:09 AM

Python和JavaScript开发者的薪资没有绝对的高低,具体取决于技能和行业需求。1.Python在数据科学和机器学习领域可能薪资更高。2.JavaScript在前端和全栈开发中需求大,薪资也可观。3.影响因素包括经验、地理位置、公司规模和特定技能。

神秘的JavaScript:它的作用以及为什么重要 神秘的JavaScript:它的作用以及为什么重要 Apr 09, 2025 am 12:07 AM

JavaScript是现代Web开发的基石,它的主要功能包括事件驱动编程、动态内容生成和异步编程。1)事件驱动编程允许网页根据用户操作动态变化。2)动态内容生成使得页面内容可以根据条件调整。3)异步编程确保用户界面不被阻塞。JavaScript广泛应用于网页交互、单页面应用和服务器端开发,极大地提升了用户体验和跨平台开发的灵活性。

如何使用JavaScript将具有相同ID的数组元素合并到一个对象中? 如何使用JavaScript将具有相同ID的数组元素合并到一个对象中? Apr 04, 2025 pm 05:09 PM

如何在JavaScript中将具有相同ID的数组元素合并到一个对象中?在处理数据时,我们常常会遇到需要将具有相同ID�...

如何实现视差滚动和元素动画效果,像资生堂官网那样?
或者:
怎样才能像资生堂官网一样,实现页面滚动伴随的动画效果? 如何实现视差滚动和元素动画效果,像资生堂官网那样? 或者: 怎样才能像资生堂官网一样,实现页面滚动伴随的动画效果? Apr 04, 2025 pm 05:36 PM

实现视差滚动和元素动画效果的探讨本文将探讨如何实现类似资生堂官网(https://www.shiseido.co.jp/sb/wonderland/)中�...

console.log输出结果差异:两次调用为何不同? console.log输出结果差异:两次调用为何不同? Apr 04, 2025 pm 05:12 PM

深入探讨console.log输出差异的根源本文将分析一段代码中console.log函数输出结果的差异,并解释其背后的原因。�...

JavaScript难以学习吗? JavaScript难以学习吗? Apr 03, 2025 am 12:20 AM

学习JavaScript不难,但有挑战。1)理解基础概念如变量、数据类型、函数等。2)掌握异步编程,通过事件循环实现。3)使用DOM操作和Promise处理异步请求。4)避免常见错误,使用调试技巧。5)优化性能,遵循最佳实践。

PowerPoint可以运行JavaScript吗? PowerPoint可以运行JavaScript吗? Apr 01, 2025 pm 05:17 PM

在PowerPoint中可以运行JavaScript,通过VBA调用外部JavaScript文件或嵌入HTML文件来实现。1.使用VBA调用JavaScript文件,需启用宏并具备VBA编程知识。2.嵌入包含JavaScript的HTML文件,简单易行但受安全限制。优点包括扩展功能和灵活性,劣势涉及安全性、兼容性和复杂性,实际应用需注意安全性、兼容性、性能和用户体验。

See all articles