Differences

This shows you the differences between two versions of the page.

Link to this comparison view

pm:prj2022:apredescu:jumper_game [2022/05/27 12:25]
ali_dhiyaa.abdul
pm:prj2022:apredescu:jumper_game [2022/06/02 13:40] (current)
ali_dhiyaa.abdul
Line 1: Line 1:
-Made By Ali Dhiyaa Abdul Karim 1221EA+===== jumper game ======
  
-{{:pm:​prj2022:​apredescu:​pm.jpeg?​200|}}+<note tip> 
 +Prezentarea pe scurt a proiectului vostru: 
 +  * a game where you have to jump and make a high score 
 +</​note>​ 
 +===== Descriere generală =====
  
-jumper game+<note tip> 
 +O schemă bloc cu toate modulele proiectului vostru, atât software cât şi hardware însoţită de o descriere a acestora precum şi a modului în care interacţionează. 
 + 
 +Exemplu de schemă bloc: http://​www.robs-projects.com/​mp3proj/​newplayer.html 
 +</​note>​ 
 + 
 +===== Hardware Design ===== 
 + 
 +<note tip> 
 +Aici puneţi tot ce ţine de hardware design: 
 +  * LCD corespund cu astia de pe arduino: 
 +rs = 12, en = 11, d4 = 6, d5 = 5, d6 = 4, d7 = 3 
 + 
 +   
 + 
 +</​note>​ 
 +<note type> 
 +Wiring Diagram :  
 +</​note>​ 
 +{{:​pm:​prj2022:​apredescu:​4fbba8ea-838e-4e53-b2a4-74d5529aa44a.jpeg?​nolink&​500 |}} 
 + 
 + 
 +===== Software Design ===== 
 + 
 + 
 +<note tip> 
 + 
 +#include <​LiquidCrystal.h>​ 
 +  
 +#define PIN_BUTTON 2 
 +  
 +#define SPRITE_RUN1 1 
 +#define SPRITE_RUN2 2 
 +#define SPRITE_JUMP 3 
 +#define SPRITE_JUMP_UPPER '​.' ​        // Use the '​.'​ character for the head 
 +#define SPRITE_JUMP_LOWER 4 
 +#define SPRITE_TERRAIN_EMPTY ' ' ​     // User the ' ' character 
 +#define SPRITE_TERRAIN_SOLID 5 
 +#define SPRITE_TERRAIN_SOLID_RIGHT 6 
 +#define SPRITE_TERRAIN_SOLID_LEFT 7 
 +  
 +#define HERO_HORIZONTAL_POSITION 1    // Horizontal position of hero on screen 
 +  
 +#define TERRAIN_WIDTH 16 
 +#define TERRAIN_EMPTY 0 
 +#define TERRAIN_LOWER_BLOCK 1 
 +#define TERRAIN_UPPER_BLOCK 2 
 +  
 +#define HERO_POSITION_OFF 0          // Hero is invisible 
 +#define HERO_POSITION_RUN_LOWER_1 1  // Hero is running on lower row (pose 1) 
 +#define HERO_POSITION_RUN_LOWER_2 2  //                              (pose 2) 
 +  
 +#define HERO_POSITION_JUMP_1 3       // Starting a jump 
 +#define HERO_POSITION_JUMP_2 4       // Half-way up 
 +#define HERO_POSITION_JUMP_3 5       // Jump is on upper row 
 +#define HERO_POSITION_JUMP_4 6       // Jump is on upper row 
 +#define HERO_POSITION_JUMP_5 7       // Jump is on upper row 
 +#define HERO_POSITION_JUMP_6 8       // Jump is on upper row 
 +#define HERO_POSITION_JUMP_7 9       // Half-way down 
 +#define HERO_POSITION_JUMP_8 10      // About to land 
 +  
 +#define HERO_POSITION_RUN_UPPER_1 11 // Hero is running on upper row (pose 1) 
 +#define HERO_POSITION_RUN_UPPER_2 12 //                              (pose 2) 
 +  
 + //​DB7 
 +     
 +const int rs = 12, en = 11, d4 = 6, d5 = 5, d6 = 4, d7 = 3; 
 +LiquidCrystal lcd(rs, en, d4, d5, d6, d7); 
 + 
 + 
 +               
 +  
 +char terrainUpper[TERRAIN_WIDTH + 1]; 
 +char terrainLower[TERRAIN_WIDTH + 1]; 
 +volatile boolean buttonPushed = false; 
 +  
 +void initializeGraphics() { 
 +    byte graphics[] = { 
 +        // Run position 1 
 +        B01100, 
 +        B01100, 
 +        B00000, 
 +        B01110, 
 +        B11100, 
 +        B01100, 
 +        B11010, 
 +        B10011, 
 +        // Run 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 i; 
 +  
 +    // Skip using character 0, this allows lcd.print() to be used to 
 +    // quickly draw multiple characters 
 +    for (i = 0; i < 7; ++i) { 
 +        lcd.createChar(i + 1, &​graphics[i * 8]); 
 +    } 
 +  
 +    for (i = 0; i < TERRAIN_WIDTH;​ ++i) { 
 +        terrainUpper[i] = SPRITE_TERRAIN_EMPTY;​ 
 +        terrainLower[i] = SPRITE_TERRAIN_EMPTY;​ 
 +    } 
 +
 +  
 +// Slide the terrain to the left in half-character increments 
 +void advanceTerrain(char* terrain, byte newTerrain) { 
 +    for (int i = 0; i < TERRAIN_WIDTH;​ ++i) { 
 +        char current = terrain[i];​ 
 +        char next = (i == TERRAIN_WIDTH-1) ? newTerrain : terrain[i+1];​ 
 +  
 +        switch (current) { 
 +            case SPRITE_TERRAIN_EMPTY:​ 
 +                terrain[i] = (next == SPRITE_TERRAIN_SOLID) ? SPRITE_TERRAIN_SOLID_RIGHT : SPRITE_TERRAIN_EMPTY;​ 
 +            break; 
 +  
 +            case SPRITE_TERRAIN_SOLID:​ 
 +                terrain[i] = (next == SPRITE_TERRAIN_EMPTY) ? SPRITE_TERRAIN_SOLID_LEFT : SPRITE_TERRAIN_SOLID;​ 
 +            break; 
 +  
 +            case SPRITE_TERRAIN_SOLID_RIGHT:​ 
 +                terrain[i] = SPRITE_TERRAIN_SOLID;​ 
 +            break; 
 +  
 +            case SPRITE_TERRAIN_SOLID_LEFT:​ 
 +                terrain[i] = SPRITE_TERRAIN_EMPTY;​ 
 +            break; 
 +        } 
 +    } 
 +
 +  
 +boolean drawHero(byte position, char* terrainUpper,​ char* terrainLower,​ unsigned int score) { 
 +    boolean collide = false; 
 +    char upperSave = terrainUpper[HERO_HORIZONTAL_POSITION];​ 
 +    char lowerSave = terrainLower[HERO_HORIZONTAL_POSITION];​ 
 +    byte upper, lower; 
 +  
 +    switch (position) { 
 +        case HERO_POSITION_OFF:​ 
 +            upper = lower = SPRITE_TERRAIN_EMPTY;​ 
 +        break; 
 +  
 +        case HERO_POSITION_RUN_LOWER_1:​ 
 +            upper = SPRITE_TERRAIN_EMPTY;​ 
 +            lower = SPRITE_RUN1;​ 
 +        break; 
 +  
 +        case HERO_POSITION_RUN_LOWER_2:​ 
 +            upper = SPRITE_TERRAIN_EMPTY;​ 
 +            lower = SPRITE_RUN2;​ 
 +        break; 
 +  
 +        case HERO_POSITION_JUMP_1:​ 
 +  
 +        case HERO_POSITION_JUMP_8:​ 
 +            upper = SPRITE_TERRAIN_EMPTY;​ 
 +            lower = SPRITE_JUMP;​ 
 +        break; 
 +  
 +        case HERO_POSITION_JUMP_2:​ 
 +  
 +        case HERO_POSITION_JUMP_7:​ 
 +            upper = SPRITE_JUMP_UPPER;​ 
 +            lower = SPRITE_JUMP_LOWER;​ 
 +        break; 
 +  
 +        case HERO_POSITION_JUMP_3:​ 
 +  
 +        case HERO_POSITION_JUMP_4:​ 
 +  
 +        case HERO_POSITION_JUMP_5:​ 
 +  
 +        case HERO_POSITION_JUMP_6:​ 
 +            upper = SPRITE_JUMP;​ 
 +            lower = SPRITE_TERRAIN_EMPTY;​ 
 +        break; 
 +  
 +        case HERO_POSITION_RUN_UPPER_1:​ 
 +            upper = SPRITE_RUN1;​ 
 +            lower = SPRITE_TERRAIN_EMPTY;​ 
 +        break; 
 +  
 +        case HERO_POSITION_RUN_UPPER_2:​ 
 +            upper = SPRITE_RUN2;​ 
 +            lower = SPRITE_TERRAIN_EMPTY;​ 
 +        break; 
 +    } 
 +  
 +    if (upper != ' ') { 
 +        terrainUpper[HERO_HORIZONTAL_POSITION] = upper; 
 +        collide = (upperSave == SPRITE_TERRAIN_EMPTY) ? false : true; 
 +    } 
 +  
 +    if (lower != ' ') { 
 +        terrainLower[HERO_HORIZONTAL_POSITION] = lower; 
 +        collide |= (lowerSave == SPRITE_TERRAIN_EMPTY) ? false : true; 
 +    } 
 +  
 +    byte digits = (score > 9999) ? 5 : (score > 999) ? 4 : (score > 99) ? 3 : (score > 9) ? 2 : 1; 
 +  
 +    // Draw the scene 
 +    terrainUpper[TERRAIN_WIDTH] = '​\0';​ 
 +    terrainLower[TERRAIN_WIDTH] = '​\0';​ 
 +    char temp = terrainUpper[16-digits];​ 
 +    terrainUpper[16-digits] = '​\0';​ 
 +    lcd.setCursor(0,​0);​ 
 +    lcd.print(terrainUpper);​ 
 +    terrainUpper[16-digits] = temp; 
 +    lcd.setCursor(0,​1);​ 
 +    lcd.print(terrainLower);​ 
 +  
 +    lcd.setCursor(16 - digits,​0);​ 
 +    lcd.print(score);​ 
 +  
 +    terrainUpper[HERO_HORIZONTAL_POSITION] = upperSave;​ 
 +    terrainLower[HERO_HORIZONTAL_POSITION] = lowerSave;​ 
 +  
 +    return collide; 
 +
 +  
 +// Handle the button push as an interrupt 
 +void buttonPush() { 
 +    buttonPushed = true; 
 +
 +  
 +void setup() { 
 +    pinMode(PIN_BUTTON,​ INPUT_PULLUP);​ 
 +  
 +    // Digital pin 2 maps to interrupt 0 
 +    attachInterrupt(0,​ buttonPush, FALLING); 
 +  
 +    initializeGraphics();​ 
 +  
 +    lcd.begin(16,​ 2); 
 +
 +  
 +void loop(){ 
 +    static byte heroPos = HERO_POSITION_RUN_LOWER_1;​ 
 +    static byte newTerrainType = TERRAIN_EMPTY;​ 
 +    static byte newTerrainDuration = 1; 
 +    static boolean playing = false; 
 +    static boolean blink = false; 
 +    static unsigned int distance = 0; 
 +  
 +    if (!playing) { 
 +        drawHero((blink) ? HERO_POSITION_OFF : heroPos, terrainUpper,​ terrainLower,​ distance >> 3); 
 +  
 +        if (blink) { 
 +        lcd.setCursor(0,​0);​ 
 +        lcd.print("​Press Start"​);​ 
 +        } 
 +  
 +        delay(250);​ 
 +        blink = !blink; 
 +  
 +        if (buttonPushed) { 
 +            initializeGraphics();​ 
 +            heroPos = HERO_POSITION_RUN_LOWER_1;​ 
 +            playing = true; 
 +            buttonPushed = false; 
 +            distance = 0; 
 +        } 
 +  
 +        return; 
 +    } 
 +  
 +    // Shift the terrain to the left 
 +    advanceTerrain(terrainLower,​ newTerrainType == TERRAIN_LOWER_BLOCK ? SPRITE_TERRAIN_SOLID : SPRITE_TERRAIN_EMPTY);​ 
 +    advanceTerrain(terrainUpper,​ newTerrainType == TERRAIN_UPPER_BLOCK ? SPRITE_TERRAIN_SOLID : SPRITE_TERRAIN_EMPTY);​ 
 +  
 +    // Make new terrain to enter on the right 
 +    if (--newTerrainDuration == 0) { 
 +        if (newTerrainType == TERRAIN_EMPTY) { 
 +            newTerrainType = (random(3) == 0) ? TERRAIN_UPPER_BLOCK : TERRAIN_LOWER_BLOCK;​ 
 +            newTerrainDuration = 2 + random(10);​ 
 +        } else { 
 +            newTerrainType = TERRAIN_EMPTY;​ 
 +            newTerrainDuration = 10 + random(10);​ 
 +        } 
 +    } 
 +  
 +    if (buttonPushed) { 
 +        if (heroPos <= HERO_POSITION_RUN_LOWER_2) 
 +            heroPos = HERO_POSITION_JUMP_1;​ 
 +  
 +        buttonPushed = false; 
 +    } 
 +  
 +    if (drawHero(heroPos,​ terrainUpper,​ terrainLower,​ distance >> 3)) { 
 +        playing = false; // The hero collided with something. Too bad. 
 +    } else { 
 +        if (heroPos == HERO_POSITION_RUN_LOWER_2 || heroPos == HERO_POSITION_JUMP_8) { 
 +            heroPos = HERO_POSITION_RUN_LOWER_1;​ 
 +        } else if ((heroPos >= HERO_POSITION_JUMP_3 && heroPos <= HERO_POSITION_JUMP_5) && terrainLower[HERO_HORIZONTAL_POSITION] != SPRITE_TERRAIN_EMPTY) { 
 +            heroPos = HERO_POSITION_RUN_UPPER_1;​ 
 +        } else if (heroPos >= HERO_POSITION_RUN_UPPER_1 && terrainLower[HERO_HORIZONTAL_POSITION] == SPRITE_TERRAIN_EMPTY) { 
 +            heroPos = HERO_POSITION_JUMP_5;​ 
 +        } else if (heroPos == HERO_POSITION_RUN_UPPER_2) { 
 +            heroPos = HERO_POSITION_RUN_UPPER_1;​ 
 +        } else { 
 +            ++heroPos;​ 
 +        } 
 +  
 +        ++distance;​ 
 +    } 
 +  
 +    delay(100);​ 
 +
 + 
 +   
 +</​note>​ 
 + 
 +===== Rezultate Obţinute ===== 
 + 
 +<note tip> 
 +Care au fost rezultatele obţinute în urma realizării proiectului vostru. 
 +</​note>​ 
 +{{:​pm:​prj2022:​apredescu:​ali_result.jpeg?​nolink&​500 |}} 
 +===== Concluzii ===== 
 + 
 +===== Download ===== 
 + 
 +<note warning>​ 
 +O arhivă (sau mai multe dacă este cazul) cu fişierele obţinute în urma realizării proiectului:​ surse, scheme, etc. Un fişier README, un ChangeLog, un script de compilare şi copiere automată pe uC crează întotdeauna o impresie bună ;-). 
 + 
 +Fişierele se încarcă pe wiki folosind facilitatea *Add Images or other files. Namespace-ul în care se încarcă fişierele este de tipul *:​pm:​prj20??:​c?​* sau *:​pm:​prj20??:​c?:​nume_student** (dacă este cazul). *Exemplu:* Dumitru Alin, 331CC -> *:​pm:​prj2009:​cc:​dumitru_alin*. 
 +</​note>​ 
 + 
 +===== Jurnal ===== 
 + 
 +<note tip> 
 +Puteți avea și o secțiune de jurnal în care să poată urmări asistentul de proiect progresul proiectului. 
 +</​note>​ 
 + 
 +===== Bibliografie/​Resurse ===== 
 + 
 +<​note>​ 
 +Listă cu documente, datasheet-uri,​ resurse Internet folosite, eventual grupate pe *Resurse Software* şi *Resurse Hardware*. 
 +</​note>​ 
 + 
 +<​html><​a class="​media mediafile mf_pdf"​ href="?​do=export_pdf">​Export to PDF</​a></​html>​
pm/prj2022/apredescu/jumper_game.1653643549.txt.gz · Last modified: 2022/05/27 12:25 by ali_dhiyaa.abdul
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0