推(搬)箱子,又名Sokoban,仓库番等,是一款堪称古玩级的电脑游戏。
提起它,笔者相信没什么人会感觉到陌生,更没什么生物会连听都没听说过。它的发展历史之久远,甚至超越了俄罗斯方块(1988年电脑游戏化)。
这款游戏最初起源于日本,是个很难争辩的事实(我知道有人反对,但笔者确实找不到什么有力的反对证据)。他由日本人(哎……)今川宏行在1981年创立游戏规则,并于1982年经日本软件公司Thinking Rabbit正式发布。比较遗憾的是,早期的推箱子并没有PC版,笔者在网络上搜索到的老版游戏也大多为90年以前的Mac OS下程式。
但说起真正令推箱子风靡于PC机的,却该感谢我们的台湾同胞李果兆先生。是他在1994年开发的仓库世家,才真正令推箱子游戏在世界各地大受推崇;仔细说来,推箱子这款小游戏之所以能有今时今日的声望与地位,固然有今川宏行的开创之功,但若说到贡献最大,承前启后的,则非中国台湾的李果兆先生莫属。
推箱子游戏的规则非常简单,就是用尽量少的推动或移动把所有箱子都推到目标点上。箱子只能推动而不能拉动;一次只能推动一个箱子。然而,尽管它的规则是很简单的,但对于不同难度的关卡,所需要的脑力却是截然不同的,有些关卡可能会花费您几个小时、几天甚至几个月的时间,也正是这种简单性和复杂性的结合,最终令推箱子类游戏风靡全球!
本回笔者在Blog中提供的,就是一款Java版推箱子游戏的简单实现。
笔者设定[上、下、左、右]为方向控制 ,[S]键为后退到上一步操作,[ESC]为重新开始当前关卡,点击键盘上对应关卡的数字键可以直接选关,需要注意的是笔者以HP限制了角色的移动次数,HP归0则挑战失败。
目前版本仅提供有5关,有需要者可参考同类游戏自行扩充,游戏源码在jar内。
下载地址1(由于google code维护,需要等此文发表的隔天才能开放下载):http://code.google.com/p/loon-simple/downloads/list
下载地址2:http://download.youkuaiyun.com/source/1397545
游戏截图:
核心代码:
Sokoban.java
package org.loon.game.simple.sokoban.control;import java.awt.Color;import java.awt.Font;import java.awt.Graphics;import java.awt.Image;import java.awt.event.KeyEvent;import org.loon.game.simple.sokoban.GraphicsUtils;import org.loon.game.simple.sokoban.LSystem;import org.loon.game.simple.sokoban.SimpleControl;/** * Copyright 2008 - 2009 * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy of * the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. * * @project loonframework * @author chenpeng * @email <a title="" href="http://hi.baidu.com/ceponline" mce_href="http://hi.baidu.com/ceponline" target="_blank">ceponline</a>@yahoo.com.cn * @version 0.1 */public class Sokoban extends SimpleControl { /** * */ private static final long serialVersionUID = 1L; private Image backImage = GraphicsUtils.loadImage("image/back1.jpg"); private Image screenImage; // 墙壁图 private Image floorImage[]; // 角色精灵 private RpgSprite sprite; // 窗体显示图 private Graphics screen; private String message = "按下 [Enter] 开始进行游戏"; private String m_stageName[] = { "关卡1", "关卡2", "关卡3", "关卡4", "关卡5", "关卡6", "关卡7" }; private int CS = 32; private int maxX, maxY, comps; private int stageNo; private boolean complete[]; private boolean boxMove[][]; private int hp[]; private int stageStates[][][]; private int ons[][]; private int role[]; private int rolex[]; private int roley[]; private int mapx[]; private int mapy[]; private int sleep = 0; private boolean succeed = false; private Stage stage; public Sokoban(Stage stage) { this.stage = stage; this.floorImage = new Image[4]; this.sprite = new RpgSprite("image/role1.gif"); this.maxX = 16; this.maxY = 13; this.comps = 0; this.complete = new boolean[stage.getMaxStageNo()]; this.boxMove = new boolean[stage.getMaxStageNo()][1500]; this.ons = new int[stage.getMaxStageNo()][1500]; this.hp = new int[stage.getMaxStageNo()]; this.stageStates = new int[stage.getMaxStageNo()][maxY][maxX]; this.role = new int[stage.getMaxStageNo()]; this.rolex = new int[stage.getMaxStageNo()]; this.roley = new int[stage.getMaxStageNo()]; this.mapx = new int[stage.getMaxStageNo()]; this.mapy = new int[stage.getMaxStageNo()]; for (int j = 0; j < 4; j++) { floorImage[j] = GraphicsUtils.loadImage("image/back" + (j + 1) + ".gif"); } this.screenImage = GraphicsUtils.createImage(CS * maxX + CS, CS * (maxY + 1) + 32, true); this.screen = screenImage.getGraphics(); for (stageNo = 0; stageNo < stage.getMaxStageNo(); stageNo++) { this.setupStage();