推箱子
源码链接地址:https://github.com/shunyue1320/sokoban.git
推箱子小游戏展示效果图:
源码链接地址:https://github.com/shunyue1320/sokoban.git
进入后执行如下图步骤就能下载到自己电脑上啦!
接下来了解一下我们用到的素材吧:
目标点 / 草坪 / 箱子 / 人物 / 障碍物
html样式就这么简单 通过canvas绘制游戏地图:
<body onkeydown="doKeyDown(event)"><!--身体-->
<div class="game">
<canvas id="canvas" width="560" height="560"></canvas>
<div id="msg"></div>
<input type="button" value="上一关" onclick="NextLevel(-1)">
<input type="button" value="下一关" onclick="NextLevel(1)">
<input type="button" value="重玩本关" onclick="NextLevel(0)">
<input type="button" value="游戏说明" onclick="showHelp()">
</div>
</body>
游戏关卡我们使用 mapdata100.js封存!
//1:围墙 2:目标点 3:箱子 4:人物
var levels=[];
levels[0]=[
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0],
[0,0,0,0,0,0,1,2,1,0,0,0,0,0,0,0],
[0,0,0,0,0,0,1,0,1,1,1,1,0,0,0,0],
[0,0,0,0,1,1,1,3,0,3,2,1,0,0,0,0],
[0,0,0,0,1,2,0,3,4,1,1,1,0,0,0,0],
[0,0,0,0,1,1,1,1,3,1,0,0,0,0,0,0],
[0,0,0,0,0,0,0,1,2,1,0,0,0,0,0,0],
[0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]];
通过关卡的坐标值我们选择对应的图片填入canvas画布:
//绘制每个游戏关卡地图
function DrawMap(level){
for (var i=0;i<level.length ;i++ )
{
for (var j=0;j<level[i].length ;j++ )
{
var pic = block;//初始图片
switch (level[i][j])
{
case 1://绘制墙壁
pic = wall;
break;
case 2://绘制陷进
pic = ball;
break;
case 3://绘制箱子
pic = box;
break;
case 4://绘制小人
pic = curMan;//小人有四个方向 具体显示哪个图片需要和上下左右方位值关联
//获取小人的坐标位置
perPosition.x = i;
perPosition.y = j;
break;
case 5://绘制箱子及陷进位置
pic = box;
break;
}
//每个图片不一样宽 需要在对应地板的中心绘制地图
cxt.drawImage(pic,w*j-(pic.width-w)/2,h*i-(pic.height-h),pic.width,pic.height)
}
}
}
通过判断人物移动的方向是否是障碍物来判断人物的行走:
//小人移动
function go(dir){
var p1,p2;
switch (dir)
{
case "up":
curMan = up;
//获取小人前面的两个坐标位置来进行判断小人是否能够移动
p1 = new Point(perPosition.x-1,perPosition.y);
p2 = new Point(perPosition.x-2,perPosition.y);
break;
case "down":
curMan = down;
p1 = new Point(perPosition.x+1,perPosition.y);
p2 = new Point(perPosition.x+2,perPosition.y);
break;
case "left":
curMan = left;
p1 = new Point(perPosition.x,perPosition.y-1);
p2 = new Point(perPosition.x,perPosition.y-2);
break;
case "right":
curMan = right;
p1 = new Point(perPosition.x,perPosition.y+1);
p2 = new Point(perPosition.x,perPosition.y+2);
break;
}
//若果小人能够移动的话,更新游戏数据,并重绘地图
if (Trygo(p1,p2))
{
moveTimes ++;
showMoveInfo();
}
//重绘地板
InitMap();
//重绘当前更新了数据的地图
DrawMap(curMap);
//若果移动完成了进入下一关
if (checkFinish())
{
//定时器解决渲染地图后再弹窗
setTimeout(()=>{
alert("恭喜过关!!");
NextLevel(1);
},0)
}
}
移动人物的键盘控件包括w a s d 与 鼠标 上下左右键:
//与键盘上的上下左右键关联
function doKeyDown(event){
switch (event.keyCode)
{
case 37://左键头
case 65:
go("left");
break;
case 38://上键头
case 87:
go("up");
break;
case 39://右箭头
case 68:
go("right");
break;
case 40://下箭头
case 83:
go("down");
break;
}