2016-09-23 3 views
1

Я начал делать «игру жизни», и я подумал, что, если бы я мог иметь больше состояний, чем 1 или 0.Что такое хороший способ хранения цвета?

Но тогда мне нужны разные цвета. Я хочу, чтобы цвета были связаны с сеткой/объектом (сетка - это класс).

Что такое хороший/достойный способ хранения цветных поддонов для быстрого/легкого доступа?

Мое настоящее, чем идеальное решение, состояло в том, чтобы иметь 4 указателя на память для каждого красного, зеленого, синего и альфа-значения.

В моем классе я имел функцию, чтобы задать цвет значения v в RGBA:

SetColor(v, r, g, b, a) //Set v to the appropriate color values 

Я хотел бы сохранить эту функцию, чтобы легко изменить цвет.

+0

«легко изменить»? какова проблема с текущей реализацией? – v78

+0

его очень грязный и использует чрезмерную память – Kriso

ответ

5

Что я использую это что-то очень просто: 4 поплавков

struct Color { 
    float r, g, b, a; 
}; 

Затем, вы можете иметь что-то вроде цвета паллета:

// a Palette of 8 colors: 
using palette_t = std::array<Color, 8> 

palette_t myPalette { /* ... */ }; 

Затем, в сетке или классе объектов, вы можете ссылку на цвет с индексом:

struct Grid { 
    // lot's of code 

private: 
    std::size_t colorIndex = 0; 
}; 

Но потом вы спросили, как получить легкий доступ к цвету (я думаю, что легкий доступ из класса Grid)

Существует много решений, которые могут существовать, и большинство будет зависеть от вашей структуры проекта. Это одна идея многих других. Надеюсь, это вдохновит вас.

Вы можете сохранить функцию, вернуть правильный цвет:

struct Grid { 
    // lot's of code 

private: 
    std::size_t colorIndex = 0; 
    std::function<Color(std::size_t)> color; 
}; 

А потом, что-то, что создать свою сетку правильно:

struct GridCreator { 
    GridCreator(const palette_t& aPalette) : palette{aPalette} {} 

    Grid create(std::size_t color) const { 
     Grid grid; 

     // create the grid 

     grid.color = [this](std::size_t index) { 
      return palette[index]; 
     }; 

     return grid; 
    } 

private: 
    const palette_t& palette; 
}; 

Тогда вы получили свободный доступ к вашей цветовой палитре без непосредственно зная, что палитра существует из класса Grid.

+0

std :: array расширяемый или исправленный? – Kriso

+0

Цель 'std :: array' - иметь массив с размером, известным во время компиляции. Вы не сможете изменить его размер во время выполнения. Однако, когда вы уже знаете размер и вы не собираетесь его изменять во время выполнения, правильный выбор - 'std :: array'. btw это намного легче, чем вектор;) –

+0

, тогда я, вероятно, пойду для вектора размера 256. – Kriso

1

Enums идеально подходят для цветовой гаммы.

  1. Подробнее читаемость кода.
  2. Лучшая оптимизация времени компилятора.

    enum Color { red, green, blue }; 
    Color r = red; 
    switch(r) 
    { 
        case red : std::cout << "red\n"; break; 
        case green: std::cout << "green\n"; break; 
        case blue : std::cout << "blue\n"; break; 
    } 
    

Для вашего особого случая. Вы можете сохранить цвет для каждой точки как одно целое.

uint32_t point_color = field[5][2].color; 
unsigned char* color = (unsigned char*)point_color[id]; 
auto r = color[0], alpha = color[3]; 

///// 

void SetColor(uint32_t& point_color,unsigned char r, 
       unsigned char g,unsigned char b,unsigned char a){ 
    point_color=r | (b*(1<<8)) | (g*(1<<16)) | (a*(1<<24)); 
} 

Достоинства этой структуры

  1. менее грязный.
  2. более быстрые операции с битами.
  3. меньше память.
+2

«Перечислимый класс» лучше, чем 'enum', подумайте об использовании этого. – Rakete1111

+0

Я не думаю, что у вас есть мой вопрос. Мне нужно получить доступ к цветам из списка на основе значения/ID. – Kriso

+0

Нет, @ Kriso, Вы все еще можете болеть его в ENUM. – v78

4

Есть множество цветов:

std::vector<std::array<unsigned char, 4>> palette { 
    {255, 0, 0, 255}, // red 
    {0, 255, 0, 255}, // green 
    {0, 0, 255, 255}, // blue 
}; 

Тогда для каждого магазина поля индекса в массиве (типа size_t). Пример:

auto id = field[5][2]; 
auto color = palette[id]; 
auto r = color[0], alpha = color[3]; 

Изменение цвета так просто, как:

palette[id] = {255, 0, 0, 127}; 

Для добавления новых цветов используйте:

palette.push_back({255, 0, 0, 127}). 

В качестве альтернативы, вы можете определить, простую структуру, так что вы можете используйте color.r, color.alpha и т. д. и напишите конструктор для легкого создания цвета.

Обратите внимание на этот пример кода C++ 11.

+0

, и как бы я мог продлить его во время выполнения. – Kriso

+0

Я отредактировал свой ответ, чтобы охватить это. – ypnos

+0

ok, так что push_back добавляет новую запись или сдвигает остальные – Kriso

0

Ваш вопрос двойственна:

  • Что такое хороший способ для хранения цвет?
  • Что такое хороший/достойный способ хранения цветных поддонов?

Если вы действительно хотите только сохранить цвет, я бы посоветовал не хранить цвета в качестве ссылок, а хранить значения RGB в одном INT32 внутри класса, где вы можете получить и установить Reg/Green/Синие значения. Сравните это с тем, как это делает .NET.

Преимущество этого метода заключается в том, что он не имеет больше места, чем с помощью указателей, и он быстро работает в get/set/compare.

Цветовая палитра представляет собой коллекцию цветов. Это довольно часто используется, если вы хотите переключить все используемые цвета на другой цвет. Например, если вы хотите, чтобы все светло-голубые цвета были туманно-синих, а все красно-красные цвета - кирпично-красные.

Используется для определения палитры в виде массива заданного размера или значений RGB. Исторически палитра содержит 16, 64 или 256 значений или иногда 2, если вам нужны только черно-белые изображения. Если вы используете палитру, каждая точка в вашей сетке имеет индекс в вашем массиве палитр, и ваша сетка имеет текущую палитру. Значением RGB точки X сетки G является G.CurrentPallette [X.PaletIndex]. Изменение всех цветов вашей сетки сразу означает переход на другую палитру: G.CurrentPalette = otherPalette.Это очень быстрый и эффективный способ изменения цвета в сетке

ли использовать метод RGB или метод палитры зависит от того, что вы хотите:

  • Вы хотите использовать только подмножество все возможные цвета, и вы хотите изменить полное подмножество на другое подмножество: используйте метод палитры
  • Вы хотите изменить цвет точек в определенном состоянии, например, изменить все желтые точки на зеленый, использовать метод палитры: измените цвет в палитре желтого цвета
  • Однако, если вы хотите только чанг а отдельные точки на вашей сетке, вероятно, более эффективны для использования метода RGB.
0

любое значение цвета имеет интервал от 0 до 255, поэтому вам нужны 3 неподписанных переменных char и еще один для букв. мы делаем целую вещь, отображая их как структуру:

typedef struct Color 
{ 
    unsigned char _ucRed; 
    unsigned char _ucGreen; 
    unsigned char _ucBlue; 
    unsigned char _ucAlpha; 
}COLOR; 
Смежные вопросы