Brick Breaker
Dependencies: 4DGL-uLCD-SE mbed-rtos mbed
Revision 0:099e4258aba4, committed 2014-10-21
- Comitter:
- hotwheelharry
- Date:
- Tue Oct 21 16:14:11 2014 +0000
- Commit message:
- Brick Breaker! It's okay
Changed in this revision
diff -r 000000000000 -r 099e4258aba4 4DGL-uLCD-SE.lib --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/4DGL-uLCD-SE.lib Tue Oct 21 16:14:11 2014 +0000 @@ -0,0 +1,1 @@ +http://developer.mbed.org/users/hotwheelharry/code/4DGL-uLCD-SE/#932d76a5b290
diff -r 000000000000 -r 099e4258aba4 Game.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Game.h Tue Oct 21 16:14:11 2014 +0000 @@ -0,0 +1,382 @@ +#include <vector> +#include "Graphics.h" +#include <cmath> +#include <string> +#include <sstream> + + +float frand(){ + return (float)rand()/(float)RAND_MAX; +} +double round(double d) +{ + return floor(d + 0.5); +} + +class Melody{ + public: + std::vector<float> notes; +}; + +class Audio{ +private: + Mutex mutex; + AnalogOut& audio; +public: + Audio(AnalogOut& ao) : audio(ao) + { + } + + void playSong(Melody& s){ + mutex.lock(); + + mutex.unlock(); + } + void triggerShot(){ + mutex.lock(); + + mutex.unlock(); + } + void run(){ + while(true){ + + Thread::wait(100); //ms + } + } +}; + +class Controller{ +public: + + AnalogIn& sliderh; + AnalogIn& sliderv; + DigitalIn& button; +public: + Controller(AnalogIn& sliderh, AnalogIn& sliderv, DigitalIn& btn) : sliderh(sliderh), sliderv(sliderv), button(btn) + { + + } +}; + + + +class Physics{ +private: + +public: + float dt; + + void step(Scene& scene){ + Block& b = scene.ball; + + if(b.locked) + { + b.store_prev(); + b.updated = true; + b.next_coord.x = scene.paddle.coord.x + scene.paddle.size.x/2.0 - b.size.x/2.0; + b.next_coord.y = scene.paddle.coord.y - b.size.y - 1; + b.next_velocity.x = 0; + b.next_velocity.y = 0; + + b.next_swap(); + return; + } + + + //move things + if(b.velocity.x != 0 || b.velocity.y != 0) + { + b.store_prev(); + b.updated = true; + b.next_coord.x = b.coord.x + dt * b.velocity.x; + b.next_coord.y = b.coord.y + dt * b.velocity.y; + + b.next_velocity.x = b.velocity.x; + b.next_velocity.y = b.velocity.y; + } + + if( b.coord.x < 0) + { + b.next_coord.x = 0; + b.next_velocity.x = b.velocity.x * -1.0; + } + if( b.coord.x + b.size.x > 128){ + b.next_coord.x = 128-b.size.x; + b.next_velocity.x = b.velocity.x * -1.0; + } + + if(b.coord.y < 0) + { + b.next_coord.y = 0; + b.next_velocity.y = b.velocity.y * -1.0; + } + + //collision with blocks + int hitcount = 0; + for(std::list<Block>::iterator j = scene.blocks.begin(); j != scene.blocks.end(); j++){ + if(j->color == 0x444444){ + hitcount++; + } + if( j->interactive && b.touching( *j ) ){ + bool h = false; + bool v = false; + + //from right + if( b.coord.x > j->coord.x && b.coord.x < (j->coord.x + j->size.x) ){ + b.next_coord.x = j->coord.x + j->size.x; + b.next_velocity.x = b.next_velocity.x * -1.0; + h = true; + } + //from left + if(b.coord.x + b.size.x > j->coord.x && b.coord.x < (j->coord.x) ){ + b.next_coord.x = j->coord.x - b.size.x; + b.next_velocity.x = b.next_velocity.x * -1.0; + h = true; + } + + // from top + if( b.coord.y + b.size.y > j->coord.y && b.coord.y < (j->coord.y) ){ + b.next_coord.y = (j->coord.y - b.size.y); + b.next_velocity.y = b.next_velocity.y * -1.0; + b.next_coord.x = b.coord.x; + v = true; + } + //from bottom + if( b.coord.y < j->coord.y + j->size.y && b.coord.y + b.size.y > (j->coord.y) ){ + b.next_coord.y = (j->coord.y + j->size.y); + b.next_velocity.y = b.next_velocity.y * -1.0; + b.next_coord.x = b.coord.x; + v = true; + } + + if(h || v){ + + j->color = 0x444444; + j->updated = true; + j->interactive = false; + } + + + + + + + scene.score++; + std::stringstream ss; + ss << "Score:" << scene.score; + scene.text[0].message = ss.str(); + scene.text[0].updated = true; + + } + else{ + b.color = WHITE; + } + } + + if(hitcount == scene.blocks.size()){ + scene.beat = true; + } + + + + //collision with paddle + if(b.next_coord.y + b.size.y > scene.paddle.coord.y && b.next_coord.y - b.velocity.y < scene.paddle.coord.y + && (b.next_coord.x + b.size.x > scene.paddle.coord.x && b.next_coord.x < scene.paddle.coord.x + scene.paddle.size.x)){ + if(!b.locked){ + float pmid = scene.paddle.coord.x + scene.paddle.size.x/2.0; + float bmid = b.next_coord.x + b.size.x/2.0; + float d = bmid - pmid; + b.next_velocity.x = b.velocity.x + d/(scene.paddle.size.x/2.0) * 30.0; + if(b.next_velocity.x > 50) + { b.next_velocity.x = 50; } + if(b.next_velocity.x < -50) + { b.next_velocity.x = -50;} + + b.next_velocity.y = (b.velocity.y * -1.0) * 1.01; + b.next_coord.x = b.coord.x; + b.next_coord.y = scene.paddle.next_coord.y - b.size.y - 1; + } + } + + + //update all the new positions + b.next_swap(); + + }; + +}; + + +class Game{ +private: + Renderer& renderer; + Audio& audio; + Controller& controller; + + Physics physics; + Scene scene; + + int level; + + Scene menu; + +public: + Game(Renderer& renderer, Audio& aud, Controller& ctrl) + : renderer(renderer), audio(aud), controller(ctrl) + { + level = 0; + scene.bg = Color((int)renderer.background); + + buildScene(); + physics.dt = 0.1; + } + +private: + void buildMenu(){ + + } + void buildScene(){ + + scene.lives = 3; + scene.score = 0; + scene.beat = false; + + // build bricks + float vertical = 10; + float spacing = 2; + vec2 bgrid = {5,3}; + vec2 bsize; + bsize.x = (renderer.screen.x-spacing) / (bgrid.x) - 2; + bsize.y = 4; + + int colorscheme = level; + + for(int i = 0; i < bgrid.x; i++){ + for(int j = 0; j < bgrid.y; j++){ + Block b; + b.velocity.x = 0; + b.velocity.y = 0; + b.size = bsize; + b.coord.x = spacing + (bsize.x + spacing)*i; + b.coord.y = spacing + (bsize.y + spacing)*j + vertical; + b.copy(); + b.color = RED; + switch(colorscheme){ + case 0: b.color = Color(0x66+round(0x99*((float)(bgrid.y-j)/(float)bgrid.y)),0,0); + break; + case 1: b.color = Color(0,0x66+round(0x99*((float)(bgrid.y-j)/(float)bgrid.y)), 0); + break; + case 2: b.color = Color(0,0,0x66+round(0x99*((float)(bgrid.y-j)/(float)bgrid.y))); + break; + case 3: b.color = Color(round(0xff*(frand())), + round(0xff*(frand())), + round(0xff*(frand())) + ); + break; + + default: b.color = RED; + } + scene.blocks.push_back(b); + } + } + + Block pad; + pad.locked = true; + pad.size.x = renderer.screen.x / 4.0; + pad.size.y = 4; + pad.coord.x = renderer.screen.x / 4.0 + pad.size.x / 2.0; + pad.coord.y = renderer.screen.y - spacing - pad.size.y; + pad.copy(); + pad.color = WHITE; + scene.paddle = pad; + + + Block b; + b.size.x = 4; + b.size.y = 4; + b.coord.x = pad.coord.x + pad.size.x/2.0 - b.size.x/2.0; + b.coord.y = pad.coord.y - b.size.y - 1; + b.color = WHITE; + b.locked = true; + b.copy(); + scene.ball = b; + + Text tscore; + tscore.coord.x = renderer.screen.x / 6 - 12; + tscore.coord.y = 0; + tscore.font = FONT_7X8; + tscore.color = WHITE; + tscore.message = "Score:0"; + scene.text.push_back(tscore); + + Text tlives; + tlives.coord.x = 0; + tlives.coord.y = 0; + tlives.font = FONT_7X8; + tlives.color = WHITE; + tlives.message = "Lives:3"; + scene.text.push_back(tlives); + } + void getInput(){ + float pos = controller.sliderh; + scene.paddle.store_prev(); + scene.paddle.coord.x = (renderer.screen.x - scene.paddle.size.x - 4) * pos + 2; + scene.paddle.updated = true; + + Block& b = scene.ball; + if(b.locked) + { + if(controller.button ){ + b.locked = false; + b.velocity.y = -80.0; + } + } + } + void gameLogic(){ + if(scene.ball.coord.y > renderer.screen.y){ + scene.lives--; + std::stringstream ss; + ss << "Lives:" << scene.lives; + scene.text[1].message = ss.str(); + scene.text[1].updated = true; + + scene.ball.locked = true; + } + + if(scene.lives == 0){ + scene = Scene(); + level = 0; + buildScene(); + + renderer.g.filled_rectangle(0, 0, 128, 10, renderer.background); + } + + if(scene.beat){ + level++; + scene.ball.store_prev(); + Block cb = scene.ball; + + int score = scene.score; + scene = Scene(); + buildScene(); + scene.score = score; + std::stringstream ss; + ss << "Score:" << scene.score; + scene.text[0].message = ss.str(); + scene.text[0].updated = true; + + renderer.g.filled_rectangle(cb.coord.x, cb.coord.y, cb.coord.x+cb.size.x, cb.coord.y+cb.size.y, renderer.background); + renderer.g.filled_rectangle(0, 0, 128, 10, renderer.background); + + } + } +public: + void loop(){ + getInput(); + gameLogic(); + physics.step(scene); + renderer.render(scene); + } + +}; +
diff -r 000000000000 -r 099e4258aba4 Graphics.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Graphics.h Tue Oct 21 16:14:11 2014 +0000 @@ -0,0 +1,195 @@ +#include <vector> +#include <string> +#include <list> + +struct vec2 { + float x; + float y; +}; + +class Physics; +class Renderer; + +class Color{ + public: + unsigned char r; + unsigned char g; + unsigned char b; + + Color() : r(0), g(0), b(0) + {} + Color(unsigned char r, unsigned char g, unsigned char b) : r(r), g(g), b(b) + {} + Color(int c) : r( (c & 0xff0000) >> 16), g( (c & 0xff00) >> 8), b(c & 0xff) + {} + + operator int(){ + int c = 0; + return c | (r << 2*8) | (g << 8) | b; + } +}; + + +class Block{ +friend Physics; +friend Renderer; + +private: + + + vec2 next_coord; + vec2 next_size; + vec2 next_velocity; + +public: + bool updated; + bool locked; //fixed position + bool interactive; //collidable in physics + bool render; + vec2 coord; + vec2 size; + vec2 velocity; + Color color; + + vec2 prev_coord; + vec2 prev_size; + + Block() : updated(true), locked(false), interactive(true), render(true) + { + coord.x = 0; + coord.y = 0; + velocity.x = 0; + velocity.y = 0; + color = RED; + size.x = 2; + size.y = 2; + } + + virtual bool touching(const Block& b){ + if ( coord.x < b.coord.x + b.size.x && + coord.x + size.x > b.coord.x && + coord.y < b.coord.y + b.size.y && + size.y + coord.y > b.coord.y + ) + { + if(this == &b){ + return false; + } + return true; + } + return false; + } + virtual void next_swap(){ + coord = next_coord; + size = next_size; + velocity = next_velocity; + } + void store_prev(){ + prev_coord = coord; + prev_size = size; + } + void copy(){ + prev_coord = coord; + prev_size = size; + + next_coord = coord; + next_size = size; + next_velocity = velocity; + } +}; + +class Text{ + public: + bool updated; + std::string message; + vec2 coord; + Color color; + int font; + Text() : color(0xffffff), updated(true) + { + } +}; +class Scene{ +public: + int lives; + int score; + bool beat; + + Color bg; + + Block paddle; + Block ball; + std::list<Block> blocks; + std::vector<Text> text; +}; + + +class Renderer{ +private: +public: + uLCD_4DGL& g; + Color background; + vec2 screen; + + Renderer(uLCD_4DGL& gfx, vec2 screen) : g(gfx), screen(screen) + { + } + void render(Scene s){ + //g.cls(); + + // draw blocks + for(std::list<Block>::iterator b = s.blocks.begin(); b != s.blocks.end(); b++){ + if(b->updated){ + //draw over where it was + //g.filled_rectangle(b->prev_coord.x, b->prev_coord.y, b->prev_coord.x+b->prev_size.x, b->prev_coord.y+b->prev_size.y, background); //x1,y1,x2,y2,color + //draw new location + g.filled_rectangle(b->coord.x, b->coord.y, b->coord.x+b->size.x, b->coord.y+b->size.y, b->color); //x1,y1,x2,y2,color + + b->updated = false; + } + } + + + + //draw paddle + { + Block* b = &(s.paddle); + if(b->updated){ + //draw over where it was + g.filled_rectangle(b->prev_coord.x, b->prev_coord.y, b->prev_coord.x+b->prev_size.x, b->prev_coord.y+b->prev_size.y, background); //x1,y1,x2,y2,color + //draw new location + g.filled_rectangle(b->coord.x, b->coord.y, b->coord.x+b->size.x, b->coord.y+b->size.y, b->color); //x1,y1,x2,y2,color + + b->updated = false; + } + } + + + //draw ball + { + Block* b = &(s.ball); + if(b->updated){ + //draw over where it was + g.filled_rectangle(b->prev_coord.x, b->prev_coord.y, b->prev_coord.x+b->prev_size.x, b->prev_coord.y+b->prev_size.y, background); //x1,y1,x2,y2,color + //draw new location + g.filled_rectangle(b->coord.x, b->coord.y, b->coord.x+b->size.x, b->coord.y+b->size.y, b->color); //x1,y1,x2,y2,color + + b->updated = false; + } + } + + + //draw text + for(size_t i = 0; i < s.text.size(); i++){ + Text& t = s.text[i]; + if(t.updated){ + g.set_font(t.font); + g.color(t.color); + g.locate(t.coord.x, t.coord.y); + g.printf(t.message.c_str()); + t.updated = false; + } + } + + } +}; \ No newline at end of file
diff -r 000000000000 -r 099e4258aba4 main.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Tue Oct 21 16:14:11 2014 +0000 @@ -0,0 +1,46 @@ +#include "mbed.h" +#include "rtos.h" +#include "uLCD_4DGL.h" + +#include "Game.h" + + +//already defined +//#define SIZE_X 128 +//#define SIZE_Y 128 + +//display +uLCD_4DGL lcd(p28,p27,p29); // serial tx, serial rx, reset pin; + +//inputs +AnalogIn sliderh(p17); +AnalogIn sliderv(p19); +DigitalIn button(p20); + +//outputs +AnalogOut aout(p18); + +//game objects +Controller controller(sliderh, sliderv, button); +vec2 screen = {SIZE_X, SIZE_Y}; +Renderer gfx(lcd, screen); +Audio audio(aout); +Game game(gfx, audio, controller); + + +void thread_audio( void const *args ){ + audio.run(); +} +int main() { + lcd.baudrate(3000000); + gfx.background = Color(0x444444); + lcd.background_color(gfx.background); + lcd.cls(); + + Thread t_audio(thread_audio); //start the audio + + while(true){ + game.loop(); + //Thread::wait(10); + } +} \ No newline at end of file
diff -r 000000000000 -r 099e4258aba4 mbed-rtos.lib --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-rtos.lib Tue Oct 21 16:14:11 2014 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/mbed_official/code/mbed-rtos/#aaa1b2c7c64c
diff -r 000000000000 -r 099e4258aba4 mbed.bld --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed.bld Tue Oct 21 16:14:11 2014 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/mbed_official/code/mbed/builds/552587b429a1 \ No newline at end of file