Pages: [1]   Go Down
Author Topic: Arduino Snake Game 360 - Test Game  (Read 1240 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 1
Posts: 2
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hello!, I'm new at this forum and relatively new at electronics and microcontrollers.

This time I've not registered here to ask about nothing but to show my experience. Last week i bought an arduino mega and some other utilities like cables, leds and a "J12864" LED display.
It took me a few nights to notice that behind the screen there's a little over-sensitive screw to adjust contrast!. Anyway... heres my first finished first test project!



And here's the crappy code: (maybe it becomes helpful to someone)

Code:
#include "U8glib.h"

//Pin Config
U8GLIB_ST7920_128X64 u8g(52, 51, 53, U8G_PIN_NONE); // SPI Com: SCK = en = 52, MOSI = rw = 51, CS = di = 53

//LED - arduino
//-----------------
//blk = ground
//bla = +5v
//psb = ground
//e   = 52
//rw  = 51
//rs  = 53
//vcc = +5v
//gnd = ground

//MegaDrive Controller Pins
//     _________
//  5  \       / 1
//    9 \_____/ 6

//joystick - arduino
//--------------------
//pin 7    = 5
//pin 9    = 4
//pin 4    = 3
//pin 3    = 2
//pin 5    = +5v
//pin 8    = ground

uint8_t uiKeySelect = 5; //Output pin for select       
uint8_t uiKeyStart = 4; //Input pin for 'start' key   
uint8_t uiKeyLeft = 3; //Input pin for 'left' key     
uint8_t uiKeyRight = 2; //Input pin for 'right' key   



//Key defs
#define KEY_NONE 0
#define KEY_LEFT 1
#define KEY_RIGHT 2
#define KEY_START 3

//Ui Defs
#define UI_WELCOME 0
#define UI_READY 1
#define UI_PLAY 2
#define UI_GAMEOVER 3

//Control variables
uint8_t uiState = UI_WELCOME;
uint8_t uiKeyCode = KEY_NONE;

//InGame variables
uint8_t startBlinkInterval = 0;
uint8_t readyInterval = 0;

int wormRadius = 4;
int wormMaxDelay = 0;
int wormDelay = 0;
int wormPieces;
int wormStartPieces = 6;
float wormDirection = 0.0;
float wormX[255];
float wormY[255];

int pelletX = 0;
int pelletY = 0;
boolean pelletVisible = true;
int pelletBlink = 0;
int pelletBlinkDelay = 2;

String scoreStr = "";
char score[]="000000";

void draw(){
  int i;
 
  switch(uiState) {
    case UI_WELCOME:
      u8g.setFont(u8g_font_fub11);
      u8g.drawStr(24, 20, "360 Worm");
     
      startBlinkInterval++;
      if (startBlinkInterval <= 40) {
         u8g.setFont(u8g_font_04b_03r);
         u8g.drawStr(35, 40, "Press start!");
      } else if (startBlinkInterval >= 80) {
         startBlinkInterval = 0;
      }
      break;
     
    case UI_READY:
      drawPieces();
     
      readyInterval++;
     
      u8g.setFont(u8g_font_04b_03r);     
      if (readyInterval <= 40) {     
         u8g.drawStr(47, 40, "Ready");
      } else if (readyInterval <= 80 && readyInterval > 40) {
         u8g.drawStr(43, 40, "Set");       
      } else if (readyInterval <= 120 && readyInterval > 80) {
         u8g.drawStr(40, 40, "Go!");       
      } else if (readyInterval > 120) {
        readyInterval = 0;
        uiState = UI_PLAY;
      }
      break;
    case UI_PLAY:
      drawPieces();   
      break;
     
    case UI_GAMEOVER:
      u8g.setColorIndex(1);
      u8g.drawBox(0, 0, 128, 64);
     
      u8g.setColorIndex(0);
      u8g.setFont(u8g_font_04b_03r);     
      u8g.drawStr(40, 30, "Game over!");
      u8g.drawStr(40, 40, "Score -");
      u8g.drawStr(76, 40, score);
      u8g.setColorIndex(1);     
      break;
  }
 
}

void drawPieces(){
  int i, x, y; 
 
  for(i=0; i<wormPieces; i++) {
     x = round(wormX[i]);
     y = round(wormY[i]);
     u8g.drawCircle(x, y, 1);
     u8g.drawPixel(x, y);
  }
 
  if (pelletVisible) {
     u8g.drawCircle(pelletX, pelletY, 2);
     u8g.drawPixel(pelletX, pelletY);
  }
 
}

void controlSetup(void) {
  pinMode(uiKeyLeft, INPUT);
  digitalWrite(uiKeyLeft, HIGH);
  pinMode(uiKeyRight, INPUT);
  digitalWrite(uiKeyRight, HIGH);
  pinMode(uiKeyStart, INPUT);
  digitalWrite(uiKeyStart, HIGH); 
 
  pinMode(uiKeySelect, OUTPUT);
  digitalWrite(uiKeySelect, HIGH);   
}

void controlStep(void) {
    uiKeyCode = KEY_NONE;
   
    digitalWrite(uiKeySelect, HIGH);
    if (digitalRead(uiKeyLeft) == LOW) {
      uiKeyCode = KEY_LEFT;
    } else if (digitalRead(uiKeyRight) == LOW) {
      uiKeyCode = KEY_RIGHT;
    }
   
    digitalWrite(uiKeySelect, LOW);
    if (digitalRead(uiKeyStart) == LOW) {
      uiKeyCode = KEY_START;   
    }
}

//Set READY to uiState, prepare initial values.
void startNewGame() {
    int i, x, y;
   
    uiState = UI_READY;
    wormPieces = wormStartPieces;
    wormDirection = 0.0;
   
    x=30; y=20;
    for (i=wormPieces-1; i>=0; i--) {
      wormX[i] = x;
      wormY[i] = y;
      x-=wormRadius;
    }
   
    resetPelletPosition();
}



//Collision test from two centres and a radius
boolean circularCollision(int x1, int y1, int x2, int y2, int r){
 
  int hyp = sqrt(pow(abs(x2-x1), 2) + pow(abs(y2-y1), 2));
 
  if (hyp <= r) return true;
 
  return false;
}

//This will pick random posible pellet positions until its far away from the worm and the corners
void resetPelletPosition(){
  boolean validPosition=false;
  int randomX, randomY, i;
 
  do {
    randomX = random(4, 124);
    randomY = random(4, 60);
   
    validPosition=true;
   
    //Near worm
    for(i=0; i<wormPieces; i++) {
      if (circularCollision(wormX[i], wormY[i], randomX, randomY, 4)) {
        validPosition=false;
        break;
      }
    }
   
    //Near corners
    if (circularCollision(0, 0, randomX, randomY, 10) ||
        circularCollision(0, 64, randomX, randomY, 10) ||
        circularCollision(128, 0, randomX, randomY, 10) ||
        circularCollision(128, 64, randomX, randomY, 10)) {
      validPosition=false;
    }
   
  } while(!validPosition);
 
  pelletX = randomX;
  pelletY = randomY;
}



void gameStep(void) {
  int i;
 
  //Press start to play game...
  if (uiKeyCode == KEY_START && uiState == UI_WELCOME) {
    startNewGame();
  }
 
  //Game over restart
  if (uiKeyCode == KEY_START && uiState == UI_GAMEOVER) {
    uiState = UI_WELCOME;
  } 
 
  //Gameplay
  if (uiState == UI_PLAY) {
     wormDelay++;
     if (wormDelay >= wormMaxDelay) {
       
       //Pellet Blink Animation
       pelletBlink++;
       if (pelletBlink >= pelletBlinkDelay) {
         pelletBlink=0;
         if (pelletVisible) {
           pelletVisible = false;
         } else {
           pelletVisible = true;
         }
       }
       
       //Pellet Collision
       if (circularCollision(wormX[wormPieces-1], wormY[wormPieces-1], pelletX, pelletY, 4)) {
         wormPieces++;
         wormX[wormPieces-1] = wormX[wormPieces-2];
         wormY[wormPieces-1] = wormY[wormPieces-2];         
         resetPelletPosition();
       }
       
       //Sides Collision (Game Over)
       if (wormX[wormPieces-1] > 128 ||
           wormX[wormPieces-1] < 0   ||
           wormY[wormPieces-1] > 64  ||
           wormY[wormPieces-1] < 0) {
             
          scoreStr = String((wormPieces - wormStartPieces) * 10);
          scoreStr.toCharArray(score, 6);
          uiState = UI_GAMEOVER;
       }
       
       //Worm Collision (Game Over)
       for(i=0; i<wormPieces-wormStartPieces; i++) {
         if (circularCollision(wormX[wormPieces-1], wormY[wormPieces-1], wormX[i], wormY[i], 2)) {
           
           scoreStr = String((wormPieces - wormStartPieces) * 10);
           scoreStr.toCharArray(score, 6);           
           uiState = UI_GAMEOVER;
           break;
         }
       }       
       
       
       //Worm Movement:
       for(i=0; i<wormPieces-1; i++) {
         wormX[i] = wormX[i+1];
         wormY[i] = wormY[i+1];         
       }

       wormX[wormPieces-1] += cos(wormDirection) * wormRadius;
       wormY[wormPieces-1] += sin(wormDirection) * wormRadius;   
       
       //Worm direction:
       switch (uiKeyCode) {
         case KEY_LEFT:
           wormDirection -= (PI/7);
           break;
         case KEY_RIGHT:
           wormDirection += (PI/7);       
           break;
       }
       
       if (wormDirection > (2*PI)) {
         wormDirection = 0;
       } else if (wormDirection < 0) {
         wormDirection = (2*PI);
       }
       
       //Reset delay
       wormDelay = 0;
     }
     
   
  }



}


void setup() {
  controlSetup();
  //Serial.begin(9600); //Serial log
}

void loop() { 
  controlStep();
 
  u8g.firstPage();
  do  {
    draw();
  } while(u8g.nextPage());
 
  gameStep();
 
  delay(5);
}

Cheers!
Logged

Belgium
Offline Offline
Edison Member
*
Karma: 68
Posts: 1918
Arduino rocks; but with my plugin it can fly rocking the world ;-)
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Congratulations.
Very well done
Best regards
Jantje
Logged

