Midterm

For my midterm I originally intended to use capacitive sensing in a menu like structure to start a game of snake. From there, I would ideally play the game but using capacitive sensing to control the movements of the snake. This turned out to be too much to ask. I couldn’t wrap my head around sending data that I could use from Arduino to Processing and I have later realized it was because I wasn’t using println so data would just keep on coming without a line to separate it and I (at the time) could not figure that out. At any rate, I did manage to make a snake game. I took a hard glance at code on the internet and realized that visualizing the code in terms of arrays was basically the key to thinking about it, both in terms of structure and code. Most games I saw online ended when the snake hit the side so I tried teleporting it.

As far as projects go, however, I felt like I underutilized my potential here. Working on the code for the snake was very easy as I found that I could use arrays very easily after handling lists last semester in python. A few commands were the same and their overall structure and just convenience allowed me to get done with the code fairly quick, albeit after looking at code online to kind of get a semblance on how to start and what things to keep in mind.

My takeaway would now be that failing at capacitive sensing at that point allowed me grow and learn from the mistakes I made and understand it better. I mean, I would have ideally like to have learned that before the project, but progress is progress. This project, however, was really my first time just consistently using processing every day and it allowed me to familiarize myself with it’s syntax and structure. I was just pleasantly surprised to see that I could relay some of my Python knowledge into this project.

This project was not completed by midterms, however, in a sense. I kept running into problems with the snake getting stuck at random points. It wasn’t until a week after that I realized I had to create a class (and at the time I had not worked with classes).

int gameWidth = 16;
int gameHeight = 16;
ArrayList<Segment> snake = new ArrayList<Segment>(); // arraylist of snake's x and y. We are basically announcing our intention to fill up arraylist snake with object segment.
float calibWidth;
float calibHeight; // Width and height of segments/food 
int headDir = RIGHT; // Direction of head
int xFood = int(gameWidth/2), yFood = int(gameHeight/2); // Coordinates of food
int headX, headY; // Coordinates of head (makes reading code easier)
int highScore; // Highscore (longest snake)

void setup() {
  size(512, 512); // Set window size
  noStroke(); // Don't outine squares
  fill(0); // Black snake/food
  frameRate(12); // Low fps
  calibHeight = height/gameHeight;
  calibWidth = width/gameWidth; // Define cell width/height
  print(snake);
  snake.add(new Segment(0, 0)); 
  print(snake);// Initialize snake
  textSize(16); // Set font size in pixels
}

void draw() {
  background(255); // White background
  rect(xFood*calibWidth, yFood*calibHeight, calibWidth, calibHeight); // Draw food
  headX = snake.get(0).x; // Set headX and headY
  headY = snake.get(0).y;
  for (int c = 1; c < snake.size(); c++) // Check all segments except head
    if (snake.get(c).x == headX && snake.get(c).y == headY) { // If the head has run into any other segment
      int tmpSize = snake.size(); // Set a temporary snake size
      for (int c2 = tmpSize-1; c2 > 0; c2--) // Remove all segments but the head
        snake.remove(c2);
    }
  if (keyPressed)
    if ((keyCode == UP && headDir != DOWN)|| (keyCode == LEFT && headDir != RIGHT) || (keyCode == DOWN&& headDir != UP) || (keyCode == RIGHT && headDir != LEFT)) // If WASD keyCode pressed and snake is not going backwards
      headDir = keyCode; // Set that to the direction
  switch(headDir) { // Add segment
  case UP: // If the head is going up
    snake.add(0, new Segment(headX, headY-1)); // Add a new segment above it
    if (snake.get(0).y == -1) // If the snake has gone out of the top
      snake.get(0).y = gameHeight-1; // Teleport it to the bottom
    break;
  case LEFT: // If the head is going left
    snake.add(0, new Segment(headX-1, headY)); // Add a new segment to its left
    if (snake.get(0).x == -1) // If the snake has gone out of the left side
      snake.get(0).x = gameWidth-1; // Teleport it to the right side
    break;
  case DOWN: // If the head is going down
    snake.add(0, new Segment(headX, headY+1)); // Add a new segment below it
    if (snake.get(0).y == gameHeight) // If the snake has gone out of the bottom
      snake.get(0).y = 0; // Teleport it to the top
    break;
  case RIGHT: // If the head is going right
    snake.add(0, new Segment(headX+1, headY)); // Add a new segment to its right
    if (snake.get(0).x == gameWidth) // If the snake has gone out of the right side
      snake.get(0).x = 0; // Teleport it to the left side
    break;
  }
  if (snake.get(0).x == xFood && snake.get(0).y == yFood) { // If snake reaches food
    snake.add(new Segment(xFood, yFood)); // Add another segment
    xFood = int(random(gameWidth)); // Move food to random place
    yFood = int(random(gameHeight));
  }
  snake.remove(snake.size()-1); // Remove tail of snake
  for (int c = 0; c < snake.size(); c=c+1)
    snake.get(c).update();// Draw snake
  if (snake.size() > highScore) // If there's a new highscore
    highScore = snake.size(); // Change the highscore to the new record
  text("Score: " + snake.size() + "nHighscore: " + highScore, 0, 16);
}

class Segment {
  int x, y; // Coordinates of segment
  Segment(int tmpX, int tmpY) { // Constructor function (initializes variables)
    x = tmpX;
    y = tmpY;
  }
  void update() {
    rect(x*calibWidth, y*calibHeight, calibWidth, calibHeight);
    
  print(x);
  print(y); // Draw the segment
  }
}

Leave a Reply