Proyecto final: Panel lúdico luminoso
Título | Panel lúdico luminoso |
---|---|
Tipo de Proyecto | Proyecto de Taller |
Palabras Clave | objetoeducativo |
Período | 2022-2022 |
Asignatura | Interacción y Performatividad |
Del Curso | Interacción y Performatividad 2022 |
Carreras | Diseño |
Alumno(s) | Javier Leiva, María Fernanda Calderón, Soledad Araya Urrutia, Soledad araya |
Profesor | Renzo Varela |
Proyecto Panel lúdico luminoso
El proyecto que aquí se presenta corresponde al encargo final del curso de interacción y performatividad del año 2022.
En grupos de 3 a 4 personas se debía construir un objeto interactivo que enseñe parte de lo visto en clases. Nuestro equipo estuvo compuesto por Javier Leiva, Soledad Araya y María Fernanda Calderón.
Propuesta de Proyecto
Nuestra propuesta consistió en replicar el juego de la snake a través del software arduino y un hardware compuesto por una protoboard, un arduino uno, un joystick y una matriz neopixel de 8x8, todo esto se vinculaba a través de cables macho-hembra y se conectada al computador a través de un cable usb.
La interacción: Ideamos el proyecto considerando dos tipos de uso. El primero mostraba una interfaz de juego dónde quedaba visible sólo la matriz y el joystick para interactuar con el objeto, al girarlo se mostraba la segunda vista, esta incluía los elementos constructivos del proyecto, es decir, el arduino, la protoboard y las conexiones. Además incluía un pequeño manual en el que se explicaba las piezas y el código utilizado para el juego.
Video
Código
#include <Adafruit_NeoPixel.h> #define PIN 2 //Output Pin #define MAX_LED 64 //Quantity of bead uint32_t c; int a = 0 , number; unsigned char huan = 0, ci = 0; unsigned char u = 40; //The font size of word group unsigned char x = 0; unsigned char Colour[3]; unsigned char go[] = {2, 3, 4, 5, 9, 14, 17, 20, 22, 26, 27, 29, 34, 35, 36, 37, 41, 46, 49, 54, 58, 59, 60, 61}; //24 unsigned char light[8][8] = { // this is the enumeration lights {0, 1, 2, 3, 4, 5, 6, 7}, {8, 9, 10, 11, 12, 13, 14, 15}, {16, 17, 18, 19, 20, 21, 22, 23}, {24, 25, 26, 27, 28, 29, 30, 31}, {32, 33, 34, 35, 36, 37, 38, 39}, {40, 41, 42, 43, 44, 45, 46, 47}, {48, 49, 50, 51, 52, 53, 54, 55}, {56, 57, 58, 59, 60, 61, 62, 63}, } ; unsigned char character[][8] = //Set the word to be sent { {0, 0, 1, 1, 1, 1, 1, 0}, {0, 0, 1, 0, 0, 0, 1, 0}, // 0 {0, 0, 1, 1, 1, 1, 1, 0}, {0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0}, // 1 {0, 0, 1, 1, 1, 1, 1, 0}, {0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 1, 1, 1, 0, 1, 0}, {0, 0, 1, 0, 1, 0, 1, 0}, // 2 {0, 0, 1, 0, 1, 1, 1, 0}, {0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 1, 0, 1, 0, 1, 0}, {0, 0, 1, 0, 1, 0, 1, 0}, // 3 {0, 0, 1, 1, 1, 1, 1, 0}, {0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 1, 1, 1, 0}, {0, 0, 0, 0, 1, 0, 0, 0}, // 4 {0, 0, 1, 1, 1, 1, 1, 0}, {0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 1, 0, 1, 1, 1, 0}, {0, 0, 1, 0, 1, 0, 1, 0}, // 5 {0, 0, 1, 1, 1, 0, 1, 0}, {0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 1, 1, 1, 1, 1, 0}, {0, 0, 1, 0, 1, 0, 1, 0}, // 6 {0, 0, 1, 1, 1, 0, 1, 0}, {0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 1, 0}, {0, 0, 0, 0, 0, 0, 1, 0}, // 7 {0, 0, 1, 1, 1, 1, 1, 0}, {0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 1, 1, 1, 1, 1, 0}, {0, 0, 1, 0, 1, 0, 1, 0}, // 8 {0, 0, 1, 1, 1, 1, 1, 0}, {0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 1, 0, 1, 1, 1, 0}, {0, 0, 1, 0, 1, 0, 1, 0}, // 9 {0, 0, 1, 1, 1, 1, 1, 0}, {0, 0, 0, 0, 0, 0, 0, 0}, }; unsigned char displayscore [8][8];
int speedS = 400; // Initial speed of snake int score; // Game score int xValue; // JoyStick-X int yValue; // JoyStick-Y int zValue; // JoyStick-Z int FX, FY; // Coordinate of food int SX, SY; // Coordinate of snake head int KEY, K; int Enabled; // Enable to restart game char sx[64] ; //Coordinate of snake body char sy[64]; Adafruit_NeoPixel strip = Adafruit_NeoPixel( MAX_LED, PIN, NEO_RGB + NEO_KHZ800 ); void RANDOM() { A: FX = random(0, 7); FY = random(0, 7);
for (int i = 0; i < 3 + score; i++) //Prevent food display on snake body { if ( FX == sx[i] && FY == sy[i]) goto A; } } void myDelay( unsigned int Time) { // During the delay period of snake movement, we have to do something like food glitter and read the direction of Joystick
for (int t = 1; t <= Time; t++) { joyStick(); delay(1); //Read the direction of Joystick } } void joyStick() {
xValue = analogRead(A0); // JoyStick-X The leftmost value is 0, the rightmost value is 1023, and the middle value is 515. yValue = analogRead(A1); // JoyStick-Y The bottom value is 0, the top value is 1023, the middle value is 510.
if (yValue > 950 && KEY != 5) { K = 8; } else if (yValue < 50 && KEY != 8) { K = 5; } else if (xValue < 50 && KEY != 6 && K != 0) { // Before operate Joystic for the first time, you can't move snake to the left direction. K = 4; } else if (xValue > 950 && KEY != 4) { K = 6; } } // Here you can compare whether the direction of keypad is opposite to the snake move direction. If it is opposite, then give up the keypad. /*****************************************************************/ void gameover() { // Once Gameover program stopped, press the central button to restart the game. unsigned char value, y;
Colour[0] = random(3 , 18); // Set color.Parameter is R G B, range 0-255. Colour[1] = random(3, 18); Colour[2] = random(3, 18); c = strip.Color(Colour[1], Colour[0], Colour[2]); value = score / 10; value = value * 4; y = 0;
for (number = value; number < value + 4; number++) { for (unsigned char vertical = 0; vertical < 8; vertical++) { displayscore[y][vertical] = character[number][vertical]; } y++; } value = score % 10; value = value * 4;
for (number = value; number < value + 4; number++) { for (unsigned char vertical = 0; vertical < 8; vertical++) { displayscore[y][vertical] = character[number][vertical];
} y++; }
for (unsigned char horizontal = 0; horizontal < 8; horizontal++) { for (unsigned char vertical = 0; vertical < 8; vertical++) {
if (displayscore[horizontal][vertical] == 1) //Judge whether the light is on. { strip.setPixelColor(light[horizontal][vertical], c); } else strip.setPixelColor(light[horizontal][vertical], 0);
} }
strip.show();//Send data delay(5000); K = 0; // Reset Joystick direction sx[0] = 2; sx[1] = 1; sx[2] = 0; sy[0] = 1; sy[1] = 1; sy[2] = 1; // Reset snake coordinate score = 0; // Reset game score speedS = 400; // The initial speed of snake
} void setup() { Serial.begin(9600); // Initialize library strip.begin(); // Send data. Default the color of each point as 0. So every point is not illuminated at the beginning. strip.show(); K = 0; // Reset the direction of Joystick sx[0] = 1; sx[1] = 1; sx[2] = 1; sy[0] = 1; sy[1] = 1; sy[2] = 1; // Reset snake coordinate score = 0; // Reset game score Colour[0] = random(3 , 18); // Set color.Parameter is R G B, range 0-255. Colour[1] = random(3, 18); Colour[2] = random(3, 18); c = strip.Color(Colour[1], Colour[0], Colour[2]); //Green Red Blue // Set color for (number = 0; number < 24; number++) { strip.setPixelColor(go[number], c); } strip.show();// Send data delay(2000); RANDOM(); //Produce food } void mobile() { KEY = K; //Every movement of snake makes the direction change for once.
if (KEY == 8) // Snake upward movement { Serial.println("Arriba"); for (int i = 2 + score; i > 0; i--) { sx[i] = sx[i - 1]; sy[i] = sy[i - 1]; } sy[0] = sy[0] - 1; if (sy[0] < 0) // Go beyond the border and continue on the other side sy[0] = 7; } else if (KEY == 5) // Snake downward movement { for (int i = 2 + score; i > 0; i--) { sx[i] = sx[i - 1]; sy[i] = sy[i - 1]; } sy[0] = sy[0] + 1; if (sy[0] > 7) // Go beyond the border and continue on the other side sy[0] = 0; } else if (KEY == 4) // Snake left movement { for (int i = 2 + score; i > 0; i--) { sx[i] = sx[i - 1]; sy[i] = sy[i - 1]; } sx[0] = sx[0] - 1; if (sx[0] < 0) // Go beyond the border and continue on the other side sx[0] = 7; } else if (KEY == 6) // Snake right movement { for (int i = 2 + score; i > 0; i--) { sx[i] = sx[i - 1]; sy[i] = sy[i - 1]; } sx[0] = sx[0] + 1; if (sx[0] > 7) // Go beyond the border and continue on the other side sx[0] = 0; } // Move snake body with button } void displays() { for (number = 0; number < 64; number++) //Clear the screen { strip.setPixelColor(number, 0); } strip.show();
Colour[0] = 40; // Set color. Parameter is R G B, range 0-255. Colour[1] = 0; Colour[2] = 0; c = strip.Color(Colour[1], Colour[0], Colour[2]); //Green Red Blue // Set color x = light[FX][FY]; //Display food strip.setPixelColor(x, c);
Colour[0] = random(3 , 18); // Set color. Parameter is R G B, range 0-255. Colour[1] = random(3, 18); Colour[2] = random(3, 18); c = strip.Color(Colour[1], Colour[0], Colour[2]); //Green Red Blue // Set color
for (int i = 2 + score; i > 0; i--) //Display snake body {
x = light[sx[i]][sy[i]]; strip.setPixelColor(x, c); }
Colour[0] = 0; // Set color. Parameter is R G B, range 0-255. Colour[1] = 40; Colour[2] = 0; c = strip.Color(Colour[1], Colour[0], Colour[2]); //Green Red Blue // Set color x = light[sx[0]][sy[0]]; //Display snake head strip.setPixelColor(x, c);
strip.show();//Send data } void loop() {
mobile(); myDelay(speedS); // Within() is delay time. displays(); SX = sx[0]; SY = sy[0]; // Get coordinate of snake head
for (int i = 1; i <= 2 + score; i++) { if ( SX == sx[i] && SY == sy[i]) gameover(); } // Judge whether snake head touched its body. If touched, then forward to GameOver.
if (SY == FY && SX == FX) { RANDOM(); score ++; Colour[0] = 40; // Set color. Parameter is R G B, range 0-255. Colour[1] = 0; Colour[2] = 0; c = strip.Color(Colour[1], Colour[0], Colour[2]); //Green Red Blue // Set color x = light[FX][FY]; //Display food strip.setPixelColor(x, c); strip.show();//Send data if ( !(score % 5)) { // Accerlerate snake speed according to the score. Every 5 foods eaten, accerlerate 100ms. speedS = speedS - 50; if (speedS < 150) // The bottom limit is 200ms. If speed lower than 200ms, the speed stays 200ms. speedS = 150; } } // Judge whether food are eaten. If snake ate food, then plus scores and regenerate food randomly. }