前言

偶然间看到很多用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. 生命游戏(两),有一种东西叫CCScrollView

    订婚app要么game'肯定不会陌生:CCScrollView并且CCTableView. 假如我不知道是什么CCScrollView,再看看testcpp要么testlua样品棒. 先说说CCScr ...

  2. SpringMVC源码解析- HandlerAdapter - ModelFactory(转)

    ModelFactory主要是两个职责: 1. 初始化model 2. 处理器执行后将modle中相应参数设置到SessionAttributes中 我们来看看具体的处理逻辑(直接充当分析目录): 1 ...

  3. UVa 514 Rails(经典栈)

     Rails  There is a famous railway station in PopPush City. Country there is incredibly hilly. The st ...

  4. UVA No Tipping

    Problem A - No Tipping As Archimedes famously observed, if you put an object on a lever arm,it will ...

  5. Html5 拖放上传图片

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

  6. outlook 当关闭时最小化到任务栏完美的解决方案

    近期使用Outlook,但很发现easy退出关闭.不能达到最小化封. 在网上找了很长时间也用outlook on the desktop插件,但该插件安装后的执行错误和被遗弃. 最后,我发现了一个叫k ...

  7. mfc配置GDI+有106个错误

    mfc配置GDI+有106个错误,处理如下,参考http://bbs.csdn.net/topics/380054079 一开始#include...放在stdafx.h里有错误,后来上面修改好了,放 ...

  8. 使用智能移动设备访问Ossim制

    使用智能移动设备访问Ossim制 下面我们用iPad,iPhone通路ossim效果系统. 高清视频:http://www.tudou.com/programs/view/TikMZ1z1ELw ip ...

  9. Python中国的学习方式处理问题

    a = '你们' 至 str 物 a = u'你们' 至 unicode 物 1. >>> print 'u'  + '你们' >>> u欢 输出乱码 2. > ...

  10. Java Web项目结构

    Java Web项目结构(一般) 1.Java src 2.JRE System Library 3.Java EE 6 Libraries 4.Web App Libraries 5.WebRoot ...