Do not PM me a question unless you are prepared to pay for consultancy.
Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -

New River, Arizona
Offline Offline
God Member
*****
Karma: 19
Posts: 935
Arduino rocks
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Wait a minute, you're new to this??  That's a very complex piece of work for a beginner that just got the stuff last week.  You must have done this kind of thing before.

Anyway, nice job, enjoy the next project.
Logged

Trying to keep my house under control http://www.desert-home.com/

Offline Offline
Newbie
*
Karma: 1
Posts: 2
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thanks, i'll do!... In fact i bought my first arduino board last week, but i made some simple circuits in the past and i love programming! So it wasn't that difficult, even more with a graphic library controlling spi com and graphic functions for me.

Saludos!
Logged

Copenhagen, Denmark
Offline Offline
Edison Member
*
Karma: 32
Posts: 1211
Have you testrun your INO file today?
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Bummer. Playing the video it just says: "Unfortunatly this SME-music-content is not availbale in Germany, because GMEA has not granted the respective music publishing rights". I am sure the video is intresting.

OT comment: I can understand that the artist wants to earn his money, and that is fair enough. But this sell, resell and trading in copyright by 3rd parties with no "artistic interest" just is too much.
(So now I have to do some Ninja-trick with IP to see it anyhow. Well, I could)
Logged

Valencia, Spain
Offline Offline
Faraday Member
**
Karma: 146
Posts: 5497
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Wait a minute, you're new to this??  That's a very complex piece of work for a beginner that just got the stuff last week.  You must have done this kind of thing before.

Anyway, nice job, enjoy the next project.

Programming is everything...!
Logged

No, I don't answer questions sent in private messages (but I do accept thank-you notes...)

Offline Offline
Newbie
*
Karma: 0
Posts: 8
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

+1
well done!
Logged

Offline Offline
Edison Member
*
Karma: 26
Posts: 1339
You do some programming to solve a problem, and some to solve it in a particular language. (CC2)
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Never knew "crappy" code was so well written smiley-wink

Nice project!
Logged

Pages: [1]   Go Up
Jump to: