-1

所以我有一个黑色图像作为黑暗(在我的游戏中)。我只想在角色周围显示一小部分。像这样

在此处输入图像描述

红色方块是玩家。绿色位是游戏中的地面(草)。黑色是阴影/黑暗。

我想要做的是从空白的黑色图像中切出一个椭圆/孔。我希望这个椭圆以玩家(红色方块)x 和 y 位置为中心。

目前我正在使用它来获得效果:

        for(int x = 0; x < width; x++) {
            for(int y = 0; y < height; y++) {
                //draw mask
                g.setColor(Color.black);
                if(!nearPlayer(x, y)) {
                    g.drawLine(x, y, x, y);
                }
            }
        }

但是,这个过程非常缓慢,并且极大地滞后了玩家的运动。

这可能吗?

4

1 回答 1

1

..玩家是红色方块。基本上我想要做的是在玩家相对于所述黑色图像的坐标周围从空白的黑色图像中切出一个圆圈。

“黑色图像”的 DYM 究竟是什么?对我来说,BG 看起来像是漆成黑色的,这对于任何纯色都更有意义。在这种情况下,只需使用 来创建红色的东西Area填充它,然后为边框设置一个笔触并将颜色设置为黑色,然后绘制它。 这个例子 展示了如何。

该短代码的相关部分是..

public void paintDaisyPart(Graphics2D g, Area daisyArea) {
    g.setClip(daisyArea);

    g.setColor(Color.YELLOW);
    g.fillRect(0, 0, 200, 200);

    g.setColor(Color.YELLOW.darker());
    g.setClip(null);
    g.setStroke(new BasicStroke(3));
    g.draw(daisyArea);
}

我一定很无聊。这是绘制上图的代码的动画SSCCE 版本。它通常显示 >130 FPS。那是在一台笨重的机器上,我告诉那个人我的规格。很“便宜”,两次提醒他我不玩(重渲染)游戏。

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.*;
import java.awt.image.BufferedImage;
import javax.swing.*;

public class DaisyDisplay {

    DaisyDisplay() {
        JPanel gui = new JPanel(new BorderLayout(2,2));

        final BufferedImage daisy = new BufferedImage(
                200,200,BufferedImage.TYPE_INT_RGB);
        final JLabel daisyLabel = new JLabel(new ImageIcon(daisy));
        gui.add(daisyLabel,BorderLayout.CENTER);
        final Daisy daisyPainter = new Daisy();
        daisyPainter.setSize(200);
        final JLabel fps = new JLabel("FPS: ");
        gui.add(fps,BorderLayout.SOUTH);

        ActionListener animator = new ActionListener() {
            int counter = 0;
            long timeLast = 0;
            long timeNow = 0;
            public void actionPerformed(ActionEvent ae) {
                Graphics2D g = daisy.createGraphics();
                g.setColor(Color.GREEN.darker());
                g.fillRect(0, 0, 200, 200);

                daisyPainter.paint(g);

                g.dispose();
                daisyLabel.repaint();

                counter++;
                timeNow = System.currentTimeMillis();
                if (timeLast<timeNow-1000) {
                    fps.setText("FPS: " + counter);
                    counter = 0;
                    timeLast = timeNow;
                }
            }
        };
        Timer timer = new Timer(1,animator);
        timer.start();

        JOptionPane.showMessageDialog(null, gui);
        timer.stop();
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                new DaisyDisplay();
            }
        });
    }
}

class Daisy {

    double size = 200;
    Point location;

    double offset = 0.0;

    public void paint(Graphics2D g) {
        Area daisyArea = getDaisyShape();
        g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, 
                RenderingHints.VALUE_ANTIALIAS_ON);

        offset += .02d;

        AffineTransform plain = g.getTransform();

        g.setTransform(AffineTransform.getRotateInstance(
                offset + (Math.PI*1/8),
                100,100));
        paintDaisyPart(g,daisyArea);

        g.setTransform(AffineTransform.getRotateInstance(
                offset + (Math.PI*3/8),
                100,100));
        paintDaisyPart(g,daisyArea);

        g.setTransform(AffineTransform.getRotateInstance(
                offset,
                100,100));
        paintDaisyPart(g,daisyArea);

        g.setTransform(AffineTransform.getRotateInstance(
                offset + (Math.PI*2/8),
                100,100));
        paintDaisyPart(g,daisyArea);

        g.setTransform(plain);
    }

    public void setLocation(Point location) {
        this.location = location;
    }

    public void paintDaisyPart(Graphics2D g, Area daisyArea) {
        g.setClip(daisyArea);

        g.setColor(Color.YELLOW);
        g.fillRect(0, 0, 200, 200);

        g.setColor(Color.YELLOW.darker());
        g.setClip(null);
        g.setStroke(new BasicStroke(3));
        g.draw(daisyArea);
    }

    public void setSize(double size) {
        this.size = size;
    }

    public Area getDaisyShape() {
        int diameter = (int)size*6/20;

        Ellipse2D.Double core = new Ellipse2D.Double(
                (size-diameter)/2,(size-diameter)/2,diameter,diameter);

        int pad = 10;
        int petalWidth = 50;
        int petalLength = 75;

        Area area = new Area(core);

        // left petal
        area.add(new Area(new Ellipse2D.Double(
                pad,(size-petalWidth)/2,petalLength,petalWidth)));
        // right petal
        area.add(new Area(new Ellipse2D.Double(
                (size-petalLength-pad),(size-petalWidth)/2,petalLength,petalWidth)));
        // top petal
        area.add(new Area(new Ellipse2D.Double(
                (size-petalWidth)/2,pad,petalWidth,petalLength)));
        // bottom petal
        area.add(new Area(new Ellipse2D.Double(
                (size-petalWidth)/2,(size-petalLength-pad),petalWidth,petalLength)));

        return area;
    }
}
于 2012-06-20T10:14:07.503 回答