> ## Documentation Index
> Fetch the complete documentation index at: https://devdocs.xbox.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Efeitos de LampArray

> Efeitos de LampArray

Chame as funções de cor de [ILampArray](/pt-BR/reference/lighting/lamparray/interfaces/ilamparray/ilamparray) dentro do loop do jogo para produzir efeitos e animações. Esta página mostra alguns exemplos.

Para simplificar, estes exemplos usarão [ILampArray::SetColor](/pt-BR/reference/lighting/lamparray/interfaces/ilamparray/methods/ilamparray_setcolor) sempre que possível para aplicar cores a todas as Lamps de um dispositivo. É possível produzir efeitos em Lamps individuais ou em conjuntos de Lamps usando [ILampArray::SetColorsForIndices](/pt-BR/reference/lighting/lamparray/interfaces/ilamparray/methods/ilamparray_setcolorsforindices).

## Esmaecimento e piscar

Faça as lâmpadas aparecerem ou desaparecerem gradualmente multiplicando os valores RGB de uma cor por uma porcentagem crescente ou decrescente ao longo de um intervalo de tempo. Crie efeitos de piscar, respiração ou flash fazendo as lâmpadas aparecerem e desaparecerem gradualmente de forma repetida.

O exemplo a seguir faz todas as Lamps de um LampArray piscarem, acendendo e apagando:

```cpp theme={null}
uint32_t currentFrame = 0;

// The total number of frames in one blink
const float blinkFrameCount = 90;

const float blinkFadeFrameCount = blinkFrameCount / 2;

// The color to fade in and out. In this example we'll use red.
const LampArrayColor mainColor = {0xFF /* r */, 0x0 /* g */, 0x0 /* b */, 0xFF /* a */};

Microsoft::WRL::ComPtr<ILampArray> lampArray;

void BlinkUpdateFrame(ILampArray* lampArrayToUpdate)
{
    LampArrayColor currentFrameColor = mainColor;

    float colorScale = 1.0;

    if (currentFrame < blinkFadeFrameCount)
    {
        // Fade out to black
        colorScale = (blinkFadeFrameCount - currentFrame) / blinkFadeFrameCount;
    }
    else
    {
        // Fade in to full color value
        colorScale = (currentFrame - blinkFadeFrameCount) / blinkFadeFrameCount;
    }

    currentFrameColor.r = static_cast<uint8_t>(mainColor.r * colorScale);
    currentFrameColor.g = static_cast<uint8_t>(mainColor.g * colorScale);
    currentFrameColor.b = static_cast<uint8_t>(mainColor.b * colorScale);

    // Apply the color
    lampArrayToUpdate->SetColor(currentFrameColor);

    // Increment our current frame, accounting for overflow
    if (++currentFrame > blinkFrameCount)
    {
        currentFrame = 0;
    }
}

void MainLoop(
    _In_ volatile bool& terminateLoop)
{
    color.a = 0xFF;

    while (!terminateLoop)
    {
        Sleep(50);

        BlinkUpdateFrame(lampArray.Get());
    }
} 
```

## Ciclos de cores

Crie ciclos de cores aumentando e diminuindo gradualmente os valores de vermelho, verde e azul de uma cor. Isso fará a transição entre uma ampla gama de cores do espectro RGB.

O exemplo a seguir executa um ciclo de cores RGB em um LampArray.

