1

I'm making a game of snake on the adafruit Neopixel shield and have run in to a problem. How do you fill out an array (in this case a 5*8 array) with values once the class has been called. This is my code so far

H file

#include <Arduino.h>
#include <Adafruit_NeoMatrix.h>
#include <streaming.h>

class Snake : public Adafruit_NeoMatrix 
{
    public:
    Snake();
    void drawSnake();

    private:
    int snakeBoard[5][8];
};

CPP file

#include "Snake.h"

Snake::Snake() : Adafruit_NeoMatrix(8, 5, D6,
  NEO_MATRIX_TOP        + NEO_MATRIX_LEFT +
  NEO_MATRIX_ROWS       + NEO_MATRIX_PROGRESSIVE,
  NEO_GRB               + NEO_KHZ800)
{
  begin(); // start the matrix
  show();

  int snakeBoard[5][8] = {{1,1,0,0,0,0,0,0},
                        {0,0,1,0,0,0,0,0},
                        {0,0,1,0,1,1,-1,0},
                        {0,0,1,1,1,0,0,0},
                        {0,0,0,0,0,0,0,0}};
}

void Snake::drawSnake()
{
  for(int y = 0; y < 5; y ++)
  {
    for(int x = 0; x < 8; x ++)
    {
      Serial << "X: " << x << " Y: " << y << " Value" << snakeBoard[x][y] << endl;
      delay(100);
    }
  }
  drawPixel(5,5,Color(0,0,255));
  show();
}

When I run the program random garbage is printed in the serial monitor.

  • When initializing an array you need to use an = – chrisl Apr 2 '18 at 14:03
  • And in your constructor you declare a new array named snakeBoard which is deleted automatically once you leave the constructor. This array covers up the array declared in the class definition – chrisl Apr 2 '18 at 14:05
1

As already mentioned by @chrisl, you are creating a new local variable which overshadows your class member.

An easy way to get what you want is to memcpy your initial values into the array:

Snake::Snake() : Adafruit_NeoMatrix(8, 5, D6,
  NEO_MATRIX_TOP        + NEO_MATRIX_LEFT +
  NEO_MATRIX_ROWS       + NEO_MATRIX_PROGRESSIVE,
  NEO_GRB               + NEO_KHZ800)
{
  begin(); // start the matrix
  show();

  int initialSnakeBoard[5][8] {{1,1,0,0,0,0,0,0},
                        {0,0,1,0,0,0,0,0},
                        {0,0,1,0,1,1,-1,0},
                        {0,0,1,1,1,0,0,0},
                        {0,0,0,0,0,0,0,0}};
  memcpy(snakeBoard, initialSnakeBoard, sizeof(initialSnakeBoard));
}

You can achieve the same thing by utilizing C++11 constructor lists to initialize your members (see here):

Snake::Snake() : Adafruit_NeoMatrix(8, 5, D6,
  NEO_MATRIX_TOP        + NEO_MATRIX_LEFT +
  NEO_MATRIX_ROWS       + NEO_MATRIX_PROGRESSIVE,
  NEO_GRB               + NEO_KHZ800), 
  snakeBoard {{1,1,0,0,0,0,0,0},
                        {0,0,1,0,0,0,0,0},
                        {0,0,1,0,1,1,-1,0},
                        {0,0,1,1,1,0,0,0},
                        {0,0,0,0,0,0,0,0}}
{
  begin(); // start the matrix
  show();
}

You also have an error in your drawSnake routine: You confused the order of the indexes. With snakeBoard[5][8] you declare 2-dimensional integer array with 5 rows containing 8 elements each. Then, snakeBoard[0] will be a pointer to the first row (which has 8 elements). So the first index is y and must only range from 0 to 4 inclusive. The function must be:

void Snake::drawSnake() {
    for(int y = 0; y < 5; y ++)
    {
        for(int x = 0; x < 8; x ++)
        {
            Serial.println("X: " + String(x) + " Y: " + String(y) + " Value " + String(snakeBoard[y][x]));
            delay(100);
        }
    }
}

This then prints all the expected array elements to the the Serial port, as tested on my Arduino Nano.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.