121、获取和使用图像应用了什么技术?
## 获取图像
Java 2D支持的 `javax.imageio.ImageIO` 类有 `read()` 方法,可将外部图像格式加载为 `BufferedImage` 格式,参数是外部图像文件的 URL,如使用 `getClass().getResource("../images/Winter.jpg")` 返回图像文件的 URL 来加载图像。
## 使用图像
`Graphics` 类有 `drawImage()` 方法用于绘制图像,该方法有多个重载版本,最简单的是:
```java
g.drawImage(img, x, y, null)
可在坐标 (x, y)
处绘制图像 img
。
在游戏中处理图像
在全局精灵继承层次结构中创建新分支,添加 AbsSpriteImage.java
子类,调整全局线性数据结构 spriteAry
的数据类型为:
new ArrayList<AbsSpriteImage>()
Java 图像技术演变
- 从 AWT 成像模型开始
- 后开发了
MediaTracker
类加速下载 - 又有
ImageIcon
类减轻编程负担
##122、用于图像精灵的新精灵继承层次结构是什么样的?
为处理图像精灵,游戏《Breakout》的新精灵继承层次结构需创建一个包含四个新类的新图像分支。首先要定义新图像分支的根类`AbsSpriteImage.java`,该类与`AbsSprite2D.java`非常相似,定义了图像的x、y、宽度和高度,还有新属性`BufferedImage`用于加载图像,且`paintSprite()`方法可实现。
由于项目`Breakout1`的第一个版本仅处理砖块,所以定义了类`BrickSprite.java`,它继承自`AbsSpriteImage.java`,且此时砖块是静态精灵,`updateSprite()`方法为空。
##123、当我们用图像代替图形绘制来替换精灵时,AbsGameCanvas.java 类应该做什么改变?
由于所有精灵都是图像,抽象类 `AbsGameCanvas.java` 中定义的全局线性数据结构 `spriteAry` 的数据类型应调整为:
```java
new ArrayList<AbsSpriteImage>()
124、如何将一维数组存储映射到二维数组排列?
将一维数组映射到二维数组,本质是映射它们的索引。对于一维数组中的每个元素索引,使用“除法”和“取模”运算。
- “除法”运算 :一维数组中的原始索引 / 二维数组的行长度,得到的商作为二维数组的 行索引 。
- “取模”运算 :得到的余数作为二维数组该行的 列索引 。
例如,一维数组中索引为 [5]
的元素,若二维数组每行有 5 个元素:
5 / 5 = 1(行索引)
5 % 5 = 0(列索引)
则该元素应映射到二维数组中索引为 [1][0]
的位置。
125、如何为每个砖块精灵分配坐标 (x, y)?
在类 GameCanvas.java
的 initBrickSprites()
方法中,通过循环遍历所有砖块,使用映射算法确定二维数组的索引,再计算每个砖块的 (x, y)
坐标,以使其适应 GUI 上的二维排列。
具体来说:
- 当
(i % Consts.BRICKS_PER_ROW == 0) 且 (i != 0)
时: - 将
x
坐标重置为0
-
将
y
坐标增加Consts.BRICK_H
,以移动到下一行 -
否则:
-
x
坐标增加Consts.BRICK_W
,以移动到下一个位置 -
y
坐标保持不变
126、如何使用事件监听器PropertyChangeListener?
使用事件监听器 PropertyChangeListener
的步骤如下:
-
确定事件源组件,例如将
BallSprite.java
类作为事件源组件,需在该类中初始化支持属性变化的对象pChange
,并添加addPropertyChangeListener(pcl)
方法,将参数pcl
分配给pChange.addPropertyChangeListener()
。 -
实现带有事件处理方法的事件监听器,例如在
GameCanvas.java
类中实现内部类LocChangeListener
,其中包含事件处理方法propertyChange()
。 -
将事件源组件注册到事件监听器,例如在
GameCanvas.java
类实例化ballSprite
对象后,通过调用addPropertyChangeListener()
方法,将new LocChangeListener()
对象作为实际参数传入,使事件源组件注册到事件监听器。
当事件源组件的属性坐标 (x,