您的位置:首页 > 编程语言 > Java开发

java基础 --- 简单的动画

2007-04-05 01:51 465 查看
java基础 --- 简单的动画

这篇主要是写在Swing程序中如何制作动画的效果。我们都知道游戏动画主要是一些连续的图片通过快速播放,由于这些连续的图片变化不是很大,因此使我们的眼睛产生影象的残留,这样就能造成动画的效果。一般以每秒24帧的速度播放图片,那么我们就感觉不出图片的停顿。
在GUI的程序中,我们可以通过线程来控制播放的速度,通过绘制不同的图片来产生动画的效果。比如:

while(播放==true)
{
绘制当前图像;
暂停时间;
if(当前图像==最后一张图像)
当前图像 = 第一张图像;
else
当前图像 = 下一张图像
}

这种方法有时候并不是最好的解决方法,因为需要很多张的图片,加载的时候就会很耗内存。特别是在游戏中,速度应该是是首先考虑的因素。那么我们还有另外一种方式,只需要1张图片,而这张图片将一些连续的动作绘制在里一起。我们仅需要不停的改变这张图片的某个位置就可以达到动画的效果。比如下面这张图片:





Graphics类中有个重载过的drawImage()方法,里面有很多的参数:
public abstract boolean drawImage(Image img,
int dx1,
int dy1,
int dx2,
int dy2,
int sx1,
int sy1,
int sx2,
int sy2,
ImageObserver observer)
首尾两个参数和其他的drawImage方法一样,这里就不再做介绍。主要是中间这8个参数。
dx1,dy1,dx2,dy2表示需要绘制到窗口的某个区域,其中dx1,dy1表示该区域的左上角坐标。dx2,dy2表示该区域的右下角坐标。
sx1,sy1,sx2,sy2表示需要绘制图片上哪个区域到窗口上,其中sx1,sy1表示该区域的左上角坐标。sx2,sy2表示该区域的右下角坐标。
下面我们就可以使用这个方法来让上面这张图片动起来。

public class EyesNext extends JFrame {

private Image image = new ImageIcon("Images/SERIAL.gif").getImage();
private int index;

public EyesNext() {
init();
}

void init() {
this.setUndecorated(true);
setSize(250, 250);
createContent();
setVisible(true);
}

private void createContent() {
MediaTracker tracker = new MediaTracker(this);
tracker.addImage(image, 0);
try
{
tracker.waitForID(0);
}
catch (InterruptedException e1)
{
e1.printStackTrace();
}
JPanel jpanelForm = new JPanel() {
protected void paintComponent(Graphics g) {
g.drawImage(image, 0, 0, 250, 250, index, 0, index + 250, 250,
this);
}
};

this.getContentPane().add(jpanelForm);
}

public static void main(String [] args) {

final EyesNext eyes = new EyesNext();
Thread thread = new Thread() {

public void run() {

while (true)
{

try
{
Thread.sleep(100);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
eyes.index = eyes.index + 250;
if (eyes.index >= 2000)
{
eyes.index = 0;
eyes.repaint();
}
else
{
eyes.repaint();

}
}
}
};
thread.start();

}

}

不过这种方法也只适合绘制一些简单点的图片。比如象上面那张,只有8个图象,并且是单行的。但是如果是多行的图象,那么有时候控制起来就不是那么容易了,比如象下面这张图片:





那么我们就需要使用图片分割方法来对这张图片进行分割,然后保存在数组里面,这样我们仅需要控制数组的下标就方便多了。
java基础类库提供了这样的方法,我们需要使用到三个类ImageProduce,CropImageFilter,FilteredImageSource。我们可以通过下面的操作步骤来完成图象的分割:
Image serial = getImage(URL);//获取联系图片
//剪切连续图片
ImageProducer src = serial .getSource();
//设置剪切区域,一维状态,改变y值构成二维
ImageFilter cut = new CropImageFilter( i*250,0,250,250);
FilteredImageSource fs = new FilteredImageSource( src , cut );
Image[ i] ani = createImage(fs);

下面我们通过一段代码来将上面的图片播放出来

public class TestCutImage extends JFrame implements Runnable{

Insets insets;
Image images [][] = new Image[5][5];
int row;
int colum;
TestCutImage(){
//获得图片的Image对象
Image image = Toolkit.getDefaultToolkit().getImage("Images/Cg0430.jpg");
//获取需要剪切的图片资源
ImageProducer porducer = image.getSource();
//下面通过两个循环分割图片,保存在一个Image类型的二维数组里
for (int i = 0; i < images.length; i++)
{
for (int j = 0; j < images[i].length; j++)
{
//CropImageFilter构造函数中的第一个参数是分割图片的左上角x坐标
//第二个参数是分割图片的左上角y坐标
//第三个参数是分割图片的宽
//第四个参数是分割图片的高
FilteredImageSource source = new FilteredImageSource(porducer,new CropImageFilter(j*128,i*96,128,96));
images[i][j] = createImage(source);

}
}
MediaTracker tracker = new MediaTracker(this);
for (int i = 0; i < images.length; i++)
{
for (int j = 0; j < images[i].length; j++)
{
tracker.addImage(images[i][j], 0);
}
}
try
{
tracker.waitForID(0);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
JPanel panel = new JPanel(){
protected void paintComponent(Graphics g) {
g.drawImage(images[row][colum], 0, 0,340,240, this);

}
};
this.getContentPane().add(panel);
setUndecorated(true);
setSize(340,240);
setVisible(true);
Thread thread = new Thread(this);
thread.start();
}

public static void main(String [] args) {

new TestCutImage();
}
public void run() {

while(true)
{
for (int i = 0; i < images.length; i++)
{
row = i;
for (int j = 0; j < images[i].length; j++)
{
colum = j;
try
{
Thread.sleep(50);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
repaint();
}
}

}
}
protected void processWindowEvent(WindowEvent e) {
if(e.getID() == WindowEvent.WINDOW_CLOSING)
{
System.exit(0);
}
}
}

分割图片后,只需要对Image数组进行操作,就比操作图片里的坐标方便多了,也更准确!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: