Snake snake,versus; char [][] pix; int gridUnit = 3; int gridSize = 40; int xc,yc; int xEgg,yEgg,xBigEgg,yBigEgg,bigEgg; int bestScore = 10; int lastScore = 10; int gameState = 0; PFont font; void setup(){ size(120,120); font = loadFont("Kartika-20.mvlw"); textFont(font); newSplash(); framerate(24); xc = (width>>1)-60; yc = (height>>1)-60; } void draw(){ background(255); noFill(); stroke(0); rect(xc,yc,gridSize*gridUnit,gridSize*gridUnit); noStroke(); fill(0); switch(gameState){ case 1: snake.move(); versus.move(); versus.AIegg(); versus.AIobject(); snake.draw(); versus.draw(); fill(255,0,0); drawEgg(); if(bigEgg > 0){ checkBigEgg(); fill(0,0,255); drawBigEgg(); } else if (random(200) == 0){ spawnBigEgg(); } if(!snake.alive){ hiScore(); gameState = 0; newSplash(); } if(!versus.alive){ //erase invisible snake body for(int i = 0; i < versus.len; i++) pix[versus.x[i]][versus.y[i]] = 0; //make new bad snake versus = new Snake(10, color(10,200,10), 0, 0); } break; case 0: gameOver(); fill(0); text("Snake Versus",xc+5,yc+30); text("Best Score:"+bestScore,xc+5,yc+80); text("Last Score:"+lastScore,xc+5,yc+100); break; } } void keyPressed(){ if(gameState == 1){ switch(key){ case '6': if(snake.d != 2){ snake.d = 0; } break; case '8': if(snake.d != 3){ snake.d = 1; } break; case '4': if(snake.d != 0){ snake.d = 2; } break; case '2': if(snake.d != 1){ snake.d = 3; } break; } switch(keyCode){ case 5: if(snake.d != 2){ snake.d = 0; } break; case 6: if(snake.d != 3){ snake.d = 1; } break; case 2: if(snake.d != 0){ snake.d = 2; } break; case 1: if(snake.d != 1){ snake.d = 3; } break; } } else{ newGame(); gameState = 1; } } void hiScore(){ lastScore = snake.len; if(lastScore > bestScore){ bestScore = lastScore; } } void printWalls(){ //used for error handling for(int i = 0; i < pix.length; i++) for(int j = 0; j < pix[i].length; j++){ switch(pix[i][j]){ case 1: fill(255,50,50); break; case 2: fill(50,50,255); break; default: fill(255); break; } rect(i*gridUnit,j*gridUnit,gridUnit,gridUnit); } } void gameOver(){ //draw a snake for current score and one for previous score; snake.move(); snake.AIegg(); snake.AIobject(); versus.move(); versus.AIegg(); versus.AIobject(); snake.draw(); versus.draw(); fill(0,255,0); drawEgg(); if(!snake.alive){ //erase invisible snake body for(int i = 0; i < snake.len; i++) pix[snake.x[i]][snake.y[i]] = 0; snake = new Snake(lastScore, color(0,0,255), 0, gridSize-1); } if(!versus.alive){ //erase invisible snake body for(int i = 0; i < versus.len; i++) pix[versus.x[i]][versus.y[i]] = 0; versus = new Snake(bestScore, color(255,0,0), 0, 0); } } void newGame(){ pix = new char[gridSize][gridSize]; snake = new Snake(10, color(0), (gridSize>>1)-10, gridSize>>1); versus = new Snake(10, color(10,200,10), 0, 0); spawnEgg(); bigEgg = 0; } void newSplash(){ pix = new char[gridSize][gridSize]; versus = new Snake(bestScore, color(255,0,0), 0, 0); snake = new Snake(lastScore, color(0,0,255), 0, gridSize-1); spawnEgg(); } void drawEgg(){ rect(xc+xEgg*gridUnit,yc+yEgg*gridUnit,gridUnit,gridUnit); } void drawBigEgg(){ rect(xc+xBigEgg*gridUnit,yc+yBigEgg*gridUnit,gridUnit,gridUnit); } void checkBigEgg(){ if(bigEgg > 0){ bigEgg--; } else if(bigEgg == 1){ pix[xBigEgg][yBigEgg] = 0; } } void spawnEgg(){ while(true){ xEgg = random(0,gridSize-1); yEgg = random(0,gridSize-1); if(pix[xEgg][yEgg] == 0){ break; } } pix[xEgg][yEgg] = 2; } void spawnBigEgg(){ while(true){ xBigEgg = random(0,gridSize-1); yBigEgg = random(0,gridSize-1); if(pix[xBigEgg][yBigEgg] == 0 ){ break; } } bigEgg = random(35,50); pix[xBigEgg][yBigEgg] = 3; } class Snake{ int [] x,y;//snake body array int d,len;//direction and length int col;//snake color boolean alive; Snake(int len, int col, int xStart, int yStart){ this.len = len; x = new int[len]; y = new int[len]; this.col = col; alive = true; d = 0; for(int i = 0; i < len; i++){ x[i] = xStart; y[i] = yStart; } move(); } void move(){ //shift values along one pix[x[0]][y[0]] = 0; for (int i = 1; i < len; i++){ x[i-1] = x[i]; y[i-1] = y[i]; } switch(d){ case 0: x[len-1]++; break; case 1: y[len-1]++; break; case 2: x[len-1]--; break; case 3: y[len-1]--; break; } //check for own body, walls and eggs if(x[len-1] < gridSize && x[len-1] > -1 && y[len-1] < gridSize && y[len-1] > -1){ switch(pix[x[len-1]][y[len-1]]){ case 1: alive = false; break; case 2: for(int i = 0; i < random(1,6); i++){ x = append(x, x[len-1]); y = append(y, y[len-1]); len++; pix[x[len-1]][y[len-1]] = 1; } spawnEgg(); break; case 3: for(int i = 0; i < random(7,15); i++){ x = append(x, x[len-1]); y = append(y, y[len-1]); len++; pix[x[len-1]][y[len-1]] = 1; } bigEgg = 0; default: pix[x[len-1]][y[len-1]] = 1; break; } } else{ alive = false; } } void draw(){ fill(col); for(int i = 0; i < len; i++){ rect(xc+x[i]*gridUnit,yc+y[i]*gridUnit,gridUnit,gridUnit); } } void AIegg(){ //veer towards egg if(xEgg > x[len-1] && d != 2) d = 0; else if(yEgg > y[len-1] && d != 3) d = 1; else if(xEgg < x[len-1] && d != 0) d = 2; else if(yEgg < y[len-1] && d != 1) d = 3; } void AIobject(){ int nowD = d; boolean free = false; int deadmeat = 0; while(!free){ //veer away from wall switch(d){ case 0: if(x[len-1] + 1 != gridSize) free = true; else{ d = 1; free = false; } break; case 1: if(y[len-1] + 1 != gridSize) free = true; else{ d = 2; free = false; } break; case 2: if(x[len-1] - 1 != -1) free = true; else{ d = 3; free = false; } break; case 3: if(y[len-1] - 1 != -1) free = true; else{ d = 0; free = false; } break; } //veer away from tail switch(d){ case 0: if(x[len-1] < gridSize - 1){ if(pix[x[len-1]+1][y[len-1]] != 1) free = true; else{ free = false; d = 1; } } break; case 1: if(y[len-1] < gridSize - 1){ if(pix[x[len-1]][y[len-1]+1] != 1) free = true; else{ free = false; d = 2; } } break; case 2: if(x[len-1] > -1){ if(pix[x[len-1]-1][y[len-1]] != 1) free = true; else{ free = false; d = 3; } } break; case 3: if(y[len-1] > -1){ if(pix[x[len-1]][y[len-1]-1] != 1) free = true; else{ free = false; d = 0; } } break; } if(++deadmeat > 7) break; } } }