For the last couple of days I've been trying to test out a game for the classic nokia snake game I've found online, but I can't seem to get it to work.
This is the code: (Yes I know it's in russian but google autotranslates it to english pretty well)
Now, for a bit of context: I'm using a CJMCU 8X8 Neopixel LED Matrix and a standard joystick. As you've probably noticed, the code in question is for a 16x16 matrix. The reason I have chosen this code in specific is because it's the only one I could find that isn't just broken for me, and also has an explanation on how the code works, (I kinda wanna understand the code I'm using so I can later tweak it :D)
So, no biggie right? If their matrix and my matrix work the same way, I should be able to just change every 256 to 64, every 16 to 8, every 15 to 7, and every 255 to 63 (excluding the 255s reffering to the rgb values ofc) and it should work.
The thing is, my matrix is also different in that the rows all go from left to right. So, in the first row we have LEDs 0 to 7, in the second row, 8 to 15, in the third 16 to 23, and so on. This code, however, is designed for rows that alternate each row. So, they start form left to right (0-7), but then they change to right to left (15-8), and then they go back to left to right (16-23), and then again, and again.
So, what I would need help with is figuring out what I'd have to change for the code to work with my matrix. Of course, the column and row calculations will have to change, but I'm not smart enough to figure out HOW exactly I also don't know if I would have to change anything else, so if you could help me, that'd be great!
Thanks! But I still don-t really understand how I would implement this into my code , Should I just replace the column and row calculation with the kMatrixSerpentineLayout == false lines? (92 to 98)
The code you're using is not particularly nice... and I can see why you are having trouble.
Firstly... the variable naming is terrible. In most cases where something is named "direction" it actually means "position". i.e. position within the grid. Very confusing.
There are some actual bugs. For example
Should be < 64, since 63 is the largest index possible.
The code is not well indented.. also makes it hard to read.
The code has virtually no comments... making it very hard to understand what it's doing
I have created a version with the above rectified... I have not addressed your specific issue, but now the code is more readable it should be relatively easy for you to see what needs to be changed. Hopefully you can also see the importance of writing more readable code.
I believe you will need to change routines:
snakeMove and snakePosition
New version
#include <FastLED.h>
//matrix settings
#define NUM_LEDS 64
#define DATA_PIN 4
#define BRIGHTNESS 8
//joystick settings
#define pinX A2 // ΠΎΡΡ X Π΄ΠΆΠΎΠΉΡΡΠΈΠΊΠ°
#define pinY A1 // ΠΎΡΡ Y Π΄ΠΆΠΎΠΉΡΡΠΈΠΊΠ°
#define swPin 2 // ΠΊΠ½ΠΎΠΏΠΊΠ° Π΄ΠΆΠΎΠΉΡΡΠΈΠΊΠ°
int snake[64]; // array of snake elements
int snakeSize = 2; // real snake size
int snakeSpeed = 500;
int row; // row number
int col; // column number
int lastPosition = 20; // start position
int i, newPosition, OlddX = 1, OlddY, f;
int red, green, blue, fred, fgreen, fblue; //colors
CRGB leds[NUM_LEDS];
void setup()
{
Serial.begin(9600);
red = random(0, 255);
green = random(0, 255);
blue = random(0, 255);
fred = random(127, 255);
fgreen = random(127, 255);
fblue = random(127, 255);
Serial.begin(9600);
pinMode(pinX, INPUT);
pinMode(pinY, INPUT);
pinMode(swPin, INPUT);
digitalWrite(swPin, HIGH);
FastLED.addLeds<NEOPIXEL, DATA_PIN>(leds, NUM_LEDS);
FastLED.setBrightness(BRIGHTNESS);
for( i=0; i<64; i++ )
{
snake[i] = 0;
}
for( i=0; i<=snakeSize; i++ )
{
snake[i] = lastPosition+i;
}
f = random(0, 63);
FastLED.show();
}
int SnakePosition(int last, int dX, int dY )
{
// Convert analog values from joystick to -1, 0, 1)
dX = map(dX, 0, 1000, -1, 1);
dY = map(dY, 0, 1000, -1, 1);
//No input, direction unchanged.
if(dX == 0 && dY == 0 && OlddX != dX)
{
dX = OlddX;
}
if(dY == 0 && dX == 0 && OlddY != dY)
{
dY = OlddY;
}
// THE LOGIC BELOW NEEDS TO BE CHANGED
int newPosition = last;
// Left/right input (1/-1)
if( dX != 0 )
{
if ( row&1 ) // Odd row
{
if( col == 0 && dX == 1) // In 1st col & moving left
{ newPosition = last -7; }
else if( col == 7 && dX == -1) // In last col & moving right
{ newPosition = last +7; }
else
newPosition = last + dX; // Any other scenario
}
else // Even row
{
if( col == 0 && dX == 1) // In 1st col & moving left
{ newPosition = last +7; }
else if( col == 7 && dX == -1 ) // In last col & moving right
{ newPosition = last -7; }
else
newPosition = last - dX; // Any other scenario
}
}
// Up/down input (1/-1)
if( dY < 0) // Moving down
{
if(row == 7 && dY == -1) // Last row (&& dY == -1 not required - always true)
{newPosition = col;}
else if ( row&1 ) // Odd row
{
newPosition = last + (col*2)+1;
}
else // Even row
{
newPosition = last + (8-col-1)+(8-col); // Any other scenario
}
}
if( dY > 0) // Moving up
{
if( row == 0 && dY == 1) // Row 0 (&& dY == 1 not required, always true)
{ newPosition = 64 - col;}
else if ( row&1 )
{
newPosition = last - (last - 8*row) - (8 - col); // Odd row
}
else
{
newPosition = last - (col*2)-1; // Even
}
}
OlddX = dX;
OlddY = dY;
return newPosition;
}
int snakeMove(int snakePosition){
// Check if we ran over ourself.
for( i=0; i<64; i++ ){
if( snake[i] == snakePosition )
{
death();
}
}
// Clear the display
FastLED.clear();
// Shuffle the positions to make room for the new snake head. This also removes the tail.
for (i=snakeSize; i>=1; i--)
{
snake[i] = snake[i-1];
}
// Create the new head.
snake[0] = snakePosition;
// Display the snake on the display
for( i=0; i<64; i++ )
{
if( snake[i] ) // If snake[i] is non zero.
{
leds[snake[i]].setRGB(red, green, blue);
}
}
FastLED.show();
// Calculate the new row & col global values. THIS LOGIC NEEDS TO BE CHANGED
row = (int)(snakePosition/8); // row number
if ( row&1 ) // Odd row
{
col = (row+1) * 8 - snakePosition - 1;
}
else // Even row
{
col = snakePosition - row * 8;
}
// This just returns what was passed in?
return snakePosition;
}
void food( int eaten )
{
if( eaten == f )
{
snakeSize++;
f = random(0, 63);
red = fred;
green = fgreen;
blue = fblue;
fred = random(0, 255);
fgreen = random(0, 255);
fblue = random(0, 255);
snakeSpeed = snakeSpeed / 1.1;
}
else
{
leds[f].setRGB(fred, fgreen, fblue);
FastLED.show();
}
}
void death()
{
snakeSize = 2;
snakeSpeed = 500;
red = 255;
green = 0;
blue = 0;
}
void color(boolean sw){
if(!sw){
red = random(0,255);
green = random(0,255);
blue = random(0,255);
}
}
void loop() {
Serial.print("lastPosition:");
Serial.print(lastPosition);
Serial.print(" newPosition:");
Serial.println(newPosition);
color( digitalRead(swPin) );
newPosition = SnakePosition(lastPosition, analogRead(pinX), analogRead(pinY));
lastPosition = snakeMove(newPosition);
food(newPosition);
delay(snakeSpeed);
}