```cpp theme={null}
uint32_t currentFrame = 0;

// The total number of frames in one cycle
const float cycleFrameCount = 180;

// The size of each "ramp" of the cycle (blending from one color to the next)
const float rampIntervalFrameCount = cycleFrameCount / 6;

// The color to set in each frame
LampArrayColor color = {};

Microsoft::WRL::ComPtr<ILampArray> lampArray;

void CycleUpdateFrame(ILampArray* lampArrayToUpdate)
{
    // Calculate the color for the current frame.
    if (currentFrame < rampIntervalFrameCount)
    {
        // Red -> yellow: increase g
        color.r = 0xFF;
        color.g = static_cast<BYTE>(0xFF * (currentFrame / rampIntervalFrameCount));
    }
    else if (currentFrame < (2 * rampIntervalFrameCount))
    {
        // Yellow -> green: decrease r
        color.r = static_cast<BYTE>(0xFF * (((2 * rampIntervalFrameCount) - currentFrame) / rampIntervalFrameCount));
        color.g = 0xFF;
    }
    else if (currentFrame < (3 * rampIntervalFrameCount))
    {
        // Green -> cyan: increase b
        color.g = 0xFF;
        color.b = static_cast<BYTE>(0xFF * ((currentFrame - (2 * rampIntervalFrameCount)) / rampIntervalFrameCount));
    }
    else if (currentFrame < (4 * rampIntervalFrameCount))
    {
        // Cyan -> blue: decrease g
        color.g = static_cast<BYTE>(0xFF * (((4 * rampIntervalFrameCount) - currentFrame) / rampIntervalFrameCount));
        color.b = 0xFF;
    }
    else if (currentFrame < (5 * rampIntervalFrameCount))
    {
        // Blue -> magenta: increase r
        color.r = static_cast<BYTE>(0xFF * ((currentFrame - (4 * rampIntervalFrameCount)) / rampIntervalFrameCount));
        color.b = 0xFF;
    }
    else
    {
        // Magenta -> red: decrease b
        color.r = 0xFF;
        color.b = static_cast<BYTE>(0xFF * ((cycleFrameCount - currentFrame) / rampIntervalFrameCount));
    }

    // Apply the color
    lampArrayToUpdate->SetColor(color);

    // Increment our current frame, accounting for overflow
    if (++currentFrame > cycleFrameCount)
    {
        currentFrame = 0;
    }
}

void MainLoop(
    _In_ volatile bool& terminateLoop)
{
    color.a = 0xFF;

    while (!terminateLoop)
    {
        Sleep(50);

        CycleUpdateFrame(lampArray.Get());
    }
}
```

## Efeitos baseados em posição

Use [ILampInfo::GetPosition](/pt-BR/reference/lighting/lamparray/interfaces/ilampinfo/methods/ilampinfo_getposition) e [ILampArray::GetBoundingBox](/pt-BR/reference/lighting/lamparray/interfaces/ilamparray/methods/ilamparray_getboundingbox) ao criar efeitos que parecem percorrer o dispositivo, como ondulações ou ondas.

O exemplo a seguir criará uma onda de Lamps esmaecendo que se move da esquerda para a direita pelo dispositivo. Observe que incorporamos os conceitos de dimensionamento da seção "Esmaecimento e piscar", mas por Lamp.

