1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167
| package test;
import java.awt.AlphaComposite;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.TexturePaint;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Optional;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class Main extends JPanel {
private static final Color TRANSPARENT_COLOR = new Color(0, 0, 0, 0);
// Source : carte quand elle est dans son état visible.
private final BufferedImage mapVisible;
// Source : carte quand elle est dans son état cachée par le brouillard de guerre (ici en niveau de gris et sans ennemis).
private final BufferedImage mapFog;
// Masque de la zone dans le champ visuel du joueur.
private final BufferedImage playerMask;
// Masque de la zone dans le champ visuel du joueur.
private final BufferedImage fogMask;
// Masque contenant les zones que le joueur a visité.
private final BufferedImage visibleBuffer;
// Buffer écran : les parties de la zone visitées par le joueur (sous brouillard de guerre).
private final BufferedImage fogBuffer;
// Buffer écran : les parties de la zone visibles par le joueur.
private final BufferedImage visitedMask;
// Texture des nuages qui sera affichée sur les zones non-visitées.
private final TexturePaint cloudTexture;
public Main() throws IOException {
super();
setMinimumSize(new Dimension(500, 500));
setPreferredSize(new Dimension(500, 500));
setMaximumSize(new Dimension(500, 500));
mapVisible = ImageIO.read(getClass().getResource("mapvisible.png"));
mapFog = ImageIO.read(getClass().getResource("mapfog.png"));
playerMask = ImageIO.read(getClass().getResource("playermask.png"));
fogMask = ImageIO.read(getClass().getResource("fogMask.png"));
visibleBuffer = new BufferedImage(500, 500, BufferedImage.TYPE_INT_ARGB);
fogBuffer = new BufferedImage(500, 500, BufferedImage.TYPE_INT_ARGB);
visitedMask = new BufferedImage(500, 500, BufferedImage.TYPE_INT_ARGB);
final BufferedImage cloudImage = ImageIO.read(getClass().getResource("clouds.png"));
cloudTexture = new TexturePaint(cloudImage, new Rectangle(0, 0, cloudImage.getWidth(), cloudImage.getHeight()));
addMouseMotionListener(new MouseAdapter() {
@Override
public void mouseMoved(MouseEvent mouseEvent) {
setPlayerPosition(new Point(mouseEvent.getX(), mouseEvent.getY()));
}
});
addMouseMotionListener(new MouseAdapter() {
@Override
public void mouseEntered(MouseEvent mouseEvent) {
setPlayerPosition(new Point(mouseEvent.getX(), mouseEvent.getY()));
}
@Override
public void mouseExited(MouseEvent e) {
setPlayerPosition(null);
}
});
addPropertyChangeListener("playerPosition", propertyChangeEvent -> updatePlayerPosition());
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
final Graphics2D g2d = (Graphics2D) g.create();
try {
g2d.setPaint(cloudTexture);
g2d.fillRect(0, 0, getWidth(), getHeight());
g2d.drawImage(fogBuffer, 0, 0, null);
g2d.drawImage(visibleBuffer, 0, 0, null);
} finally {
g2d.dispose();
}
}
////////////////////////////////////////////////////////////////////////////
private Point lasPosition;
private void updatePlayerPosition() {
final Graphics2D visitedg2d = visitedMask.createGraphics();
final Graphics2D fogg2d = fogBuffer.createGraphics();
final Graphics2D visibleg2d = visibleBuffer.createGraphics();
// Clear visible area with transparent color.
clearSurface(visibleg2d, visibleBuffer.getWidth(), visibleBuffer.getHeight());
final Optional<Point> positionOptional = Optional.ofNullable(getPlayerPosition());
positionOptional.ifPresent(position -> {
if (lasPosition == null || lasPosition.distance(position) > 30) {
// Visited mask.
visitedg2d.setComposite(AlphaComposite.SrcOver);
visitedg2d.drawImage(fogMask, position.x - fogMask.getWidth() / 2, position.y - fogMask.getHeight() / 2, null);
// Visited area.
// Clear fog area with transparent color.
clearSurface(fogg2d, fogBuffer.getWidth(), fogBuffer.getHeight());
fogg2d.setComposite(AlphaComposite.SrcOver);
fogg2d.drawImage(visitedMask, 0, 0, null);
fogg2d.setComposite(AlphaComposite.SrcIn);
fogg2d.drawImage(mapFog, 0, 0, null);
lasPosition = position;
}
// Visible area.
visibleg2d.setComposite(AlphaComposite.SrcOver);
visibleg2d.drawImage(playerMask, position.x - playerMask.getWidth() / 2, position.y - playerMask.getHeight() / 2, null);
visibleg2d.setComposite(AlphaComposite.SrcIn);
visibleg2d.drawImage(mapVisible, 0, 0, null);
});
visitedg2d.dispose();
fogg2d.dispose();
visibleg2d.dispose();
repaint();
}
private void clearSurface(final Graphics2D g2d, final int width, final int height) {
g2d.setComposite(AlphaComposite.SrcOver);
g2d.setPaint(Color.BLACK);
g2d.fillRect(0, 0, width, height);
g2d.setComposite(AlphaComposite.SrcIn);
g2d.setPaint(TRANSPARENT_COLOR);
g2d.fillRect(0, 0, width, height);
g2d.setComposite(AlphaComposite.SrcOver);
}
////////////////////////////////////////////////////////////////////////////
public final void setPlayerPosition(final Point value) {
putClientProperty("playerPosition", value);
}
public final Point getPlayerPosition() {
return (Point) getClientProperty("playerPosition");
}
////////////////////////////////////////////////////////////////////////////
public static void main(String[] args) {
SwingUtilities.invokeLater(Main::createUI);
}
private static void createUI() {
try {
final Main main = new Main();
final JFrame jframe = new JFrame("Test");
jframe.setLayout(new BorderLayout());
jframe.add(main, BorderLayout.CENTER);
jframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jframe.setResizable(false);
jframe.setVisible(true);
jframe.pack();
} catch (IOException ex) {
Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
}
}
} |
Partager