欢乐3d推箱子2第142关是不是错的

前言偶然间看到很多用js写游戏的感觉很炫酷的样子,所以就想试试,就看了一些资料和某前端站点的视屏。于是乎就自己动手实践了一下,上推箱子截图
感觉很丑陋,但是功能是实现了。再说貌似大多都是这样的吧,这一关其实还是有点难度的,我做完之后想检测一下下一关正确么,居然还玩了以后才通关。如果你看到这张图让你想起了你童年的回忆,说明你老了,这里可以试玩一下(很遗憾没有链接地址,最后又源码可以下载)。css布局主要考虑的是地图是怎么动态生成的,地图中有灰色的,还有墙,箱子,蓝色,红色背景,人物。先看css代码吧* {
padding: 0;
margin: 0;
border: 0;
#container {
position: relative;
margin: 20px auto;
width: 50px;
height: 50px;
float: left;
background: #666;
width: 50px;
height: 50px;
float: left;
background: url(images/wall.png);
width: 50px;
height: 50px;
float: left;
background: red;
width: 50px;
height: 50px;
float: left;
background: blue;
width: 50px;
height: 50px;
position: absolute;
background: url(images/box.png);
width: 50px;
height: 50px;
position: absolute;
background: url(images/person.png);
}代码中的pos0/pos1/pos2/pos3/主要是墙,箱子,蓝色红色背景的样式,其中person和box就是人物和箱子的样式,这里用样式下标来节省部分js代码其次body中html布局,这里就很简单了,就是一个带id的div,其余的内容均动态生成,因为每个关卡的地图数据都是不一样的。js代码部分1 $(function () {2 Game.init($(&#container&));//初始化容器3 });4 var Game = {5 gk: [{//关卡6 map: [//地图数据 按照坐标呈现的数组格式7 1, 1, 2, 2, 2, 2, 1, 1,8 1, 1, 2, 3, 3, 2, 1, 1,9 1, 2, 2, 0, 3, 2, 2, 1, 10 1, 2, 0, 0, 0, 3, 2, 1, 11 2, 2, 0, 0, 0, 0, 2, 2, 12 2, 0, 0, 2, 0, 0, 0, 2, 13 2, 0, 0, 0, 0, 0, 0, 2, 14 2, 2, 2, 2, 2, 2, 2, 2 15 ], 16 box: [//箱子 坐标点对象 17 { x: 4, y: 3 }, 18 { x: 3, y: 4 }, 19 { x: 4, y: 5 }, 20 { x: 5, y: 5 } 21 ], 22 person: { x: 3, y: 6 }//人物 坐标点对象 23 }, 24 { 25 map: [ 26 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 1, 27 1, 1, 1, 1, 2, 0, 2, 2, 0, 0, 2, 1, 28 1, 1, 1, 1, 2, 0, 0, 0, 0, 0, 2, 1, 29 2, 2, 2, 2, 0, 0, 2, 0, 0, 0, 2, 1, 30 3, 3, 3, 2, 0, 0, 0, 0, 0, 0, 2, 2, 31 3, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 2, 32 3, 0, 0, 0, 0, 0, 0, 2, 2, 0, 0, 2, 33 3, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 2, 34 3, 3, 3, 2, 2, 2, 0, 0, 2, 0, 0, 2, 35 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 2, 1, 36 1, 1, 1, 1, 2, 0, 0, 2, 0, 0, 2, 1, 37 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 1, 38 ], 39 box: [ 40 { x: 8, y: 3 }, 41 { x: 9, y: 3 }, 42 { x: 7, y: 4 }, 43 { x: 6, y: 7 }, 44 { x: 7, y: 5 }, 45 { x: 7, y: 8 }, 46 { x: 8, y: 9 }, 47 { x: 4, y: 5 }, 48 { x: 6, y: 6 } 49
50 ], 51 person: { x: 3, y: 6 } 52 } 53 ], 54 init: function (oParent) { 55 this.oParent = oP//此处将外层的对象引进来
56 this.iNow = 0; 57 this.createMap(this.iNow); 58 }, 59 createMap: function (iNow) { 60 //创建地图 很关键的是 将元素的样式下标和地图的坐标点关联 61 document.title = &第& + (iNow + 1) + &关&; 62 this.newJson = this.gk[iNow]; 63
64 this.oParent.css(&width&, Math.sqrt(this.newJson.map.length) * 50); 65 var tempHtml = ''; 66 $.each(this.newJson.map, $.proxy(function (i, elem) { 67 tempHtml += '&div class=&pos' + elem + '&&&/div&'; 68 }, this)); 69 this.oParent.append(tempHtml); 70 this.createBox(); 71 this.createPerson(); 72 }, 73 createBox: function () {//布局箱子所在的位置 74 $.each(this.newJson.box, $.proxy(function (i, elem) { 75 var oBox = $('&div class=&box&&&/div&'); 76 oBox.css({ 'left': elem.x * 50, 'top': elem.y * 50 }); 77 this.oParent.append(oBox); 78 }, this)); 79 }, 80 createPerson: function () {//布局人物所在的位置 81 var oPerson = $('&div class=&person&&&/div&'); 82 var pos = this.newJson. 83 oPerson.css({ 'left': pos.x * 50, 'top': pos.y * 50 }); 84 oPerson.data('x', pos.x);//缓存在oPerson上的数据 85 oPerson.data('y', pos.y); 86 this.oParent.append(oPerson); 87 this.bindPerson(oPerson); 88 }, 89 bindPerson: function (oPerson) {//绑定对人物←↑→↓操作 90 $(document).keydown($.proxy(function (ev) { 91 switch (ev.which) { 92 case 37: //← 93 oPerson.css('backgroundPosition', '-150px 0'); 94 this.movePerson(oPerson, { x: -1 }); 95 break; 96 case 38: //↑ 97 oPerson.css(&backgroundPosition&, &0 0&); 98 this.movePerson(oPerson, { y: -1 }); 99 break;100 case 39: //→101 oPerson.css(&backgroundPosition&, &-50px 0&);102 this.movePerson(oPerson, { x: 1 });103 break;104 case 40: //↓105 oPerson.css(&backgroundPosition&, &100px 0&);106 this.movePerson(oPerson, { y: 1 });107 break;108 default:109 }110 }, this));111 },112 movePerson: function (oP, opt) {//移动人物113 var xValue = opt.x || 0;114 var yValue = opt.y || 0;115 var length = Math.sqrt(this.newJson.map.length);116 var currentMapIndex = (oP.data('x') + xValue) + (oP.data('y') + yValue) *117 if (this.newJson.map[currentMapIndex] != 2) {//遇到墙的判断118 oP.data('x', oP.data('x') + xValue);119 oP.data('y', oP.data('y') + yValue);120 oP.css({ &left&: oP.data(&x&) * 50, &top&: oP.data(&y&) * 50 });121 $(&.box&).each($.proxy(function (i, elem) {122 //当和箱子发生碰撞时遇到墙的判断123 if (this.pz(oP, $(elem)) && this.newJson.map[(oP.data('x') + xValue) + (oP.data('y') + yValue) * length] != 2) {124 $(elem).css({ 'left': (oP.data('x') + xValue) * 50, 'top': (oP.data('y') + yValue) * 50 });125 $(&.box&).each($.proxy(function (j, elem2) {126 if (this.pz($(elem), $(elem2)) && elem != elem2) {127 //当遇到箱子和箱子的的碰撞时同时前面也不是强的判断128 $(elem).css({ 'left': oP.data('x') * 50, 'top': oP.data('y') * 50 });129 oP.data('x', oP.data('x') - xValue);130 oP.data('y', oP.data('y') - yValue);131 oP.css({ &left&: oP.data(&x&) * 50, &top&: oP.data(&y&) * 50 });132 }133 }, this));134 }135 else if (this.pz(oP, $(elem))) {//和墙之间的碰撞136 oP.data('x', oP.data('x') - xValue);137 oP.data('y', oP.data('y') - yValue);138 oP.css({ &left&: oP.data(&x&) * 50, &top&: oP.data(&y&) * 50 });139 }140 }, this));141 }142 this.nextShow();143 },144 nextShow: function () {//判断是否赢145 var iNum = 0;146 //红色区域所在的位置是否全部被箱子所占据147 $(&.box&).each($.proxy(function (i, elem) {148 $(&.pos3&).each($.proxy(function (j, elem1) {149 if (this.pz($(elem), $(elem1))) {150 iNum++;151 }152 }, this));153 }, this));154 if (iNum == this.newJson.box.length) {155 this.iNow++;156 this.createMap(this.iNow);157 }158 },159 pz: function (obj1, obj2) { //碰撞检测160 var L1 = obj1.offset().161 var R1 = obj1.offset().left + obj1.width();162 var T1 = obj1.offset().163 var B1 = obj1.offset().top + obj1.height();164 165 var L2 = obj2.offset().166 var R2 = obj2.offset().left + obj2.width();167 var T2 = obj2.offset().168 var B2 = obj2.offset().top + obj2.height();169 if (L1 &= R2 || B2 &= T1 || T2 &= B1 || R1 &= L2)170 { return false; }171 else172 { return true; }173 }174 }; 基本代码中都有注释,应该是可以理解的,具体如果你有疑问那么请留言,我定会回复。 我个人认为其中的精华部分就是首先地图数据的构造用一维数组来确定地图坐标,其中的内容的数据和样式中pos的下标的数据对应起来感觉很赞。其次是逻辑判断,比如当人物推箱子是发现前面是墙,推箱子遇到箱子时前面也是箱子,此时如果又遇到了墙怎么处理。最后判断输赢就是如果红色区域的位置全部被箱子所占据那么也就表示通过,进入下一关,当然下一关的数据我是自己随意填充的。如果你有兴趣请自行解决。结论这种类似的小游戏重在思路,如果复杂的话就要考虑架构性能等问题了,我猜的。因为没有做大的游戏,如有错误请指出。如果你觉得不错就支持推荐一下。 download PushBox
无相关信息经验内容仅供参考,如果您需解决具体问题(尤其法律、医学等领域),建议您详细咨询相关领域专业人士。
请扫描分享到朋友圈后使用快捷导航没有帐号?
虽然放眼望去一堆粗放派,不过诸如《投影寻真》、《像素魂斗罗2》、《羊群终结者》等...
库克和乔布斯的风格迥异,所以造就了苹果公司在一些政策上的改变。也许你曾经怀疑,乔...
世上平板千千万,为什么诺基亚N1能脱颖而出?
只要是一家互联网巨头,似乎都逃不脱“擅自收集用户信息”的指控。
小编在这里汇总了一些当日更新的实用插件。
苹果公司 CEO 蒂姆·库克最近拜访了一个对于苹果公司高管来说并不算熟悉的地方:美国...
若都能顺利量产,下半年 64 位手机们的选择还是很丰富的。
美国食品及药物管理局(FDA)在周二发布的初步指引显示,任何的可穿戴设备想要被归类...
《飞艇面包店》(Airship Bakery)是一款梦幻且很有欧式复古风的休闲三消游戏,游戏采...
随着现在的科学技术不断发展,现在的孩子们在很小的时候就开始享受这些高科技带给我们...
《Calista》是 THINKSUIT 推出的一款图片编辑软件,他给用户提供了 10 种风格类型超过...
由万代南梦宫(BANDAI NAMCO)打造的经典日系 S·RPG《召唤之夜》系列手游新作《召唤...
Com2uS 新作《龙族骑士(Dragon Knights)》近日新鲜上架,这款 RPG 再一次加入“龙族...
SQUARE ENIX 在手游平台上如果不炒冷饭的话,那多半就要坑一个大的,比如说日本区最近...
Cartoon Network 的《探险活宝》系列又出新作了,这款命名为《探险活宝:游戏巫师...
iOS 产品的续航一直都是硬伤,如果能够将充电时间减少一半,听起来也是一个不错的选择...
PowerLite是一款可以插入智能手机的外置闪光灯。除了能在黑暗场景当中提供足够的光亮...
通过 Citrix 的远程桌面应用,再加上 Citrix X1 鼠标和蓝牙外接键盘,iPad 就可以变身...
未来能插 Lightning 接口就好了。
去年,苹果悄悄地为其 iOS 设备的 Lightning 接口添加了一项新规范,允许第三方厂商生...
智能手机续航仍然是目前业界仍难解决的最大难题,应运而生的充电宝虽说能暂时的为智能...
目前围绕苹果移动设备而诞生的硬件生态系统越来越庞大,苹果也想出新的对策,在其中选...
拿手机出来看个信息而已,敢不敢再装 X 一点。
求助,iPhone4 8G恢复6.1.3一直提示未知错误-1
注册时间 最后登录
在线时间460 小时 UID
主题帖子人气
红苹果, 积分 302, 距离下一级还需 198 积分
首先说说机子的来源......
lz悲剧的在上学期和这学期被偷了一台4S和5,深知治安差不敢再动大钱,于是淘宝了一台8G iphone4,价格很便宜。
回来一查,已经激活了两三天,行货,还有360+天的保修,电话支持未到期,大喜,貌似捡到宝了
两个月过去了,一直使用正常,今天想升级ios7 beta5,刷之,提示未知错误,恢复的话需要开发者账号,只能先恢复6.1.3,但是恢复了两遍仍然提示未知错误-1 !!这是神马情况?!
上网一搜,吓了一大跳,说什么提示未知错误-1的可能是硬件问题,也有很多说是低价iPhone4 8g的都是板机质量极差神马的。。
但是我都验证序列号是行货了而且还有将近一年保修和90天电话支持,会是板机么?!求助大神。。。
求大神指点解决方法人品败到家已经不敢再买手机了。。。请求大神救活我手中的8g小4啊啊啊啊。。。。。
未知错误-1啊啊啊啊。。。。
<p id="rate_2509" onmouseover="showTip(this)" tip="如果你是买的淘宝上普遍那种销量比较大而且价格又便宜的8G,基本都是翻新机或者妖机&人气 + 1
" class="mtn mbn">
如果你是买的淘宝上普遍那种销量比较大而且价格又便宜的8G,基本都是翻新机或者妖机
注册时间 最后登录
在线时间590 小时 UID
主题帖子人气
注册时间 最后登录
在线时间460 小时 UID
主题帖子人气
回 1楼(初识) 的帖子
查序列号显示是行货还有很久保修,会是妖机么?引用第1楼初识于 19:21发表的
:妖机?......
注册时间 最后登录
在线时间888 小时 UID
主题帖子人气
换台电脑试下,还有,8G有其特定固件,要选对
注册时间 最后登录
在线时间716 小时 UID
主题帖子人气
用红雪踢出恢复模式
注册时间 最后登录
在线时间428 小时 UID
主题帖子人气
注册时间 最后登录
在线时间218 小时 UID
主题帖子人气
对jz-08-07 22:52在楼主发表的主题评分:人气:+1;
首先说说机子的来源......
lz悲剧的在上学期和这学期被偷了一台4S和5,深知治安差不敢再动大钱,于是淘宝了一台8G iphone4,价格很便宜。
.......如果你是买的淘宝上普遍那种销量比较大而且价格又便宜的8G,基本都是翻新机或者妖机。。都是好多台共用一个新的序列号
注册时间 最后登录
在线时间171 小时 UID
主题帖子人气
以你使用过几台苹果设备来讲应该不难分辨,为止错误1和-1也不是什么大问题吧,论坛搜索一下
注册时间 最后登录
在线时间460 小时 UID
主题帖子人气
回 6楼(shdyll) 的帖子
引用第6楼shdyll于 22:52发表的
:如果你是买的淘宝上普遍那种销量比较大而且价格又便宜的8G,基本都是翻新机或者妖机。。都是好多台共用一个新的序列号......还有办法救活么。。。我不想再买手机了买穷了。。。
注册时间 最后登录
在线时间174 小时 UID
主题帖子人气
快修:400-021-0200
错误-1是主板三无,估计你可能买到妖机了。序列号查询显示在保,机器不一定是原封未动的。
iphone ipad imac macbook专业维修
威锋旗下产品
Hi~我是威威!
沪ICP备号-1 丨 深公安网监备案号 5
增值电信业务经营许可证:
Powered by Discuz!使用 C# 开发智能手机软件:推箱子(十)介绍 Common/DataFile.cs 源程序文件 - 谷普下载 |
| 您所在的位置: >
> 使用 C# 开发智能手机软件:推箱子(十)介绍 Common/DataFile.cs 源程序文件使用 C# 开发智能手机软件:推箱子(十)介绍 Common/DataFile.cs 源程序文件编辑:超级兜兜&&&&来源:谷普下载站&&&&更新:&&&&人气:加载中...&&&&字号:|标签:&&&&&&&&&&&&
这是“ C# :”系列的第十篇。在这篇中, /DataFile.cs 。这个中包含密封类 DataFile,用来管理数据文件。 & &上图是数据文件 konka.bxb 的结构图。该数据文件大小为 297 字节,包含三个关卡,各个关卡的大小分别为:“8x7”、“8x7”和“9x5”。内容如下: & &1. 文件头(32字节,图中的青色部分)。首先是保留的四个字节。然后是一个字节的数据文件版本号(目前为“2”)。接着是三个字节的标志(内容为“BOX”)。接着是十六字节的组名(编码为“GB2312”,本数据文件中为“康佳”)。接着是总关数(Int32,四个字节,因为本组共有三个关卡,所以内容为“3”)。最后是关起始地址位置(Int32,四个字节,本数据文件中的内容为“0x11D”)。 & &2. 以关数据头(32字节,图中的部分)开始的各关数据。首先是一个字节的关数据头开始标志(“@”)。然后是一个字节的标志(最低位:0:未通关,1:已通关)。接着是通关总步数(Int32,四个字节)。接着是通关步数(Int32,四个字节)。接着是十四个字节的保留字段。接着是本关的宽度(Int32,四个字节)。接着是本关的高度(Int32,四个字节)。最后是“本关宽度x本关高度”个字节的关数据,也就是说中每个单元格占一个字节,取值范围是“0”到“7”,分别表示:0:地,1:槽,2:墙,,3:砖,4:箱子放在地上,5:箱子放在槽上,6:工人站在地上,7:工人站在槽上。注意,每一个关卡必须刚好有一个工人。 3. 数据文件的最后是各关起始地址列表(“总关数x4”个字节,图中的黄色部分)。每关的起始地址均为四个字节(Int32),所以共有“总关数x4”个字节。 & &密封类 DataFile 的源代码中有详细的注释,很容易看懂。 & &1. InitMap 法子用来初始化。地图的大小是“(关的高度+2) x (关的宽度+2)”,这是为了在地图四周砌上围墙,以免算法越出地图边界。 & &2. DeleteLevel 法子用来删除指定的关。注意,删除关时并不删除关数据,只是将该关的起始地址从各关地址列表中删除,然后将文件缩短四个字节(因为各关地址列表在数据文件的最后)。这样数据文件中就可能包含不需要的冗余数据。通过“菜单 -& 数据 -& 转换”,先“导出”,然后“导入”,可以消除冗余数据。 &1 using S &2 using System.IO; &3 using System.D &4 using System.Collections.G &5 using System.Windows.F &6
&7 namespace Skyiv.Ben.PushBox. &8 { &9 & // data/&group&.bxb 文件款式 10 & // 保留 ver(2) BOX 组名- 总关数 第1关起始地址位置 11 & // 0--3 4----- 5-7 8--23 24--27 28-------------31 12 & // 13 & // @ Flag 总步数 推箱子步数 保留- wide- high- data 14 & // 0 1--- 2----5 6--------9 10-23 24-27 28-31 32.. 15 & // Flag: 最低位: 0:未通关 1:已通关 16 & // 17 & // 第1关起始地址 第2关起始地址 . 最后一关起始地址 18 & // 0-----------3 4-----------7 . (文件最后四字节) 19 & // 20 & // steps/&group&&level&.bxs 文件款式见 Step.cs 21 & // 其中&level&为关数(1起始),最少四位,不足前补零 22 & // 23 & // text/&group&.bxa 文件款式 24 & // 0 - land & & & & & & SPACE 25 & // 1 + slot & & & & & & . 26 & // 2 # wall & & & & & & # 27 & // 3 % brick & & & & & &N/A 28 & // 4 x box on land & & &$ 29 & // 5 X box on slot & & &* 30 & // 6 ( man on land & & &@ 31 & // 7 ) man on slot & & &+ &.XSB 文件款式 32 & // 行如果以!开头的话, 则为组名(不能超过16个字符) 33 & // 以:开头的行为通关步骤, 款式同(.bxs)文件 34 & // 以&#39;开头的行为注释, 完全忽略 35 & // 各关之间必须以空行分隔 36
37 & /// &summary& 38 & /// 管理数据文件: *.bxb &*.bxa &*.bxs 39 & /// &/summary& 40 & sealed class DataFile : IDisposable 41 & { 42 & & const byte DataVersion = 2; & & & // 数据文件(.bxb)的版本 43 & & const byte LevelFlag = (byte)&#39;@&#39;; // 数据文件(.bxb)的关标志 44 & & const char RemChar = &#39;&#39;&#39;; & & & &// 文本文件(.bxa)的注释 45 & & const char StepsChar = &#39;:&#39;; & & & // 文本文件(.bxa)的通关步骤 46
47 & & FileS & &// 数据文件根基流 48 & & BinaryR &// 数据文件读取器 49 & & BinaryW &// 数据文件写入器 50 & & string groupN // 当前组名称 51 & & int[] & & &// 各关起始地址列表,最后一项为第1关起始地址位置 52 & & byte[,] & & &// 当前关地图 53 & & int maxL & & // 总关数 54 & & Size levelS & // 当前关尺寸(以单元格为单位) 55 & & P & & // 当前工人位置(以单元格为单位) 56 & & & & & & // 工人数 57 & & & & & & // 箱子数 58 & & & & & &// 槽数 59 & & & & & &// 总任务数 60 & & & & & &// 已完成任务数 61 & & bool isF &// 是否曾经通关 62 & & int movedS & // 通关的总步数 63 & & int pushedS &// 通关的推箱子步数 64 & & string fileName { get { return Path.GetFileNameWithoutExtension(fs.Name); } } // 数据文件主名 65
66 & & public string GroupName { get { return groupN } } 67 & & public int MaxLevel { get { return maxL } } 68 & & public byte[,] Map { get { } } 69 & & public Size LevelSize { get { return levelS } } 70 & & public bool IsFinished { get { return isF } } 71 & & public int MovedSteps { get { return movedS } } 72 & & public int PushedSteps { get { return pushedS } } 73 & & public Point Worker { get { } } 74 & & public bool HasWorker { get { return mans != 0; } } 75 & & public int Boxs { get { } } 76 & & public int Slots { get { } } 77 & & public int Tasks { get { } } 78 & & public int Boths { get { } set { boths = } } 79
80 & & /// &summary& 81 & & /// 装入组数据 82 & & /// &/summary& 83 & & /// &param name=&name&&组文件名&/param& 84 & & public void LoadGroup(string name) 85 & & { 86 & & & Dispose(); 87 & & & fs = new bine(Pub.DataDirectory, name + Pub.DataExtName), FileMode.Open); 88 & & & br = new BinaryReader(fs, Pub.Encode); 89 & & & bw = new BinaryWriter(fs, Pub.Encode); 90 & & & br.ReadInt32(); // 保留 91 & & & if (br.ReadByte() != DataVersion) throw new Exception(&数据文件版本错&); 92 & & & byte[] bs = br.ReadBytes(3); // 数据文件标志:BOX 93 & & & for (int i = 0; i & bs.L i++) if (bs[i] != &BOX&[i]) throw new Exception(&数据文件标志错&); 94 & & & bs = br.ReadBytes(16); // 组名 95 & & & for (int i = 0; i & bs.L i++) if (bs[i] == 0) bs[i] = 32; 96 & & & groupName = Pub.Encode.GetString(bs, 0, bs.Length).Trim(); 97 & & & if (groupName.Length == 0) groupName = fileN // 如果数据文件中组名为空,则用数据文件主名代替 98 & & & maxLevel = br.ReadInt32(); // 总关数 99 & & & int addrPos = br.ReadInt32(); // 第1关起始地址位置100 & & & br.BaseStream.Seek(addrPos, SeekOrigin.Begin);101 & & & addrs = new int[maxLevel + 1]; // 各关起始地址列表,最后一项为第1关起始地址位置102 & & & for (int i = 0; i & maxL i++) addrs[i] = br.ReadInt32();103 & & & addrs[maxLevel] = addrP // 第1关起始地址位置104 & & & if (addrPos + 4 * maxLevel != br.BaseStream.Length) throw new Exception(&数据文件地址表必须位于数据最后&);105 & & }106 107 & & /// &summary&108 & & /// 装入关数据109 & & /// &/summary&110 & & /// &param name=&level&&关数&/param&111 & & public void LoadLevel(int level)112 & & {113 & & & LoadLevelHead(level);114 & & & InitMap();115 & & & for (int i = 1; i &= levelSize.H i++)116 & & & {117 & & & & for (int j = 1; j &= levelSize.W j++)118 & & & & {119 & & & & & map[i, j] = br.ReadByte();120 & & & & & UpdateCounts(j, i, true);121 & & & & }122 & & & }123 & & & if (mans != 1) throw new Exception(&读取关数据失败:必须刚好有一个工人&);124 & & & tasks = Math.Min(boxs, slots);125 & & }126 127 & & /// &summary&128 & & /// 新建一关129 & & /// &/summary&130 & & /// &param name=&isCopy&&是否复制当前关&/param&131 & & /// &param name=&size&&新建关的尺寸&/param&132 & & public void NewLevel(bool isCopy, Size size)133 & & {134 & & & Size levelSizeOem = levelS135 & & & byte[,] mapOem = isCopy ? (byte[,])map.Clone() :136 & & & levelSize =137 & & & InitMap();138 & & & for (int i = 1; i &= levelSize.H i++)139 & & & {140 & & & & for (int j = 1; j &= levelSize.W j++)141 & & & & {142 & & & & & map[i, j] = (isCopy && i &= levelSizeOem.Height && j &= levelSizeOem.Width) ? mapOem[i, j] : Block.L143 & & & & & UpdateCounts(j, i, true);144 & & & & }145 & & & }146 & & & if (mans != 1 && mans != 0) throw new Exception(&不能超过一个工人&);147 & & & tasks = Math.Min(boxs, slots);148 & & }149 150 & & /// &summary&151 & & /// 初始化地图152 & & /// &/summary&153 & & private void InitMap()154 & & {155 & & & map = new byte[levelSize.Height + 2, levelSize.Width + 2];156 & & & for (int i = 0; i &= levelSize.Height + 1; i++) map[i, 0] = map[i, levelSize.Width + 1] = Block.W157 & & & for (int j = 0; j &= levelSize.Width + 1; j++) map[0, j] = map[levelSize.Height + 1, j] = Block.W158 & & & mans = boxs = slots = boths = 0;159 & & }160 161 & & /// &summary&162 & & /// 根据地图项目统计信息163 & & /// &/summary&164 & & /// &param name=&x&&当前位置横坐标&/param&165 & & /// &param name=&y&&当前位置纵坐标&/param&166 & & /// &param name=&isAdd&&加或减&/param&167 & & public void UpdateCounts(int x, int y, bool isAdd)168 & & {169 & & & int sign = isAdd ? 1 : -1;170 & & & if (Block.IsBox(map[y, x])) boxs +=171 & & & if (Block.IsSlot(map[y, x])) slots +=172 & & & if (Block.Box1 == map[y, x]) boths +=173 & & & if (Block.IsMan(map[y, x]))174 & & & {175 & & & & mans +=176 & & & & worker = isAdd ? new Point(x, y) : Point.E177 & & & }178 & & }179 180 & & /// &summary&181 & & /// 装入关数据头182 & & /// &/summary&183 & & /// &param name=&level&&关数&/param&184 & & void LoadLevelHead(int level)185 & & {186 & & & if (level & maxLevel - 1) throw new Exception(string.Format(&当前关数({0})不能大于总关数({1})&, level + 1, maxLevel));187 & & & br.BaseStream.Seek(addrs[level], SeekOrigin.Begin);188 & & & if (br.ReadByte() != LevelFlag) throw new Exception(&关数据标志错&);189 & & & isFinished = (br.ReadByte() & 1) == 1; // 是否曾经通关190 & & & movedSteps = br.ReadInt32(); // 通关的总步数191 & & & pushedSteps = br.ReadInt32(); // 通关的推箱子步数192 & & & br.ReadBytes(14); // 保留193 & & & levelSize.Width = br.ReadInt32();194 & & & levelSize.Height = br.ReadInt32();195 & & }196 197 & & /// &summary&198 & & /// 当前关数据199 & & /// &/summary&200 & & /// &param name=&level&&关数&/param&201 & & /// &param name=&steps&&通关步骤&/param&202 & & /// &param name=&pushs&&推箱子步数&/param&203 & & public void SaveLevel(int level, Step[] steps, int pushs)204 & & {205 & & & SaveLevelHead(level, steps.Length, pushs);206 & & & SaveLevelSteps(level, Pub.ToString(steps));207 & & & LoadLevelHead(level);208 & & }209 210 & & /// &summary&211 & & /// 更新当前关头数据212 & & /// &/summary&213 & & /// &param name=&level&&关数&/param&214 & & /// &param name=&moves&&通关步数&/param&215 & & /// &param name=&pushs&&推箱子步数&/param&216 & & void SaveLevelHead(int level, int moves, int pushs)217 & & {218 & & & if (level & maxLevel - 1) throw new Exception(&关数太大&);219 & & & bw.BaseStream.Seek(addrs[level] + 1, SeekOrigin.Begin);220 & & & bw.Write((byte)1); // 是否曾经通关221 & & & bw.Write(moves); // 通关的总步数222 & & & bw.Write(pushs); // 通关的推箱子步数223 & & }224 225 & & /// &summary&226 & & /// 保存通关步骤227 & & /// &/summary&228 & & /// &param name=&level&&关数&/param&229 & & /// &param name=&steps&&通关步骤&/param&230 & & void SaveLevelSteps(int level, string steps)231 & & {232 & & & if (!Directory.Exists(Pub.StepsDirectory)) Directory.CreateDirectory(Pub.StepsDirectory);233 & & & Fcl.WriteAllText(GetStepsFileName(fileName, level), steps);234 & & }235 236 & & /// &summary&237 & & /// 给出通关步骤238 & & /// &/summary&239 & & /// &param name=&level&&关数&/param&240 & & /// &returns&通关步骤&/returns&241 & & public string GetSteps(int level)242 & & {243 & & & return GetSteps(fileName, level);244 & & }245 246 & & string GetSteps(string name, int level)247 & & {248 & & & return Fcl.ReadAllText(GetStepsFileName(name, level));249 & & }250 251 & & string GetStepsFileName(string name, int level)252 & & {253 & & & bine(Pub.StepsDirectory, name + (level + 1).ToString(&D4&) + Pub.StepsExtName);254 & & }255 256 & & /// &summary&257 & & /// &删除通关步骤文件258 & & /// &/summary&259 & & /// &param name=&level&&关数&/param&260 & & private void DeleteStepsFile(int level)261 & & {262 & & & // 虽然 File.Delete(): 删除指定的文件。如果指定的文件不存在,则不引发异常。 263 & & & // 但是: 如果指定的路径无效,还是会引发 DirectoryNotFoundException 异常。264 & & & // 所以需要先用 File.Exists() 判断一下文件是否存在265 & & & string name = GetStepsFileName(fileName, level);266 & & & if (File.Exists(name)) File.Delete(name);267 & & }268 269 & & /// &summary&270 & & /// 保存数据271 & & /// &/summary&272 & & /// &param name=&isNew&&是否新建&/param&273 & & /// &param name=&level&&要保存的关数&/param&274 & & public void SaveDesign(bool isNew, int level)275 & & {276 & & & if (isNew && level != maxLevel) throw new Exception(&新建的关必须在最后一关之后&);277 & & & bw.BaseStream.Seek(addrs[level], SeekOrigin.Begin);278 & & & WriteLevel(level, string.Empty); // 如果不是新建,则关尺寸不能比原来的大279 & & & if (isNew)280 & & & {281 & & & & Fcl.Resize(ref addrs, addrs.Length + 1);282 & & & & addrs[++maxLevel] = (int)bw.BaseStream.P283 & & & & WriteAddrs();284 & & & }285 & & & DeleteStepsFile(level); // 删除通关步骤文件286 & & }287 288 & & /// &summary&289 & & /// 删除最后一关290 & & /// &/summary&291 & & /// &param name=&level&&关数(必须是最后一关)&/param&292 & & public void DeleteLastLevel(int level)293 & & {294 & & & if (level != maxLevel - 1) throw new Exception(&要删除的关必须是最后一关&);295 & & & DeleteLevel(level);296 & & & DeleteStepsFile(level); // 删除通关步骤文件,如果被删除的关不是最后一关,以后各关的通关步骤文件就不对了297 & & }298 299 & & /// &summary&300 & & /// 删除指定的关301 & & /// &/summary&302 & & /// &param name=&level&&关数&/param&303 & & void DeleteLevel(int level)304 & & {305 & & & for (int i = level + 1; i &= maxL i++) addrs[i - 1] = addrs[i]; // 之后的关起始地址前移306 & & & --maxL // 更新总关数307 & & & WriteAddrs();308 & & }309 310 & & /// &summary&311 & & /// 更新各关起始地址列表及总关数和第1关起始地址位置312 & & /// &/summary&313 & & private void WriteAddrs()314 & & {315 & & & bw.Seek(addrs[maxLevel], SeekOrigin.Begin);316 & & & for (int i = 0; i & maxL i++) bw.Write(addrs[i]); // 各关起始地址317 & & & bw.BaseStream.SetLength(bw.BaseStream.Position); // 关起始地址列表位于数据文件最后, 用于删除关的情况318 & & & bw.Seek(24, SeekOrigin.Begin);319 & & & bw.Write(maxLevel); // 总关数320 & & & bw.Write(addrs[maxLevel]); // 第1关起始地址位置321 & & }322 323 & & /// &summary&324 & & /// 更新组名325 & & /// &/summary&326 & & void WriteGroupName()327 & & {328 & & & byte[] bs = new byte[16];329 & & & byte[] bn = Pub.Encode.GetBytes(groupName);330 & & & for (int i = 0; i & bs.Length && i & bn.L i++) bs[i] = bn[i];331 & & & for (int i = bn.L i & bs.L i++) bs[i] = 32;332 & & & bw.Seek(8, SeekOrigin.Begin);333 & & & bw.Write(bs); // 组名334 & & }335 336 & & /// &summary&337 & & /// 写关数据和通关步骤338 & & /// 注意:调用本函数前必须定位到数据文件的正确位置339 & & /// &/summary&340 & & /// &param name=&level&&关数&/param&341 & & /// &param name=&steps&&通关步骤&/param&342 & & /// &returns&本关的统计信息&/returns&343 & & string WriteLevel(int level, string steps)344 & & {345 & & & bw.Write(LevelFlag); // 关标志346 & & & bw.Write((byte)(string.IsNullOrEmpty(steps) ? 0 : 1)); // 标志:是否已通关347 & & & bw.Write(steps.Length); // 总步数348 & & & bw.Write(GetPushSteps(steps)); // 推箱子步数349 & & & bw.Write(new byte[14]); // 保留350 & & & bw.Write(levelSize.Width); // 当前关宽度351 & & & bw.Write(levelSize.Height); // 当前关高度352 & & & mans = slots = boxs = 0;353 & & & int lands = 0, walls = 0, bricks = 0;354 & & & for (int i = 1; i &= levelSize.H i++)355 & & & {356 & & & & for (int j = 1; j &= levelSize.W j++)357 & & & & {358 & & & & & bw.Write(map[i, j]);359 & & & & & switch (map[i, j])360 & & & & & {361 & & & & & & case Block.Land: lands++;362 & & & & & & case Block.Slot: slots++;363 & & & & & & case Block.Wall: walls++;364 & & & & & & case Block.Brick: bricks++;365 & & & & & & case Block.Box0: lands++; boxs++;366 & & & & & & case Block.Box1: slots++; boxs++;367 & & & & & & case Block.Man0: lands++; mans++;368 & & & & & & case Block.Man1: slots++; mans++;369 & & & & & }370 & & & & }371 & & & }372 & & & if (mans != 1) ErrorExit(true, level + 1, &必须刚好有一个工人&);373 & & & if (!string.IsNullOrEmpty(steps)) SaveLevelSteps(level, steps);374 & & & return string.Format(&{1}: {2} {3} {4} {5} {6} {7} {8}{0}&,375 & & & & Fcl.NewLine, level + 1, Pub.ToString(levelSize), walls, bricks, lands, slots, boxs, steps.Length);376 & & }377 378 & & /// &summary&379 & & /// 根据通关步骤给出推箱子步数380 & & /// &/summary&381 & & /// &param name=&steps&&通关步骤&/param&382 & & /// &returns&推箱子步数&/returns&383 & & int GetPushSteps(string steps)384 & & {385 & & & int n = 0;386 & & & foreach (char c in steps) if (((Step)c).IsBox) n++;387 & & &388 & & }389 390 & & /// &summary&391 & & /// 数据导入392 & & /// &/summary&393 & & /// &param name=&name&&数据文件主名&/param&394 & & /// &param name=&maxLevelSize&&最大关尺寸&/param&395 & & /// &param name=&tbxMsg&&显示相关信息的文本框&/param&396 & & public void Import(string name, int maxLevelSize, TextBox tbxMsg)397 & & {398 & & & try399 & & & {400 & & & & tbxMsg.Text = string.Format(&{1} =& {2}{0}&, Fcl.NewLine, name + Pub.TextExtName, name + Pub.DataExtName);401 & & & & if (!Directory.Exists(Pub.DataDirectory)) Directory.CreateDirectory(Pub.DataDirectory);402 & & & & using (StreamReader sr = new bine(Pub.TextDirectory, name + Pub.TextExtName), Pub.Encode))403 & & & & {404 & & & & & Dispose();405 & & & & & fs = new bine(Pub.DataDirectory, name + Pub.DataExtName), FileMode.Create, FileAccess.Write);406 & & & & & bw = new BinaryWriter(fs, Pub.Encode);407 & & & & & byte[] buf = new byte[32];408 & & & & & buf[4] = DataV409 & & & & & buf[5] = (byte)&#39;B&#39;;410 & & & & & buf[6] = (byte)&#39;O&#39;;411 & & & & & buf[7] = (byte)&#39;X&#39;;412 & & & & & bw.Write(buf);413 & & & & & map = new byte[maxLevelSize + 2, maxLevelSize + 2];414 & & & & & List&int& addrList = new List&int&(); // 各关起始地址列表,最后一项为第1关起始地址位置415 & & & & & addrList.Add((int)bw.BaseStream.Position); // 第1关起始地址416 & & & & & groupName = // 组名417 & & & & & int level = 0;418 & & & & & levelSize = Size.E419 & & & & & string steps = &&; // 通关步骤420 & & & & & bool isFirst =421 & & & & & for (int line = 1; ; line++)422 & & & & & {423 & & & & & & string s = sr.ReadLine();424 & & & & & & if (s != null) s = s.Trim();425 & & & & & & if (line == 1 && s != null && s.Length & 0 && s[0] == &#39;!&#39;)426 & & & & & & {427 & & & & & & & groupName = s.Substring(1).Trim();428 & & & & & & & tbxMsg.Text += &组名: [& + groupName + &]& + Fcl.NewL429 & & & & & & &430 & & & & & & }431 & & & & & & if (isFirst)432 & & & & & & {433 & & & & & & & isFirst =434 & & & & & & & tbxMsg.Text += &#: 宽x高 墙 砖 地 槽 箱 通关步数& + Fcl.NewL435 & & & & & & }436 & & & & & & if ((s == null || s.Length == 0) && levelSize != Size.Empty)437 & & & & & & {438 & & & & & & & tbxMsg.Text += WriteLevel(level, steps);439 & & & & & & & addrList.Add((int)bw.BaseStream.Position); // 下一关起始地址440 & & & & & & & level++;441 & & & & & & & levelSize = Size.E442 & & & & & & & steps = &&;443 & & & & & & }444 & & & & & & if (s == null)445 & & & & & & if (s.Length == 0 || s[0] == RemChar)446 & & & & & & if (s[0] == StepsChar)447 & & & & & & {448 & & & & & & & steps = s.Substring(1).Trim(); // 通关步骤449 & & & & & & &450 & & & & & & }451 & & & & & & levelSize.Height++;452 & & & & & & if (levelSize.Height == 1) levelSize.Width = s.L453 & & & & & & else if (levelSize.Width != s.Length) ErrorExit(false, line, &宽度不齐&);454 & & & & & & if (levelSize.Width & maxLevelSize) ErrorExit(false, line, GetMessage(&宽度太大&, true));455 & & & & & & if (levelSize.Height & maxLevelSize) ErrorExit(false, line, GetMessage(&高度太大&, true));456 & & & & & & for (int i = 0; i & levelSize.W i++)457 & & & & & & & if (!Block.IsBlock(map[levelSize.Height, i + 1] = Block.GetByte(s[i])))458 & & & & & & & & ErrorExit(false, line, &非法字符:[& + s[i] + &]&);459 & & & & & }460 & & & & & addrs = addrList.ToArray();461 & & & & & maxLevel =462 & & & & & WriteAddrs();463 & & & & & WriteGroupName();464 & & & & }465 & & & }466 & & & catch (OutOfMemoryException ex)467 & & & {468 & & & & throw new Exception(GetMessage(&内存不足&, false), ex);469 & & & }470 & & & finally471 & & & {472 & & & & Dispose();473 & & & }474 & & & tbxMsg.Text += &导入完成&;475 & & }476 477 & & string GetMessage(string msg1, bool isIncrease)478 & & {479 & & & return msg1 + &,请在“菜单 -& 选项”对话框中& + (isIncrease ? &增加& : &减少&) +&“最大关尺寸”&;480 & & }481 482 & & /// &summary&483 & & /// 数据导出484 & & /// &/summary&485 & & /// &param name=&name&&数据文件主名&/param&486 & & /// &param name=&tbxMsg&&显示相关信息的文本框&/param&487 & & public void Export(string name, TextBox tbxMsg)488 & & {489 & & & try490 & & & {491 & & & & tbxMsg.Text = string.Format(&{1} =& {2}{0}&, Fcl.NewLine, name + Pub.DataExtName, name + Pub.TextExtName);492 & & & & LoadGroup(name);493 & & & & if (!Directory.Exists(Pub.TextDirectory)) Directory.CreateDirectory(Pub.TextDirectory);494 & & & & using (StreamWriter sw = new StreamWriter(495 & & & & & bine(Pub.TextDirectory, name + Pub.TextExtName), false, Pub.Encode))496 & & & & {497 & & & & & sw.WriteLine(&! {0}&, groupName);498 & & & & & tbxMsg.Text += &组名: [& + groupName + &]& + Fcl.NewL499 & & & & & tbxMsg.Text += &#: 宽x高 总任务数 通关步数& + Fcl.NewL500 & & & & & for (int level = 0; level & maxL level++)501 & & & & & {502 & & & & & & LoadLevel(level);503 & & & & & & sw.WriteLine(&{0}[{1}]&, RemChar, level + 1); // 注释:第几关504 & & & & & & for (int y = 0; y & levelSize.H y++)505 & & & & & & {506 & & & & & & & for (int x = 0; x & levelSize.W x++) sw.Write(Block.GetChar(map[y + 1, x + 1]));507 & & & & & & & sw.WriteLine();508 & & & & & & }509 & & & & & & string steps = GetSteps(name, level); // 通关步骤510 & & & & & & if (!string.IsNullOrEmpty(steps)) sw.WriteLine(StepsChar + steps);511 & & & & & & sw.WriteLine();512 & & & & & & tbxMsg.Text += string.Format(&{1}: {2} {3} {4}{0}&,513 & & & & & & & Fcl.NewLine, level + 1, Pub.ToString(levelSize), tasks, steps.Length);514 & & & & & }515 & & & & }516 & & & }517 & & & finally518 & & & {519 & & & & Dispose();520 & & & }521 & & & tbxMsg.Text += &导出完成&;522 & & }523 524 & & void ErrorExit(bool isLevel, int idx, string msg)525 & & {526 & & & throw new Exception(string.Format(&错误:第{0}{1}:{2}&, idx, isLevel ? &关& : &行&, msg));527 & & }528 529 & & public void Dispose()530 & & {531 & & & if (br != null) br.Close();532 & & & if (bw != null) bw.Close();533 & & & if (fs != null) fs.Close();534 & & & br =535 & & & bw =536 & & & fs =537 & & }538 & }539 }540
分享到:   
评论列表(网友评论仅供网友表达个人看法,并不表明本站同意其观点或证实其描述)

我要回帖

更多关于 推箱子 的文章

 

随机推荐