Elements used in the Balls and Things games for the RETRO.

Dependents:   RETRO_BallsAndPaddle RETRO_BallAndHoles

Ball.cpp

Committer:
maxint
Date:
2015-03-02
Revision:
8:19dd2a538cbe
Parent:
7:4fa3edaa1201

File content as of revision 8:19dd2a538cbe:

#include "Ball.h"

Ball::Ball() : vSpeed()
{   // constructor
}

Ball::Ball(LCD_ST7735* pDisp) : vSpeed()
{   // constructor
    this->pDisp=pDisp;
    this->fActive=false;
}

uint16_t Ball::dimmedColor(uint16_t uColor)
{
    uint16_t r, g, b;
   
    r=(uColor >> 11) <<3;
    g=((uColor >> 5) & 0x3F) <<2;
    b=(uColor & 0x1F) << 3;
    r=r*2/3;
    g=g*2/3;
    b=b*2/3;

    return(Color565::fromRGB((uint16_t)r,(uint16_t)g,(uint16_t)b));
}

void Ball::initialize(int nX, int nY, int nR, uint16_t uColor)
{
    this->pos.set(nX, nY);
    this->nRadius=nR;
    this->uColor=uColor;
    this->uColorHigh=uColor;
    this->uColorMid=dimmedColor(uColorHigh);
    this->uColorLow=dimmedColor(uColorMid);

}

void Ball::setSpeed(int X, int Y)
{
    this->vSpeed.set(X, Y);
}

void Ball::changeSpeed(bool fUp)
{
    if(fUp)
    {
        if(this->vSpeed.getSize()<=4.0) this->vSpeed.add(1.0);
    }
    else
    {
        if(this->vSpeed.getSize()>=1.0)
            this->vSpeed.add(-1.0);
        else        // TODO: added code below to allow zero speed pause of ball
            this->vSpeed.set(0,0);
    }
}

void Ball::unmove()
{   // move back to previous position
    pos.set(pos.getPrev());
}

void Ball::update()
{
    this->pos.move(this->vSpeed);
}

Circle Ball::getBoundingCircle()
{
    return(Circle(this->pos.getX(), this->pos.getY(), this->nRadius));
}

bool Ball::collides(Rectangle r)
{
    Circle cBall=this->getBoundingCircle();
    Rectangle rBall=cBall.getBoundingRectangle();

/*    
char szBuffer[256];
sprintf(szBuffer, "c:%d,%d      ", cBall.getX(), cBall.getY());
this->pDisp->drawString(font_oem, 0, 0, szBuffer);
*/
    return(rBall.collides(r));
}

bool Ball::collides(Circle cObject)
{
    Circle cBall=this->getBoundingCircle();
    Rectangle rBall=cBall.getBoundingRectangle();
    Rectangle rObject=cObject.getBoundingRectangle();

    return(rBall.collides(rObject));
}


bool Ball::collides(Line ln)
{
    Circle cBall=this->getBoundingCircle();
    return(cBall.collides(ln));
}

void Ball::Bounce(Vector vBounce)
{   // change the direction in a certain direction
    this->unmove(); // undo move to pre-bouncing position to avoid drawing on colliding position

    this->vSpeed.multiply(vBounce);

    // check speed w/max
    if(this->vSpeed.y>5.0) this->vSpeed.y=5;
    if(this->vSpeed.x>5.0) this->vSpeed.x=5;
    if(this->vSpeed.y<-5.0) this->vSpeed.y=-5;
    if(this->vSpeed.x<-5.0) this->vSpeed.x=-5;
}

void Ball::BounceAgainst(Vector vBounce)
{   // change the direction in a certain direction
    this->unmove(); // undo move to pre-bouncing position to avoid drawing on colliding position

    //this->vSpeed.multiply(vBounce);
    this->vSpeed.bounce(vBounce);

    // check speed w/max
    if(this->vSpeed.y>5.0) this->vSpeed.y=5;
    if(this->vSpeed.x>5.0) this->vSpeed.x=5;
    if(this->vSpeed.y<-5.0) this->vSpeed.y=-5;
    if(this->vSpeed.x<-5.0) this->vSpeed.x=-5;

//    if(abs(vSpeed.x)>abs(vSpeed.y))
//        vSpeed.x=vSpeed.x/abs(vSpeed.x) * abs(vSpeed.y);
}



void Ball::clear()
{
    Point p=pos.getCur();
    this->pDisp->fillCircle(p.getX(),p.getY(), this->nRadius, Color565::Black, Color565::Black);
}

void Ball::clearPrev()
{
    Point p=pos.getPrev();
    this->pDisp->fillCircle(p.getX(),p.getY(), this->nRadius, Color565::Black, Color565::Black);
}


void Ball::draw()
{   // render the object on the screen, based on its current position
    Point p=pos.getCur();
    if(this->nRadius>3)
    {
        this->pDisp->fillCircle(p.getX(), p.getY(), this->nRadius, this->uColorLow, this->uColorLow);
        this->pDisp->fillCircle(p.getX()-this->nRadius/3, p.getY()-this->nRadius/3, this->nRadius/2, this->uColorMid, this->uColorMid);
        this->pDisp->setPixel(p.getX()-this->nRadius/2, p.getY()-this->nRadius/2, this->uColorHigh);
    }
    else
        this->pDisp->fillCircle(p.getX(), p.getY(), this->nRadius, this->uColorMid, this->uColorMid);
}

void Ball::redraw()
{   // redraw the ball if its position has changed
    if(pos.hasChanged())
    {
        clearPrev();
        draw();
    }
}