首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >我应该如何渲染一个2D手电筒效果?

我应该如何渲染一个2D手电筒效果?
EN

Stack Overflow用户
提问于 2012-12-21 09:27:04
回答 2查看 1.8K关注 0票数 3

我试图在我的2D游戏中制作手电筒效果。我的手电筒是一个线段,从实体在一个特定的角度延伸。手电筒可以指向任何方向。手电筒的强度也不同(手电筒光束的长度)。

我想找出最好的(最简单的?)和最灵活的方式来渲染手电筒的效果。尤其是平铺的地图。

我能想到两种方法。但我不知道如何实施:

  1. 只绘制平铺地图的圆锥形/圆段部分。
  2. 用黑色纹理覆盖屏幕,并在黑色纹理上穿孔代码。这样我就可以改变洞的属性了。

如果libGDX能够这样做的话,我不知道从哪里开始使用这个/这些名称是什么。

EN

回答 2

Stack Overflow用户

发布于 2012-12-21 18:50:08

第一号称为模具缓冲区。但你会发现很难达到软效果。--放轻松

第二位:,你只需要一个有光的纹理。完全黑色的区域可以画成在光精灵周围重复黑色精灵(左、右、上、下)。或者您可以将其与模具缓冲区混合使用。或者,您可以仔细计算纹理坐标,并使用GL.clamp_to_edge传播所有黑色像素。根据你如何渲染你的场景,你可以先渲染你的光与阿尔法信息,然后混合场景(根据dst_alpha变暗)。--没有那么难执行。

的第三个将是关于着色器的研究(GLES 2.0)。你可以渲染一个网格来填充洞的屏幕,并用一些着色计算使它变暗。--这是最灵活的选择,也是最困难的选择(反正与火箭科学相去甚远)。

有些选项听起来比其他的更好,但是提供你提供的信息,我没有什么可以告诉你的。你有一个很好的起点,从哪里开始研究。

**如果您选择使用纹理,考虑有几个不同的纹理取决于电池。你可以对它们进行一点缩放或修饰,但是拥有不同的纹理要灵活得多。

票数 6
EN

Stack Overflow用户

发布于 2012-12-23 05:18:36

如果图形元素是BufferedImageGraphics2D实例,您可以这样处理它。

代码语言:javascript
复制
import java.awt.*;
import java.awt.geom.*;
import java.awt.image.BufferedImage;
import javax.swing.*;

public class FlashLight {

    public static void main(String[] args) throws Exception {
        Robot robot = new Robot();
        int w = 500, h = 200;
        Rectangle rect = new Rectangle(0, 0, w, h);
        final BufferedImage bi = robot.createScreenCapture(rect);
        final BufferedImage bi2 = FlashLight.draw(
                bi, 10, 180, 420, 90, .3,
                new Color(255, 255, 120, 15), new Color(0, 0, 0, 220));
        final BufferedImage bi3 = FlashLight.draw(
                bi, 10, 180, 420, 90, .3,
                new Color(180, 250, 255, 15), new Color(0, 0, 0, 220));

        Runnable r = new Runnable() {

            @Override
            public void run() {
                JPanel gui = new JPanel(new GridLayout(3,0,2,2));
                gui.add(new JLabel(new ImageIcon(bi2)));
                gui.add(new JLabel(new ImageIcon(bi)));
                gui.add(new JLabel(new ImageIcon(bi3)));

                JOptionPane.showMessageDialog(null,gui);
            }
        };
        // Swing GUIs should be created and updated on the EDT
        // http://docs.oracle.com/javase/tutorial/uiswing/concurrency/initial.html
        SwingUtilities.invokeLater(r);
    }

    public static BufferedImage draw(
            BufferedImage source,
            double x1, double y1, double x2, double y2,
            double beamWidth,
            Color beamColor, Color darknessColor) {
        RenderingHints hints = new RenderingHints(
              RenderingHints.KEY_ANTIALIASING,
                RenderingHints.VALUE_ANTIALIAS_ON);

        BufferedImage bi = new BufferedImage(
                source.getWidth(), source.getHeight(),
                BufferedImage.TYPE_INT_ARGB);

        Graphics2D g = bi.createGraphics();
        g.setRenderingHints(hints);

        g.drawImage(source, 0, 0, null);

        // Create a conical shape to constrain the beam
        double distance = Math.sqrt(Math.pow(x1 - x2, 2d) + Math.pow(y1 - y2, 2d));
        double tangent = (y2 - y1) / (x2 - x1);
        double theta = Math.atan(tangent);
        System.out.println(
                "distance: " + distance
                + "  tangent: " + tangent
                + "  theta: " + theta);
        double minTheta = theta + beamWidth / 2;
        double maxTheta = theta - beamWidth / 2;
        double xMin = x1 + distance * Math.cos(minTheta);
        double yMin = y1 + distance * Math.sin(minTheta);

        double xMax = x1 + distance * Math.cos(maxTheta);
        double yMax = y1 + distance * Math.sin(maxTheta);

        Polygon beam = new Polygon();
        beam.addPoint((int) x1, (int) y1);
        beam.addPoint((int) xMax, (int) yMax);
        beam.addPoint((int) xMin, (int) yMin);

        g.setColor(beamColor);
        GradientPaint gp = new GradientPaint(
                (int)x1,(int)y1, beamColor,
                (int)x2,(int)y2, darknessColor);
        g.setClip(beam);
        g.setPaint(gp);
        g.fillRect(0, 0, bi.getWidth(), bi.getHeight());

        // create an area the size of the image, but lacking the beam area
        Area darknessArea = new Area(new Rectangle(0, 0, bi.getWidth(), bi.getHeight()));
        darknessArea.subtract(new Area(beam));
        g.setColor(darknessColor);
        g.setClip(darknessArea);
        g.fillRect(0, 0, bi.getWidth(), bi.getHeight());

        // fill in the beam edges with black (mostly to smooth lines)
        g.setClip(null);
        g.setColor(Color.BLACK);
        g.setStroke(new BasicStroke(2));
        g.draw(new Line2D.Double(x1,y1,xMin,yMin));
        g.draw(new Line2D.Double(x1,y1,xMax,yMax));

        g.dispose();

        return bi;
    }
}
票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/13987435

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档