前言

偶然间看到很多用js写游戏的感觉很炫酷的样子,所以就想试试,就看了一些资料和某前端站点的视屏。于是乎就自己动手实践了一下,上推箱子截图

感觉很丑陋,但是功能是实现了。再说貌似大多都是这样的吧,这一关其实还是有点难度的,我做完之后想检测一下下一关正确么,居然玩了20分钟才通关。

如果你看到这张图让你想起了你童年的回忆,说明你老了,这里可以试玩一下(很遗憾没有链接地址,最后又源码可以下载)。

css布局

主要考虑的是地图是怎么动态生成的,地图中有灰色的,还有墙,箱子,蓝色,红色背景,人物。先看css代码吧

* {
padding:;
margin:;
} img {
border:;
} #container {
position: relative;
margin: 20px auto;
} .pos1 {
width: 50px;
height: 50px;
float: left;
background: #666;
} .pos2 {
width: 50px;
height: 50px;
float: left;
background: url(images/wall.png);
} .pos3 {
width: 50px;
height: 50px;
float: left;
background: red;
} .pos0 {
width: 50px;
height: 50px;
float: left;
background: blue;
} .box {
width: 50px;
height: 50px;
position: absolute;
background: url(images/box.png);
} .person {
width: 50px;
height: 50px;
position: absolute;
background: url(images/person.png);
}

代码中的pos0/pos1/pos2/pos3/主要是墙,箱子,蓝色红色背景的样式,其中person和box就是人物和箱子的样式,

这里用样式下标来节省部分js代码

其次body中html布局,这里就很简单了,就是一个带id的div,其余的内容均动态生成,因为每个关卡的地图数据都是不一样的。

