2012-06-20 2 views
-1

Итак, у меня есть черное изображение, которое действует как темнота (в моей игре). Я хочу показать небольшую часть вокруг персонажа. Как такРезка части изображения и сохранение исходного изображения

enter image description here

Красный квадрат является игроком. Зеленый бит - это земля в игре (трава). Черный - это тень/тьма.

Что я хочу сделать, это вырезать эллипс/отверстие из чистого, черного изображения. Я хочу, чтобы этот Эллипс был сосредоточен вокруг игроков (красный квадрат) 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); 
       } 
      } 
     } 

Но эти процессы крайне медленно и laggs движение игроков резко.

Возможно ли это?

+0

Является ли «игроком» красная квадратная вещь или зеленый круг вокруг нее? Вы просто хотите «черную границу» вокруг этого элемента? –

+0

Чтобы лучше помочь, опубликуйте [SSCCE] (http://sscce.org/). –

+0

Да, игрок - это красный квадрат. В основном, что я хочу сделать, это вырезать круг из пустого, черного изображения вокруг координат игрока относительно указанного черного изображения. –

ответ

1

.. Игрок является красным квадратом. В основном, что я хочу сделать, это вырезать круг из пустого, черного изображения вокруг координат игрока относительно указанного черного изображения.

Что такое DYM от «черного изображения» - точно? Для меня это похоже на то, что BG окрашен в черный цвет, что имеет смысл для любого сплошного цвета. В этом случае просто создайте красную вещь, используя Area, заполните, затем для границы установите штрих & цвет на черный, и нарисовать. This example показывает, как.

Соответствующая часть этого короткого кода ..

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; 
    } 
} 
+0

Вот что моя игра на самом деле выглядит как http://puu.sh/ChJ5. Это то, на что похоже, используя код, который я предоставил. Я хочу найти лучший и эффективный способ сделать это. Зеленый круг - это трава в моей игре, а красный - игрок. Черный внешний вид - скрытая местность. Я хочу, чтобы иметь возможность вырезать круг на черном изображении, которое у меня есть (охватывает весь экран игры) относительно позиции моих игроков в игре. –

+0

Я рассмотрю его далее, когда вы предоставляете ** [SSCCE] (http://sscce.org/) ** (например, код, который я связал), а не фрагменты кода и текстовые описания. –

+0

См. Также анимированный SSCCE, который я опубликовал. Что FPS делает на вашей машине, точно так же? Я вижу> 130 FPS. –