```cpp theme={null}
Microsoft::WRL::ComPtr<ILampArray> lampArray;

uint32_t currentFrame = 0;

// The total number of frames in one wave
const uint32_t waveFrameCount = 30;

// The number of frames it takes for each Lamp to fade out
const uint32_t fadeDurationInFrames = 10;

// Helper class for per-Lamp effect state information
struct LampContext
{
    uint32_t lampIndex;

    // How far to the right this Lamp is located compared to the total length of the device.
    float xPercentage;

    // The number of frames left in this Lamp's fade-out
    uint32_t fadeFramesRemaining;
};

std::vector<LampContext> lampContexts;

// The Lamp indices for the device, in sorted order by position from left to right
std::vector<uint32_t> indices;

// The colors to set in each frame
std::vector<LampArrayColor> colors;

// The index in the sorted array representing the peak of the wave
uint32_t lastUpdatedIndex = 0;

// The base color to use in the wave effect
const LampArrayColor mainColor = {0xFF /* r */, 0x0 /* g */, 0x0 /* b */, 0xFF /* a */};

void WaveUpdateFrame(ILampArray* lampArrayToUpdate)
{
    float framePercentage = (float)currentFrame / (float)myFrameCount;

    const uint32_t lampCount = lampArrayToUpdate->GetLampCount();
    for (uint32_t i = 0; i < lampCount; i++)
    {
        auto& lampContext = lampContexts[i];

        // Mark any Lamps for which we should start a new fade-out.
        // Use lastUpdatedIndex to track which Lamps we've started in this wave.
        if (i >= lastUpdatedIndex && lampContext.xPercentage <= framePercentage)
        {
            lastUpdatedIndex = i;

            // This Lamp should start at full brightness on this frame.
            lampContext.fadeFramesRemaining = fadeDurationInFrames + 1;
        }

        // Process fade-outs for any Lamps that have fade-out frames remaining
        if (lampContext.fadeFramesRemaining > 0)
        {
            lampContext.fadeFramesRemaining--;

            // Optimization: use the full strength color for the first fade-out frame (without scaling)
            if (lampContext.fadeFramesRemaining == fadeDurationInFrames)
            {
                colors[i] = mainColor;
            }
            else
            {
                // Scale the main color down based on how many fade-out frames are remaining for this Lamp.
                float scaleFactor = (float)lampContext.fadeFramesRemaining / (float)fadeDurationInFrames;

                auto& lampColor = colors[i];
                lampColor.r = static_cast<BYTE>(scaleFactor * mainColor.r);
                lampColor.g = static_cast<BYTE>(scaleFactor * mainColor.g);
                lampColor.b = static_cast<BYTE>(scaleFactor * mainColor.b);
            }
        }
    }

    // Apply the color
    lampArrayToUpdate->SetColorsForIndices(lampCount, indices.data(), colors.data());

    // Increment our current frame, accounting for overflow
    if (++currentFrame > waveFrameCount)
    {
        currentFrame = 0;

        // The peak of the wave also needs to wrap around
        lastUpdatedIndex = 0;
    }
}

HRESULT MainLoop(
    _In_ volatile bool& terminateLoop)
{
    color.a = 0xFF;

    // Set up contexts
    const uint32_t lampCount = lampArray->GetLampCount();
    for (uint32_t i = 0; i < lampCount; i++)
    {
        LampContext context = {};
        context.lampIndex = i;

        Microsoft::WRL::ComPtr<ILampInfo> lampInfo;
        RETURN_IF_FAILED(lampArray->GetLampInfo(i, &lampInfo));

        LampArrayPosition lampPosition = {};
        lampInfo->GetPosition(&lampPosition);

        // Our position values will be relative to the total length of the device.
        context.xPercentage = (float)lampPosition.xInMeters / (float)boundingBox.xInMeters;

        lampContexts.push_back(context);
    }

    // Sort the contexts by position from left to right
    std::sort(lampContexts.begin(),
        lampContexts.end(),
        [](LampContext const& a, LampContext const& b)
        {
            return a.xPercentage < b.xPercentage;
        });

    // Set up our indices buffer in sorted order
    for (uint32_t i = 0; i < lampCount; i++)
    {
        indices[i] = lampContexts[i].lampIndex;
    }

    colors.resize(lampCount);

    // Animation loop for the sample
    while (!terminateLoop)
    {
        Sleep(33);
        WaveUpdateFrame(lampArray.Get());
    }

    return S_OK;
}
```

## Confira também

[Visão geral da API de iluminação](/pt-BR/build/core-features/common/lighting/gc-lighting-toc)
[Referência de ILampArray](/pt-BR/reference/lighting/lamparray/interfaces/ilamparray/ilamparray)


## Related topics

- [API de iluminação e LampArray no XBOX e no PC](/pt-BR/build/core-features/common/lighting/index.md)
- [Noções básicas do LampArray](/pt-BR/build/core-features/common/lighting/lighting-basics.md)
- [Definir cores em um LampArray](/pt-BR/build/core-features/common/lighting/lighting-colors.md)
- [Referência de membros da API LampArray](/pt-BR/reference/lighting/lamparray/lamparray_members.md)
- [Referência da API de iluminação para periféricos LampArray](/pt-BR/reference/lighting/gc-reference-lighting-toc.md)
