Java游戏2D重叠阴影与Swing

Pat*_*man 7 java swing java-2d paintcomponent

我目前正在使用Swing作为我的主要绘图组件开发2D Java游戏.每个对象都有一个阴影(BufferedImage),但每个阴影都与其他阴影重叠.是否可以只让阴影不相互重叠?因为如果物体在它下面,我仍然希望阴影在玩家上方绘制,而不是如果物体在玩家之上.为清晰起见,这是一张图片:

截图

我看过alpha合成,我想我需要Source Out?我还想过让所有阴影(没有透明度)在一个图层上绘制,然后用透明度绘制它,然后它不会像以前那样在玩家和其他对象上绘制.

我有一个Draw对象,它是一个JPanel并覆盖paintComponent方法.在这个方法中,我绘制当前房间的地板,然后迭代属于当前房间的对象列表,并调用每个对象的绘制方法来绘制所有内容.

对象绘制方法:

public void draw(Graphics g) {
    if (visible && checkInScreen()) {

        // The required drawing location
        int drawLocationX = getX() - globalCameraX;
        int drawLocationY = getY() - globalCameraY;

        if (shadow) {
            g.drawImage(shadowImages.get(imageIndex),
                    drawLocationX + shadowOffset.x + (getImageWidth()/2),
                    drawLocationY + shadowOffset.y, null);
        }
        g.drawImage(images.get(imageIndex), drawLocationX, drawLocationY, null);

        //Collisionbox
        if (SHOW_COLLISION_BOXES){
            g.setColor(Color.WHITE);
            g.drawRect(drawLocationX + getCollBoxX(), drawLocationY + getCollBoxY(), getCollBoxW() - getCollBoxX(), getCollBoxH() - getCollBoxY());
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

如果这个问题已被提出,我很抱歉,但我找不到类似的东西.

Rob*_*Fry 1

为了解决这个问题,我要做的就是拥有一个阴影层位图。我的意思是:将阴影纹理保存为布尔值的二维数组(表示阴影像素的位置)。

您可以用它做的就是逻辑上或将阴影贴图组合在一起以创建单个图层,该图层可以分层在树纹理后面以创建阴影。

您可能需要将布尔值更改为浮点数以表示阴影的颜色/强度,然后进行更大的计算以将阴影合并在一起。

下面的 ShadowMap 类用于存储每个阴影的数据:

class ShadowMap {

    public int xPos, yPos;
    public boolean[][] array;

    public ShadowMap(int xPos, int yPos, boolean[][] array) {
        this.xPos = xPos;
        this.yPos = yPos;
        this.array = array;
    }

}
Run Code Online (Sandbox Code Playgroud)

ShadowLayer 类为整个屏幕创建一个 2D 数组,包含每个像素是否存在阴影:

class ShadowLayer {

    public static boolean[][] array = new boolean[SCREEN_WIDTH][SCREEN_HEIGHT];

    public static makeNew(ShadowMap[] shadows) {
        for (int x = 0; x < SCREEN_WIDTH; x++) {
            for (int y = 0; y < SCREEN_HEIGHT; y++) {
                array[x][y] = false;
            }
        }
        for (ShadowMap map : shadows) {
            for (int i = 0; i < SCREEN_WIDTH; i++) {
                for (int j = 0; j < SCREEN_HEIGHT; j++) {
                    // Logical or such that the pixel at (x, y) has a shadow 
                    // if any shadow map also has a shadow at pixel (x, y)
                    array[i + map.xPos][j + map.yPos] |= map.array[i][j];
                }
            }
        }
    }

}
Run Code Online (Sandbox Code Playgroud)

使用这个 ShadowLayer 类,如果 ShadowMap 在同一像素上有阴影,则只需使屏幕上的每个像素变暗即可:

public static Color ajustPixelForShadows(int x, int y, Color pixel) {
    return ShadowMap.array[x][y] ? pixel.darken() : pixel;
}
Run Code Online (Sandbox Code Playgroud)