Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: mbed ll16j23s_test_docs
SnakeEngine/SnakeEngine.cpp
- Committer:
- JoeShotton
- Date:
- 2020-05-25
- Revision:
- 9:0571880085cc
- Parent:
- 8:bcc3403d7e79
- Child:
- 10:a2d643b3c782
File content as of revision 9:0571880085cc:
#include "SnakeEngine.h" SnakeEngine::SnakeEngine() { //constructor score = 0; _menu_select = 0; _map_select = 0; _game_state = 1; _pot2 = 0.5; _death = false; } SnakeEngine::~SnakeEngine() { //destructor } void SnakeEngine::game_init(Gamepad &pad, N5110 &lcd, FXOS8700CQ &mag){ transition_black(lcd); transition_white(lcd); map_run(lcd); _food.init(mag); _body.init(); _food.rand_pos(pad, lcd); menu_flash(pad, 3); } void SnakeEngine::game_run(Gamepad &pad, N5110 &lcd){ //input??? map_run(lcd); _body.run(pad, lcd, _death); _food.run(lcd); snake_food_collision(pad, lcd, _body._length); if (_death == true) { printf("Dead!"); _game_state = 4; death_init(pad, lcd); } //snake-wall collision } void SnakeEngine::snake_food_collision(Gamepad &pad, N5110 &lcd, int &_length) { if (_food._x == _body._x_head && _food._y == _body._y_head){ //printf("FOOD!"); pad.led(3,0.9); pad.led(6,0.9); while (_food.rand_pos(pad, lcd) == false){ _food.rand_pos(pad, lcd); printf("Reselected food position\n"); } _body.add_length(5); score++; pad.led(3,0.0); pad.led(6,0.0); } } void SnakeEngine::map_run(N5110 &lcd) { switch(_map_select+1) { case 2: map2_draw(lcd); snake_map2_collision(); break; case 3: map3_draw(lcd); snake_map3_collision(); break; case 4: map4_draw(lcd); snake_map4_collision(); break; } } void SnakeEngine::snake_map2_collision() { if (_body._x_head < 2 || _body._x_head > 81 || _body._y_head < 2 || _body._y_head > 45){ //if snakehead coords exceed the ring coords _death = true; } } void SnakeEngine::snake_map3_collision() { if ((_body._x_head == 40 || _body._x_head == 42) && (_body._y_head < 16 || _body._y_head > 30)){ //if head is at the either of the N/S walls' x coords, and above (y=18) or below (y=30), trigger death _death = true; } else if ((_body._x_head < 16 || _body._x_head > 66) && (_body._y_head == 22 || _body._y_head == 24)){ //if head is at west of x=18 or east of x=66, and at either of the W/E wall's y coords, trigger death _death = true; } } void SnakeEngine::snake_map4_collision() { /* for(int i = 0; i < 48; i++){ if(_body._x_head == MAP 4 COORDS && _body._y_head == MAP 4 COORDS) { return true; } */ } void SnakeEngine::map2_draw(N5110 &lcd){ lcd.drawRect(0, 0, 84, 48,FILL_TRANSPARENT); lcd.drawRect(1, 1, 82, 46,FILL_TRANSPARENT); } void SnakeEngine::map3_draw(N5110 &lcd){ lcd.drawRect(40, 0, 4, 16,FILL_BLACK); //N wall lcd.drawRect(68, 22, 16, 4,FILL_BLACK);//E wall lcd.drawRect(40, 32, 4, 16,FILL_BLACK);//S wall lcd.drawRect(0, 22, 16, 4,FILL_BLACK); //W wall } void SnakeEngine::map4_draw(N5110 &lcd){ lcd.drawRect(12, 8, 4, 4,FILL_BLACK); //NW square lcd.drawRect(12, 36, 4, 4,FILL_BLACK);//SW square lcd.drawRect(68, 8, 4, 4,FILL_BLACK); //NE square lcd.drawRect(68, 36, 4, 4,FILL_BLACK);//SE square lcd.drawRect(38, 6, 8, 8,FILL_BLACK); //N large square lcd.drawRect(24, 20, 8, 8,FILL_BLACK);//E large square lcd.drawRect(38, 34, 8, 8,FILL_BLACK);//S large square lcd.drawRect(52, 20, 8, 8,FILL_BLACK);//W large square } void SnakeEngine::transition_black(N5110 &lcd) { //lcd.clear(); for (int j = 0; j < 21; j += 4) { //j iterator controls the size and location of current loop //printf("j: %d\n", j); for (int i = 1; i < 84 - (2*j); i += 2) { //i iterator controls length of rectangles lcd.drawRect(j, j, i + 1, 4, FILL_BLACK); //top horizontal rectangle lcd.drawRect(83 - j - i, 44 - j, i + 1, 4, FILL_BLACK); //bottom horizontal rectangle wait_ms(5); lcd.refresh(); //refreshes screen without clearing it to maintain previous loops } for (int i = 1; i < 43 - (2*j); i += 2) { //i iterator controls length of rectangles lcd.drawRect(80 - j, 4 + j, 4, i,FILL_BLACK); //right vertical rectangle lcd.drawRect(j, 44 - i - j, 4, i,FILL_BLACK); //left vertical rectangle wait_ms(5); lcd.refresh(); //refreshes screen without clearing it to maintain previous loops } } //wait_ms(500); } void SnakeEngine::transition_white(N5110 &lcd) { //lcd.clear(); for (int j = 0; j < 21; j += 4) { //printf("j: %d\n", j); for (int i = 1; i < 84 - (2*j); i += 2) { lcd.drawRect(j, j, i + 1, 4, FILL_WHITE); lcd.drawRect(83 - j - i, 44 - j, i + 1, 4, FILL_WHITE); wait_ms(5); lcd.refresh(); } for (int i = 1; i < 43 - (2*j); i += 2) { lcd.drawRect(80 - j, 4 + j, 4, i,FILL_WHITE); lcd.drawRect(j, 44 - i - j, 4, i,FILL_WHITE); wait_ms(5); lcd.refresh(); } } //wait_ms(500); } void SnakeEngine::menu1_init(Gamepad &pad, N5110 &lcd){ contrast(pad, lcd); transition_black(lcd); transition_white(lcd); lcd.clear(); lcd.refresh(); //printf("Menu 2\n"); lcd.printString(" SNAKE",3,0); lcd.printString("Play",30,2); lcd.drawCircle(24,19,3,FILL_TRANSPARENT); lcd.printString("Maps",30,3); lcd.drawCircle(24,27,3,FILL_TRANSPARENT); lcd.refresh(); menu_flash(pad, 2); } void SnakeEngine::menu1_select(N5110 &lcd, Gamepad &pad, FXOS8700CQ &mag){ //printf("Menu 1\n"); if (pad.X_pressed() == true){ //detect if 'up' selection _menu_select--; } else if (pad.B_pressed() == true){ //detect if 'down' selection _menu_select++; } _menu_select = ((_menu_select % 2) + 2) % 2; //wrap around numbers, ie down on 2 goes to 1 and up on 1 goes to 2 select_circles(lcd, _menu_select + 1); //draw black circle in selected option //printf("Option: %d\n", _menu_select + 1); if (pad.A_pressed() == true){ //if option 1 selected and 'A' pressed if (_menu_select == 0){ game_init(pad, lcd, mag); //Initialise game _game_state = 3; //switch state } else { menu2_init(pad, lcd); //Initialise menu 2 _game_state = 2; //switch state } } } void SnakeEngine::menu2_init(Gamepad &pad, N5110 &lcd){ //transition_black(lcd); //transition_white(lcd); //printf("Menu 1\n"); lcd.clear(); lcd.printString(" MAPS",0,0); lcd.printString("Empty",30,2); lcd.drawCircle(24,19,3,FILL_TRANSPARENT); lcd.printString("Ring",30,3); lcd.drawCircle(24,27,3,FILL_TRANSPARENT); lcd.printString("Cross",30,4); lcd.drawCircle(24,35,3,FILL_TRANSPARENT); lcd.printString("Spots",30,5); lcd.drawCircle(24,43,3,FILL_TRANSPARENT); lcd.refresh(); menu_flash(pad, 2); } void SnakeEngine::menu2_select(N5110 &lcd, Gamepad &pad){ //printf("Menu 2\n"); if (pad.X_pressed() == true){ _map_select--; } else if (pad.B_pressed() == true){ _map_select++; } else if (pad.Y_pressed() == true){ preview(pad, lcd, _map_select+1); } else if (pad.A_pressed() == true){ //game_init(); _game_state = 3; } //printf("Map: %d\n", _map_select); _map_select = ((_map_select % 4) + 4) % 4; select_circles(lcd, _map_select+1); } void SnakeEngine::death_init(Gamepad &pad, N5110 &lcd){ _death = 0; _menu_select = 0; transition_black(lcd); transition_white(lcd); //printf("Game over\n"); lcd.printString(" GAME OVER",3,0); lcd.printString(" Score:",0,1); char buffer[14]; sprintf(buffer," %2d",score); lcd.printString(buffer,0,2); lcd.printString("Again!",30,4); lcd.drawCircle(24,35,3,FILL_TRANSPARENT); lcd.printString("Maps",30,5); lcd.drawCircle(24,43,3,FILL_TRANSPARENT); lcd.refresh(); menu_flash(pad, 1); } void SnakeEngine::death_select(N5110 &lcd, Gamepad &pad, FXOS8700CQ &mag){ //printf("Menu 1\n"); if (pad.X_pressed() == true){ //detect if 'up' selection _menu_select--; } else if (pad.B_pressed() == true){ //detect if 'down' selection _menu_select++; } _menu_select = ((_menu_select % 2) + 2) % 2; //wrap around numbers, ie down on 2 goes to 1 and up on 1 goes to 2 select_circles(lcd, _menu_select + 3); //draw black circle in selected option //printf("Option: %d\n", _menu_select + 1); if (pad.A_pressed() == true){ //if option 1 selected and 'A' pressed if (_menu_select == 0){ game_init(pad, lcd, mag); //Initialise game _game_state = 3; //switch state } else { menu2_init(pad, lcd); //Initialise menu 2 _game_state = 2; //switch state } } } void SnakeEngine::select_circles(N5110 &lcd, int line) { for(int i = 19; i < 52; i +=8) { lcd.drawCircle(24,i,2,FILL_WHITE); } lcd.drawCircle(24,11+line*8,2,FILL_BLACK); lcd.refresh(); wait_ms(200); //snake_select1.render(lcd, 0, 8); //wait_ms(200); //snake_select2.render(lcd, 0, 8); //wait_ms(200); //snake_select3.render(lcd, 0, 8); //wait_ms(200); } void SnakeEngine::preview(Gamepad &pad, N5110 &lcd, int _map_select){ lcd.clear(); switch(_map_select) { case 1: lcd.clear(); lcd.printString("(Empty)",21,2); break; case 2: map2_draw(lcd); //lcd.printString("Ring",30,2); break; case 3: map3_draw(lcd); //lcd.printString("Cross",27,2); break; case 4: map4_draw(lcd); //lcd.printString("Spots",27,2); break; } lcd.refresh(); wait_ms(1000); lcd.clear(); menu2_init(pad, lcd); } void SnakeEngine::contrast(Gamepad &pad, N5110 &lcd){ _pot2 = pad.read_pot2(); lcd.setContrast(0.25 + _pot2 * 0.5); //printf("Contrast: %f\n", 0.25 + _pot2 * 0.5); } void SnakeEngine::menu_flash(Gamepad &pad, int led){ for(int i = 1; i < 7; i++){ pad.led(led, i % 2); pad.led(led + 3, i % 2); wait_ms(100); } }