HTML小游戏设计(1)- 人物拼图游戏

游戏介绍:拼图游戏将一幅图片分隔成若干拼块并且随机打乱,需要移动拼块,最后还原图形。

程序设计思路:HTML5可以把图片整合到网页中,使用canvas元素可以在这个空白的画布填充线条、载入图片和设置动画效果。游戏程序首先以正确顺序排列图片的缩略图,然后按照行列数将图片分成很多拼块,按照顺序编号;游戏开始时,打乱这个编号数组,玩家可以用鼠标点击拼块和空白块交换位置,当编号数组按照之前顺序,则游戏结束。

程序代码,注释在code中

(1)主界面

<!doctype html>
<html>
<head>
  <title>拼图小游戏</title>
  <style>
  .picture {
    border: 1px solid black;  /*盒子模型的边框就是围绕着内容及补白的线*/
  }
  </style>
</head>

<body>
  <div id="title">
    <h2>拼图小游戏</h2>
  </div>
  <div id="slider">
    <form>    <!--  <form> 标签用于为用户输入创建 HTML 表单。 表单能够包含 input 元素 -->
      <label>容易</label>
      <input type="range" id="scale" value="4" min="3" max="5" step="1">  <!-- 调节难度 -->
      <label>难</label>
    </form>
    <br>
  </div>

  <div id="main" class="main">
    <canvas id="puzzle" width="316px" height="316px"></canvas>
  </div>
  <script src="sliding.js"></script>

</body>
</html>

(2)JavaScript代码

var context = document.getElementById('puzzle').getContext('2d');

var img = new Image();
img.src = '1.jpg';
img.addEventListener('load', drawTiles, false);  //load事件侦听,完成图片加载才下一步

var boardSize = document.getElementById('puzzle').width;
var tileCount = document.getElementById('scale').value;  //获取难度的value

var tileSize = boardSize / tileCount;

var clickLoc = new Object;  //生成新对象,记录鼠标点击位置
clickLoc.x = 0;
clickLoc.y = 0;

var emptyLoc = new Object;  //保存空白拼图的位置
emptyLoc.x = 0;
emptyLoc.y = 0;

var solved = false;  //判断拼图是否完成

var boardParts = new Object;  //一维数组存储每个拼块的编号
setBoard();

// 滑块移动时触发的onchange事件,改变游戏难度
document.getElementById('scale').onchange = function() {
  tileCount = this.value;
  tileSize = boardSize / tileCount;  //每个拼块的大小
  setBoard();
  drawTiles();
};

// 计算鼠标单击前的位置所对应的网格坐标
document.getElementById('puzzle').onmousemove = function(e) {
  clickLoc.x = Math.floor((e.pageX - this.offsetLeft) / tileSize);  //e.pageX是鼠标的位置,e是event
  clickLoc.y = Math.floor((e.pageY - this.offsetTop) / tileSize);   //Math.floor向下取整
};                                                                  //offsetLeft是边缘位置

// 只有间距为1才可以移动拼块
document.getElementById('puzzle').onclick = function() {
  if (distance(clickLoc.x, clickLoc.y, emptyLoc.x, emptyLoc.y) == 1) {
    slideTile(emptyLoc, clickLoc);  //交换拼块的位置
    drawTiles();
  }
  if (solved) {
    setTimeout(function() {alert("good job!");}, 500);  //延时弹出成功了
  }
};

// 把图像划分为多个拼块, 第一个拼块boardParts[2][2]=(0,0)
function setBoard() {
  boardParts = new Array(tileCount);  //定义为数组,游戏为简单时-tileCount=3
  for (var i = 0; i < tileCount; ++i) {
    boardParts[i] = new Array(tileCount);  //定位为二维数组
    for (var j = 0; j < tileCount; ++j) {
      boardParts[i][j] = new Object;
      boardParts[i][j].x = (tileCount - 1) - i;
      boardParts[i][j].y = (tileCount - 1) - j;
    }
  }
  emptyLoc.x = boardParts[tileCount - 1][tileCount - 1].x;
  emptyLoc.y = boardParts[tileCount - 1][tileCount - 1].y;
  solved = false;
}

//在屏幕上显示拼块
function drawTiles() {
  context.clearRect ( 0 , 0 , boardSize , boardSize );  //在给定矩形内清空一个矩形:
  for (var i = 0; i < tileCount; ++i) {
    for (var j = 0; j < tileCount; ++j) {
      var x = boardParts[i][j].x;
      var y = boardParts[i][j].y;
      if(i != emptyLoc.x || j != emptyLoc.y || solved == true) {
        context.drawImage(img, x * tileSize, y * tileSize, tileSize, tileSize,
            i * tileSize, j * tileSize, tileSize, tileSize);  //图片对象、图片x,y坐标、图片宽高、目标x,y坐标
      }
    }
  }
}

function distance(x1, y1, x2, y2) {
  return Math.abs(x1 - x2) + Math.abs(y1 - y2);
}

function slideTile(toLoc, fromLoc) {
  if (!solved) {
    boardParts[toLoc.x][toLoc.y].x = boardParts[fromLoc.x][fromLoc.y].x;
    boardParts[toLoc.x][toLoc.y].y = boardParts[fromLoc.x][fromLoc.y].y;
    boardParts[fromLoc.x][fromLoc.y].x = tileCount - 1;     // 一直选择[2,2]作为空白拼块
    boardParts[fromLoc.x][fromLoc.y].y = tileCount - 1;
    toLoc.x = fromLoc.x;
    toLoc.y = fromLoc.y;
    checkSolved();
  }
}

function checkSolved() {
  var flag = true;
  for (var i = 0; i < tileCount; ++i) {
    for (var j = 0; j < tileCount; ++j) {
      if (boardParts[i][j].x != i || boardParts[i][j].y != j) {  //||表示or
        flag = false;
      }
    }
  }
  solved = flag;
}

效果演示:

   点击拼块移动     

其他难度演示:

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值