Pokemon World (ECE 4180 project)
WELCOME TO POKEMON WORLD
Project by
Jin Ha Hwang and Hokyung Hwang
Overview
A popular Japanese oriented Nintendo game was implemented using an mbed microcontroller. This game is traditionally played using several game devices such as Nintendo, personal computer, or even mobile phones. Players get one Pokemon and increase their physical abilities by fighting various Pokemons. History of Pokemon game can be found in http://en.wikipedia.org/wiki/Pok%C3%A9mon_%28video_game_series%29. For the implementation, three different types of Pokemon are added for indication of Pokemon type counter. The user will have pushbuttons to explore the Pokemon World for finding enemies and increase their Pokemon.
Diagram
Components Used
- uLCD-144-G2 : The serial miniature LCD module is used to display Pokemon world providing the user interface for the game. Instructions and several useful references can be found here: http://developer.mbed.org/users/4180_1/notebook/ulcd-144-g2-128-by-128-color-lcd/
- Pushbuttons : Pushbuttons are used to explore Pokemon world by selecting different menus from the LCD module. Pushbuttons are used to explore up, down, and select menu. Instructions and several useful references can be found here: http://developer.mbed.org/users/4180_1/notebook/pushbuttons/
- Speaker : Speaker is used to give more variety of fun when user wins or loses to enemy. It generates different sounds according to the result of the fight. Instructions and several useful references can be found here: http://developer.mbed.org/users/4180_1/notebook/using-a-speaker-for-audio-output/
- RGB LED : RGE LED module is also used to give more variety of fun when user wins or loses to enemy. It generates different sounds according to the result of the fight. Instructions and several useful references can be found here: http://developer.mbed.org/users/4180_1/notebook/rgb-leds/
Photos
Overview
Game Menu
Type Select
Match Result
Video
Play video
Pin Setup
mbed | uLCD |
---|---|
5v | +5v |
p9 | Tx |
p10 | Rx |
GND | GND |
p11 | RES |
mbed | Pushbuttons | Command |
---|---|---|
p12 | pb1 | Up |
p13 | pb2 | Down |
p14 | pb3 | Select |
mbed | Speaker |
---|---|
3.3v | Speaker+ |
p26 | Speaker- |
mbed | RGB LED |
---|---|
p23 | RED |
p22 | GREEN |
p21 | BLUE |
GND | GND |
Code
player.h
#include <string> typedef unsigned int uns; extern std::string TYPEStr[3]; typedef enum Type {FIRE, WATER, GRASS} Type_e; class Player { public: Player(); Player(uns, uns, Type_e); //fight int fight(Player p); //lvlup void lvlUp(); void checkEXP(); //setting void setType(Type_e); std::string toString(void); protected: //stats uns lvl; Type_e type; uns attackDmg; uns exp; float crit; };
player.cpp
#include "Player.h" #include <stdio.h> std::string TYPEStr[3] = {"FIRE", "WATER", "GRASS"}; Player::Player(void) { Player(1, 10, FIRE); } Player::Player(uns l, uns att, Type_e t) { lvl = l; attackDmg = att; type = t; crit = 0.0f; } int Player::fight(Player p) { int win = 0; uns newAtt = 0; if ((p.type == FIRE && type == WATER )|| (p.type == GRASS && type == FIRE) || (p.type == WATER && type == GRASS)) { newAtt = 2 * attackDmg; if (newAtt >= p.attackDmg) win = 1; else if (newAtt < p.attackDmg) win = -1; } else if ((p.type == WATER && type == FIRE) || (p.type == GRASS && type == WATER) || (p.type == FIRE && type == GRASS)) { newAtt = (uns)(attackDmg >> 1); if (newAtt >= p.attackDmg) win = 1; else if (newAtt < p.attackDmg) win = -1; } else { newAtt = attackDmg; if (newAtt >= p.attackDmg) win = 1; else if (newAtt < p.attackDmg) win = -1; } if (win == 1) exp += 20; return win; } void Player::lvlUp() { lvl++; attackDmg += 2; crit += 0.05f; exp = 0; } void Player::checkEXP() { if (exp >= 100) { Player::lvlUp(); } } void Player::setType(Type_e t) { type = t; } std::string Player::toString(void) { std::string res = "STAT:\n" ; char num[40]; sprintf(num, "AttackDmg: %u \nType: %s", attackDmg, TYPEStr[type].c_str()); res += num; return (res); }
main.cpp
#include "mbed.h" #include "uLCD_4DGL.h" #include "Player.h" #include "rtos.h" #include "Speaker.h" #define OFFSET 40 #define ARRX 90 #define ARRY 43 #define PI 3.1415192 typedef enum State {START, MENU, CHOICE, PLMENU, FIGHT, STATS} GameState; PwmOut R(p23); PwmOut G(p22); PwmOut B(p21); DigitalOut myled(LED1); uLCD_4DGL uLCD(p9, p10, p11); DigitalIn up(p12); DigitalIn down(p13); //change pin to whatever you want(DigitalIn) DigitalIn select(p14); Speaker mySpeaker(p26); void winEffect() { mySpeaker.PlayNote(783.991,1,0.5); wait(0.5f); mySpeaker.PlayNote(698.456,0.5,0.5); for (int i = 0; i < 3; ++i) { B = 0.5; G = 0; wait(0.1f); G = 0.5; B = 0; wait(0.1f); B = 0.5; G = 0; wait(0.1f); G = 0.5; B = 0; wait(0.1f); B = 0; G = 0; } } void loseEffect() { mySpeaker.PlayNote(583.991,1,0.5); wait(0.5f); mySpeaker.PlayNote(798.456,0.5,0.5); for (int i = 0; i < 3; ++i) { R = 0.5; G = 0; wait(0.1f); G = 0.5; R = 0; wait(0.1f); R = 0.5; G = 0; wait(0.1f); G = 0.5; R = 0; wait(0.1f); R = 0; G = 0; } } void drawArr(int x, int y, int color) { int r = 10; uLCD.line(x, y, x + (int) r * cos(PI / 6), y + (int) r * sin(PI / 6), color); uLCD.line(x, y, x + (int) r * cos(PI / 6), y - (int) r * sin(PI / 6), color); } void drawStart() { uLCD.text_string("PLAY", 5, 5, FONT_7X8, WHITE); uLCD.text_string("MENU", 5, 10, FONT_7X8, WHITE); } void drawChoice() { uLCD.text_string("FIRE", 5, 2, FONT_7X8, RED); uLCD.text_string("WATER", 5, 7, FONT_7X8, BLUE); uLCD.text_string("GRASS", 5, 12, FONT_7X8, GREEN); } void drawPlayerMenu() { uLCD.text_string("FIGHT", 5, 5, FONT_7X8, WHITE); uLCD.text_string("VIEW STAT", 5, 10, FONT_7X8, WHITE); } void drawFight(Player e, int a, std::string name) { std::string sss = e.toString(); std::string m = ""; if (a == 1) { m = "\nYou won and \nyou got 20 exp points"; } else if (a == -1) { m = "\nYou lost"; } std::string newStr = "You met Enemy\n:" + name + "\n" + sss + m; char z[130]; strncpy(z, newStr.c_str(), sizeof(z)); uLCD.text_string(z, 0, 5, FONT_7X8, WHITE); } int main() { //Thread th1(winEffect); srand(time(NULL)); int ind = 0; Player pl(1, 10, FIRE); std::string nameList[42] = {"Abra", "Absol", "Azelf", "Banette", "Bastiodon", "Beautifly", "Bidoof", "Carvanha", "Clefairy", "Cresselia", "Crobat", "Darkrai", "Delphox", "Dialga", "Ditto", "Doduo", "Dratini", "Dugtrio", "Gothitelle", "Grovyle", "Haxorus", "Honedge", "Hoopa", "Jirachi", "Keldeo", "Lugia", "Makuhita", "Marill", "Meowth", "Minun", "Remoraid", "Rhyhorn", "Sableye", "Sandile", "Sawk", "Sylveon", "Tauros", "Togepi", "Victini", "Wailord", "Wingull", "Zubat"}; Player enemy[6] = {Player(1, 15, FIRE), Player (1, 20, WATER), Player(1, 15, GRASS), Player(2, 10, FIRE), Player(4, 55, WATER), Player(2, 12, GRASS)}; myled = 0; int offset = 0; int oldposY = 0; GameState state = START; up.mode(PullUp); down.mode(PullUp); select.mode(PullUp); while(1) { if (state == START) { drawStart(); drawArr(ARRX, oldposY, BLACK); drawArr(ARRX, ARRY + offset, WHITE); oldposY = ARRY + offset; if (!up) { if (offset != 0) offset = 0; } else if (!down) { if (offset == 0) offset = OFFSET; } if (!select) { //if (offset == 0) { state = CHOICE; offset = 0; oldposY = 0; uLCD.cls(); //} } } else if (state == MENU) { } else if (state == CHOICE) { drawChoice(); drawArr(ARRX, oldposY, BLACK); drawArr(ARRX, 19 + offset, WHITE); oldposY = 19 + offset; if (!up) { if (offset == OFFSET) offset = 0; else if (offset == 2 * OFFSET) offset = OFFSET; } else if (!down) { if (offset == 0) offset = OFFSET; else if (offset == OFFSET) offset = 2 * OFFSET; } if (!select) { if (offset == 0) pl.setType(FIRE); else if (offset == OFFSET) pl.setType(WATER); else if (offset == (OFFSET >> 1)) pl.setType(GRASS); uLCD.cls(); oldposY = 0; state = PLMENU; offset = 0; } } else if (state == PLMENU) { drawPlayerMenu(); drawArr(ARRX, oldposY, BLACK); drawArr(ARRX, ARRY + offset, WHITE); oldposY = ARRY + offset; if (!up) { if (offset != 0) offset = 0; } else if (!down) { if (offset == 0) offset = OFFSET; } if (!select) { if (offset == 0) { state = FIGHT; } else { state = STATS; } offset = 0; oldposY = 0; uLCD.cls(); } } else if (state == FIGHT) { ind = rand() % 6; int ind2 = rand() % 42; std::string str = nameList[ind2]; Player ene = enemy[ind]; int w = pl.fight(ene); pl.checkEXP(); drawFight(ene, w, str); if (w == 1) { winEffect(); } else if (w == -1) { loseEffect(); } /* if (!select) { offset = 0; oldposY = 0; uLCD.cls(); state = PLMENU; }*/ wait(2.0f); uLCD.cls(); state = PLMENU; } else if (state == STATS) { std::string sss = pl.toString(); char c[100]; strncpy(c, sss.c_str(), sizeof(c)); uLCD.text_string(c, 2, 4, FONT_7X8, WHITE); if (!select) { offset = 0; oldposY = 0; uLCD.cls(); state = PLMENU; } } } }
Please log in to post comments.