<!DOCTYPE html>
<html>
<head>
<title>Sokaban</title>
<meta charset="utf-8">
<style type="text/css">
.roads {
width: 50px;
height: 50px;
background: url(img/roods.png);
background-size: 100% 100%;
}
.people {
width: 50px;
height: 50px;
background-size: 100% 100%;
}
.box {
background: url(img/box.png) !important;
background-size: 100% 100%;
}
.finish {
background: url(img/finish.png);
background-size: 100% 100%;
}
.walls {
background: url(img/walls.png);
background-size: 100% 100%;
}
</style>
</head>
<body>
</body>
</html>
<script type="text/javascript" src='js/jquery-3.1.0.js'></script>
<script type="text/javascript">
sokaban({
"num": 20,
'people': 'people', //人物样式
'box': 'box', //盒子样式
'walls': 'walls', //墙壁样式
'finish': 'finish', //结束样式
'roads': 'roads' //路的样式
})
function sokaban(obj) {
var num = obj.num + 2, //地图大小
people = obj.people, //人物样式
box = obj.box, //盒子样式
walls = obj.walls, //墙壁样式
finish = obj.finish, //结束样式
roads = obj.roads,
$arry = [],
$walls = []; //路的样式
//创建地图
$('body').append('<div id=\"box\"></div>');
$('#box').css({
'position': 'absolute',
'top': '50px',
'left': '50px',
'width': (50 * num) + 'px',
'height': (50 * num) + 'px'
});
//循环出路
for (var m = 0; m < num; m++) {
var top_now = m * 50;
for (n = 0; n < num; n++) {
var left_now = n * 50;
$('#box').append('<div class=\'' + roads + ' check\'></div>');
$('.' + roads).last().css({
'position': 'absolute',
'top': (top_now) + 'px',
'left': (left_now) + 'px'
});
}
}
//循环出外墙
for (var k = 1; k <= num * num; k++) {
if (k <= num - 1 || k > num * (num - 1)) {
$('.check').eq(k - 1).addClass(walls);
$walls.push(k - 1);
} else if (k % num == 0 || k % num == 1) {
$('.check').eq(k - 1).addClass(walls);
$walls.push(k - 1);
}
}
//添加按钮
$('<button id=\'addwalls\'>添加墙</button>').appendTo(document.body);
$('<button id=\'remove\'>删除</button>').appendTo(document.body);
$('<button id=\'addpeople\'>添加人</button>').appendTo(document.body);
$('<button id=\'addend\'>添加结束</button>').appendTo(document.body);
$('<button id=\'addbox\'>添加箱子</button>').appendTo(document.body);
$('<button id=\'gogo\'>GO!</button>').appendTo(document.body);
//为按钮绑定事件
$('#remove').click(function() {
$('.check').unbind('click');
$('.check').bind('click', function() {
var flag = 1;
for (var i = 0; i < $walls.length; i++) {
if ($(this).index() == $walls[i]) {
flag = 0;
}
}
if (flag) {
$(this).attr('class', '');
$(this).addClass(roads);
$(this).addClass('check');
}
})
});
//添加开始
$('#gogo').click(function() {
gogogo();
});
//添加墙
$('#addwalls').click(function() {
$('.check').unbind('click');
$('.check').bind('click', function() {
if ($(this).hasClass(box) || $(this).hasClass(finish) || $(this).hasClass(people)) {
return;
}
$(this).addClass(walls);
});
});
//添加人
$('#addpeople').click(function() {
$('.check').unbind('click');
$('.check').bind('click', function() {
if ($('.' + people).length > 0) {
return;
}
if ($(this).hasClass(box) || $(this).hasClass(finish) || $(this).hasClass(walls)) {
return;
}
$(this).addClass(people);
$('<img src=\'img/pig.png\'>').appendTo($(this));
});
});
//添加终点
$('#addend').click(function() {
$('.check').unbind('click');
$('.check').bind('click', function() {
if ($('.' + finish).length > 5) {
alert('不可以大于6!');
return;
}
if ($(this).hasClass(box) || $(this).hasClass(people) || $(this).hasClass(walls)) {
return;
}
$(this).addClass(finish);
});
});
//添加
$('#addbox').click(function() {
$('.check').unbind('click');
$('.check').bind('click', function() {
if ($('.' + box).length > 5) {
alert('不可以大于6!');
return;
}
if ($(this).hasClass(finish) || $(this).hasClass(people) || $(this).hasClass(walls)) {
return;
}
$(this).addClass(box);
});
});
function gogogo() {
if ($('.' + people).length == 0) {
alert('必须有人!');
return;
}
if ($('.' + box).length < 1) {
alert('必须有箱子!');
return;
}
if ($('.' + box).length != $('.' + finish).length) {
alert('箱子和终点个数必须统一');
return;
}
$('.check').unbind('click');
$('#remove').unbind('click');
$('#addwalls').unbind('click');
$('#addend').unbind('click');
$('#addbox').unbind('click');
$('#gogo').unbind('click');
$(window).keydown(function(event) { //当鼠标按下时,传入事件对象~
switch (event.keyCode) { //获取键值码
case 37: //如果键值码为37,代表着我的键盘上的左键
move(-1, 90)
break; //跳出swich
case 38:
move(-num, 180)
break; //跳出swich
case 39:
move(1, -90)
break; //跳出swich
case 40:
move(num, 0)
break; //跳出swich
}
})
}
function move(target, deg) {
var $index = $('.' + people).index();
$('.check').eq($index).find('img').css('transform', 'rotate(' + deg + 'deg)');
if ($('.check').eq($index + target).hasClass(walls)) {
return;
} else if ($('.check').eq($index + target).hasClass(box)) {
if ($('.check').eq($index + (target * 2)).hasClass(walls)) {
return;
} else if ($('.check').eq($index + (target * 2)).hasClass(box)) {
return;
}
}
$('.check').eq($index).removeClass(people).find('img').remove();
var $pic = $('<img src=\'img/pig.png\'>');
$pic.css('transform', 'rotate(' + deg + 'deg)');
$('.check').eq($index + target).addClass(people).append($pic);
if ($('.check').eq($index + target).hasClass(box)) {
$('.check').eq($index + target).removeClass(box);
$('.check').eq($index + (target * 2)).addClass(box);
var $trueNum = 0;
for (var z = 0; z < $('.check').length; z++) {
if ($('.check').eq(z).hasClass(finish + ' ' + box)) {
$trueNum++;
}
}
if ($trueNum == $('.' + box).length) {
//在这里,我使用了一个setTimeout是因为,在进行测试的时候,发现在chrome中alert会在我移动完之前就会弹出,导致了先出现了弹框,再执行了移动。firefox中的测试是移动箱子和弹框两者同时进行,为了避免在chrome中出现先弹出对话框再执行代码的问题,我使用了延迟100毫秒的方法。
setTimeout(function() {
alert('you win');
}, 100);
}
}
}
}
</script>
下面是用到的素材图片:





来源:https://www.cnblogs.com/superZz/p/5875945.html