该游戏的一个现代版本如今在sokoban pro网站上可以玩了。因为所有的最重要的部分(如读取/写xml,移动和绘画)在本文的源代码中提供,所以我决定在此讨论第一个原始的版本。
最近的版本(v1.0b)相对于现在这个版本包括了下列几个方面的改进:
·"官方"beta发行版
·增加菜单支持
·我发现使窗口的大小在每一级中改变是十分令人恼火的事情,所以在当前版本中它变为固定的
·你可以在不同级间来回跳动,但是仅限于你以前已经完成的级上
·针对级别的撤消功能
·splash屏幕和图标
·修改了许多错误
·也许还有其它一些
在游戏开始时,你可以创建一个新的玩家或选择一个现有的玩家。既然sokoban pro能够保存你的进度,那么你还可以选择是否你想要继续你的上一次游戏。在创建一个玩家后,你可以选择一个级别集合。一个级别集合包含你喜欢的尽可能多的级别。sokoban pro带有原来的boxworld游戏中的前40个级别。级别集合被存储在xml文件中,这意味着你可以从互联网上不同的sokoban站点下载级别集合。你还可以创建你自己的级别。当你把它们放到级别目录中时,sokoban pro将自动地识别级别集合。
你用一个xml文件来实现保存游戏。它保存最后玩完的级别集合和最后的玩的级别,这样你可以从你上次玩游戏时离开的地方继续玩下去。另外,它还保存你已经完成的级别及相应的得分(移动和推的数目)。如果你重玩一级并且你的执行更好一些的话,那么你的分数将被更新。
基本上,该游戏由下列几个类组成:
·levelset-包含所有的有关一个级别集合(作者信息,级别数目,等等……)的信息。它也把级别集合xml中的级别装载到内存中。
·level-代表在一个级别集合中的一个级别。这里发生的最重要的事情是它追踪所有的你的移动。在玩家移动或推一个盒子时,它更新在一个级别中的项。它更新相应的图形并实现撤消功能,并且最后在屏幕上绘制出级别。
·playerdata-追踪所有的玩家信息。基本上,它反映出你的savegame。
·board(form)-主表单处理所有的玩家输入并且初始化所有的对象。
·players(form)-让你创建一新的玩家或选择一个现有的玩家。
·levels(form)-让你选择一个你想要玩的级别集合。
该应用程序使用读取和写xml文件。例如,下列方法-savelevel()-在玩家完成一级后它存储玩家数据。
| public void savelevel(level level) { xmldocument doc = new xmldocument(); doc.load(filename); xmlnode lastfinishedlvl = doc.selectsinglenode("//lastfinishedlevel"); lastfinishedlvl.innertext = level.levelnr.tostring(); xmlnode setname = doc.selectsinglenode("/savegame/levelsets/" +"levelset[@title = \"" + level.levelsetname + "\"]"); xmlnode nodelevel = setname.selectsinglenode("level[@levelnr = " + level.levelnr + "]"); if (nodelevel == null){ xmlelement nodenewlevel = doc.createelement("level"); xmlattribute xa = doc.createattribute("levelnr"); xa.value = level.levelnr.tostring(); nodenewlevel.attributes.append(xa); xmlelement moves = doc.createelement("moves"); moves.innertext = level.moves.tostring(); xmlelement pushes = doc.createelement("pushes"); pushes.innertext = level.pushes.tostring(); nodenewlevel.appendchild(moves); nodenewlevel.appendchild(pushes); setname.appendchild(nodenewlevel); } else{ xmlelement moves = nodelevel["moves"]; xmlelement pushes = nodelevel["pushes"]; int nrofmoves = int.parse(moves.innertext); int nrofpushes = int.parse(pushes.innertext); if (level.pushes < nrofpushes){ pushes.innertext = level.pushes.tostring(); moves.innertext = level.moves.tostring(); } else if (level.pushes == nrofpushes && level.moves < nrofmoves) moves.innertext = level.moves.tostring(); } doc.save(filename); } |
| xmlnode setname = doc.selectsinglenode("/savegame/levelsets/"+"levelset[@title = \"" + level.levelsetname + "\"]"); |
| xmlnode nodelevel = setname.selectsinglenode("level[@levelnr = "+ level.levelnr + "]"); |
| //绘制级别 for (int i = 0; i < width; i++){ for (int j = 0; j < height; j++){ image image = getlevelimage(levelmap[i, j], sokodirection); g.drawimage(image, item_size + i * item_size, item_size + j * item_size, item_size, item_size); //设置sokoban的位置 if (levelmap[i, j] == itemtype.sokoban levelmap[i, j] == itemtype.sokobanongoal){ sokoposx = i; sokoposy = j; } } } |
Java Asp PHP .Net XML C/C++ CGI VB Jsp J2ee J2se J2me EJB Servlet Tomcat Resin Struts Weblogic Eclipse ANT GUI JMS Web servise IDEA Webphere Hibernate Spring Jboss Applet Swing Socket Javamail Perl Ajax P2P 安全 模式 框架 测试 开源 游戏
Windows XP Windows 2000 Windows 2003 Windows Me Windows 9.x Linux UNIX 注册表 操作系统 服务器 应用服务器