【问题标题】:Difficulty understanding image loading date for java game development难以理解 Java 游戏开发的图像加载日期
【发布时间】:2018-06-15 03:08:11
【问题描述】:

我正在参考 RealtutsGML 的 java 游戏编程系列创建一个 java 游戏。我很难理解这段代码的某些部分是如何工作的。我了解图像部分的 getWidth 和 getHeight 但在 for 循环中,我迷路了。

向导类是玩家,方块是地图周围的屏障。该地图是我在 Photoshop 中制作的 64 x 64 图像,由一堆红色像素组成,这些像素代表应该在其中生成块对象的位置,以及一个代表向导/玩家生成位置的绿色像素。

    private void loadLevel(BufferedImage image) {
    int w = image.getWidth();
    int h = image.getHeight();

    for(int xx = 0; xx < w; xx++) {
        for(int yy = 0; yy < h; yy++) {
            int pixels = image.getRGB(xx, yy);
            int red = (pixels >> 16) & 0xff;
            int green = (pixels >> 8) & 0xff;
            int blue = (pixels) & 0xff;

            if(red == 255) 
                handler.addObject(new Block(xx * 32, yy * 32, ID.Block));
            if(green == 255)
                handler.addObject(new Wizard(xx * 32, yy * 32, ID.Player, 
                handler));
        }
    }
}

我难以理解的部分是int pixels = image.getRGB(xx, yy) 这是否意味着像素存储红色、绿色和蓝色的值,如果是,像素如何存储多个值?

下一部分我不明白的是

 int red = (pixels >> 16) & 0xff;
 int green = (pixels >> 8) & 0xff;
 int blue = (pixels) & 0xff;

为什么我们将红色、蓝色和绿色变量的像素向右移动 16 和 8,然后在它们上加上 & 0xff?

最后一部分是为什么我们将 handler.addObject 方法中的 xx 和 yy 值乘以 32。每个块对象和向导对象都是 32 乘 32,但为什么我们需要将整个图像乘以 32。

我已经查看了 oracle 网站来解释 & 位运算符,它确实有点帮助,但我仍然很难理解它在这种情况下是如何工作的。

【问题讨论】:

    标签: java bitwise-operators bufferedimage game-development


    【解决方案1】:

    单个像素可以存储在一个(32 位)整数中。

    颜色 RGB 的每个分量都在 0 到 255 之间,其中 (0,0,0) 是黑色,(255,255,255) 是白色,然后你就有了介于两者之间的所有颜色。 0 到 255 可以以 8 位存储,这意味着您可以以 24 位存储 RGB 数据。接下来的 8 位可能未使用,或者用于存储 alpha 数据或其他任何内容,但这在这里并不重要。

    因此可以将像素读取为整数,并且通常是您处理图像数据的方式,因为值是整数。

    位运算符用于“提取”整数的特定部分,因为前 8 位存储蓝色数据,接下来的 8 位存储绿色数据,接下来的 8 位存储红色数据。请注意,“第一”是从右到左阅读,因为大量数据存储在little endian even though it looks reversed to humans

    如果您不知道按位移位的工作原理,可以在此处阅读:What are bitwise shift (bit-shift) operators and how do they work?。基本上,这是获得所需位的简单方法。

    因此,如果您将 24 位颜色数据想象成 32 位整数,如下所示:

    rrrrrrrrggggggggbbbbbbbb
    

    通过说像素 >> 8,你得到

            rrrrrrrrgggggggg
    

    但是,如果您按原样读取结果值,您将获得所有您不想要的额外红色数据。因此,您 & 使用 0xff 以保留最后 8 位,即您的绿色组件,然后删除(或归零)任何其他位。

    至于 32 间隔的方块和巫师位置,我最好的猜测是你的游戏地图被表示为一个大小为 32x32 的格子的网格。为什么?因为如果你所有的精灵都彼此存储一个像素,你只会一团糟。使用图像来创建生成点是通过将平铺坐标(在图像上)映射到屏幕上的像素坐标来完成的。也就是说,你图片中的像素 (0,0) 是网格的左上角,而你图片中的像素 (0, 1) 代表下面的一个瓦片(游戏中是 32 像素)。

    基本上,您有一个 64x64 的图块地图,游戏将在屏幕上初始化对象的位置,假设每个图块的大小为 32x32,使用您的图像作为“绘制”布局的一种方式地图。

    【讨论】:

    • 我打算标记为重复,但我喜欢你的回答。 stackoverflow.com/questions/6001211/…
    • 这里使用“字节”可能会造成混淆,因为一个字节通常是一个 8 位的单位。
    • @anneb 字节的使用不正确。我在想 32 位整数,但不知道为什么我称它为字节。我删除了对“字节”一词的引用
    • 感谢您的回答。 0xFF到底是什么,它代表什么?
    • @Louis 0xFF 在二进制中是 1111 1111。将其用作 AND 掩码将保留前 8 位并将其余位清零。
    猜你喜欢
    • 2013-06-26
    • 2014-04-09
    • 2019-04-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-22
    • 2011-12-29
    • 1970-01-01
    相关资源
    最近更新 更多