Made a cave-navigation game using a Spectra Symbol softpot. The resistance of the softpot changes depending on where you press it, so you can do an Arduino analogRead() on the voltage output to determine where the circle goes on the screen. You have to make sure to add a resistor (I think I used a 100k resistor) going from the middle pin to ground (or power), or else the output floats.

Code available in the full post.

Here’s the Arduino code. The middle pin of the softpot should go to analog input pin 2:

1
2
3
4
5
6
7
8
9
10
int analogPin = 2;
 
void setup() {
  Serial.begin(9600);
}
 
void loop() {
  Serial.println(analogRead(analogPin));
  delay(100);
}

And here’s the Processing code. First, create a file named “score.dat” in the folder, and put a number on the first line. Sorry for the lack of commenting.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
import processing.serial.*;
 
///////////////
// Constants //
///////////////
 
// High score data file
PrintWriter file;
String FILE_NAME = "score.dat";
 
// Serial input setup
String PORT_NAME = "COM3";   // Change this
int BAUD_RATE = 9600;
int SERIAL_IN_MAX = 1023;
 
// Font setup
PFont font;
String FONT_NAME = "Arial";
int FONT_SIZE = 20;
 
// Graphics setup constants
int FPS = 60;
int SCREEN_SIZE[] = {550,400};
int BG_COLOR = #000000;
int LINE_COLOR = #00FF00;
int TEXT_COLOR = #FFFFFF;
int CENTER_X = SCREEN_SIZE[0]/2;
int CENTER_Y = SCREEN_SIZE[1]/2;
 
// Player information constants
int PLAYER_SIZE = 6;
int HALF_PLAYER_SIZE = PLAYER_SIZE/2;
 
// Difficulty constants
int VERTICAL_RATE_RANGE[] = {2, 7};
int VERTICAL_RATE_CHANGE = 500;
int GAP_SIZE_RANGE[] = {25, 50};
int GAP_SIZE_CHANGE = 500;
 
int OBSTACLE_UPPER_BOUND = 100;
int OBSTACLE_LOWER_BOUND = SCREEN_SIZE[1]-100;
 
// Circular buffer constants
int SCROLL_SPEED = 2;
int BUFFER_SIZE = SCREEN_SIZE[0]/SCROLL_SPEED;
 
///////////////
// Variables //
///////////////
 
Serial arduino;
 
String serialString = "";
char byteReceived = 0;
int serialValue = 512;
int serialValueBuffer = serialValue;
 
float playerY = CENTER_Y;
int playerX = SCREEN_SIZE[0]/10;
int score, highScore, verticalRate, gapSize = 0;
 
int[] buffer = new int[BUFFER_SIZE];
int bufferWritePos = 0;
int bufferWritePosPrev = BUFFER_SIZE-1;
int bufferReadPos = 0;
int bufferCheckIndex = 0;
 
//////////////////////////
// Function definitions //
//////////////////////////
 
void setup() {
  size(SCREEN_SIZE[0],SCREEN_SIZE[1]);
 
  font = createFont(FONT_NAME, FONT_SIZE);  // Initialize font
  textFont(font);
 
  arduino = new Serial(this, PORT_NAME, BAUD_RATE);
 
  rectMode(CENTER);
  frameRate(FPS);
 
  reset();
 
  highScore = int(loadStrings(FILE_NAME)[0]);
  file = createWriter(FILE_NAME);
}
 
void draw() {
  if (arduino.available() > 0) {
    getData();
  }
  clearScreen();
  updateBackground();
  drawPlayer();
  scoreUpdate();
  difficultyCheck();
  checkDeath();
}
 
void reset() {
  score = 0;
 
  for (int i = 0; i < BUFFER_SIZE; i++) {
    buffer[i] = CENTER_Y;
  }
}
 
void checkDeath() {
  bufferCheckIndex = (bufferWritePos+playerX/SCROLL_SPEED)%BUFFER_SIZE;
  if (playerY + HALF_PLAYER_SIZE > buffer[bufferCheckIndex]+gapSize ||
      playerY - HALF_PLAYER_SIZE < buffer[bufferCheckIndex]-gapSize) {
    textAlign(CENTER, BOTTOM);
    text("GAME OVER",CENTER_X,CENTER_Y);
    text("Move in between the lines to try again",CENTER_X,CENTER_Y+FONT_SIZE);
    reset();
  }
}
 
void scoreUpdate() {
  score ++;
  if (score > highScore) {
    highScore = score;
  }
 
  fill(LINE_COLOR);
  stroke(TEXT_COLOR);
  textAlign(RIGHT, TOP);
  text("High Score:", SCREEN_SIZE[0]-70, 0);
  text("Score:", SCREEN_SIZE[0]-70, FONT_SIZE);
 
  text(nfc(highScore), SCREEN_SIZE[0], 0);
  text(nfc(score), SCREEN_SIZE[0], FONT_SIZE);
}
 
void difficultyCheck() {
  score ++;
  gapSize = max(GAP_SIZE_RANGE[1]-score/GAP_SIZE_CHANGE, GAP_SIZE_RANGE[0]);
  verticalRate = min(VERTICAL_RATE_RANGE[0]+score/VERTICAL_RATE_CHANGE, VERTICAL_RATE_RANGE[1]);
}
 
void clearScreen() {
  background(BG_COLOR);
}
 
void drawPlayer() {
  playerY = map(serialValue, 0, 1023, 0, SCREEN_SIZE[1]);
  fill(LINE_COLOR);
  ellipse(playerX, playerY, PLAYER_SIZE, PLAYER_SIZE);
}
 
void getData() {
  byteReceived = char(arduino.read());
  if (byteReceived != '\n') {
    serialString += byteReceived;
  } else {
    serialString = serialString.substring(0,serialString.length()-1);
 
    if (int(serialString) != 0) {
      serialValueBuffer = int(serialString);
    }
    serialValue = (3*serialValue+serialValueBuffer)/4;
    serialString = "";
  }
}
 
void updateBackground() {
  buffer[bufferWritePos] = buffer[bufferWritePosPrev] + int(random(-verticalRate,verticalRate));
 
  if (buffer[bufferWritePos] > OBSTACLE_LOWER_BOUND) {
    buffer[bufferWritePos] = OBSTACLE_LOWER_BOUND;
  }
  if (buffer[bufferWritePos] < OBSTACLE_UPPER_BOUND) {
    buffer[bufferWritePos] = OBSTACLE_UPPER_BOUND;
  }
 
  bufferWritePosPrev = bufferWritePos;
  bufferWritePos ++;
  bufferWritePos %= BUFFER_SIZE;
 
  drawObstacles(-gapSize);
  drawObstacles(gapSize);
}
 
void drawObstacles(int offset) {
  bufferReadPos = bufferWritePos;
 
  stroke(LINE_COLOR);
  noFill();
 
  int x, y;
  beginShape();
  for (int i = 0; i < BUFFER_SIZE; i++) {
    x = i*SCROLL_SPEED;
    y = buffer[bufferReadPos]+offset;
    vertex(x,y);
 
    bufferReadPos ++;
    bufferReadPos %= BUFFER_SIZE;
  }
  endShape();
}
 
void stop() {
  file.println(highScore);
  file.flush();
  file.close();
  exit();
}
Tagged with:
 

Comments are closed.