簡體   English   中英

嘗試將整數范圍轉換為RGB顏色

[英]Trying to convert Integer range to RGB color

我知道你們都非常忙碌,所以我會保持簡短和重點。

我正在開發一款有趣的小游戲。 游戲中有敵人。 為簡單起見,將它們視為彩色方塊。 我想最小化任何HUD,所以我決定通過它們的顏色順利顯示生物的生命值(綠色為健康,黃色為受損,紅色為近乎死亡)。

見圖: 在此輸入圖像描述

然而,我真的很難想出一個將(int)hp值轉換為RGB顏色的高效方法。 從0到255映射到單個int根本不會成為問題 - 這是一個示例函數,它正是這樣做的:

public int mapHpToGreyscale(int input) {

    //input = current hp
    double minHealth = 0;
    double maxHealth = hpmax;
    double minColValue = 0;
    double maxColValue = 255;

    int output = (int) ((input - minHealth) / (maxHealth - minHealth) * (maxColValue - minColValue) + minColValue);

    return output;
}

有沒有一種快速簡便的方法來實現我想做的事情? 我很感激任何意見。

說明

首先,我的回答是這個的改編版本: 計算從綠色到紅色的顏色值 我決定創建該JavaScript解決方案的Java版本。 代碼,您可以直接插入代碼而無需自己轉移所有內容。

我們的想法是使用HSL色調,飽和度,亮度 )色彩空間而不是RGB (紅色,綠色,藍色)。 紅色表示色調值 ,綠色表示120° ,黃色介於60°之間,色調平滑過渡

色調色圈 HSL色彩空間

我們將修正100%的飽和度和50%的亮度,但如果您願意,可以使用這些值。


用法

以下是在代碼中使用它的方法:

// A value between 1.0 (green) to 0.0 (red)
double percentage = ...
// Get the color (120° is green, 0° is red)
Color color = transitionOfHueRange(percentage, 120, 0);

那就是結果范圍:

Hue范圍示例


其他方法

這是transitionOfHueRange方法。 它接受介於0.01.0之間的percentage值以及介於0360之間的hue范圍:

public static Color transitionOfHueRange(double percentage, int startHue, int endHue) {
    // From 'startHue' 'percentage'-many to 'endHue'
    // Finally map from [0°, 360°] -> [0, 1.0] by dividing
    double hue = ((percentage * (endHue - startHue)) + startHue) / 360;

    double saturation = 1.0;
    double lightness = 0.5;

    // Get the color
    return hslColorToRgb(hue, saturation, lightness);
}

這是hslColorToRgb函數。 它接受從0.01.0 HSL值:

public static Color hslColorToRgb(double hue, double saturation, double lightness) {
    if (saturation == 0.0) {
        // The color is achromatic (has no color)
        // Thus use its lightness for a grey-scale color
        int grey = percToColor(lightness);
        return new Color(grey, grey, grey);
    }

    double q;
    if (lightness < 0.5) {
        q = lightness * (1 + saturation);
    } else {
        q = lightness + saturation - lightness * saturation;
    }
    double p = 2 * lightness - q;

    double oneThird = 1.0 / 3;
    double red = percToColor(hueToRgb(p, q, hue + oneThird));
    double green = percToColor(hueToRgb(p, q, hue));
    double blue = percToColor(hueToRgb(p, q, hue - oneThird));

    return new Color(red, green, blue);
}

hueToRgb方法:

public static double hueToRgb(double p, double q, double t) {
    if (t < 0) {
        t += 1;
    }
    if (t > 1) {
        t -= 1;
    }

    if (t < 1.0 / 6) {
        return p + (q - p) * 6 * t;
    }
    if (t < 1.0 / 2) {
        return q;
    }
    if (t < 2.0 / 3) {
        return p + (q - p) * (2.0 / 3 - t) * 6;
    }
    return p;
}

最后是小實用方法percToColor

public static int percToColor(double percentage) {
    return Math.round(percentage * 255);
}

這個答案是基於算法的答案算法之一:如何使用RGB值從黃色漸變為黃色? 有人在評論中提到。

請注意,此示例中未使用minHealthminColValue ,但實現起來應該不會太難。

import java.awt.Color;
import java.awt.GridLayout;

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;

public class HealthColors {

    static double minHealth = 0;// unused here
    static double maxHealth = 100;
    static double minColValue = 0;// unused here
    static double maxColValue = 255;

    public static void main(final String[] args) {

        JFrame frame = new JFrame();

        JPanel content = new JPanel();

        content.setLayout(new GridLayout(10, 10, 2, 2));

        for (int i = 0; i < maxHealth; i++) {

            int value = (int) (Math.random() * maxHealth + 1);

            JLabel label = new JLabel("" + value, SwingConstants.CENTER);
            label.setOpaque(true);
            label.setBackground(mapHpToColor(value));

            content.add(label);

        }

        frame.setContentPane(content);
        frame.pack();
        frame.setVisible(true);

    }

    public static Color mapHpToColor(final int input) {

        //input = current hp

        double redValue = (input > maxHealth / 2 ? 1 - 2 * (input - maxHealth / 2) / maxHealth : 1.0) * maxColValue;
        double greenValue = (input > maxHealth / 2 ? 1.0 : 2 * input / maxHealth) * maxColValue;
        double blueValue = 0;

        Color hpColor = new Color((int) redValue, (int) greenValue, (int) blueValue);

        return hpColor;
    }

}

在此輸入圖像描述

有沒有一種快速簡便的方法來實現我想做的事情?

是的,有,你甚至可以重用自己的代碼,只是那些常量應該是參數:

public int mapHpToComponent(int input,
    double minHealth, double maxHealth,
    double minComponentValue, double maxComponentValue) {

    int output = (int) ((input - minHealth) / (maxHealth - minHealth) *
        (maxComponentValue - minComponentValue) + minComponentValue);

    return output;
}

然后將其應用於調色板段。 有兩個,一個從HP = 0 ... 50開始,G = 0 ... 255,然后第二個段是HP = 50 ... 100和R = 255 ... 0:

public int mapHpToColor(int input){
    if(input<50){ // first segment
        int R=255;
        int G=mapHpToComponent(input,0,50,0,255);
        int B=0;
        return (R<<16)+(G<<8)+B;
    } else {
        int R=mapHpToComponent(input,50,100,255,0);
        int G=255;
        int B=0;
        return (R<<16)+(G<<8)+B;
    }
}

(是的,min / maxComponentValue可能是開始/結束,因為這是他們真正的。)

import java.lang.Math;

public class Color {
    public int r;
    public int g;
    public int b;
    public Color() {
        r = 0;
        g = 0;
        b = 0;
    }
};

public static Color hpToColor(float hp, float maxhp) {
    Color color = new Color();
    float alpha = hp / maxhp;

    if (alpha <= 0.5) {
        color.r = 255;
        color.g = Math.round((alpha * 2) * 255);
        color.b = 0;
    } else {
        color.r = Math.round(((1 - alpha) * 2) * 255);
        color.g = 255;
        color.b = 0;
    }

    return color;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM