源代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="pingtu.css">
<title>Document</title>
</head>
<body>
<div id="container">
<h3>HTML5画布项目之4*4拼图游戏</h3>
<hr>
<div id="timeBox">
共计时间:<span id="time">00:00:00</span>
</div>
<canvas id="myCanvas" width="400" height="400" style="border: 1px solid">
对不起,您的浏览器不支持HTML5和画布支持API</canvas>
<div>
<button onclick="restartGame () ">
重新开始
</button>
</div>
<audio id="audio" src="music/单依纯-爱的回归线(Live).mp3" preload="">对不起,您的浏览器不支持HTML5音频播放</audio>
<!-- 音量调节进度条 -->
<div>
音量:<input id="volume" type="range" min="0" max="1" step="0.1" onchange="setVolume()">
</div>
<!-- 显示歌曲名称 -->
<div>当前正在播放:<span id="title">爱的回归线</span></div>
<!-- 音乐播放器按钮 -->
<div class="anniu">
<button onclick="lastMusic()"><img src="images/previous.png" alt="" width="50" height="50"></button>
<button id="toggleBtn" onclick="toggleMusic()"><img src="images/play.png" alt="" width="50"
height="50"></button>
<button onclick="nextMusic()"><img src="images/next.png" alt="" width="50" height="50"></button>
</div>
</div>
<script>
//获取画布对象
var c = document.getElementById('myCanvas');
//获取2D的context对象
var ctx = c.getContext('2d');
//定义拼图小方块的边长
var w = 100;
//定义初始方块位置
var num = [[0, 1, 2, 3], [10, 11, 12, 13], [20, 21, 22, 23], [30, 31, 32, 33]];
//声明拼图的图片素材来源
var img = new Image();
img.src = "images/qq01.jpg";
//当图片加载完毕时
img.onload = function () {
//打乱拼图的位置
generateNum();
// 在画布上绘制拼图
drawCanvas();
}
//打乱并圏的位置
function generateNum() {
for (var i = 0; i < 50; i++) {
var i1 = Math.round(Math.random() * 2);
var j1 = Math.round(Math.random() * 2);
var i2 = Math.round(Math.random() * 2);
var j2 = Math.round(Math.random() * 2);
var temp = num[i1][j1];
num[i1][j1] = num[i2][j2];
num[i2][j2] = temp;
}
}
//絵制并圏
function drawCanvas() {
//清空囲布
ctx.clearRect(0, 0, 400, 400);
//使用双重for循坏絵制3X3的并圏
for (var i = 0; i < 4; i++) {
for (var j = 0; j < 4; j++) {
if (num[i][j] != 33) {
var row = parseInt(num[i][j] / 10);
var col = num[i][j] % 10;
ctx.drawImage(img, col * w, row * w, w, w, j * w, i * w, w, w);
}
}
}
}
//监听鼠标单击事件
c.onmousedown = function (e) {
//获取画布边界
var bound = c.getBoundingClientRect();
//获取鼠标在画布上的坐标位置(x, y)
var x = e.pageX - bound.left;
var y = e.pageY - bound.top;
//将x和y换算成几行几列
var row = parseInt(y / 100);
var col = parseInt(x / 100);
//如果当前单击的不是空白区域
if (num[row][col] != 33) {
//移动单击的方块
detectBox(row, col);
//重新绘制画布
drawCanvas();
//检查游戏是否成功
var isWin = checkWin();
//如果游戏成功
if (isWin) {
// 清除计算器
clearInterval(timer);
//绘制完整图片
ctx.drawImage(img, 0, 0);
//设置字体为serif,加粗、68号字
ctx.font = "bold 68px serif";
ctx.fillStyle = "red";
ctx.fillText("游戏成功", 20, 150);
}
}
}
//移动单击的方块
function detectBox(i, j) {
//如果单击的方块不在最上面一行
if (i > 0) {
//检测空白区域是否在当前方块的正上方
if (num[i - 1][j] == 33) {
//交换空白区域与当前方块的位置
num[i - 1][j] = num[i][j];
num[i][j] = 33;
return;
}
}
//如果单击的方块不在最下面一行
if (i < 3) {//检测空白区域是否在当前方块的正下方
if (num[i + 1][j] == 33) {//交换空白区域与当前方块的位置
num[i + 1][j] = num[i][j];
num[i][j] = 33;
return;
}
}
//如果单击的方块不在最左边一列
if (j > 0) {
//检测空白区域是否在当前方块的左边
if (num[i][j - 1] == 33) {
//交换空白区域与当前方块的位置
num[i][j - 1] = num[i][j];
num[i][j] = 33;
return;
}
}
//如果单击的方块不在最右边一列
if (j < 3) {
//检测空白区域是否在当前方块的右边
if (num[i][j + 1] == 33) {
//交换空白区域与当前方块的位置
num[i][j + 1] = num[i][j];
num[i][j] = 33;
return;
}
}
}
//胜利的判断
function checkWin() {
//使用双重for循环遍历整个数组
for (var i = 0; i < 4; i++) {
for (var j = 0; j < 4; j++) {
// 如果有其中一块方块的位置不对
if (num[i][j] != i * 10 + j) {
//返回假
return false;
}
}
}
//返回真
return true;
}
var time = document.getElementById("time");
//初始化计时器的时、分、秒
var h = 0,
m = 0,
s = 0;
function getCurrentTime() {
//将时、分、秒转换为整数以便进行自增或赋值
s = parseInt(s);
m = parseInt(m);
h = parseInt(h);
//每秒变量s先自增1
s++;
if (s == 60) {
//如果秒已经达到60,则归
s = 0;
//分钟自增1
m++;
}
if (m == 60) {
//如果分钟也达到60,则归。
m = 0;
// 小时自增1
h++;
}
//修改时、分、秒的显示效果,使其保持两位数
if (s < 10)
s = "0" + s;
if (m < 10)
m = "0" + m;
if (h < 10)
h = "0" + h;
//将当前计时的时间显示在页面上
time.innerHTML = h + ":" + m + ":" + s;
}
//重新开始游戏
function restartGame() {
//清除计时器
clearInterval(timer);
//时间清零
s = 0;
m = 0;
h = 0;
//重新显示时间
getCurrentTime();
timer = setInterval("getCurrentTime ()", 1000);
//重新打乱拼图顺序
generateNum();
//绘制拼图
drawCanvas();
}
//每隔1000毫秒(1秒)刷新一次时间
var timer = setInterval("getCurrentTime() ", 1000);
// 音乐播放
var music = document.getElementById("audio");
var volume = document.getElementById("volume");
var toggleBtn = document.getElementById("toggleBtn");
var list = new Array("music/单依纯-爱的回归线(Live).mp3", "music/EndlessHorizon.mp3", "music/月光下的云海.mp3");
var titleList = new Array("爱的回归线", "无尽的地平线", "月光下的云海");
var i = 0;
function setVolume() {
music.volume = volume.value;
}
function toggleMusic() {
if (music.paused) {
music.play();
toggleBtn.innerHTML = '<img src="images/pause.png" width="50" height="50"/>';
} else {
music.pause();
toggleBtn.innerHTML = '<img src="images/play.png" width="50" height="50"/>';
}
}
// 切换下一首歌曲
function nextMusic() {
if (i == list.length - 1)
i = 0;
else
i++;
music.pause();
music.src = list[i];
title.innerHTML = titleList[i];
music.play();
}
// 切换上一首歌曲
function lastMusic() {
if (i == 0)
i = list.length - 1;
else
i--;
music.pause();
music.src = list[i];
title.innerHTML = titleList[i];
music.play();
}
</script>
</body>
</html>
css样式
body {
background-color: silver;
}
#container {
text-align: center;
margin: auto; padding: 0; background-color: white;
width: 600px; padding: 20px;
box-shadow: 10px 10px 15px black;
}
#timeBox {
margin: 10px 0; font-size: 18px;
}
button {
width: 200px; height: 50px;
margin: 10px 0;
border: 0; font-size: 25px; font-weight: bold;
color: white; outline: none;
background-color: lightcoral;
}
button:hover {
background-color: coral;
}
.anniu button{
width: 80px;
text-align: center;
margin: 10px;
background: transparent;
border: 0;
outline: 0;
}
#remove01{
margin: 10px auto;
}
运行结果图
原图