开源中国-程序员在线工具:
游戏由障碍、空地、箱子、终点与玩家组成。
通过上下左右控制玩家推动箱子。当箱子的推动方向没有障碍时,向前移动到新的位置,玩家也向前移动一步。
当所有箱子都处于终点时,游戏胜利,按回车键进入下一关。当完成所有关卡时,按回车键结束游戏。
在游戏中按R建重新开始本关。
从网上下载推箱子游戏的地图素材与背景音乐。
首先最容易想到的是一个管理地图信息的 Map 类,其中应该包括一个关卡地图中的所有信息。
其次应该有一个 DataManager 类来从文件中读取地图、读取图片,并能根据读入的地图文件与关卡编号创造出所需的 Map 类的对象。
游戏中最不能缺少的是 GameManager 类,用于管理游戏的所有逻辑。
最后是一个窗口,用于综合所有的管理类,将输入传入 GameManager 类以及显示游戏画面。
因此设计出Map类,其中有4个私有成员:二维数组 byte map[ ][ ] 储存地图上的元素,int level 储存当前地图的等级,manX、manY 表示玩家当前所在的位置。
对于每一种地图元素,我们都需要用一个数字来表示。因此我们定义一些 byte 类型的常量。 考虑到进入下一个关卡与重置本关都要新建一个Map对象,因此构造方法有两种,一种传入level,一种则不需要。 /** 构造一个地图对象,不设定等级 */
/** 构造一个地图对象并指定等级 */
构造Map时,我们只需要传入表示地图元素的二维数组与等级即可,玩家的位置可以由地图计算得到。
这里没有判断地图的合法性,即主角是否只有一个、箱子与终点是否对应以及谜题是否有解。因为这里的地图是事先写入文件中的,在写入时就应该保证合法性。
/** 初始化一个地图对象 */
// 判断类型k是否为主角
/** 计算主角在地图中的位置 */
在实际使用中,我们需要有公有方法来获得地图的一些信息。
/** 获取主角在地图中的X坐标 */
/** 获取主角在地图中的y坐标 */
此时,游戏基础的地图类就完成了。
GameManager 是游戏中最重要的类,它负责管理游戏中的所有行为,是一个游戏的核心。
类中首先要有一个Map对象,然后还要有一个方法能够接受新的Map对象创建新游戏。
接下来是游戏的操作,玩家按下上下左右四个方向键,能够向四个方向移动或推箱子。
对于这个功能,我们没有必要写4个方法。只需要一个能接受方向变量的方法即可。
移动的过程分两种情况讨论,前方为空地、前方为箱子且能推动。
如此一来游戏的主逻辑就构建完成了。
最后是一些传递信息的方法。
/** 获取游戏是否可操作 */
/** 设置游戏是否可操作 */
DataManager 要做的很简单,从文件中读取数据即可。
/** 读取文件中的地图数据 */
对于地图,仅仅读取文件中的数据还是不够的,还要能返回一个 Map 对象。
// 获取等级为level的地图的一个副本
在读取地图文件时还要用一个变量来记录关卡总数。
由于本游戏只需要一个固定背景音乐,不需要音效,所以 SoundManager 任务很简单。
以下是该类中的一些私有变量。
初始化 GameFrame 时,需要新建三个管理器的对象,添加监听器。
/** 构造一个游戏窗体 */
为了获取贴图的坐标,还要更新坐标信息。
// 更新地图信息与贴图位置
当用户有按键操作时,根据不同的输入进行不同的处理。
由于操作后画面有可能变化,所以要调用repaint()重绘画面。
若按键结束后游戏胜利,则设置游戏状态为 false 。
为了防止屏幕闪烁,采用双缓冲技术。
至此,一个简单的推箱子游戏就完成了。
关键:推箱子的逻辑、双缓冲绘图。