461 lines
20 KiB
Java
461 lines
20 KiB
Java
import java.awt.AlphaComposite;
|
|
import java.awt.Color;
|
|
import java.awt.Graphics2D;
|
|
import java.awt.RenderingHints;
|
|
import java.awt.image.BufferedImage;
|
|
import java.io.IOException;
|
|
import java.nio.file.Files;
|
|
import java.nio.file.Path;
|
|
import java.util.List;
|
|
import java.util.Random;
|
|
|
|
import javax.imageio.ImageIO;
|
|
|
|
public final class PassiveMobArtGenerator {
|
|
private static final int MASTER_SIZE = 256;
|
|
private static final int CARD_SIZE = 64;
|
|
private static final int PIXEL = 4;
|
|
|
|
private static final Path ROOT = Path.of("").toAbsolutePath();
|
|
private static final Path FULL_ART_DIR = ROOT.resolve("Full Art").resolve("passive_mobs");
|
|
private static final Path CARD_ART_DIR = ROOT.resolve("src")
|
|
.resolve("main")
|
|
.resolve("resources")
|
|
.resolve("assets")
|
|
.resolve("minetriad")
|
|
.resolve("textures")
|
|
.resolve("item")
|
|
.resolve("cards");
|
|
|
|
private record MobArt(String name, Color base, Color dark, Color light, Color backgroundTop, Color backgroundBottom,
|
|
Color accent, List<String> features) {
|
|
}
|
|
|
|
private static final List<MobArt> MOBS = List.of(
|
|
mob("axolotl", rgb(244, 173, 203), rgb(232, 144, 187), rgb(124, 62, 110), rgb(95, 173, 207), rgb(19, 76, 113), rgb(255, 214, 122), "gills"),
|
|
mob("bee", rgb(255, 213, 62), rgb(84, 57, 29), rgb(255, 246, 196), rgb(131, 200, 95), rgb(50, 112, 49), rgb(226, 248, 255), "wings", "stripe"),
|
|
mob("camel", rgb(193, 154, 101), rgb(128, 94, 57), rgb(232, 203, 155), rgb(241, 194, 120), rgb(189, 110, 49), rgb(77, 148, 192), "ears"),
|
|
mob("cat", rgb(217, 176, 92), rgb(105, 76, 44), rgb(247, 229, 174), rgb(142, 186, 228), rgb(71, 99, 143), rgb(158, 219, 110), "ears", "snout"),
|
|
mob("chicken", rgb(243, 246, 239), rgb(208, 72, 46), rgb(251, 205, 61), rgb(161, 212, 127), rgb(89, 130, 70), rgb(164, 199, 245), "beak", "crest"),
|
|
mob("cod", rgb(145, 117, 88), rgb(95, 76, 52), rgb(211, 185, 149), rgb(57, 136, 170), rgb(15, 62, 97), rgb(230, 120, 74), "fins"),
|
|
mob("cow", rgb(116, 77, 52), rgb(59, 37, 25), rgb(231, 219, 206), rgb(144, 196, 110), rgb(75, 115, 59), rgb(162, 212, 255), "horns", "snout", "spots"),
|
|
mob("donkey", rgb(143, 118, 92), rgb(81, 62, 44), rgb(218, 202, 182), rgb(131, 170, 210), rgb(66, 90, 129), rgb(125, 193, 98), "long_ears", "snout"),
|
|
mob("fox", rgb(222, 110, 57), rgb(108, 55, 34), rgb(250, 239, 221), rgb(145, 204, 130), rgb(68, 109, 71), rgb(247, 214, 119), "ears", "snout"),
|
|
mob("frog", rgb(132, 176, 92), rgb(70, 108, 54), rgb(208, 219, 171), rgb(121, 180, 116), rgb(63, 110, 68), rgb(255, 220, 128), "frog_eyes"),
|
|
mob("glow_squid", rgb(96, 172, 188), rgb(41, 87, 101), rgb(163, 231, 246), rgb(38, 52, 102), rgb(11, 18, 39), rgb(119, 243, 255), "tentacles", "glow"),
|
|
mob("goat", rgb(208, 196, 184), rgb(121, 110, 98), rgb(245, 240, 233), rgb(160, 196, 193), rgb(92, 124, 122), rgb(192, 171, 101), "horns", "beard"),
|
|
mob("horse", rgb(122, 83, 55), rgb(65, 44, 28), rgb(236, 219, 187), rgb(134, 188, 121), rgb(64, 111, 67), rgb(187, 223, 255), "ears", "snout"),
|
|
mob("llama", rgb(220, 197, 162), rgb(140, 112, 80), rgb(248, 236, 219), rgb(170, 197, 122), rgb(88, 118, 72), rgb(197, 122, 67), "long_ears"),
|
|
mob("mooshroom", rgb(187, 54, 44), rgb(98, 26, 24), rgb(239, 226, 208), rgb(114, 162, 94), rgb(61, 103, 52), rgb(237, 247, 215), "horns", "snout", "spots", "mushroom"),
|
|
mob("mule", rgb(133, 104, 80), rgb(76, 57, 42), rgb(220, 205, 186), rgb(150, 188, 132), rgb(76, 112, 74), rgb(113, 166, 211), "long_ears", "snout"),
|
|
mob("ocelot", rgb(220, 185, 82), rgb(112, 85, 33), rgb(249, 228, 158), rgb(117, 178, 113), rgb(56, 104, 59), rgb(236, 191, 94), "ears", "snout", "spots"),
|
|
mob("panda", rgb(235, 238, 242), rgb(42, 46, 52), rgb(255, 255, 255), rgb(137, 198, 124), rgb(70, 111, 64), rgb(198, 227, 141), "ears", "panda_eyes"),
|
|
mob("parrot", rgb(205, 61, 57), rgb(42, 88, 182), rgb(255, 214, 54), rgb(115, 190, 155), rgb(52, 94, 102), rgb(182, 238, 93), "beak", "crest", "wings"),
|
|
mob("pig", rgb(233, 167, 182), rgb(168, 99, 122), rgb(250, 208, 217), rgb(133, 193, 115), rgb(74, 116, 67), rgb(204, 230, 255), "snout"),
|
|
mob("polar_bear", rgb(238, 243, 247), rgb(152, 173, 191), rgb(255, 255, 255), rgb(146, 188, 217), rgb(82, 117, 149), rgb(195, 225, 255), "ears", "snout"),
|
|
mob("rabbit", rgb(187, 173, 162), rgb(117, 98, 86), rgb(240, 231, 222), rgb(166, 203, 111), rgb(87, 118, 63), rgb(255, 215, 145), "long_ears", "snout"),
|
|
mob("salmon", rgb(214, 120, 95), rgb(121, 76, 60), rgb(247, 183, 162), rgb(72, 146, 175), rgb(17, 69, 107), rgb(225, 212, 117), "fins"),
|
|
mob("sheep", rgb(233, 235, 241), rgb(128, 100, 74), rgb(255, 255, 255), rgb(142, 197, 117), rgb(81, 123, 68), rgb(168, 218, 255), "wool", "snout"),
|
|
mob("sniffer", rgb(127, 95, 66), rgb(73, 52, 39), rgb(180, 141, 106), rgb(102, 152, 88), rgb(54, 93, 55), rgb(222, 106, 58), "snout", "moss"),
|
|
mob("squid", rgb(133, 92, 176), rgb(63, 41, 91), rgb(212, 181, 236), rgb(58, 102, 153), rgb(20, 35, 74), rgb(185, 132, 236), "tentacles"),
|
|
mob("strider", rgb(209, 84, 72), rgb(111, 36, 36), rgb(246, 166, 133), rgb(231, 144, 71), rgb(129, 68, 35), rgb(101, 38, 38), "tentacles", "snout"),
|
|
mob("turtle", rgb(107, 150, 77), rgb(57, 92, 45), rgb(194, 176, 88), rgb(92, 166, 143), rgb(44, 100, 100), rgb(223, 232, 176), "shell"),
|
|
mob("wolf", rgb(181, 188, 197), rgb(91, 98, 109), rgb(231, 235, 239), rgb(118, 164, 188), rgb(63, 97, 115), rgb(209, 67, 57), "ears", "snout"));
|
|
|
|
public static void main(String[] args) throws IOException {
|
|
Files.createDirectories(FULL_ART_DIR);
|
|
Files.createDirectories(CARD_ART_DIR);
|
|
|
|
for (MobArt mob : MOBS) {
|
|
BufferedImage master = generateArt(mob);
|
|
ImageIO.write(master, "png", FULL_ART_DIR.resolve(mob.name() + ".png").toFile());
|
|
ImageIO.write(scale(master, CARD_SIZE, CARD_SIZE), "png", CARD_ART_DIR.resolve(mob.name() + ".png").toFile());
|
|
}
|
|
|
|
System.out.println("Generated " + MOBS.size() + " passive mob paintings.");
|
|
}
|
|
|
|
private static BufferedImage generateArt(MobArt mob) {
|
|
BufferedImage image = new BufferedImage(MASTER_SIZE, MASTER_SIZE, BufferedImage.TYPE_INT_ARGB);
|
|
Random random = new Random(mob.name().hashCode());
|
|
paintBackground(image, mob, random);
|
|
|
|
Graphics2D g = image.createGraphics();
|
|
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF);
|
|
g.setComposite(AlphaComposite.SrcOver);
|
|
|
|
drawHead(g, mob, random);
|
|
addForeground(g, mob, random);
|
|
addAtmosphere(g, mob, random);
|
|
|
|
g.dispose();
|
|
return image;
|
|
}
|
|
|
|
private static void paintBackground(BufferedImage image, MobArt mob, Random random) {
|
|
for (int y = 0; y < MASTER_SIZE; y++) {
|
|
double blend = (double) y / (MASTER_SIZE - 1);
|
|
double wave = Math.sin((y / (double) MASTER_SIZE) * Math.PI * 3.0) * 0.08;
|
|
Color row = mix(mob.backgroundTop(), mob.backgroundBottom(), clamp01(blend + wave));
|
|
for (int x = 0; x < MASTER_SIZE; x++) {
|
|
double distanceX = x - (MASTER_SIZE / 2.0);
|
|
double distanceY = y - (MASTER_SIZE / 2.0);
|
|
double vignette = (distanceX * distanceX + distanceY * distanceY) / (MASTER_SIZE * (double) MASTER_SIZE);
|
|
Color shaded = shade(row, vignette * 0.65);
|
|
int noise = random.nextInt(17) - 8;
|
|
image.setRGB(x, y, shift(shaded, noise).getRGB());
|
|
}
|
|
}
|
|
|
|
Graphics2D g = image.createGraphics();
|
|
for (int i = 0; i < 10; i++) {
|
|
int radius = random.nextInt(35) + 18;
|
|
int x = random.nextInt(MASTER_SIZE + 40) - 20;
|
|
int y = random.nextInt(MASTER_SIZE + 40) - 20;
|
|
g.setColor(alpha(mob.accent(), random.nextInt(56) + 40));
|
|
g.fillOval(x, y, radius, radius);
|
|
}
|
|
|
|
for (int i = 0; i < 55; i++) {
|
|
int x = random.nextInt(MASTER_SIZE);
|
|
int y = random.nextInt(MASTER_SIZE);
|
|
int size = random.nextInt(5) + 2;
|
|
g.setColor(alpha(tint(mob.accent(), 0.35), random.nextInt(31) + 18));
|
|
g.fillRect(x, y, size, size);
|
|
}
|
|
g.dispose();
|
|
}
|
|
|
|
private static void drawHead(Graphics2D g, MobArt mob, Random random) {
|
|
Color outline = shade(mob.dark(), 0.18);
|
|
block(g, 16, 15, 32, 26, mob.base(), outline);
|
|
block(g, 18, 17, 28, 9, tint(mob.light(), 0.08), null);
|
|
block(g, 18, 26, 28, 13, mob.base(), null);
|
|
block(g, 22, 41, 20, 8, shade(mob.base(), 0.12), outline);
|
|
|
|
if (has(mob, "spots")) {
|
|
spot(g, 20, 20, 4, 4, shade(mob.dark(), 0.08));
|
|
spot(g, 39, 23, 5, 4, shade(mob.dark(), 0.08));
|
|
spot(g, 24, 31, 4, 3, shade(mob.dark(), 0.08));
|
|
}
|
|
|
|
if (has(mob, "wool")) {
|
|
puff(g, 16, 14, mob, outline);
|
|
puff(g, 22, 11, mob, outline);
|
|
puff(g, 30, 10, mob, outline);
|
|
puff(g, 38, 12, mob, outline);
|
|
puff(g, 44, 15, mob, outline);
|
|
}
|
|
|
|
if (has(mob, "moss")) {
|
|
block(g, 18, 14, 9, 4, rgb(92, 138, 78), null);
|
|
block(g, 37, 15, 7, 3, rgb(92, 138, 78), null);
|
|
block(g, 30, 18, 8, 3, rgb(92, 138, 78), null);
|
|
}
|
|
|
|
if (has(mob, "shell")) {
|
|
block(g, 21, 21, 22, 17, mob.light(), outline);
|
|
for (int stripeX : new int[]{25, 32, 39}) {
|
|
block(g, stripeX, 23, 2, 13, tint(mob.base(), 0.1), null);
|
|
}
|
|
}
|
|
|
|
if (has(mob, "frog_eyes")) {
|
|
eyeBump(g, 18, mob.light(), outline);
|
|
eyeBump(g, 40, mob.light(), outline);
|
|
}
|
|
|
|
if (has(mob, "ears")) {
|
|
ear(g, 15, mob.base(), outline);
|
|
ear(g, 43, mob.base(), outline);
|
|
}
|
|
|
|
if (has(mob, "long_ears")) {
|
|
longEar(g, 15, mob.base(), mob.light(), outline);
|
|
longEar(g, 44, mob.base(), mob.light(), outline);
|
|
}
|
|
|
|
if (has(mob, "horns")) {
|
|
horn(g, 16, mob.light(), outline);
|
|
horn(g, 45, mob.light(), outline);
|
|
}
|
|
|
|
if (has(mob, "gills")) {
|
|
block(g, 9, 22, 4, 12, tint(mob.base(), 0.06), outline);
|
|
block(g, 51, 22, 4, 12, tint(mob.base(), 0.06), outline);
|
|
}
|
|
|
|
if (has(mob, "beard")) {
|
|
block(g, 30, 47, 4, 5, tint(mob.light(), 0.12), outline);
|
|
}
|
|
|
|
if (has(mob, "mushroom")) {
|
|
mushroom(g, 15, outline);
|
|
mushroom(g, 39, outline);
|
|
}
|
|
|
|
if (has(mob, "wings")) {
|
|
wing(g, 2, tint(mob.light(), 0.25), tint(mob.light(), 0.05));
|
|
wing(g, 54, tint(mob.light(), 0.25), tint(mob.light(), 0.05));
|
|
}
|
|
|
|
if (has(mob, "tentacles")) {
|
|
int[] tentacles = {19, 24, 29, 34, 39, 44};
|
|
for (int i = 0; i < tentacles.length; i++) {
|
|
block(g, tentacles[i], 41 + (i % 2), 3, 12, shade(mob.base(), 0.12), outline);
|
|
}
|
|
}
|
|
|
|
if (has(mob, "fins")) {
|
|
fin(g, 8, tint(mob.light(), 0.18), outline);
|
|
fin(g, 51, tint(mob.light(), 0.18), outline);
|
|
block(g, 29, 11, 6, 7, tint(mob.light(), 0.18), outline);
|
|
}
|
|
|
|
if (has(mob, "stripe")) {
|
|
block(g, 18, 22, 28, 3, mob.dark(), null);
|
|
block(g, 18, 28, 28, 3, mob.dark(), null);
|
|
block(g, 18, 34, 28, 3, mob.dark(), null);
|
|
}
|
|
|
|
if (has(mob, "glow")) {
|
|
sparkle(g, 20, 18, 4, 4, tint(mob.accent(), 0.25));
|
|
sparkle(g, 40, 21, 3, 3, tint(mob.accent(), 0.25));
|
|
sparkle(g, 24, 31, 3, 3, tint(mob.accent(), 0.25));
|
|
sparkle(g, 37, 34, 4, 4, tint(mob.accent(), 0.25));
|
|
}
|
|
|
|
if (has(mob, "panda_eyes")) {
|
|
eyePatch(g, 16, mob.dark(), outline);
|
|
eyePatch(g, 40, mob.dark(), outline);
|
|
}
|
|
|
|
if (has(mob, "crest")) {
|
|
block(g, 28, 11, 8, 4, mob.accent(), outline);
|
|
}
|
|
|
|
if (has(mob, "snout")) {
|
|
block(g, 24, 34, 16, 9, mob.light(), outline);
|
|
block(g, 27, 37, 3, 3, mob.dark(), null);
|
|
block(g, 34, 37, 3, 3, mob.dark(), null);
|
|
}
|
|
|
|
Color eyeWhite = tint(mob.light(), 0.25);
|
|
Color eyeFill = ("panda".equals(mob.name()) || "wolf".equals(mob.name())) ? rgb(212, 61, 56) : mob.accent();
|
|
eye(g, 21, eyeWhite, eyeFill, outline);
|
|
eye(g, 37, eyeWhite, eyeFill, outline);
|
|
|
|
if ("cod".equals(mob.name()) || "salmon".equals(mob.name())) {
|
|
block(g, 18, 30, 4, 2, mob.dark(), null);
|
|
block(g, 42, 30, 4, 2, mob.dark(), null);
|
|
}
|
|
|
|
switch (mob.name()) {
|
|
case "bee" -> block(g, 24, 35, 16, 6, tint(mob.base(), 0.1), outline);
|
|
case "parrot" -> {
|
|
block(g, 28, 33, 8, 10, mob.accent(), outline);
|
|
block(g, 31, 38, 2, 3, mob.dark(), null);
|
|
}
|
|
case "chicken" -> {
|
|
block(g, 27, 33, 10, 7, mob.accent(), outline);
|
|
block(g, 29, 40, 6, 3, rgb(220, 41, 38), null);
|
|
}
|
|
case "frog" -> block(g, 25, 37, 14, 3, shade(mob.base(), 0.2), null);
|
|
case "glow_squid" -> block(g, 18, 18, 28, 20, shade(mob.base(), 0.05), outline);
|
|
case "strider" -> {
|
|
block(g, 24, 17, 16, 10, shade(mob.base(), 0.08), outline);
|
|
block(g, 20, 24, 24, 4, tint(mob.light(), 0.1), null);
|
|
}
|
|
case "sniffer" -> {
|
|
block(g, 18, 24, 28, 16, shade(mob.base(), 0.04), outline);
|
|
block(g, 23, 35, 18, 6, rgb(229, 120, 67), outline);
|
|
}
|
|
default -> {
|
|
}
|
|
}
|
|
|
|
Color shadow = shade(mob.base(), 0.18);
|
|
fill(g, 18, 40, 28, 1, shadow);
|
|
fill(g, 16, 39, 2, 2, shadow);
|
|
fill(g, 46, 39, 2, 2, shadow);
|
|
|
|
for (int i = 0; i < 8; i++) {
|
|
int x = random.nextInt(33) + 14;
|
|
int y = random.nextInt(37) + 13;
|
|
if (random.nextDouble() < 0.35) {
|
|
fill(g, x, y, 1, 1, tint(mob.light(), 0.18));
|
|
}
|
|
}
|
|
}
|
|
|
|
private static void addForeground(Graphics2D g, MobArt mob, Random random) {
|
|
for (int i = 0; i < 12; i++) {
|
|
int x = random.nextInt(59);
|
|
int y = random.nextInt(15) + 48;
|
|
int height = random.nextInt(7) + 2;
|
|
fill(g, x, y, 2, height, tint(mob.backgroundTop(), 0.06));
|
|
}
|
|
|
|
if (List.of("cod", "salmon", "squid", "glow_squid", "axolotl", "turtle").contains(mob.name())) {
|
|
Color wave = tint(mob.backgroundTop(), 0.12);
|
|
for (int y : new int[]{45, 50, 55}) {
|
|
for (int x = 0; x < 64; x += 6) {
|
|
fill(g, x, y, 4, 1, wave);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (List.of("bee", "parrot").contains(mob.name())) {
|
|
fill(g, 10, 16, 2, 2, tint(mob.light(), 0.35));
|
|
fill(g, 49, 16, 2, 2, tint(mob.light(), 0.35));
|
|
}
|
|
|
|
if (List.of("mooshroom", "cow", "sheep", "pig", "horse", "goat").contains(mob.name())) {
|
|
fill(g, 11, 52, 4, 6, shade(mob.dark(), 0.1));
|
|
fill(g, 50, 52, 4, 6, shade(mob.dark(), 0.1));
|
|
}
|
|
}
|
|
|
|
private static void addAtmosphere(Graphics2D g, MobArt mob, Random random) {
|
|
for (int i = 0; i < 18; i++) {
|
|
int x = random.nextInt(MASTER_SIZE - 20) + 10;
|
|
int y = random.nextInt(MASTER_SIZE - 16) + 8;
|
|
int size = random.nextInt(5) + 3;
|
|
g.setColor(alpha(tint(mob.accent(), 0.25), random.nextInt(36) + 20));
|
|
g.fillOval(x, y, size, size);
|
|
}
|
|
}
|
|
|
|
private static BufferedImage scale(BufferedImage source, int width, int height) {
|
|
BufferedImage scaled = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
|
|
Graphics2D g = scaled.createGraphics();
|
|
g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR);
|
|
g.drawImage(source, 0, 0, width, height, null);
|
|
g.dispose();
|
|
return scaled;
|
|
}
|
|
|
|
private static MobArt mob(String name, Color base, Color dark, Color light, Color backgroundTop, Color backgroundBottom,
|
|
Color accent, String... features) {
|
|
return new MobArt(name, base, dark, light, backgroundTop, backgroundBottom, accent, List.of(features));
|
|
}
|
|
|
|
private static boolean has(MobArt mob, String feature) {
|
|
return mob.features().contains(feature);
|
|
}
|
|
|
|
private static void puff(Graphics2D g, int x, int y, MobArt mob, Color outline) {
|
|
block(g, x, y, 6, 6, tint(mob.light(), 0.08), outline);
|
|
}
|
|
|
|
private static void ear(Graphics2D g, int x, Color base, Color outline) {
|
|
block(g, x, 9, 6, 8, base, outline);
|
|
}
|
|
|
|
private static void longEar(Graphics2D g, int x, Color base, Color light, Color outline) {
|
|
block(g, x, 4, 5, 14, base, outline);
|
|
block(g, x + 1, 7, 2, 8, tint(light, 0.14), null);
|
|
}
|
|
|
|
private static void horn(Graphics2D g, int x, Color light, Color outline) {
|
|
block(g, x, 8, 3, 9, tint(light, 0.2), outline);
|
|
}
|
|
|
|
private static void mushroom(Graphics2D g, int x, Color outline) {
|
|
block(g, x, 7, 10, 4, rgb(222, 204, 196), outline);
|
|
block(g, x + 2, 3, 6, 6, rgb(194, 51, 47), outline);
|
|
}
|
|
|
|
private static void wing(Graphics2D g, int x, Color fill, Color outline) {
|
|
block(g, x, 20, 8, 14, fill, outline);
|
|
}
|
|
|
|
private static void fin(Graphics2D g, int x, Color fill, Color outline) {
|
|
block(g, x, 25, 5, 10, fill, outline);
|
|
}
|
|
|
|
private static void eyeBump(Graphics2D g, int x, Color fill, Color outline) {
|
|
block(g, x, 10, 6, 6, fill, outline);
|
|
}
|
|
|
|
private static void eyePatch(Graphics2D g, int x, Color fill, Color outline) {
|
|
block(g, x, 24, 8, 8, fill, outline);
|
|
}
|
|
|
|
private static void eye(Graphics2D g, int x, Color white, Color iris, Color outline) {
|
|
block(g, x, 24, 5, 5, white, outline);
|
|
block(g, x + 1, 25, 2, 2, iris, null);
|
|
}
|
|
|
|
private static void sparkle(Graphics2D g, int x, int y, int w, int h, Color fill) {
|
|
block(g, x, y, w, h, fill, null);
|
|
}
|
|
|
|
private static void spot(Graphics2D g, int x, int y, int w, int h, Color fill) {
|
|
block(g, x, y, w, h, fill, null);
|
|
}
|
|
|
|
private static void block(Graphics2D g, int x, int y, int w, int h, Color fill, Color outline) {
|
|
fill(g, x, y, w, h, fill);
|
|
if (outline != null) {
|
|
fill(g, x, y, w, 1, outline);
|
|
fill(g, x, y + h - 1, w, 1, outline);
|
|
fill(g, x, y, 1, h, outline);
|
|
fill(g, x + w - 1, y, 1, h, outline);
|
|
}
|
|
}
|
|
|
|
private static void fill(Graphics2D g, int x, int y, int w, int h, Color color) {
|
|
g.setColor(color);
|
|
g.fillRect(x * PIXEL, y * PIXEL, w * PIXEL, h * PIXEL);
|
|
}
|
|
|
|
private static Color tint(Color color, double amount) {
|
|
return new Color(
|
|
clamp(color.getRed() + ((255 - color.getRed()) * amount)),
|
|
clamp(color.getGreen() + ((255 - color.getGreen()) * amount)),
|
|
clamp(color.getBlue() + ((255 - color.getBlue()) * amount))
|
|
);
|
|
}
|
|
|
|
private static Color shade(Color color, double amount) {
|
|
return new Color(
|
|
clamp(color.getRed() * (1.0 - amount)),
|
|
clamp(color.getGreen() * (1.0 - amount)),
|
|
clamp(color.getBlue() * (1.0 - amount))
|
|
);
|
|
}
|
|
|
|
private static Color shift(Color color, int amount) {
|
|
return new Color(
|
|
clamp(color.getRed() + amount),
|
|
clamp(color.getGreen() + amount),
|
|
clamp(color.getBlue() + amount)
|
|
);
|
|
}
|
|
|
|
private static Color mix(Color a, Color b, double amount) {
|
|
return new Color(
|
|
clamp(a.getRed() + ((b.getRed() - a.getRed()) * amount)),
|
|
clamp(a.getGreen() + ((b.getGreen() - a.getGreen()) * amount)),
|
|
clamp(a.getBlue() + ((b.getBlue() - a.getBlue()) * amount))
|
|
);
|
|
}
|
|
|
|
private static Color alpha(Color color, int alpha) {
|
|
return new Color(color.getRed(), color.getGreen(), color.getBlue(), alpha);
|
|
}
|
|
|
|
private static Color rgb(int red, int green, int blue) {
|
|
return new Color(red, green, blue);
|
|
}
|
|
|
|
private static int clamp(double value) {
|
|
return Math.max(0, Math.min(255, (int) Math.round(value)));
|
|
}
|
|
|
|
private static double clamp01(double value) {
|
|
return Math.max(0.0, Math.min(1.0, value));
|
|
}
|
|
}
|