将BufferedImage中的球形区域设置为有效的某种不透明度

时间:2015-07-02 13:38:32

标签: java bufferedimage isometric

首先,我已经搜索了Google和SO以获得此答案,仅查找如何将实际像素更改为某个alpha值,这将非常慢或实际上成为BufferedImage <的一部分通过使用lwg2.setComposite(AlphaComposite.getInstance(AlphaComposite.CLEAR)),em>完全透明。这是我需要的确切功能,但是,我需要将值设置为小于1f,这对于AlphaComposite.CLEAR的特定实例无法做到。

我希望这个实现的目的是让玩家落后于我的2.5d游戏中的墙变得透明,如下所示:example

我的游戏背后的逻辑是地形是一个BufferedImage,它只在被调用时更新,然后将其余的墙等等绘制到另一个BufferedImage上,其中实体也是因此,不透明度变换只会影响树木(或墙壁)。

这是我正在使用atm的代码,但正如我所说,我不希望我绘制的圆圈使图像的一部分完全透明,但只是略微(约50%):

g2.setComposite(AlphaComposite.getInstance(AlphaComposite.CLEAR, 0.5f));
g2.fillOval(x - (int) (TILE_WIDTH * 1), y - (int) (TILE_HEIGHT * 1.5), TILE_WIDTH * 2, TILE_HEIGHT * 3);

0.5f构造函数中的AlphaComposite不执行任何操作。)

我需要这个效率的原因是因为我每秒更新此图像30次,所以效率&gt;质量。

1 个答案:

答案 0 :(得分:0)

所以,我最终通过不使图像的一部分半透明地操纵图像来解决问题,而是操纵我正在绘制的图像的不透明度。正如@ user343760和@NESPowerGlove所提到的那样,当玩家支持它时,我可以让我使用半透明的资产。由于我使用底层网格阵列​​来支持我的游戏,所以我可以通过计算tile.x - 1 == (int) player.xtile.y - 1== (int) player.y来完成此操作。在等轴测图中,这意味着玩家在我们的视角中位于其正上方的瓷砖上。然后我必须解决这个问题,如果wall.z大于0或1,因此有一个问题,即如果墙壁在瓷砖上方延伸z = 5,则瓷砖5阻挡“吼叫”,玩家可以阻挡他。对于这个问题,我实现了以下解决方案:

for(int i = 0; i < wall.getAsset(1f).getHeight()/TILE_HEIGHT; i++) {
    if((tile.x - i - wall.z == (int) world.player.getX() && tile.y - i -wall.z == (int) world.player.getY())) {
        lwg2.drawImage(wall.getAsset(0.5f), x, y, this);                                            
    }
}

这也确保了图像是透明的,即使玩家位于墙壁所在的瓷砖“上方”的瓷砖“上方”,就超出该极限的图像而言。我已经通过使用for循环修正了这个问题,该循环在i次上面看image.height/tile_height次,具体取决于BufferedImage,这是一个通用常量。

如果你需要使图像的一部分透明,我没有找到无故障的解决方案,除了操纵低级别g2.setComposite(AlphaComposite.getInstance(AlphaComposite.CLEAR));中的像素。如果您还想直接删除图像的一部分,请使用代码g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER));并按正常方式绘制。请记住通过Composite切换回普通合成。

您还可以使用g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, opacity)); opacity首先使用某种不透明度绘制,其中float0f,其值为1f 0f1f完全透明且<form id="form1" runat="server"> <div class="listTitle"><% Response.Write(strListTitle); %> <asp:GridView ID="gv1" runat="server" DataKeyNames="id" CellPadding="2" AutoGenerateDeleteButton="True" OnRowDeleting="gv1_RowDeleting" OnRowDeleted="gv1_deleteItem"> </asp:GridView> </div> </form> </div> <!-- close middle --> <div id="footer"> <asp:SqlDataSource ID="DS" runat="server" ConnectionString="<%$ ConnectionStrings:conn %>"> <DeleteParameters> <asp:Parameter Name="id"/> </DeleteParameters> </asp:SqlDataSource> </div> 完全不透明。

我希望这能帮到那里的任何人。如果您找到更好的方法,请为将来的读者留下评论。

这就是我的解决方案:):

working example