Brick Breaker

Dependencies:   4DGL-uLCD-SE mbed-rtos mbed

Files at this revision

API Documentation at this revision

Comitter:
hotwheelharry
Date:
Tue Oct 21 16:14:11 2014 +0000
Commit message:
Brick Breaker! It's okay

Changed in this revision

4DGL-uLCD-SE.lib Show annotated file Show diff for this revision Revisions of this file
Game.h Show annotated file Show diff for this revision Revisions of this file
Graphics.h Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
mbed-rtos.lib Show annotated file Show diff for this revision Revisions of this file
mbed.bld Show annotated file Show diff for this revision Revisions of this file
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