SnakeOut v0.9

I want to share my first stable version of Snake for Arduino with the internet. As I said in an earlier post, this version of Snake does not need an Extra shield for your Arduino, it only needs a video plug, and 2 resistors (like the schematic below).

For testing purposes, controls are via a processing sketch, so every enthusiast is able to control the snake, without hacking a game pad first… I will present the code for both the game and the processing sketch below, in a format that is (hopefully) readable and understandable.

Schematic

The schematic is made by the same people who made it possible to do TVout on the arduino:

Plug Schematic

Video Plug schematic. SYNC, VIDEO and GND are respectively 9,7 and GND on the arduino UNO

Instructions

Install the TVOut Library

Create a new Arduino sketch with the code below

Create a new Processing sketch with the code below (do not forget to change the comport)

And one last thing; In the PollSerial.cpp library file (libraries/pollserial), change line 30 from

#define BUFFER_SIZE 64

into

#define BUFFER_SIZE 8

Arduino couldn’t handle this big buffer altogether with the video stuff, and with this smaller buffer it is responding really good 🙂

Arduino sketch

/\*   Snake for Arduino Snake Game with output via a video plug using the TVOut library. A Processing sketch is used to send key commands to let the snake move, but this can easily be replaced by physical buttons in next versions The circuit: \* Video Plug Connected to Pin 7,9 and GND created 2011 by Pepijn Fens V0.9: First stable version \*/ #include  #include  #include  #define memory 25 TVout TV; pollserial pserial; byte vres = 120; byte hres = 104; byte x = vres/2; byte y = hres/2; byte xfield,yfield,wfield,hfield; byte dx,dy,dir; byte tailx,taily,taildx,taildy; byte taildir; byte bend\_x[memory]; byte bend\_y[memory]; byte bend\_dir[memory]; byte i,j; //bend index from the head and tail int score; int foodx,foody; void setup(){   TV.begin(PAL,hres,vres);   TV.select\_font(font4x6);   TV.set\_hbi\_hook(pserial.begin(57600));   TV.print(5,2,"score ");   initialize(); } void loop() {   char buf = 0;   if (pserial.available()) {     buf = (char) pserial.read();     pserial.flush();   }   switch(buf){     case 'U': if (dir != 'D') {dx=0; dy=-1; dir='U'; addBend(dir);} break;     case 'D': if (dir != 'U') {dx=0; dy=1; dir='D';  addBend(dir);  } break;     case 'R': if (dir != 'L') {dx=1; dy=0; dir='R';  addBend(dir); } break;     case 'L': if (dir != 'R') {dx=-1; dy=0; dir='L';  addBend(dir); } break;   }   if (dir!=0){   if (tailx == bend\_x[j] && taily == bend\_y[j]) {     taildir = bend\_dir[j];     j++;    if (j >= memory) { j=0; } //go searching for the next bend in the snake, and so on   }   switch(taildir) {     case 'U': taildx=0; taildy=-1; break;     case 'D': taildx=0; taildy=1; break;     case 'R': taildx=1; taildy=0; break;     case 'L': taildx=-1; taildy=0; break;     case 'O': taildx=0; taildy=0; break;   }   moveTail();   moveHead();   } } void moveHead(){   x += dx;   y += dy;   boolean border = false;   if (x > xfield+wfield-1 ) { x = xfield+1; border=true;}   if (x < xfield+1 ) { x =xfield+wfield-1; border=true;}   if (y > yfield+hfield-2) {y = yfield+1; border=true;}   if (y < yfield+1 ) {y =yfield+hfield-1; border=true;}   if (x == foodx && y == foody) {grow(); border=true;}   if (TV.get\_pixel(x,y) == 1 && border==false ){    gameover();   }   TV.set\_pixel(x,y,1);   delay(1000/30); //FPS } void moveTail(){   tailx += taildx;   taily += taildy;   if (tailx > xfield+wfield-1 ) { tailx = xfield+1;}   if (tailx < xfield+1 ) { tailx =xfield+wfield-1;}   if (taily > yfield+hfield-2) {taily = yfield+1;}   if (taily < yfield+1 ) {taily =yfield+hfield-1;}   TV.set\_pixel(tailx,taily,0); } void addBend(char direction) { bend\_dir[i]=direction; bend\_x[i] = x; bend\_y[i] = y; i++; if (i >= memory) { i = 0; } } void grow() {   score += 10;   drawscore();   newfood();   moveHead();   moveHead(); } void newfood() {   foodx = random(xfield+5,xfield+wfield-5);   foody = random(yfield+5,yfield+hfield-5);   TV.set\_pixel(foodx,foody,1); } void drawscore() {   TV.print(30,2,score,10); } void gameover() {   dx=0;   dy=0;   taildir='O';   TV.print(50,50,"GAME OVER");   delay(5000); //if Game Over, wait 5 seconds....   initialize(); } void initialize() {   drawscore();   xfield=5; //where the field is on the screen   yfield=10;   wfield=hres-(xfield\*2); //defining dimensions   hfield=vres-15;   TV.draw\_rect(xfield,yfield,wfield,hfield,1,0);   TV.set\_pixel(x,y,1); //Set middle pixel to white=start   TV.set\_pixel(x-1,y,1);   TV.set\_pixel(x-2,y,1);   taildir = 'R'; //start with tail to the right   tailx = x-3;   taily = y;   newfood(); //setup first food   dir = 0;   dx = 0;   dy = 0;   i = 0;   j= 0;   score=0;   for (int k=0; k

Processing Sketch

import processing.serial.*; Serial myPort;  // Create object from Serial class int val;        // Data received from the serial port char tempKey; void setup() {   tempKey=0;   size(200, 200);   myPort = new Serial(this, "COM19", 57600); //Change COM19 to whatever comport you are using } void draw() {   background(255); } void keyPressed() {   println(key);   switch(key){   case 'w': myPort.write('U'); break;//up    case 'a': myPort.write('L'); break; //left    case 's': myPort.write('D'); break; //down    case 'd': myPort.write('R'); break; //right    } }