js代码部分

 $(function () {
Game.init($("#container"));//初始化容器
});
var Game = {
gk: [{//关卡
map: [//地图数据 按照坐标呈现的数组格式
1, 1, 2, 2, 2, 2, 1, 1,
1, 1, 2, 3, 3, 2, 1, 1,
1, 2, 2, 0, 3, 2, 2, 1,
1, 2, 0, 0, 0, 3, 2, 1,
2, 2, 0, 0, 0, 0, 2, 2,
2, 0, 0, 2, 0, 0, 0, 2,
2, 0, 0, 0, 0, 0, 0, 2,
2, 2, 2, 2, 2, 2, 2, 2
],
box: [//箱子 坐标点对象
{ x: 4, y: 3 },
{ x: 3, y: 4 },
{ x: 4, y: 5 },
{ x: 5, y: 5 }
],
person: { x: 3, y: 6 }//人物 坐标点对象
},
{
map: [
1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 1,
1, 1, 1, 1, 2, 0, 2, 2, 0, 0, 2, 1,
1, 1, 1, 1, 2, 0, 0, 0, 0, 0, 2, 1,
2, 2, 2, 2, 0, 0, 2, 0, 0, 0, 2, 1,
3, 3, 3, 2, 0, 0, 0, 0, 0, 0, 2, 2,
3, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 2,
3, 0, 0, 0, 0, 0, 0, 2, 2, 0, 0, 2,
3, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 2,
3, 3, 3, 2, 2, 2, 0, 0, 2, 0, 0, 2,
2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 2, 1,
1, 1, 1, 1, 2, 0, 0, 2, 0, 0, 2, 1,
1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 1,
],
box: [
{ x: 8, y: 3 },
{ x: 9, y: 3 },
{ x: 7, y: 4 },
{ x: 6, y: 7 },
{ x: 7, y: 5 },
{ x: 7, y: 8 },
{ x: 8, y: 9 },
{ x: 4, y: 5 },
{ x: 6, y: 6 } ],
person: { x: 3, y: 6 }
}
],
init: function (oParent) {
this.oParent = oParent;//此处将外层的对象引进来
this.iNow = 0;
this.createMap(this.iNow);
},
createMap: function (iNow) {
//创建地图 很关键的是 将元素的样式下标和地图的坐标点关联
this.oParent.empty(); document.title = "第" + (iNow + 1) + "关";
this.newJson = this.gk[iNow]; this.oParent.css("width", Math.sqrt(this.newJson.map.length) * 50);
var tempHtml = '';
$.each(this.newJson.map, $.proxy(function (i, elem) {
tempHtml += '<div class="pos' + elem + '"></div>';
}, this));
this.oParent.append(tempHtml);
this.createBox();
this.createPerson();
},
createBox: function () {//布局箱子所在的位置
$.each(this.newJson.box, $.proxy(function (i, elem) {
var oBox = $('<div class="box"></div>');
oBox.css({ 'left': elem.x * 50, 'top': elem.y * 50 });
this.oParent.append(oBox);
}, this));
},
createPerson: function () {//布局人物所在的位置
var oPerson = $('<div class="person"></div>');
var pos = this.newJson.person;
oPerson.css({ 'left': pos.x * 50, 'top': pos.y * 50 });
oPerson.data('x', pos.x);//缓存在oPerson上的数据
oPerson.data('y', pos.y);
this.oParent.append(oPerson);
this.bindPerson(oPerson);
},
bindPerson: function (oPerson) {//绑定对人物←↑→↓操作
$(document).keydown($.proxy(function (ev) {
switch (ev.which) {
case 37: //←
oPerson.css('backgroundPosition', '-150px 0');
this.movePerson(oPerson, { x: -1 });
break;
case 38: //↑
oPerson.css("backgroundPosition", "0 0");
this.movePerson(oPerson, { y: -1 });
break;
case 39: //→
oPerson.css("backgroundPosition", "-50px 0");
this.movePerson(oPerson, { x: 1 });
break;
case 40: //↓
oPerson.css("backgroundPosition", "100px 0");
this.movePerson(oPerson, { y: 1 });
break;
default:
}
}, this));
},
movePerson: function (oP, opt) {//移动人物
var xValue = opt.x || 0;
var yValue = opt.y || 0;
var length = Math.sqrt(this.newJson.map.length);
var currentMapIndex = (oP.data('x') + xValue) + (oP.data('y') + yValue) * length;
if (this.newJson.map[currentMapIndex] != 2) {//遇到墙的判断
oP.data('x', oP.data('x') + xValue);
oP.data('y', oP.data('y') + yValue);
oP.css({ "left": oP.data("x") * 50, "top": oP.data("y") * 50 });
$(".box").each($.proxy(function (i, elem) {
//当和箱子发生碰撞时遇到墙的判断
if (this.pz(oP, $(elem)) && this.newJson.map[(oP.data('x') + xValue) + (oP.data('y') + yValue) * length] != 2) {
$(elem).css({ 'left': (oP.data('x') + xValue) * 50, 'top': (oP.data('y') + yValue) * 50 });
$(".box").each($.proxy(function (j, elem2) {
if (this.pz($(elem), $(elem2)) && elem != elem2) {
//当遇到箱子和箱子的的碰撞时同时前面也不是强的判断
$(elem).css({ 'left': oP.data('x') * 50, 'top': oP.data('y') * 50 });
oP.data('x', oP.data('x') - xValue);
oP.data('y', oP.data('y') - yValue);
oP.css({ "left": oP.data("x") * 50, "top": oP.data("y") * 50 });
}
}, this));
}
else if (this.pz(oP, $(elem))) {//和墙之间的碰撞
oP.data('x', oP.data('x') - xValue);
oP.data('y', oP.data('y') - yValue);
oP.css({ "left": oP.data("x") * 50, "top": oP.data("y") * 50 });
}
}, this));
}
this.nextShow();
},
nextShow: function () {//判断是否赢
var iNum = 0;
//红色区域所在的位置是否全部被箱子所占据
$(".box").each($.proxy(function (i, elem) {
$(".pos3").each($.proxy(function (j, elem1) {
if (this.pz($(elem), $(elem1))) {
iNum++;
}
}, this));
}, this));
if (iNum == this.newJson.box.length) {
this.iNow++;
this.createMap(this.iNow);
}
},
pz: function (obj1, obj2) { //碰撞检测
var L1 = obj1.offset().left;
var R1 = obj1.offset().left + obj1.width();
var T1 = obj1.offset().top;
var B1 = obj1.offset().top + obj1.height(); var L2 = obj2.offset().left;
var R2 = obj2.offset().left + obj2.width();
var T2 = obj2.offset().top;
var B2 = obj2.offset().top + obj2.height();
if (L1 >= R2 || B2 <= T1 || T2 >= B1 || R1 <= L2)
{ return false; }
else
{ return true; }
}
};

基本代码中都有注释,应该是可以理解的,具体如果你有疑问那么请留言,我定会回复。

我个人认为其中的精华部分就是首先地图数据的构造用一维数组来确定地图坐标,其中的内容的数据和样式中pos的下标的数据对应起来感觉很赞。

其次是逻辑判断,比如当人物推箱子是发现前面是墙,推箱子遇到箱子时前面也是箱子,此时如果又遇到了墙怎么处理。最后判断输赢就是如果红色区域的位置全部被箱子所占据那么也就

表示通过,进入下一关,当然下一关的数据我是自己随意填充的。如果你有兴趣请自行解决。

结论

这种类似的小游戏重在思路,如果复杂的话就要考虑架构性能等问题了,我猜的。因为没有做大的游戏,如有错误请指出。如果你觉得不错就支持推荐一下。

download PushBox

