1
23#include <LiquidCrystal.h>
24#include "pitches.h"
25LiquidCrystal lcd(7, 8, 9, 10, 11, 12);
26
27const int JUMP_PIN = 2;
28const int BUZZER_PIN = 5;
29const int DUCK_PIN = 18;
30
31const int JUMP_PITCH = 2700;
32const int JUMP_PITCH_DURATION = 50;
33const int DUCK_PITCH = 1350;
34const int DUCK_PITCH_DURATION = 50;
35const int DIE_PITCH = 200;
36const int DIE_PITCH_DURATION = 500;
37const int TICKSPEED = 90;
38const int JUMP_LENGTH = 3;
39const byte stickStep1[8] = {
40 B01110,
41 B01110,
42 B00101,
43 B11111,
44 B10100,
45 B00110,
46 B11001,
47 B00001,
48};
49const byte stickStep2[8] = {
50 B01110,
51 B01110,
52 B00101,
53 B11111,
54 B10100,
55 B00110,
56 B01011,
57 B01000,
58};
59const byte stickJump[8] = {
60 B01110,
61 B01110,
62 B00100,
63 B11111,
64 B00100,
65 B11111,
66 B10001,
67 B00000,
68};
69const byte stickDuck[8] = {
70 B00000,
71 B00000,
72 B00000,
73 B01110,
74 B01110,
75 B11111,
76 B00100,
77 B11111,
78};
79const byte hill[8] = {
80 B00000,
81 B00100,
82 B01010,
83 B01110,
84 B11101,
85 B10101,
86 B11001,
87 B11111,
88};
89const byte crow1[8] = {
90 B00111,
91 B00100,
92 B00110,
93 B01111,
94 B11111,
95 B01111,
96 B00110,
97 B00111,
98};
99const byte crow2[8] {
100 B00111,
101 B00110,
102 B01111,
103 B11111,
104 B01111,
105 B00110,
106 B00110,
107 B00111,
108};
109
110volatile int jumpPhase = JUMP_LENGTH + 1;
111int gameTick = 0;
112int crowX = 40;
113int hillX = 25;
114bool playerY = 0;
115volatile bool ducking = LOW;
116bool loopBreaker = 1;
117bool crowGo = 0;
118int score = 0;
119
120void setup() {
121 pinMode(JUMP_PIN, INPUT);
122 pinMode(BUZZER_PIN, OUTPUT);
123 lcd.begin(16, 2);
124 lcd.createChar(0, hill);
125 lcd.createChar(1, stickStep1);
126 lcd.createChar(2, stickStep2);
127 lcd.createChar(3, stickJump);
128 lcd.createChar(4, stickDuck);
129 lcd.createChar(5, crow1);
130 lcd.createChar(6, crow2);
131 attachInterrupt(digitalPinToInterrupt(JUMP_PIN), seeJumping, RISING);
132 attachInterrupt(digitalPinToInterrupt(DUCK_PIN), seeDucking, CHANGE);
133}
134
135void loop() {
136 playerY = 0;
137 if (jumpPhase < JUMP_LENGTH) {
138 playerY = 1;
139 }
140
141 drawSprites();
142
143 loopBreaker = 1;
144 if (hillX < 16) {
145 if (crowX < hillX) {
146 hillX += 8;
147 loopBreaker = 0;
148 }
149 if (loopBreaker) {
150 lcd.setCursor(hillX, 1);
151 lcd.write((byte)0);
152 }
153 }
154 if (hillX < 1) {
155 if (jumpPhase < JUMP_LENGTH) {
156 score++;
157 hillX = 16 + rand() % 8;
158 } else {
159 endGame();
160 }
161 }
162 if (crowX < 16) {
163 lcd.setCursor(crowX, 0);
164 if (gameTick % 8 < 4) {
165 lcd.write((byte)5);
166 } else {
167 lcd.write((byte)6);
168 }
169 }
170 if (crowX < 1) {
171 if (ducking) {
172 score++;
173 crowX = 24 + rand() % 16;
174 } else {
175 endGame();
176 }
177 }
178 lcd.setCursor(0, playerY);
179 lcd.print(" ");
180 jumpPhase++;
181 hillX--;
182 crowGo = !crowGo;
183 crowX -= crowGo;
184 gameTick++;
185 delay(TICKSPEED);
186}
187
188void endGame() {
189 lcd.clear();
190 lcd.setCursor(0, 0);
191 lcd.print("Score: ");
192 lcd.setCursor(7, 0);
193 lcd.print(score);
194 tone(BUZZER_PIN, DIE_PITCH, DIE_PITCH_DURATION);
195 while (!digitalRead(JUMP_PIN)) {
196 lcd.setCursor(0, 1);
197 if (millis() % 500 < 250) {
198 lcd.print("Jump to Continue");
199 } else {
200 lcd.print(" ");
201 }
202 }
203 lcd.clear();
204 score = 0;
205 hillX = 25;
206 crowX = 40;
207}
208
209void drawSprites() {
210 lcd.setCursor(0, 1 - playerY);
211
212 if (!ducking) {
213 if (!playerY) {
214 if ((gameTick % 4) < 2 ) {
215 lcd.write((byte)1);
216 } else {
217 lcd.write((byte)2);
218 }
219 } else {
220 lcd.write((byte)3);
221 }
222 } else {
223 lcd.write((byte)4);
224 }
225 lcd.setCursor(1, 1);
226 lcd.print(" ");
227 lcd.setCursor(1, 0);
228 lcd.print(" ");
229}
230void seeJumping() {
231 if (jumpPhase > (JUMP_LENGTH + 2) && !ducking) {
232 jumpPhase = 0;
233 tone(BUZZER_PIN, JUMP_PITCH, JUMP_PITCH_DURATION);
234 }
235
236}
237void seeDucking() {
238 ducking = digitalRead(DUCK_PIN);
239 if (ducking) {
240 jumpPhase = JUMP_LENGTH;
241 tone(BUZZER_PIN, DUCK_PITCH, DUCK_PITCH_DURATION);
242 }
243}
244