rel="File-List" href="file:///C:%5CDOCUME%7E1%5CADMINI%7E1%5CLOCALS%7E1%5CTemp%5Cmsohtml1%5C01%5Cclip_filelist.xml" />
这两天家里断网了,以前早就想过做这个俄罗斯方块游戏,也复习一下Swing(找工作啦). 看netbeans工程的创建日期, 是6.21,只是搞了个JFrame, 现在正好做完。
源代码
设计
随机生成一个物体
如果物体不可以再移动{
结束游戏
}
否则{
侦听键盘
判断键盘动作是否有效(撞墙或撞已经存在的物体)
如果有效{
移动或者变形
}
否则{
物体是否接触到了已经存在的物体
如果是{
把物体加入到已经存在的物体列表里, 消除可以消除的行
随机生成下一个物体, 执行这个流程
}
否则{
移动或者变形
}
}
此外, 还有一个独立的线程, 在没有键盘事件的情况下, 物体自动下落。 随机生成物体也是在一个独立的线程里实现的, 虽然不必要。
实现思路: 一点点波折
把整个窗口划成一个个的正方形格子, 物体就在格子里步进。每个格子的状态: 有物体,没有物体,用一个比特位或者一个int就可以表示, 整个格子可以表示为一个二维或者一维数组。
根据物体所在的位置, 可以映射到前面提到的数组, 进而判断物体的有效性。
但这个方法除了实现映射的繁琐外, 物体的位置不准确: 有时, 只做水平移动时, 纵坐标值也会改变。行不通了。
后来发现Area类有一些方法,直接就在物体上操作的:相交, 变形等。简单明了就用它了。
一些编码说明
×每个物体由两个rectangle构成, 见Unit包。 物体有一个唯一的编号, 当物体被随机生成时, 这个标号被引用来生成相应的物体(工厂方法??)。
这两个rectangle被add到同一个Area allInOne, 通过allInOne的getBounds(), 可以确定物体的中心, 用以旋转物体
从现在的实现来看, 任何样式的物体只要是被这样组合起来的, 都是可以被接受而不必修改其他部分的代码。
进一步来说, 任何样式的图形, 只要是由方块合起来的都可以接受的。
× 键盘事件侦听
侦听方向键: 上, 变形; 下, 加速; 左, 左移; 右, 移动。
当键盘事件发生后, 先根据这个事件生成一个AffineTransform, 在原来物体上实行这个AffineTransform, 产生一个新的物体。 如果新物体有效, 对原物体进行变换, 否则。。。
× 边界检测
预先定义左, 右, 底三个不可见的Area, 就是边界, 如果一个物体和这三个Area有交, 就撞墙了
× 消除
物体下落时, 撞到已经存在的物体时, 就把这个物体加入到已经存在的物体列表里。我并没有实现这样一个列表, 而是定义了一个Area allBlocks, 已经存在的物体都被加入到这个Area。
当一个物体被加入后, 通过这个物体的allInOne变量的getBounds知道哪些行可能受到了影响。 在allBlocks中扫描这些行, 如果某一行可以被消除, 在allBlocks中得到这一行上面的物体Above和下面的物体Below,把Above和Below合起来, 这一行就是被消除了。
让这个游戏更有趣: 一些常用的方法
× 加入音乐
× 加入数据统计
× 加入联网
× 来点动画,卡通
× 3D化
× 设定级别: 随着级别的增加,增加物体类型和物体下落速度, 增加构造复杂的物体
× 物体由图片覆盖
× 当某些行被消除后,Below的某些列可能出现空缺, 而对应的Above列是有物体的, Above的这个列可以继续下落
× 来点隐藏控制信息, 来点惊喜
× 提示下一个或者多个物体, 这样玩家就可以作出更多选择
× AI: 电脑怎么玩俄罗斯方块
一个小游戏也可以做的如此复杂。 还在网上看到这个游戏做了个毕业设计的, 4
W多字的报告,真夸张(厉害?)。
附:
1. 个人练习,粗糙(ugly?) 没有严格的测试。
2. 最近看了TopLanguage, 非常的厉害, 看了后感觉到自己简直要掌握世界的真理了。
3. Java API 做的很好
4. 游戏挺简单, 特别是熟悉API后, 实现起来就快了
5. 或许, 我可以一直扩展这个游戏, 让他完美
|