jQuery版推箱子游戏详解和源码的更多相关文章

  1. Django模型验证器详解和源码分析

    转发请注明来源 在Django的模型字段参数中,有一个参数叫做validators,这个参数是用来指定当前字段需要使用的验证器,也就是对字段数据的合法性进行验证,比如大小.类型等. Django的验证 ...

  2. 微服务生态组件之Spring Cloud OpenFeign详解和源码分析

    Spring Cloud OpenFeign 概述 Spring Cloud OpenFeign 官网地址 https://spring.io/projects/spring-cloud-openfe ...

  3. 微服务生态组件之Spring Cloud LoadBalancer详解和源码分析

    Spring Cloud LoadBalancer 概述 Spring Cloud LoadBalancer目前Spring官方是放在spring-cloud-commons里,Spring Clou ...

  4. jquery $.trim()去除字符串空格详解

    jquery $.trim()去除字符串空格详解 语法 jQuery.trim()函数用于去除字符串两端的空白字符. 作用 该函数可以去除字符串开始和末尾两端的空白字符(直到遇到第一个非空白字符串为止 ...

  5. JavaScript写一个小乌龟推箱子游戏

    推箱子游戏是老游戏了, 网上有各种各样的版本, 说下推箱子游戏的简单实现,以及我找到的一些参考视频和实例: 推箱子游戏的在线DEMO : 打开 如下是效果图: 这个拖箱子游戏做了移动端的适配, 我使用 ...

  6. MySql绿色版配置及使用详解

    原文:MySql绿色版配置及使用详解 最近在做项目开发时用到了MySql数据库,在看了一些有关MySql的文章后,很快就上手使用了.在使用的过程中还是出现了一些问题,因为使用的是绿色免安装版的MySq ...

  7. 用HTML5+原生js实现的推箱子游戏

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  8. C# 推箱子游戏&对战游戏

    推箱子游戏提纲,只有向右向上的操作,向左向下同理,后期需完善. namespace 推箱子 { class Program { static void Main(string[] args) { // ...

  9. 【CCpp程序设计2017】推箱子游戏

    我的还……支持撤销!用链表实现! 题目:推箱子小游戏(基于console) 功能要求: 将p09迷宫游戏改造为“推箱子”游戏: 在地图中增加箱子.箱子目标位置等图形: 当玩家将所有箱子归位,则显示玩家 ...

随机推荐

  1. 【Bible for kids】 儿童圣经 App

    [Bible for kids] 儿童圣经App 除了<The Bible>这个由YouVersion团队开发的全球下载量和安装数目第一的圣经类.安装量已逾1亿8千万的App之外,YouV ...

  2. 【Android基础】Activity之间进行参数传递的三种方式

    1.使用Intent进行传输 //发送数据的Activity class button implements OnClickListener{ @Override public void onClic ...

  3. HDU 1864最大报销额(一维背包)

    题目地址:HDU 1864 刚上来看着挺麻烦的..细致看了看原来好简单好简单...仅仅要去掉一些不符合要求的发票,剩下的就是最简单的背包问题了..对于小数问题,仅仅要*100就变成整数了. 代码例如以 ...

  4. 使用autoconf和automake生成Makefile文件(转)

    Makefile好难写 曾经也总结了一篇关于Makefile的文章<make和makefile的简单学习>.但是,总结完以后,发现写Makefile真的是一件非常痛苦的事情,的确非常痛苦. ...

  5. maven的webapp产品热销部署eclipse,biz和其他子项目jar一揽子的解决方案无法找到!

    eclipse maven 这也太坑.. ..右键单击该项目 在这里,当地仓库子项目jar新增可以成功启动tomcat... ( maven项目年初进口eclipse他们是正常的. 当...的时候we ...

  6. 【ASP.NET】判断访问网站的客户端是PC还是手机

    原文:[ASP.NET]判断访问网站的客户端是PC还是手机 主要就是通过客户端传递的User-agent来判断访问网站的客户端是PC还是手机,.NET中就是Request.ServerVariable ...

  7. android 原生应用、Web应用、混合应用优缺点分析

    近期开发几个项目,牵涉到android的几种开发模式.对于原生态开发.web 应用开发以及混合模式开发,本人觉得并非哪一种就是最好的,哪一种就是最差的,这个全然是依据项目的实际需求,选择一种合适的开发 ...

  8. Cocos2d-Java安装和配置跨平台游戏引擎以及相关的开发工具

    假设认为博文图片不清晰.能够Ctrl+鼠标滚动缩放网页比例 Cocos2d-Java是什么? http://blog.csdn.net/touchsnow/article/details/387047 ...

  9. Android+NDK+OpenGLES开发环境配置

    1.资源 (1).Android的eclipse开发环境 我用adt-bundle-windows-x86.官方主页就能下载.这是一个打包的版本号,直接执行eclipse.exe你可以开始 (2).N ...

  10. asp.net webapi 多文件上传

    使用enctype="multipart/form-data"来进行操作 /// <summary> /// 上传图片 /// </summary> /// ...