`
NewTamato
  • 浏览: 101521 次
  • 性别: Icon_minigender_2
  • 来自: 北京
社区版块
存档分类
最新评论

java游戏编程3

阅读更多
大家可能注意到了上面例子中的我们下降的圆看起来不是很清晰,带着很严重的闪烁。这种现象在写游戏程序中是普遍存在的现象。 这是由于我们的repaint()函数导致的结果,由于它在调用paint()函数前会自动清除屏幕,所以在一个毫秒内我们会看到一个空白的屏幕,在快速的变换操作中就出现了闪烁现象。

  解决这种闪烁现象有几种方法,下面是两种方法的列举说明,其他的方式大家可以自己尝试。

  第一种:我们始终不清除屏幕显示,但是这个方法会带来个附作用,我们下降的圆不在是一个圆了,而是一条直线,因为它的下降过程中没有了断点,保留了所有的圆球的影象。我们只要在Ball.java内加上如下代码update(Graphics g) {paint(g)},你就会看到一条很长的线拉出来。有兴趣的朋友可以试试。

  第二种:使用双缓冲机制(Double buffering)

  现在大部分的游戏都是采用双缓冲机制来解决屏幕的闪烁现象,我们就以此为例来进行说明,有关缓冲区及相关缓冲机制的概念,大家可参考附录的缓冲说明。

  而我们的程序中简单的说就是在显示我们想要的图画之前,把所有的图画先在后台绘制好并存放到相应的图像变量中去。当需要显示时直接复制到前台屏幕就可以了。

  具体实现:

   1.首先我们用createImage方法新建一后台图像类变量

   2.然后使用getGraphics()方法得到当前图像的图形关联

   3.在后台处理所有相关的处理,如清除屏幕,后台绘画等等

  当完成所有的后台工作后,复制已经绘制好的图像到前台,并覆盖前台的存在图像。这样我们的所有操作都是在后台前行,在屏幕显示新的图像前,这些内容都已经存在于后台了。所以你也将在任何时刻都看不到空屏幕的存在。也即代表闪烁消除了。

  下面我们来看看相关的代码说明:

  在开始之前我们得先在程序的开始部分声明两个实例变量用来存储后台图画。如下:

private Image bgImage;
private Graphics bg; 


  然后我们利用update()方法来实现双缓冲机制。

  Update()方法要实现下面三个步骤:

   1.清除屏幕上的组件

   2.设置相关联组件的前景色

   3.调用paint方法重画屏幕

public void update (Graphics g)
{

// 初始化buffer
if (bgImage == null)
{

bgImage = createImage (this.getSize().width, this.getSize().height);
bg = bgImage.getGraphics ();

}

// 后台清屏,即设置圆球组件和后台一样的颜色,大小
bg.setColor (getBackground ());
bg.fillRect (0, 0, this.getSize().width, this.getSize().height);

// 绘制相应的元素组件
bg.setColor (getForeground());
paint (bg);

// 在屏幕上重画已经绘制好的圆
g.drawImage (bgImage, 0, 0, this);

}



  此处g 为屏幕图形,bg为g的后台关联。而bgimage包含了bg图形。请于此处来看看我们的源代码例子及演示效果。

  改变运动方向

  我们已经解决了动画的两个很重要的问题,移动动画和闪烁消除。但是我们很快会发现一个问题,球从屏幕顶上落下来后,就不见了。这可不是我们所需要的。我们要的是一个生动的画面。如何让我们的球不穿过屏幕而始终在屏幕上活动呢?在开始之前,我建议大家自己想办法解决,如果你能自己处理好了。你的水平将会有一个很大的提高。如果没有想出好办法,没关系,下面我们将很详细的说明球的方向改变的技术。

  不知道大家注意了没有,在上面我们说到球的移动时,我们是通过增加y的值,让线程重画新的圆位置和图形。如果改变y的值的大小球的下降速度也会改变。不错,这就是我们的解决方法 ,我们只要用一个变量来存储这个速度的大小而不用固定的值。在线程执行也即run方法处我们用代码改变速度的方向,球的方向也会改变。即设置这个变量”speed”为”-1”。当然在设置值前我们要进行判断,你是想让球穿过屏幕从别一边开始显示,还是来回反弹呢!如果想来回反弹,我们只要不让球的半径值超过applet屏幕显示区域就可以了。此处我们用r/2来表示球的半径。

//反弹下落球
if (y > appletsize_y – r/2)
{

// 改变方向
x_speed = -1;

}
// 反弹上升球
else if ( < r/2)
{

// 改变方向
x_speed = +1;

}



  至于如何让球穿过从屏幕顶上重新下降,我们在此没有说明,也不会说明了。留给大家自己去想想,已经很简单了。在下面我们附上了两种方式的源代码和执行文件。如果大家运行程序,大家可能会发现,我们的球的大小和速度有一些改变。这里是为了更好的反应演示效果。
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics