Electronic Minora project, 2D array question/problen

I am trying to create an “Electronic Minora” in the 2D 32x8 matrix. I am not a SW developer but here is a working code which does everything I wanted (BIG Thanks to @zranger1 who helped me to create nice looking candle flickering):

var candlesNumber     = 3

var matriWwidth       = 32
var matrixHeight      = 8

var candlesMaxNumber  = 8
var candleWidth       = 3

// Pre-defined Candle Base Size
var candleBaseHeight  = array(candlesMaxNumber)
candleBaseHeight[0]   = 2
candleBaseHeight[1]   = 3
candleBaseHeight[2]   = 4
candleBaseHeight[3]   = 3
candleBaseHeight[4]   = 2
candleBaseHeight[5]   = 3
candleBaseHeight[6]   = 4
candleBaseHeight[7]   = 3

// Predefined Pixel Colors Array
var candleOffset = array(candlesMaxNumber + 1)[candlesMaxNumber] =
[
  // X - Candle Offset per Candle
  // Y - Candle Numbers
  [15,  0,  0,  0,  0,  0,  0,  0],
  [ 9, 20,  0,  0,  0,  0,  0,  0],
  [ 6, 15, 24,  0,  0,  0,  0,  0],
  [ 4, 11, 18, 25,  0,  0,  0,  0],
  [ 3,  9, 15, 21, 27,  0,  0,  0],
  [ 2,  7, 12, 17, 22, 27,  0,  0],
  [ 1,  5, 10, 14, 19, 23, 28,  0],
  [ 0,  4,  8, 12, 16, 20, 24, 28]
]

// Candle's Base Brightness and Color
var vBase = 0.15
var hBase = 0
var sBase = 0

// Candle's Fire Brightness and Color
var vFire = 1
var hFire = 0.05
var sFire = 1

// Calculated Parameters
var t1    = 0;

export function beforeRender(delta)
{
  // Build a timer using accumulated milliseconds
  // Denominator controls speed of noise field traversal (flicker speed)
  // The % 256 is used to keep values in a reasonable range for
  // input to noise function.
  t1 = (t1 + delta/2000) % 256;
}

export function render2D(index, x, y)
{
  X = floor(x * matriWwidth)
  Y = floor(y * matrixHeight)

  candleNumber = floor(X / (matriWwidth / candlesNumber))

  candleStartX = candleOffset[candlesNumber - 1][candleNumber]
  candleStopX  = (candleStartX + candleWidth)

  if  ((X >= candleStartX) && (X < candleStopX))
  {
    if (Y >= (matrixHeight - candleBaseHeight[candleNumber]))
    {
      v = vBase
      h = hBase
      s = sBase
    }
    else
    {
      // generate positive perlin noise value for current coordinates, offset by timer
      // this will be used both for pixel brightness and to determine the maximum
      // height of the current candle ()
      v = abs(perlin(Y+t1, X-t1, 0.5, PI))

      // if pixel is above max flame height, turn it off.  Otherwise
      // set it to perlin noise value.
      v = (y >= (vFire * v)-0.1) ? v : 0;
      h = hFire
      s = sFire
    }
  }
  else
  {
    v = 0
  }

  hsv(h, s, v)
}

Code works but I have a question about 2-dimentional arrays. I was not able to create nice looking candle’s spacing mathematically so I decide to use 2D array for spacing/offsets which depends on number of lighted candles. Array has 8x8 elements. I was able to create this array :

// Predefined Pixel Colors Array
var candleOffset = array(candlesMaxNumber + 1)[candlesMaxNumber] =
[
  // X - Candle Offset per Candle
  // Y - Candle Numbers
  [15,  0,  0,  0,  0,  0,  0,  0],
  [ 9, 20,  0,  0,  0,  0,  0,  0],
  [ 6, 15, 24,  0,  0,  0,  0,  0],
  [ 4, 11, 18, 25,  0,  0,  0,  0],
  [ 3,  9, 15, 21, 27,  0,  0,  0],
  [ 2,  7, 12, 17, 22, 27,  0,  0],
  [ 1,  5, 10, 14, 19, 23, 28,  0],
  [ 0,  4,  8, 12, 16, 20, 24, 28]
]

but I had to increase first index by 1. Otherwise I am getting “out of range” error.
I really cannot understand why I cannot create a symmetrical array. This error always pops up for any size square (A x A) arrays. Asymmetrical arrays do not produce this error.
What I am missing?

I think the way you’re defining your 2D array looks off to me. Usually it would be:

var TwoDArray = [[x1, y1], [x2, y2]]

// or

var TwoDArray = array(2)
TwoDArray[0] = array(2)
TwoDArray[1] = array(2)
TwoDArray[0][0] = x1 // etc

Instead, this statement:


var candleOffset = array(candlesMaxNumber + 1)[candlesMaxNumber] =
[
  // X - Candle Offset per Candle
  // Y - Candle Numbers
  [15,  0,  0,  0,  0,  0,  0,  0],
// etc

While I’m not even sure how the interpreter would execute it, it seems to allocate a 9 element blank array and store the 2D array literal (the values in the square brackets) in the last element of the 9-element 2D array (so actually making a 3D array). The other elements in the 1st dimension are probably zeros in Pixelblaze, so they can’t be accessed like candleOffset[0][N] - there’s no second dimension in that first element.

Thank you very much for the response but now I am very confused. I am using 2D array definition what I posted in a few different patterns. Originally I copied this definition from the existing pattern I found in a Pattern Library (I forgot what it was). Surprisingly everything works as expected except for the first index cannot be the same as second.

I just tested yours suggested example (first line) and sure, everything is working as expected.

Many BIG Thank you for making things very clear.