Java Applet图片平铺

这篇博客总结了Java2游戏编程API中关于平铺图像的内容,特别是通过Applet实现ItemListener接口来处理ComboBox状态变化。代码示例展示了如何使用Hashtable存储图片和名称的对应关系,以及如何在Choice中选择图片并绘制平铺效果。核心逻辑在于遍历界面,不断绘制图片直至超出边界。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这是学习了Java2游戏编程的Java API章节中的平铺图像这一部分后的总结。

这个Applet实现了一个ItemListener接口。这是个新东西,我们来看看它的具体作用。

ItemListener其实是个监听器接口(谁都知道)。这与javascript中我们对与鼠标单击等事件的处理类似。ItemListener主要用于像ComboBox这类的,具有明显状态的控件。而ItemListener得作用之一就是监听这类控件的状态变化。ItemState改变的时候,函数itemStateChanged(ItemEvent e)就会被调用。这里需要注意的是,改变一次下拉列表框的选择会触发2次itemStateChanged,因为上一次的选项由selected变成了unselected,而当前的选项由unselected变成了selected。

好了,知道了ItemListener的主要功能,我们就可以开始着手于代码的分析了,代码如下:

package bear.game.titleimage;

import java.applet.Applet;
import java.awt.BorderLayout;
import java.awt.Choice;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.MediaTracker;
import java.awt.Panel;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.geom.AffineTransform;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Hashtable;

public class TileImage extends Applet implements ItemListener{
	
	private Hashtable imageTable;
	private Choice selections;
	private int imageSize;
	
	private final String[] filenames = {"water.GIF", "grass.gif"};
	
	
	@Override	
	public void init()
	{
		int n = filenames.length;
		imageTable = new Hashtable(n);
		selections = new Choice();
		Panel p = new Panel();
		p.add(selections, BorderLayout.SOUTH);
		p.setBackground(Color.RED);
		
		setLayout(new BorderLayout());
		add(p, BorderLayout.SOUTH);
		selections.addItemListener(this);
		
	
		for(int i = 0 ; i < n ; i++)
		{
			URL url;
			try {
				url = new URL(getCodeBase()+"\\"+filenames[i]);
				
				//BufferedImage img = ImageIO.read(url);
				Image img = getImage(getCodeBase(), filenames[i]);
				MediaTracker media = new MediaTracker(this);
				media.addImage(img, 1);
				try {
					media.waitForID(1);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				System.out.println(img.getHeight(this));
				imageTable.put(filenames[i], img);
				selections.add(filenames[i]);
				if(i == 0)
				{
					imageSize = img.getHeight(this);
				}
			} catch (MalformedURLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}
	
	public void paint(Graphics g)
	{
		Graphics2D g2d = (Graphics2D) g;
		int width = getSize().width;
		int height = getSize().height;
		
		
		AffineTransform at = new AffineTransform();
		Image curImage = (Image)imageTable.get(selections.getSelectedItem());
		int y = 0;
		while(y < height)
		{
			int x = 0;
			while(x < width)
			{
				at.setToTranslation(x, y);
				g2d.drawImage(curImage, at, this);
				x += imageSize;
			}
			y += imageSize;
		}
		
	}
	
	public void itemStateChanged(ItemEvent arg0) {
		// TODO Auto-generated method stub
		repaint();
	}

}

用书中给的示例总是卡住,所以这里我将书中的

while(image.getWidth(this) < 0);
...

这句改掉了,我利用MediaTracker追踪图片的加载状态。MediaTracker对象的waitForID(int index)方法在加载完由ID指定的图片以前一直等待。

此处还可以使用BufferedImage进行操作,效果更好。利用BufferedImage进行处理的代码如下:

package bear.game.titleimage;

import java.applet.Applet;
import java.awt.BorderLayout;
import java.awt.Choice;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Panel;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.URL;
import java.util.Hashtable;

import javax.imageio.ImageIO;

public class TileImage extends Applet implements ItemListener{
	
	private Hashtable imageTable;
	private Choice selections;
	private int imageSize;
	
	private final String[] filenames = {"water.GIF", "grass.gif"};
	
	
	@Override	
	public void init()
	{
		int n = filenames.length;
		imageTable = new Hashtable(n);
		selections = new Choice();
		Panel p = new Panel();
		p.add(selections, BorderLayout.SOUTH);
		p.setBackground(Color.RED);
		
		setLayout(new BorderLayout());
		add(p, BorderLayout.SOUTH);
		selections.addItemListener(this);
		
	
		for(int i = 0 ; i < n ; i++)
		{
			URL url;
			try {
				url = new URL(getCodeBase()+"\\"+filenames[i]);
				BufferedImage img = ImageIO.read(url);
				imageTable.put(filenames[i], img);
				selections.add(filenames[i]);
				if(i == 0)
				{
					imageSize = img.getHeight(this);
				}
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}
	//...
}

以上说的只是加载图片的部分,接下来说明的是如何让ComboBox的选择与Applet的paint方法相联系。

这里我们定义了一个Hashtable,它是java内置的,我们用它来进行图片以及名字的对应关系的存储。同时我们还定义了Choice,也即是我们所谓的ComboBox。

然后我们的主要思想是通过在paint()中将Choice中选中的字符串传递给Hashtable,然后筛选出我们需要的图片,然后绘制它的平铺图,这部分代码参见init函数。

(注意Hashtable的put和get方法的使用)


接下来我们来看平铺是怎么画的。思想比较清晰,就是从(0, 0)开始,不断绘制图片,直到下一次绘制的左上角已经超出了程序界面的边界时,我们才停止绘制。代码如下:

//...
        public void paint(Graphics g)
	{
		Graphics2D g2d = (Graphics2D) g;
		int width = getSize().width;
		int height = getSize().height;
		
		
		AffineTransform at = new AffineTransform();
		Image curImage = (Image)imageTable.get(selections.getSelectedItem());
		int y = 0;
		while(y < height)
		{
			int x = 0;
			while(x < width)
			{
				at.setToTranslation(x, y);
				g2d.drawImage(curImage, at, this);
				x += imageSize;
			}
			y += imageSize;
		}
		
	}
//...

这里我们使用的图片是长宽相等的,所以统一用imageSize定义。

实现的效果嘛,自己实现吧,我不想贴图片啊,因为要是以后连接失效了,只剩下个叉叉很丑的。( ̄□ ̄||)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值