如何在BufferedImage上删除像素?用Graphics实现游戏简易光照
实现简易椭圆挖洞式光照系统的方案
核心思路
先绘制全屏幕的半透明暗层,再通过清除椭圆区域像素的alpha值(让该区域完全透明)模拟光源效果,关键是利用Java2D的AlphaComposite.Clear合成规则实现“挖洞”。
具体实现步骤&代码示例
// 1. 创建和游戏窗口同尺寸的带Alpha通道的图像(必须用TYPE_INT_ARGB,否则不支持透明) int screenWidth = 800; int screenHeight = 600; BufferedImage lightMask = new BufferedImage(screenWidth, screenHeight, BufferedImage.TYPE_INT_ARGB); Graphics2D g2d = lightMask.createGraphics(); // 2. 填充半透明黑底暗层(最后一个参数是alpha值,0=完全透明,255=完全不透明) g2d.setColor(new Color(0, 0, 0, 200)); g2d.fillRect(0, 0, screenWidth, screenHeight); // 3. 保存原有合成规则,临时切换为Clear模式(此模式下绘制内容会清除目标像素,变成完全透明) Composite originalComposite = g2d.getComposite(); g2d.setComposite(AlphaComposite.Clear); // 4. 绘制椭圆形状的光源区域——这个区域会被“挖空”变成透明 int lightCenterX = 300; int lightCenterY = 250; int lightSizeW = 120; int lightSizeH = 100; // fillOval的参数是:左上角X, 左上角Y, 宽度, 高度,所以要计算左上角位置让椭圆居中 g2d.fillOval(lightCenterX - lightSizeW/2, lightCenterY - lightSizeH/2, lightSizeW, lightSizeH); // 5. 恢复原有合成规则,避免影响后续绘制操作 g2d.setComposite(originalComposite); g2d.dispose(); // 6. 最后把这个光照遮罩画到游戏窗口的画布上 // 假设gameGraphics是游戏窗口的Graphics对象 gameGraphics.drawImage(lightMask, 0, 0, null);
注意事项
- 要用
fillOval而非drawOval:前者填充整个椭圆区域,后者只画边框,只有填充才能实现整块透明的光源效果。 - 必须使用带Alpha通道的BufferedImage类型:比如
TYPE_INT_ARGB,否则无法设置像素的透明属性。 - 如果需要多个光源,重复步骤3-4即可,每次画新的椭圆挖洞。
内容的提问来源于stack exchange,提问作者BlockManBlue
相关产品推荐
相关产品推荐

