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:
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 } }