Elements used in the Balls and Things games for the RETRO.
Dependents: RETRO_BallsAndPaddle RETRO_BallAndHoles
Ball.cpp@3:441dc90d10ce, 2015-02-26 (annotated)
- Committer:
- maxint
- Date:
- Thu Feb 26 11:46:46 2015 +0000
- Revision:
- 3:441dc90d10ce
- Parent:
- 2:74bc9b16fb88
- Child:
- 5:065f19e08dcb
added line shape and collision methods
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
maxint | 0:3d0db4e183ee | 1 | #include "Ball.h" |
maxint | 0:3d0db4e183ee | 2 | |
maxint | 0:3d0db4e183ee | 3 | Ball::Ball() : vSpeed() |
maxint | 0:3d0db4e183ee | 4 | { // constructor |
maxint | 0:3d0db4e183ee | 5 | } |
maxint | 0:3d0db4e183ee | 6 | |
maxint | 0:3d0db4e183ee | 7 | Ball::Ball(LCD_ST7735* pDisp) : vSpeed() |
maxint | 0:3d0db4e183ee | 8 | { // constructor |
maxint | 0:3d0db4e183ee | 9 | this->pDisp=pDisp; |
maxint | 0:3d0db4e183ee | 10 | this->fActive=false; |
maxint | 0:3d0db4e183ee | 11 | } |
maxint | 0:3d0db4e183ee | 12 | |
maxint | 0:3d0db4e183ee | 13 | uint16_t Ball::dimmedColor(uint16_t uColor) |
maxint | 0:3d0db4e183ee | 14 | { |
maxint | 0:3d0db4e183ee | 15 | uint16_t r, g, b; |
maxint | 0:3d0db4e183ee | 16 | |
maxint | 0:3d0db4e183ee | 17 | r=(uColor >> 11) <<3; |
maxint | 0:3d0db4e183ee | 18 | g=((uColor >> 5) & 0x3F) <<2; |
maxint | 0:3d0db4e183ee | 19 | b=(uColor & 0x1F) << 3; |
maxint | 0:3d0db4e183ee | 20 | r=r*2/3; |
maxint | 0:3d0db4e183ee | 21 | g=g*2/3; |
maxint | 0:3d0db4e183ee | 22 | b=b*2/3; |
maxint | 0:3d0db4e183ee | 23 | // r=r/2; |
maxint | 0:3d0db4e183ee | 24 | // g=g/2; |
maxint | 0:3d0db4e183ee | 25 | // b=b/2; |
maxint | 0:3d0db4e183ee | 26 | |
maxint | 0:3d0db4e183ee | 27 | return(Color565::fromRGB((uint16_t)r,(uint16_t)g,(uint16_t)b)); |
maxint | 0:3d0db4e183ee | 28 | } |
maxint | 0:3d0db4e183ee | 29 | |
maxint | 0:3d0db4e183ee | 30 | void Ball::initialize(int nX, int nY, int nR, uint16_t uColor) |
maxint | 0:3d0db4e183ee | 31 | { |
maxint | 0:3d0db4e183ee | 32 | this->pos.set(nX, nY); |
maxint | 0:3d0db4e183ee | 33 | this->nRadius=nR; |
maxint | 0:3d0db4e183ee | 34 | this->uColor=uColor; |
maxint | 0:3d0db4e183ee | 35 | this->uColorHigh=uColor; |
maxint | 0:3d0db4e183ee | 36 | this->uColorMid=dimmedColor(uColorHigh); |
maxint | 0:3d0db4e183ee | 37 | this->uColorLow=dimmedColor(uColorMid); |
maxint | 0:3d0db4e183ee | 38 | |
maxint | 0:3d0db4e183ee | 39 | } |
maxint | 0:3d0db4e183ee | 40 | |
maxint | 0:3d0db4e183ee | 41 | void Ball::setSpeed(int X, int Y) |
maxint | 0:3d0db4e183ee | 42 | { |
maxint | 0:3d0db4e183ee | 43 | this->vSpeed.set(X, Y); |
maxint | 0:3d0db4e183ee | 44 | } |
maxint | 0:3d0db4e183ee | 45 | |
maxint | 0:3d0db4e183ee | 46 | void Ball::changeSpeed(bool fUp) |
maxint | 0:3d0db4e183ee | 47 | { |
maxint | 0:3d0db4e183ee | 48 | if(fUp) |
maxint | 0:3d0db4e183ee | 49 | { |
maxint | 0:3d0db4e183ee | 50 | if(this->vSpeed.getSize()<=4.0) this->vSpeed.add(1.0); |
maxint | 0:3d0db4e183ee | 51 | } |
maxint | 0:3d0db4e183ee | 52 | else |
maxint | 0:3d0db4e183ee | 53 | { |
maxint | 0:3d0db4e183ee | 54 | if(this->vSpeed.getSize()>=1.0) |
maxint | 0:3d0db4e183ee | 55 | this->vSpeed.add(-1.0); |
maxint | 0:3d0db4e183ee | 56 | else // TODO: added code below to allow zero speed pause of ball |
maxint | 0:3d0db4e183ee | 57 | this->vSpeed.set(0,0); |
maxint | 0:3d0db4e183ee | 58 | } |
maxint | 0:3d0db4e183ee | 59 | } |
maxint | 0:3d0db4e183ee | 60 | |
maxint | 0:3d0db4e183ee | 61 | void Ball::unmove() |
maxint | 0:3d0db4e183ee | 62 | { // move back to previous position |
maxint | 0:3d0db4e183ee | 63 | pos.set(pos.getPrev()); |
maxint | 0:3d0db4e183ee | 64 | } |
maxint | 0:3d0db4e183ee | 65 | |
maxint | 0:3d0db4e183ee | 66 | void Ball::update() |
maxint | 0:3d0db4e183ee | 67 | { |
maxint | 0:3d0db4e183ee | 68 | this->pos.move(this->vSpeed); |
maxint | 0:3d0db4e183ee | 69 | } |
maxint | 0:3d0db4e183ee | 70 | |
maxint | 0:3d0db4e183ee | 71 | Circle Ball::getBoundingCircle() |
maxint | 0:3d0db4e183ee | 72 | { |
maxint | 0:3d0db4e183ee | 73 | return(Circle(this->pos.getX(), this->pos.getY(), this->nRadius)); |
maxint | 0:3d0db4e183ee | 74 | } |
maxint | 0:3d0db4e183ee | 75 | |
maxint | 0:3d0db4e183ee | 76 | bool Ball::collides(Rectangle r) |
maxint | 0:3d0db4e183ee | 77 | { |
maxint | 0:3d0db4e183ee | 78 | Circle cBall=this->getBoundingCircle(); |
maxint | 0:3d0db4e183ee | 79 | Rectangle rBall=cBall.getBoundingRectangle(); |
maxint | 0:3d0db4e183ee | 80 | |
maxint | 0:3d0db4e183ee | 81 | /* |
maxint | 0:3d0db4e183ee | 82 | char szBuffer[256]; |
maxint | 0:3d0db4e183ee | 83 | sprintf(szBuffer, "c:%d,%d ", cBall.getX(), cBall.getY()); |
maxint | 0:3d0db4e183ee | 84 | this->pDisp->drawString(font_oem, 0, 0, szBuffer); |
maxint | 0:3d0db4e183ee | 85 | */ |
maxint | 0:3d0db4e183ee | 86 | return(rBall.collides(r)); |
maxint | 0:3d0db4e183ee | 87 | } |
maxint | 0:3d0db4e183ee | 88 | |
maxint | 3:441dc90d10ce | 89 | bool Ball::collides(Line ln) |
maxint | 3:441dc90d10ce | 90 | { |
maxint | 3:441dc90d10ce | 91 | Circle cBall=this->getBoundingCircle(); |
maxint | 3:441dc90d10ce | 92 | return(cBall.collides(ln)); |
maxint | 3:441dc90d10ce | 93 | } |
maxint | 3:441dc90d10ce | 94 | |
maxint | 0:3d0db4e183ee | 95 | void Ball::Bounce(Vector vBounce) |
maxint | 0:3d0db4e183ee | 96 | { // change the direction in a certain direction |
maxint | 0:3d0db4e183ee | 97 | this->unmove(); // undo move to pre-bouncing position to avoid drawing on colliding position |
maxint | 0:3d0db4e183ee | 98 | |
maxint | 0:3d0db4e183ee | 99 | this->vSpeed.multiply(vBounce); |
maxint | 2:74bc9b16fb88 | 100 | //this->vSpeed.bounce(vBounce); |
maxint | 0:3d0db4e183ee | 101 | |
maxint | 0:3d0db4e183ee | 102 | // check speed w/max |
maxint | 0:3d0db4e183ee | 103 | if(this->vSpeed.y>5.0) this->vSpeed.y=5; |
maxint | 2:74bc9b16fb88 | 104 | if(this->vSpeed.x>5.0) this->vSpeed.x=5; |
maxint | 2:74bc9b16fb88 | 105 | if(this->vSpeed.y<-5.0) this->vSpeed.y=-5; |
maxint | 2:74bc9b16fb88 | 106 | if(this->vSpeed.x<-5.0) this->vSpeed.x=-5; |
maxint | 2:74bc9b16fb88 | 107 | } |
maxint | 2:74bc9b16fb88 | 108 | |
maxint | 2:74bc9b16fb88 | 109 | void Ball::BounceAgainst(Vector vBounce) |
maxint | 2:74bc9b16fb88 | 110 | { // change the direction in a certain direction |
maxint | 2:74bc9b16fb88 | 111 | this->unmove(); // undo move to pre-bouncing position to avoid drawing on colliding position |
maxint | 2:74bc9b16fb88 | 112 | |
maxint | 2:74bc9b16fb88 | 113 | //this->vSpeed.multiply(vBounce); |
maxint | 2:74bc9b16fb88 | 114 | this->vSpeed.bounce(vBounce); |
maxint | 2:74bc9b16fb88 | 115 | |
maxint | 2:74bc9b16fb88 | 116 | // check speed w/max |
maxint | 2:74bc9b16fb88 | 117 | if(this->vSpeed.y>5.0) this->vSpeed.y=5; |
maxint | 2:74bc9b16fb88 | 118 | if(this->vSpeed.x>5.0) this->vSpeed.x=5; |
maxint | 2:74bc9b16fb88 | 119 | if(this->vSpeed.y<-5.0) this->vSpeed.y=-5; |
maxint | 2:74bc9b16fb88 | 120 | if(this->vSpeed.x<-5.0) this->vSpeed.x=-5; |
maxint | 2:74bc9b16fb88 | 121 | |
maxint | 2:74bc9b16fb88 | 122 | if(abs(vSpeed.x)>abs(vSpeed.y)) |
maxint | 2:74bc9b16fb88 | 123 | vSpeed.x=vSpeed.x/abs(vSpeed.x) * abs(vSpeed.y); |
maxint | 2:74bc9b16fb88 | 124 | |
maxint | 2:74bc9b16fb88 | 125 | /* |
maxint | 2:74bc9b16fb88 | 126 | if(this->vSpeed.y>0 && this->vSpeed.y<1.0) this->vSpeed.y=1; |
maxint | 2:74bc9b16fb88 | 127 | if(this->vSpeed.x>0 && this->vSpeed.x<1.0) this->vSpeed.x=1; |
maxint | 2:74bc9b16fb88 | 128 | if(this->vSpeed.y<0 && this->vSpeed.y>-1.0) this->vSpeed.y=-1; |
maxint | 2:74bc9b16fb88 | 129 | if(this->vSpeed.x<0 && this->vSpeed.x>-1.0) this->vSpeed.x=-1; |
maxint | 2:74bc9b16fb88 | 130 | */ |
maxint | 0:3d0db4e183ee | 131 | } |
maxint | 0:3d0db4e183ee | 132 | |
maxint | 0:3d0db4e183ee | 133 | |
maxint | 0:3d0db4e183ee | 134 | |
maxint | 0:3d0db4e183ee | 135 | void Ball::clear() |
maxint | 0:3d0db4e183ee | 136 | { |
maxint | 0:3d0db4e183ee | 137 | Point p=pos.getCur(); |
maxint | 0:3d0db4e183ee | 138 | this->pDisp->fillCircle(p.getX(),p.getY(), this->nRadius, Color565::Black, Color565::Black); |
maxint | 0:3d0db4e183ee | 139 | } |
maxint | 0:3d0db4e183ee | 140 | |
maxint | 0:3d0db4e183ee | 141 | void Ball::clearPrev() |
maxint | 0:3d0db4e183ee | 142 | { |
maxint | 0:3d0db4e183ee | 143 | Point p=pos.getPrev(); |
maxint | 0:3d0db4e183ee | 144 | this->pDisp->fillCircle(p.getX(),p.getY(), this->nRadius, Color565::Black, Color565::Black); |
maxint | 0:3d0db4e183ee | 145 | } |
maxint | 0:3d0db4e183ee | 146 | |
maxint | 0:3d0db4e183ee | 147 | |
maxint | 0:3d0db4e183ee | 148 | void Ball::draw() |
maxint | 0:3d0db4e183ee | 149 | { // render the object on the screen, based on its current position |
maxint | 0:3d0db4e183ee | 150 | Point p=pos.getCur(); |
maxint | 0:3d0db4e183ee | 151 | if(this->nRadius>3) |
maxint | 0:3d0db4e183ee | 152 | { |
maxint | 0:3d0db4e183ee | 153 | this->pDisp->fillCircle(p.getX(), p.getY(), this->nRadius, this->uColorLow, this->uColorLow); |
maxint | 0:3d0db4e183ee | 154 | this->pDisp->fillCircle(p.getX()-this->nRadius/3, p.getY()-this->nRadius/3, this->nRadius/2, this->uColorMid, this->uColorMid); |
maxint | 0:3d0db4e183ee | 155 | this->pDisp->setPixel(p.getX()-this->nRadius/2, p.getY()-this->nRadius/2, this->uColorHigh); |
maxint | 0:3d0db4e183ee | 156 | } |
maxint | 0:3d0db4e183ee | 157 | else |
maxint | 0:3d0db4e183ee | 158 | this->pDisp->fillCircle(p.getX(), p.getY(), this->nRadius, this->uColorMid, this->uColorMid); |
maxint | 0:3d0db4e183ee | 159 | } |
maxint | 0:3d0db4e183ee | 160 | |
maxint | 0:3d0db4e183ee | 161 | void Ball::redraw() |
maxint | 0:3d0db4e183ee | 162 | { // redraw the ball if its position has changed |
maxint | 0:3d0db4e183ee | 163 | if(pos.hasChanged()) |
maxint | 0:3d0db4e183ee | 164 | { |
maxint | 0:3d0db4e183ee | 165 | clearPrev(); |
maxint | 0:3d0db4e183ee | 166 | draw(); |
maxint | 0:3d0db4e183ee | 167 | } |
maxint | 0:3d0db4e183ee | 168 | } |