Kostadin Chakarov / Mbed 2 deprecated el17kec

Dependencies:   mbed

Revision:
8:9b77eea95088
Parent:
7:cd3cafda3dd4
Child:
9:f720f5d87420
--- a/Map/Map.cpp	Wed Apr 10 09:18:25 2019 +0000
+++ b/Map/Map.cpp	Wed May 08 13:49:01 2019 +0000
@@ -1,13 +1,15 @@
 #include "Map.h"
 #include "Ball.h"
 
+// Levels
+
 void Level1::initBricks(Map & map)
 {
     int w = 41;
     int h = 2;
     int gap = 1;
     int y = 0;
-    for (int j = 0; j < 7; ++j) {
+    for (int j = 0; j < 9; ++j) {
         int x = 0;
         for (int i = 0; i < 2; ++i) {
             Brick b;
@@ -25,14 +27,14 @@
 
 void Level2::initBricks(Map & map)
 {
-    int w = 5;
-    int h = 1;
+    int w = 20;
+    int h = 2;
     int gap = 1;
     int y = 0;
 
-    for (int j = 0; j < 15; ++j) {
+    for (int j = 0; j < 9; ++j) {
         int x = 0;
-        for (int i = 0; i < 14; ++i) {
+        for (int i = 0; i < 4; ++i) {
             Brick b;
             b.x = x;
             b.y = y;
@@ -47,7 +49,88 @@
 }
 
 
-// Constructor
+// Power-Ups
+
+  
+//                      rows,cols
+int powerUpPaddleSizeSprite[PowerUpH][PowerUpW] =   {
+    { 0,1,0 },
+    { 1,1,1 },
+    { 0,1,0 },
+    { 1,1,1 }
+};
+
+//                      rows,cols
+int powerUpPaddleSpeedSprite[PowerUpH][PowerUpW] =   {
+    { 0,1,0 },
+    { 0,1,0 },
+    { 1,1,1 },
+    { 1,1,1 }
+};
+
+//                      rows,cols
+int powerUpBallSpeedSprite[PowerUpH][PowerUpW] =   {
+    { 0,1,0 },
+    { 1,1,1 },
+    { 1,1,1 },
+    { 0,1,0 }
+};
+
+void PowerUpType::draw(N5110 &lcd, PowerUp &pUp) {
+    //printf("%f, %f; %d,%d - %d\n", pUp.getPos().x,pUp.getPos().y,pUp.getH(),pUp.getW(), (int)((int*)sprite));
+    lcd.drawSprite(pUp.getPos().x,pUp.getPos().y,pUp.getH(),pUp.getW(), (int*)sprite);
+}
+
+PowerUpType* PowerUpTypes[3] = {
+    new PaddleSizePUpType(0, *powerUpPaddleSizeSprite),
+    new PaddleSpeedPUpType(1, *powerUpPaddleSpeedSprite),
+    new BallSpeedPUpType(2, *powerUpBallSpeedSprite)
+};
+
+PowerUp::PowerUp(float x, float y, PowerUpType& pUpType) : _pUpType(&pUpType)
+ {
+    pos.x = x;
+    pos.y = y;
+    velocity.x = 0;
+    velocity.y = 0.5f;
+    w = PowerUpW;
+    h = PowerUpH;
+}
+
+
+void PowerUp::draw(N5110 &lcd) {
+    //printf("powerup %.02f , %.02f, %d\n", pos.x, pos.y, powerUpSprite[0][2]);
+    _pUpType->draw(lcd, *this);
+}
+
+void PaddleSizePUpType::giveBonus(Paddle &paddle, Ball &ball) {
+    int add = 2;
+    paddle.setW(paddle.getW()+add);
+}
+
+void PaddleSpeedPUpType::giveBonus(Paddle &paddle, Ball &ball) {
+    float add = 0.2f;
+    paddle.setSpeed(paddle.getSpeed() + add);
+}
+
+void BallSpeedPUpType::giveBonus(Paddle &paddle, Ball &ball) {
+    float multiply = 0.9f;
+    Vector2D& v = ball.getVelocity();
+    
+    // 1. create variable speed = magnitude (length) of v
+    // 2. change speed by ...
+    // 3. Then normalize v and multiply by speed
+    float oldSpeed = sqrt(v.x*v.x + v.y*v.y);
+    float speed = oldSpeed * multiply;
+    
+    v.x = (v.x / oldSpeed) * speed;
+    v.y = (v.y / oldSpeed) * speed;
+    
+}
+
+// Map
+
+/** Constructor */
 Map::Map()
 {
     levels.push_back(new Level1());
@@ -56,7 +139,7 @@
 }
 
 
-// Destructor
+/** Destructor */
 Map::~Map()
 {
 
@@ -66,17 +149,22 @@
 {
     bricks.clear();
 
-    Level* level = levels[currentLevel];
+    Level *level = levels[currentLevel];
     level->initBricks(*this);
 }
 
 void Map::drawMap(N5110 &lcd)
-{
+{   
     vector<Brick>::size_type end = bricks.size();
     for (int i = 0; i < end; i++) {
         const Brick& b = bricks[i];
         lcd.drawRect(b.x,b.y,b.w,b.h,FILL_BLACK);
     }
+    
+    
+    for (int i = 0; i < powerUps.size(); i++) {
+        powerUps[i].draw(lcd);
+    }
 }
 //See: https://stackoverflow.com/questions/31022269/collision-detection-between-two-rectangles-in-java
 bool rectIntersect(
@@ -125,10 +213,6 @@
     //float cx = b.x + b.w/2.0f;
     float cy = b.y + b.h/2.0f;
 
-    // distance between ball and rectangle center
-    //float dx = x - cx;
-    //float dy = y - cy;
-
     Vector2D &vel = obj.getVelocity();
     float thresh = 0.1;
     if (x > rightX - thresh) {
@@ -154,18 +238,67 @@
     }
 }
 
-void Map::checkCollision(GameObject &obj)
+void Map::checkCollision(Ball &ball, Paddle &paddle)
 {
+    // check bricks
     vector<Brick>::size_type end = bricks.size();
     for (int i = 0; i < end; i++) {
         const Brick& b = bricks[i];
         if (rectIntersect(b.x, b.y, b.w, b.h,
-                          obj.getPos().x, obj.getPos().y, obj.getW(), obj.getH())) {
-            resolveCollision(b, obj);
+                          ball.getPos().x, ball.getPos().y, ball.getW(), ball.getH())) {
+            // brick collision event!
+            
+            // bounce the ball
+            resolveCollision(b, ball);
+            
+            // (maybe) spawn power-up
+            onBrickHit(b);
+            
+            // remove brick
             bricks.erase(bricks.begin() + i);
+            
             break;
+        
         }
     }
+    
+    /** check power ups */
+    for (int i = 0; i < powerUps.size(); i++) 
+    {
+        PowerUp& p = powerUps[i];
+        /** use rectIntersect to check for collisions between power-up and pad */
+        if (rectIntersect(p.getPos().x, p.getPos().y, p.getW(), p.getH(),
+                          paddle.getPos().x, paddle.getPos().y, paddle.getW(), paddle.getH())) {
+            
+            p.giveBonus(paddle, ball);
+                            
+            powerUps.erase(&p);
+            break;             
+        }
+                          
+    }
+}
+
+void Map::onBrickHit(const Brick& brick) {
+    if ((rand() % 100) < PowerUpDropChancePct) {
+        // spawn power up
+        int type = rand() % 3;  // each power up has the same rarity
+        
+        //printf("Power up - t=%d", type);
+        PowerUpType& pUpType = *PowerUpTypes[type];
+        
+        //printf(", pUpType=%d\n", pUpType.type);
+        
+        powerUps.push_back( 
+            PowerUp(brick.x+(brick.w/2)-PowerUpW/2, brick.y, pUpType)
+        );
+       }
+}
+
+void Map::update() {
+    for (int i = 0; i < powerUps.size(); i++) {
+        powerUps[i].move();
+    }
 }
 
 bool Map::checkLevel()
@@ -173,7 +306,7 @@
     if (bricks.size() == 0) {
         // cleared level
         ++currentLevel;
-        printf("cleared level! %d %d\n", currentLevel, hasWon());
+        // printf("cleared level! %d %d\n", currentLevel, hasWon());
         if (!hasWon()) {
             // initialize next level
             initBricks();
@@ -187,4 +320,5 @@
 {
     currentLevel = 0;
     initBricks();
+    powerUps.clear();
 }
\ No newline at end of file