jQuery版推箱子游戏详解和源码
前言
偶然间看到很多用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的下标的数据对应起来感觉很赞。
其次是逻辑判断,比如当人物推箱子是发现前面是墙,推箱子遇到箱子时前面也是箱子,此时如果又遇到了墙怎么处理。最后判断输赢就是如果红色区域的位置全部被箱子所占据那么也就
表示通过,进入下一关,当然下一关的数据我是自己随意填充的。如果你有兴趣请自行解决。
结论
这种类似的小游戏重在思路,如果复杂的话就要考虑架构性能等问题了,我猜的。因为没有做大的游戏,如有错误请指出。如果你觉得不错就支持推荐一下。
jQuery版推箱子游戏详解和源码的更多相关文章
- Django模型验证器详解和源码分析
转发请注明来源 在Django的模型字段参数中,有一个参数叫做validators,这个参数是用来指定当前字段需要使用的验证器,也就是对字段数据的合法性进行验证,比如大小.类型等. Django的验证 ...
- 微服务生态组件之Spring Cloud OpenFeign详解和源码分析
Spring Cloud OpenFeign 概述 Spring Cloud OpenFeign 官网地址 https://spring.io/projects/spring-cloud-openfe ...
- 微服务生态组件之Spring Cloud LoadBalancer详解和源码分析
Spring Cloud LoadBalancer 概述 Spring Cloud LoadBalancer目前Spring官方是放在spring-cloud-commons里,Spring Clou ...
- jquery $.trim()去除字符串空格详解
jquery $.trim()去除字符串空格详解 语法 jQuery.trim()函数用于去除字符串两端的空白字符. 作用 该函数可以去除字符串开始和末尾两端的空白字符(直到遇到第一个非空白字符串为止 ...
- JavaScript写一个小乌龟推箱子游戏
推箱子游戏是老游戏了, 网上有各种各样的版本, 说下推箱子游戏的简单实现,以及我找到的一些参考视频和实例: 推箱子游戏的在线DEMO : 打开 如下是效果图: 这个拖箱子游戏做了移动端的适配, 我使用 ...
- MySql绿色版配置及使用详解
原文:MySql绿色版配置及使用详解 最近在做项目开发时用到了MySql数据库,在看了一些有关MySql的文章后,很快就上手使用了.在使用的过程中还是出现了一些问题,因为使用的是绿色免安装版的MySq ...
- 用HTML5+原生js实现的推箱子游戏
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
- C# 推箱子游戏&对战游戏
推箱子游戏提纲,只有向右向上的操作,向左向下同理,后期需完善. namespace 推箱子 { class Program { static void Main(string[] args) { // ...
- 【CCpp程序设计2017】推箱子游戏
我的还……支持撤销!用链表实现! 题目:推箱子小游戏(基于console) 功能要求: 将p09迷宫游戏改造为“推箱子”游戏: 在地图中增加箱子.箱子目标位置等图形: 当玩家将所有箱子归位,则显示玩家 ...
随机推荐
- phonegap+emberjs+python手机店发展,html5实现本地车类别~
商城开发项目,现在需要做出APP,无奈出场前android但不是很精通.最后选择phonegap实现app. 由于之前办理购物车分为登陆和登陆后两种情况,登录前必须充分利用本地存储.而基于phoneg ...
- HDU 3988 Harry Potter and the Hide Story(数论-整数和素数)
Harry Potter and the Hide Story Problem Description iSea is tired of writing the story of Harry Pott ...
- SDUT 2933-人活着系列Streetlights(最小生成树Kruskal+和理查德设置来实现)
人活着系列之Streetlights Time Limit: 1000ms Memory limit: 65536K 有疑问?点这里^_^ 题目描写叙述 人活着假设是为了家庭,亲情----能够说 ...
- XCL-Charts绘画面积图(AreaChart) 例1
样本区域地图,发现区域图的时候把做向上注视位置图更具优势的管理.在改变. 区域图网格和轴是不一样的处理与其它图, 它是用来表示其影响范围的覆盖范围,车桥无段伸出. 在这里下处理. watermark/ ...
- Oracle批量执行脚本文件
以下是Oracle批量执行脚本文件的步骤和方法 1.创建脚本文件(xx.sql): 例如文件CreateTable Create table tb1( id varchar2(30), Name va ...
- 于linux已安装moodle
本文介绍了两个虚拟机的安装linux server 及相关服务,随着后这些基础.安装应用程序服务 moodle 2.7+ 它是使用最广泛的平台,网络课程. 在安装过程中moodle之前,需要支持软件 ...
- MEF初体验之三:Exports声明
组合部件通过[ExportAttribute]声明exports.在MEF中,有这么几种成员可声明exports的方式:组合部件(类).字段.属性和方法.我们来看下ExportAttribute类的声 ...
- IOS 数据库管理系统(SQLite)
嵌入式数据库 SQLite嵌入式数据库的优势 1.支持事件,你并不需要配置,无需安装,不需要管理员 2.支持部分脂肪SQL92 3.完整的数据库被存储在磁盘上的文件的顶部,相同的数据库文件可以在不同机 ...
- SQL入门学习2-聚合与排序
3-1 对表进行聚合查询 聚合函数 所谓聚合,就是将多行汇总为一行. 函数名 功能 COUNT 计算表中的记录数(行数) SUM 计算表中数值列的数据合计值 AVG 计算表中数值列的数据平均值 MAX ...
- Oracle cloud control 12c 的启动与关闭
Oracle cloud control 12c整个安装比較复杂,光是安装路径的选择,登录password,端口号等众多个配置不免让人眼花缭乱,目不暇接.本文描写叙述的是安装完成后怎样获取安装时设定的 ...