桌面弹球是游戏中常见的游戏,从以前的掌上游戏机到如今的手机游戏,都是一个十分经典的游戏。玩家控制一个可以左右移动的挡板去改变运动中小球的移动方向,目的是用小球消除游戏屏幕中的所有 砖块 , 不同颜色的砖块有着不一样的效果, 例如: 黄色砖块五魔法效果 、 粉色的砖块弹球可以穿越 , 咖啡色的砖块可以使小球加速,绿色的砖块可以使小球发色子弹 等等。本 节 主要介绍如何实现一个简单的弹球游戏,让读者了解“动画”的实现原理。
其实所谓的动画就是一张一张图片的不断演示,让人看上去有动感,最后 使用 Java 中的 双缓冲 去重复绘图, 防止游戏的屏幕闪烁 , 我开发的 桌面弹球游戏的效果如图所示 :
一、 动画原理
简单地来说,动画是利用人的视觉暂留的生理特性,实现出来的一种假象,只要每隔一段时间(这个时间少于人的视频暂留时间)就重新绘制一幅状态改变的图片,就能造成这种“动”的假象。我们在程序中不断的进行 擦除,然后不断的画出新的图片 ,对程序来讲,只需要在短时间内进行多次的绘画,并且每次绘画都需要改变绘画的相关值,就可以达到“动画”的效果。
二、 弹球游戏开发
在做游戏前,得先实现一个主界面,然后往界面上添加各种物件以及图片。在这个游戏的开发中,我们有 6 个类( BallUI 主界面, Ball 弹球类, MapUI 地图类, Stick 挡板类, Shot 子弹类, Magic 魔法类),这些类实现不同的效果,使弹球游戏玩的更有意思。在下面将介绍主要的几个类
三、 Ball 弹球类
这个类是一个线程,当游戏启动的时候,界面中会出现一个小球,点开始按钮后,线程启动,小球开始运动,其中小球的速度是线程的 sleep 时间和小球在界面中位置的改变这两个因素决定的。实现小球的动其实很简单,看下代码就知道:
// 先擦除,把颜色设为背景色(黑色)
g .setColor(Color. BLACK );
g .fillRect( x0 , y0 , 15, 15);
// 再在下一刻画出小球(白色),假设坐标都加 1
g .setColor(Color. WHITE );
g .fillRect( x0 +1 , y0 +1 , 15, 15);
然后这个处理很多主要的操作:
1. 游戏输赢的操作。当小球移动时,用挡板来实现小球的反弹,但当没接住的时候,小球会往下掉,这时就会判游戏结束。如图:
<!--EndFragment-->
判断游戏是否胜利,只有把所有的砖块都打掉,这时弹出对话框,显示你已经胜利,如图:
1. 这个类最主要的任务是来判断小球与砖块的碰撞、与墙壁的碰撞以及与挡板的碰撞。当碰撞时,用不同的方法来处理小球下一时刻的运动,也就是说,当小球碰到挡板时要反弹,碰到墙壁时也要反弹,这些都还好处理;但是当小球碰到不同砖块时候,要产生不同的效果,这是游戏比较难的地方,不同的效果调用的方法也就不同。
四、 MapUI 地图类
这个类是来创建地图,在文档存储了一份文件,是对这个地图的解释,当调用这份文件的时候,地图自动会在界面中创建。
由于涉及到文件,那么不可避免的要使用文件输入流,创建文件输入流的对象去读取文件,把读到的内容用一个 char 二维数组存储起来,然后再主界面中调用这个类,实现二维数组转换成地图的方法,这样地图就形成了。
五、 主界面 BallUI
这个类是去调用所用的类,从而实现弹球游戏。启动不同的线程,使小球的运动形式不一样以及游戏的可玩性得到提高。在调用线程后,当游戏结束时,记得关闭所有线程,不然浪费 CPU 资源。
最后我想谈的是双缓冲处理屏幕的闪烁问题,在游戏的开发中,让我头疼的就是屏幕的闪烁,不仅看的不爽,且对眼睛的伤害也是极大的。这里我们有三个主要的实物(小球、砖块、挡板),我们分别对这些物体进行重绘,从而解决闪屏的问题。看如下代码:
public void paint(Graphics g){
// 在重绘函数中实现双缓冲机制
offSreenImage = this .createImage(500,490);
// 获得截取图片的画布
Graphics gImage= offSreenImage .getGraphics();
// System.out.println(gImage.getColor());
// 获取画布的底色并且使用这种颜色填充画布,如果没有填充效果的画,则会出现拖动的效果
gImage.setColor(gImage.getColor());
// 有清楚上一步图像的功能,
gImage.fillRect(0, 0, 500, 490);
// 调用父类的重绘方法,传入的是截取图片上的画布,防止再从最底层来重绘
super .paint(gImage);
//重绘地图,也即是重绘砖块
for ( int i=0;i< chars . length ;i++){
for ( int j=0;j< chars [i]. length ;j++){
if ( chars [i][j]!=0){
char c = chars [i][j];
if (c!= ' ' ){
String path = "images/" +c+ ".jpg" ;
//根据路径构造图片对象
ImageIcon icon = MapUI. createImageIcon (path);
gImage.drawImage(icon.getImage(), 35*j, 15*i, null );
}
}
}
}
//挡板的重绘
Stick stick = new Stick();
int x=Stick. x0 ;
gImage.setColor(Color. red );
stick.createStick(gImage, x-2-1,460-2-2-1-2-2, 100, 15);
//小球的重绘
Ball ball= new Ball();
ball.createBall(gImage, Ball. x0 , Ball. y0 );
// 将接下来的图片加载到窗体画布上去,才能得到每次画的效果
g.drawImage( offSreenImage , 0, 0, null );
}
最后,由于本人知识的不足,游戏中还存在很多问题,且游戏的效果也不是特别的好,游戏的可玩性不高。但总体来说,这次游戏的开发让我的编程能力得到提升,同时也能处理一些简单的问题。
<!--EndFragment--><!--EndFragment-->
<!--EndFragment-->