This is an old revision of the document!
Scopul acestui proiect este să ofere utilizatorilor un joc Super Mario, care poate fi jucat în timpul liber. Proiectul a fost creat pentru a fi ușor de jucat și de înțeles, fiind util și pentru învățarea conceptelor hardware și software.
int gameOver[] = { NOTE_C5,-4, NOTE_G4,-4, NOTE_E4,4, NOTE_A4,-8, NOTE_B4,-8, NOTE_A4,-8, NOTE_GS4,-8, NOTE_AS4,-8, NOTE_GS4,-8, NOTE_G4,8, NOTE_D4,8, NOTE_E4,-2, };
void graphics(){
byte man[64] = {
// position 1
B01100,
B01100,
B00000,
B01110,
B11100,
B01100,
B11010,
B10011,
// position 2
B01100,
B01100,
B00000,
B01100,
B01100,
B01100,
B01100,
B01110,
// Jump
B01100,
B01100,
B00000,
B11110,
B01101,
B11111,
B10000,
B00000,
// Jump lower
B11110,
B01101,
B11111,
B10000,
B00000,
B00000,
B00000,
B00000,
// Ground
B11111,
B11111,
B11111,
B11111,
B11111,
B11111,
B11111,
B11111,
// Ground right
B00011,
B00011,
B00011,
B00011,
B00011,
B00011,
B00011,
B00011,
// Ground left
B11000,
B11000,
B11000,
B11000,
B11000,
B11000,
B11000,
B11000
};
int g;
for (g = 0; g < 8; g++) {
lcd.createChar(g, &man[g*8]);
}
}
void startGame(){
lcd.setCursor (1,1);
lcd.print("Press Up to Start!");
lcd.setCursor (0,1);
currentPos = run_1;
}
void drawmanWalk(){
man_low_pos=1; lcd.setCursor(0,1); currentPos = run_2; lcd.write(byte(currentPos)); delay(120); lcd.setCursor(0,1); currentPos = run_1; lcd.write(byte(currentPos)); delay(120); detect();
}
void drawmanJump(){
man_low_pos=1; man_up_pos=1; lcd.setCursor (0,0); currentPosUp = jump_half_head; lcd.write(byte(currentPosUp)); lcd.setCursor (0,1); currentPosDown = jump_half_body; lcd.write(byte(currentPosDown)); detect();
tone(buzzer, NOTE_A6, 100); delay(110); drawObject();
man_low_pos=0;
man_up_pos=1;
lcd.setCursor (0,0);
currentPosUp = jump_high;
lcd.write(byte(currentPosUp));
lcd.setCursor (0,1);
lcd.print(" ");
detect();
delay(110);
drawObject();
detect();
delay(140);
drawObject();
detect();
man_low_pos=1;
man_up_pos=1;
lcd.setCursor (0,0);
currentPosUp = jump_half_head;
lcd.write(byte(currentPosUp));
lcd.setCursor (0,1);
currentPosDown = jump_half_body;
lcd.write(byte(currentPosDown));
delay(140);
lcd.setCursor(0,0);
lcd.print(" ");
man_up_pos=0;
man_low_pos=1;
detect();
}
void objectRandom (int upperBG[], int lowerBG[]){
int ObjectPos = random(5,10);
switch (ObjectPos){
case upperObject1:
lowerBG[16] = empty;
if (lowerBG[15] == lowerObject1)
upperBG[16] = empty;
else
upperBG[16] = upperObject1;
break;
case lowerObject1:
if ((lowerBG[15] == lowerObject1)||
(lowerBG[14] == lowerObject1)||
(lowerBG[13] == lowerObject1)||
(upperBG[15] == upperObject1)){
lowerBG[16] = empty;
}
else
lowerBG[16] = lowerObject1;
break;
case empty:
case 8:
case 9:
case 10:
upperBG[16] = empty;
lowerBG[16] = empty;
break;
}
}
void detect(){
if((man_up_pos==1 && upperBG[0]!=7)||
(man_low_pos==1&&lowerBG[0]!=7)){
lcd.clear();
lcd.setCursor(1,0);
playing = false;
scoring = false;
}
}
void drawObject (){
if(millis() - ts > 300) {
ts = millis();
objectRandom(upperBG,lowerBG);
}
for (int i = 0; i < 16; i++){
upperBG[i]=upperBG[i+1];
lowerBG[i]=lowerBG[i+1];
}
if(upperBG[0]!=7){
lcd.setCursor(0,0);
lcd.write(byte(upperBG[0]));
}
else if(man_up_pos==0){
lcd.setCursor(0,0);
lcd.print(" ");
}
if(lowerBG[0]!=7){
lcd.setCursor(0,1);
lcd.write(byte(lowerBG[0]));
}
else if(man_low_pos==0){
lcd.setCursor(0,1);
lcd.print(" ");
}
for (int i = 1; i < 16; i++){
lcd.setCursor(i,0);
lcd.write(byte(upperBG[i]));
lcd.setCursor(i,1);
lcd.write(byte(lowerBG[i]));
}
}
void over(){
digitalWrite(RED_LED, HIGH);
int wholenote = (60000 * 4) / 200;
int noteDuration = 0;
for(int i = 0; i < 24; i+=2){
int divider = gameOver[i + 1];
if (divider > 0) {
noteDuration = (wholenote) / divider;
} else if (divider < 0) {
noteDuration = (wholenote) / abs(divider);
noteDuration *= 1.5;
}
tone(buzzer, gameOver[i], noteDuration * 0.9);
delay(noteDuration);
noTone(buzzer);
}
lcd.clear();
lcd.setCursor (5,1);
lcd.print ("Game Over!");
lcd.setCursor (3,2);
lcd.print ("Your Score:");
lcd.setCursor (14,2);
lcd.print (score);
delay(delay_time);
game_over = true;
}
void setup() {
Serial.begin(9600); pinMode(jump_button, INPUT); digitalWrite(jump_button, HIGH); graphics(); lcd.begin(20, 4); lcd.backlight(); pinMode(buzzerPin, OUTPUT); pinMode(RED_LED, OUTPUT); digitalWrite(RED_LED, LOW);
}
void loop() {
while(game_over) {
buttonPushed = (digitalRead(jump_button) == LOW);
if(buttonPushed) {
lcd.clear();
buttonPushed = false;
playing = false;
scoring = false;
score = 0;
for(int i = 0; i < 17; i++) {
upperBG[i]= empty;
lowerBG[i] = empty;
}
game_over = false;
}
}
buttonPushed = (digitalRead(jump_button) == LOW);
if (!playing && score == 0) {
startGame();
digitalWrite(RED_LED, LOW);
if (buttonPushed) {
graphics();
playing = true;
scoring = true;
buttonPushed = false;
lcd.clear();
}
}
if(!playing && score > 0) {
over();
}
if (playing){
drawObject();
drawmanWalk();
if((mode == 0 || mode == 1 ) && buttonPushed){
drawmanJump();
buttonPushed = false;
}
if(mode == 1) {
if (lowerBG[3] == lowerObject1){
digitalWrite(RED_LED, HIGH);
} else {
digitalWrite(RED_LED, LOW);
}
}
if(mode == 2) {
if (man_low_pos==1 && lowerBG[2]!=7){
drawmanJump();
}
}
}
if (scoring == true){
score++; }
}
Proiectul m-a ajutat să aprofundez conceptele studiate la laboratoarele de PM, mai ales să înțeleg utilizarea protocolului I2C.
Melodia SuperMario : https://github.com/robsoncouto/arduino-songs/blob/master/supermariobros/supermariobros.ino
Configurare I2C: https://www.youtube.com/watch?v=EAeuxjtkumM&t=125s