Sprites and Resource Management 精灵和资源管理
The Sprite class Sprite类
The sprite class will act as a wrapper round the standard java.awt.Image. However, its going to give us a place holder to expand things later on.
译:sprite类将作为一个包装器包装标准 java.awt.Image 类。这样的设计是可扩展的。
So heres the sprite class. Essentially it just takes and holds an image which can be drawn at a specified location onto a graphics context.
译:因此,Sprite类在本质上只是需要,并持有一个可以绘制到图形上下文指定位置的图片。
public class Sprite {
/** The image to be drawn for this sprite 表示精灵的图片*/
private Image image;
/**
* Create a new sprite based on an image
* 基于一个图片创建一个精灵(Sprite实例)
* @param image The image that is this sprite
*/
public Sprite(Image image) {
this.image = image;
}
/**
* Get the width of the drawn sprite
* 获得表示该精灵的图片的宽度,以像素为单位
* @return The width in pixels of this sprite
*/
public int getWidth() {
return image.getWidth(null);
}
/**
* Get the height of the drawn sprite
* 获得表示该精灵的图片的高度,以像素为单位
* @return The height in pixels of this sprite
*/
public int getHeight() {
return image.getHeight(null);
}
/**
* Draw the sprite onto the graphics context provided
* 利用参数提供的图形上下文(g)莱绘制精灵,x和y是精灵的横坐标和纵坐标
* @param g The graphics context on which to draw the sprite
* @param x The x location at which to draw the sprite
* @param y The y location at which to draw the sprite
*/
public void draw(Graphics g,int x,int y) {
g.drawImage(image,x,y,null);
}
}
Sprite Loading and Management 精灵的加载和管理
An important part of any game is managing the resources that are used. In our case we're just looking at sprites. However, we do only want to load any single sprite once. It would also be handy if the collection of sprites existing in one central location. With this in mind we'll implement a SpriteStore object. This will be responsible for loading and caching sprites. To make it easy to get hold of the sprite store we'll implement it as a singleton.
译:管理用到的资源是任何一个游戏的重要组成部分,而我们主要关注精灵。我们希望每一个精灵只被加载一次。并且方便一群精灵出现在屏幕的中心位置。根据这种想法我们实现了一个 SpriteStore 对象。它负责加载和缓存精灵。为了易于控制精灵的存储我们将 SpriteStore 设计成了单例。
Implementing the singleton 实现单例
A singleton simply means thats theres a single instance of the object available statically. In many cases this is done simply for convienience, however sometimes there are good design reasons for enforcing that there is only a single instance of the class ever created.
译:单例简单来说就是一个类只有唯一的一个可用实例对象。很多情况下我们这么做是为了将问题简化。但是有时候有更好的设计原因迫使我们限制一个类只可能被创建一个唯一的实例。
Implementing this in our sprite store looks like this:
译:SpriteStore 的实现如下:
/** The single instance of this class 当前类的唯一实例*/
private static SpriteStore single = new SpriteStore();
/**
* Get the single instance of this class
* 获得类的唯一实例
* @return The single instance of this class
*/
public static SpriteStore get() {
return single;
}
The "single" is the single instance of the class ever created. The static get method gives us access to the single instance.
译:“单例”指一个类只能被创建的一个唯一的实例。静态 get 方法使我们可以获取该类唯一的实例。
Loading the Sprites 加载精灵
The first step is to retrieve the sprite image from disk. Generally in Java it makes sense to use the ClassLoader to find the image for you. This makes it much easier to deploy games with the resources packaged up. However, some people are more comfortable to use direct file access which is also perfectly viable. For this tutorial we'll stick to the ClassLoader since it makes webstart possible.
译:第一步要做的是从硬盘上获取精灵图片。在Java中,我们通常可以使用ClassLoader来加载图片(类加载器根据类路径来加载资源,所有我们需要将图片和类一起保存在包里)。这样我们很容易将图片资源和类一起打包发布。有些同志更愿意使用直接访问文件这种可行的好办法(使用标准I/O库)。但在本文中我们坚持使用 ClassLoader ,因为它支持 webstart。(注意,加载精灵,缓存精灵都在 getSprite(String ref) 方法实现,ref为图片路径)
The first step is locate the sprite:
译:第一步是定位精灵(其实就是定位精灵的显示图片):
URL url = this.getClass().getClassLoader().getResource(ref);
Its important to note that the chain of functions used to get to the class is only there to support specialised class loaders (like the one found in WebStart). The retrieved URL will point to the image specified in the string "ref" relative to the classpath.
译:重点注意上面代码中的方法调用链是为了获得当前类的专门类加载器(就像在 webstart中找到的一样)。返回的URL 指向相对于类路径根目录的路径字符串参数“ref”指定的图片。
The next step is to actually load in the image. In Java this is a simple matter of using the utlity class ImageIO. To load our image we use this code:
译:下一步要做的是加载图片。在Java中,使用实用工具类 ImageIO来加载图片是非常简单的问题。我们使用下面的代码来加载图片:
sourceImage = ImageIO.read(url);
Finally, we need to allocate some accelerated graphics memory to store our image in. This will allow the image to be drawn without the CPU getting involved, we just want the graphics card to do the work for us.
译:最后,我们需要分配一些显存用于存储我们加载的图片。这样绘图时就不会占用CPU资源,我们仅仅靠显卡就可以完成绘图工作了。
Allocating the graphics memory is achieved like so:
译:我们这样分配显存:
// create an accelerated image of the right size to store our sprite in
//创建一个合适尺寸的加速图形,将精灵保存在其中
//GraphicsConfiguration 类描述图形目标(如打印机或监视器)
GraphicsConfiguration gc = GraphicsEnvironment.getLocalGraphicsEnvironment().
getDefaultScreenDevice().getDefaultConfiguration();
Image image = gc.createCompatibleImage(sourceImage.getWidth(),
sourceImage.getHeight(),
Transparency.BITMASK);
补充解释:Transparency 接口定义用于实现类的通用透明模式。其 BITMASK 常量属性表示完全不透明的图像数据(alpha 值为 1.0)或完全透明的图像数据(alpha 值为 0.0)。
The final step is to draw our loaded image into our accelerated graphics image. This essentially creates our sprite:
译:最后一步是绘制我们加载的图片到分配的显存。这实际上就创建了精灵:
// draw our source image into the accelerated image
//将源图绘制入加速图片
image.getGraphics().drawImage(sourceImage,0,0,null);
The only thing we have left to do is create our actual Sprite object.
译:我们需要做的唯一剩余的事情就是创建我们的精灵对象。
Caching the Sprites 缓存精灵
The other responsibility of our SpriteStore is to cahce the images that have been loaded. To achieve this we add a HashMap. This map will link the string references to images to the sprites that our loaded. Whenever we load a sprite we add it to the map like this:
译:SpriteStore 的另外一个责任是缓存已经加载的图片。我们使用一个HashMap 来实现缓存图片。这个 map 通过字符串来映射我们加载的精灵和精灵拥有的图片。当我们加载一个精灵后,我们把它这样添加到 map 里:
// create a sprite, add it the cache then return it
//创建一个精灵,把它添加到缓存中
Sprite sprite = new Sprite(image);
sprites.put(ref,sprite);
Likewise, whenever a sprite is requested we check whether its already in the map. If it is, we return our cached copy instead of loading a new copy:
译:同样地,每当需要一个精灵时我们都检查它是否已经在这个map里了。如果存在,我们返回缓存的拷贝而不是重新加载一个新的拷贝。
// if we've already got the sprite in the cache then just return the existing version
//如果我们想获取的精灵在缓存中已经有了,则直接返回已存在的精灵
if (sprites.get(ref) != null) {
return (Sprite) sprites.get(ref);
}
学软件开发,到蜂鸟科技!
超强的师资力量 、完善的课程体系 、超低的培训价格 、真实的企业项目。
网址:www.ntcsoft.com
电话:0371-63839606
郑州软件开发兴趣小组群:38236716
posted on 2010-11-25 23:52
whistler 阅读(434)
评论(0) 编辑 收藏