您的位置:首页 > 其它

扫雷游戏制作全过程 03 时间伪动画

2012-01-09 12:45 549 查看
现在把地雷模块先放一下,开始设计时间模块。可以用JLabel来显示数字,也可以用其来显示表示数字的图片。我选择了后者。其实最开始想做成时间翻页的效果,其实也能实现,但是如果使用下面的方法真的过于麻烦了。

有一点要注意的是:

我们显示图片时应该等到 图片被下载完成后才启动装载过程,然后显示完整的图像。但是getImage可以在没有载入全部的图像的情况下立即返回。如果创建一个显示多幅图片的动画,可以使用getImage来将所有的图片载入一个数组,以便JLabel有序的显示,但是动画的第一次运行不一定是有效的,因为JLabel类要等到整个图像被装载后才显示它。

为了避免这个问题,Java提供了MedioTracker类。

MedioTracker能自动追踪一个或多个图片的装载进度。我们可以使用它阻塞其他的操作直到一个或多个图像(相关连的)被完全载入。

我把它实现的全过程写到了loadPicture方法中:(这个是可用的)

public void loadPicture()
{
MediaTracker tracker = new MediaTracker(this);
for(int i=0;i<images.length ;i++)
{
images[i] = getToolkit().getImage("image/Time/"+i+"t.png");
tracker.addImage(images[i], i);
}
try
{
tracker.waitForAll();
}
catch(InterruptedException ie){}
}
代替了最初可能各种显示有误的(这个是有问题的):

public void loadPicture()
{
for(int i=0;i<images.length ;i++)
{
images[i] = getToolkit().getImage("image/Time/"+i+"t.png");
}
}


您可以在源代码中注释掉上面的正确的方法,把原来注释掉的有问题的方法还原,看看效果如何。

当然,有问题的这个方法运行起来并不是每一次都有问题,多试几次,或者增加图片的个数效果就比较明显了。

在这里,我将两个方法分别运行的效果图传上来了:





我们接下来说如何来实现时间为动画的。首先我们将0-9十张图片加载到了images数组中,

然后启动一个线程,添加一个计数器,每隔1秒自加1.(根据具体情况,也可以0.1s。。。)

我设定了分钟和秒两个大块,而又细分为四个动态改变的小块。其改变的时间和范围由左到右分别是:

0-5*600s

0-9*60s

0-5*10s

0-9*1s

其实仅仅通过时间刷新来判断是否达到图片的刷新条件就OK了。具体实现的代码如下:

好像这段代码有点太繁琐了,大部分都是在修饰界面。关键的代码就是上面的loadPicture,还有下面的那个重写的paintComponent的图片与时间的对应函数关系。

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.MediaTracker;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.border.BevelBorder;
import javax.swing.border.SoftBevelBorder;

class TimePanel extends JPanel
{
private JPanel panel0 = new JPanel();
private JPanel panel1 = new JPanel();
private JPanel panel2 = new JPanel();
private MicPanel micpanel[] = new MicPanel[4];
/*********************************************/
private Image images[] = new Image[10];
private long current = 0;
/**初始化的时候默认不显示跑*/
private boolean stop = true;

public static void main(String[] args)
{
JFrame frame = new JFrame();
TimePanel tpanel = new TimePanel();
frame.add(tpanel);
frame.pack();
frame.setVisible(true);
}

public TimePanel()
{
loadPicture();
initOther();
panel1.add(micpanel[2] = new MicPanel(10,6),BorderLayout.WEST);
panel1.add(micpanel[3] = new MicPanel(1,10),BorderLayout.EAST);
panel2.add(micpanel[0] = new MicPanel(600,6),BorderLayout.WEST);
panel2.add(micpanel[1] = new MicPanel(60,10),BorderLayout.EAST);
startTime();
reStarted();
}

public void loadPicture()
{
MediaTracker tracker = new MediaTracker(this);
for(int i=0;i<images.length ;i++)
{
images[i] = getToolkit().getImage(i+"t.png");
tracker.addImage(images[i], i);
}
try
{
tracker.waitForAll();
}
catch(InterruptedException ie){}
}

/*
public void loadPicture()
{

for(int i=0;i<images.length ;i++)
{
images[i] = getToolkit().getImage(+i+"t.png");
}
}
*/

public void startTime()
{
stop = true;
MyRunnable myrun = new MyRunnable();
Thread thread = new Thread(myrun);
thread.start();
}

public void initOther()
{
panel0.setLayout(new BorderLayout());
panel1.setLayout(new BorderLayout());
panel2.setLayout(new BorderLayout());
/*panel1放分钟,panel2放秒*/

panel0.add(panel1,BorderLayout.EAST);
panel0.add(panel2,BorderLayout.WEST);
/*不透明的话就不美观了*/
panel0.setOpaque(false);
panel1.setOpaque(false);
panel2.setOpaque(false);
this.setOpaque(false);
/*设置突出的边框*/
panel1.setBorder(new SoftBevelBorder(BevelBorder.RAISED));
panel2.setBorder(new SoftBevelBorder(BevelBorder.RAISED));
panel0.setBorder(new SoftBevelBorder(BevelBorder.RAISED));//(BevelBorder.LOWERED));
add(panel0);
try
{
UIManager.setLookAndFeel("com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel");
SwingUtilities.updateComponentTreeUI(this);
}
catch(Exception e) { e.printStackTrace(); }
}

class MicPanel extends JPanel
{
private int cut_time;
private int limit_time;

public MicPanel(int copy_cut,int copy_limit)
{
//super();
cut_time = copy_cut;
limit_time = copy_limit;
repaint();
}
/*原来这是非常有用的,要重写这个方法*/
public Dimension getPreferredSize()
{
return new Dimension(images[0].getWidth(this),images[0].getHeight(this));
}

public void paintComponent(Graphics g)
{
super.paintComponent(g);
g.drawImage(images[(int)(current/cut_time)%limit_time],0,0,this);
}
}

public void reStarted()
{
current = 0;
stop = false;
}

public void stoped()
{
stop = true;
}

class MyRunnable implements Runnable
{
public void run()
{
while(true)
{
if(!stop)
{
try{
current++;
Thread.sleep(1000);
micpanel[0].repaint();
micpanel[1].repaint();
micpanel[2].repaint();
micpanel[3].repaint();
}catch(InterruptedException ie){}
}
}
}
}
}


图片和源代码已经上传。(关于MediaTracker的部分,我是参考的《java程序设计进阶教程》(清华大学出版社))。

看完了这个例子,我想您应该也能想到如何很麻烦的制作出时间在纸上翻页的效果来,简单的伪动画也可以通过修改sleep的时间片段的长短来实现。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: