bool Region::intersects(const Region& region) const { if (!m_bounds.intersects(region.m_bounds)) return false; // FIXME: this could be optimized. Region tempRegion(*this); tempRegion.intersect(region); return !tempRegion.isEmpty(); }
bool RegionTestcase::RegionsAreEqual(BRegion *regionA, BRegion *regionB) { bool result = false; if (regionA->CountRects() == regionB->CountRects()) { bool gotAMatch = true; for(int i = 0; i < regionA->CountRects(); i++) { gotAMatch = false; for(int j = 0; j < regionB->CountRects(); j++) { if (regionA->RectAt(i) == regionB->RectAt(j)) { gotAMatch = true; break; } } if (!gotAMatch) { break; } } if (gotAMatch) { result = true; } } if (!result) { BRegion tempRegion(*regionA); tempRegion.Exclude(regionB); if (RegionIsEmpty(&tempRegion)) { tempRegion = *regionB; tempRegion.Exclude(regionA); if (RegionIsEmpty(&tempRegion)) { result = true; } } } if (result) { assert(regionA->Frame() == regionB->Frame()); if (regionA->CountRects() == 0) { assert(RegionIsEmpty(regionA)); assert(RegionIsEmpty(regionB)); } } return(result); }
void StateBadVista::update() { const int LOGO_SIDE = logo.getWidth() / 2; const int LOGO_TOP = logo.getHeight() / 2; arm.setScaleX(1); arm.setScaleY(1); arm.setRotation(-armAngle); logo.setScaleX(1); logo.setScaleY(1); logo.setRotation(-armAngle * 0.5f); if(bvState == BV_WINDUP) { float radians = armAngle * 3.14159f / 180.0f; logo.setPosition( (int) LOGO_INIT_X + (armAngle * 0.25f) - (50 * sin(radians)), (int) LOGO_INIT_Y - 100 + (100 * cos(radians))); return; } if(bvState == BV_PITCHED) { // Calculate motion region #ifdef PENJIN_FIXED SimpleRegion tempRegion(logoX, logoY, fixedpoint::fix2int(logoX + logoVelocityX), fixedpoint::fix2int(logoY + logoVelocityY)); #else SimpleRegion tempRegion(logoX, logoY, logoX + logoVelocityX, logoY + logoVelocityY); #endif SimpleRegion motion( tempRegion.x1() - LOGO_SIDE, tempRegion.y1() - LOGO_TOP, tempRegion.x2() + LOGO_SIDE, tempRegion.y2() + LOGO_TOP); if (hitObstacle(horizontalObstacles, motion)) { if (bounce.isPlaying()) bounce.stop(); bounce.play(); logoVelocityX *= BOUNCE_DECAY; logoVelocityY *= BOUNCE_DECAY; logoVelocityY *= -1; numBounces++; } if (hitObstacle(verticalObstacles, motion)) { if (bounce.isPlaying()) bounce.stop(); bounce.play(); logoVelocityX *= BOUNCE_DECAY; logoVelocityY *= BOUNCE_DECAY; logoVelocityX *= -1; } // Sometimes the ball gets caught inside the side of the litter can: // neither inside nor out. The following two paragraphs seek to prevent // that. if (hitObstacle(basketLeft, motion)) { bounce.play(); logoVelocityX *= BOUNCE_DECAY; logoVelocityY *= BOUNCE_DECAY; if (logoX >= BASKET_LEFT_INSIDE && logoVelocityX < 0) logoVelocityX *= -1; if (logoX < BASKET_LEFT_INSIDE && logoVelocityX > 0) logoVelocityX *= -1; } if (hitObstacle(basketRight, motion)) { bounce.play(); logoVelocityX *= BOUNCE_DECAY; logoVelocityY *= BOUNCE_DECAY; if (logoX >= BASKET_RIGHT_INSIDE && logoVelocityX < 0) logoVelocityX *= -1; if (logoX < BASKET_RIGHT_INSIDE && logoVelocityX > 0) logoVelocityX *= -1; } if (hitObstacle(playerObstacle, motion)) { init(); return; } SimpleRegion logoPosition(logoX - LOGO_SIDE, logoY - LOGO_TOP, logoX + LOGO_SIDE, logoY + LOGO_TOP); // Check for end of game if (ballStopped()) { bool won = inBasket(); variables[0].setValue(won ? 1 : 0); if (won) bvState = BV_WON; else bvState = BV_LOST; counter.start(); } // Ensure gravity doesn't overcome the bounce decay if (inBasket()) { // Once the logo enters the basket, don't let it bounce out float newYPos = GRAVITY + logoVelocityY + logoY + LOGO_TOP; if (logoVelocityY < 1 && BASKET_BOT - logoY < LOGO_TOP + 5) { logoVelocityY = 0; logoVelocityX = 0; logoY = BASKET_BOT - LOGO_TOP; } else if (BASKET_TOP < newYPos && newYPos < BASKET_BOT) logoVelocityY += GRAVITY; else if (newYPos > BASKET_BOT) logoVelocityY = BASKET_BOT - logoY - LOGO_TOP; else logoVelocityY = BASKET_TOP - logoY - LOGO_TOP; } else { if (GRAVITY + logoVelocityY + logoY + LOGO_TOP < FLOOR) logoVelocityY += GRAVITY; else logoVelocityY = FLOOR - logoY - LOGO_TOP; } #ifdef PENJIN_FIXED logoY += fixedpoint::fix2int(logoVelocityY); logoX += fixedpoint::fix2int(logoVelocityX); #else logoY += logoVelocityY; logoX += logoVelocityX; #endif logo.setPosition(logoX - LOGO_SIDE, logoY - LOGO_TOP); return; } if(bvState == BV_LOST) { if(pwned) { bounce.loadSound("music/BadVista/chimes.ogg"); bounce.play(); backsound.stop(); backsound.loadMusic("music/BadVista/pp.bv.windows.e.egg.ogg"); backsound.setLooping(false); backsound.play(); if (pwned_count < PWNED_PWNED) loserBackground.loadSprite("images/BadVista/stopped.jpg"); else loserBackground.loadSprite("images/BadVista/lost.png"); bvState = BV_PWNED; } else if(counter.getScaledTicks() > END_DELAY) setNextState(STATE_MAIN); } if(bvState == BV_WON) { if(counter.getScaledTicks() > END_DELAY) setNextState(STATE_MAIN); } if(bvState == BV_PWNED) { if(counter.getScaledTicks() > LOSER_DELAY && !backsound.isPlaying()) setNextState(STATE_MAIN); } }
void RegionExclude::CheckExclude(BRegion *resultRegion, BRegion *testRegionA, BRegion *testRegionB) { bool resultRegionEmpty = RegionIsEmpty(resultRegion); bool testRegionAEmpty = RegionIsEmpty(testRegionA); bool testRegionBEmpty = RegionIsEmpty(testRegionB); if (RegionsAreEqual(testRegionA, testRegionB)) { assert(resultRegionEmpty); } if (RegionsAreEqual(resultRegion, testRegionA)) { BRegion tempRegion(*testRegionA); tempRegion.IntersectWith(testRegionB); assert(RegionIsEmpty(&tempRegion)); } if (RegionsAreEqual(resultRegion, testRegionB)) { assert(resultRegionEmpty); assert(testRegionAEmpty); assert(testRegionBEmpty); } if ((!resultRegionEmpty) && (!testRegionAEmpty) && (!testRegionBEmpty)) { BRect resultRegionFrame(resultRegion->Frame()); BRect testRegionAFrame(testRegionA->Frame()); BRect testRegionBFrame(testRegionB->Frame()); if (!testRegionAFrame.Intersects(testRegionBFrame)) { assert(testRegionAFrame == resultRegionFrame); assert(RegionsAreEqual(resultRegion, testRegionA)); } else { assert(testRegionAFrame.Contains(resultRegionFrame)); } } if (testRegionBEmpty) { assert(RegionsAreEqual(resultRegion, testRegionA)); } else { assert(!RegionsAreEqual(resultRegion, testRegionB)); for(int i = 0; i < testRegionB->CountRects(); i++) { BRect tempRect = testRegionB->RectAt(i); assert(testRegionB->Intersects(tempRect)); assert(!resultRegion->Intersects(tempRect)); BPoint *pointArray; int numPoints = GetPointsInRect(tempRect, &pointArray); for (int j = 0; j < numPoints; j++) { assert(testRegionB->Contains(pointArray[j])); assert(!resultRegion->Contains(pointArray[j])); } } } if (testRegionAEmpty) { assert(resultRegionEmpty); } else { for(int i = 0; i < testRegionA->CountRects(); i++) { BRect tempRect = testRegionA->RectAt(i); assert(testRegionA->Intersects(tempRect)); if (!testRegionB->Intersects(tempRect)) { assert(resultRegion->Intersects(tempRect)); } BPoint *pointArray; int numPoints = GetPointsInRect(tempRect, &pointArray); for (int j = 0; j < numPoints; j++) { assert(testRegionA->Contains(pointArray[j])); if (testRegionB->Contains(pointArray[j])) { assert(!resultRegion->Contains(pointArray[j])); } else { assert(resultRegion->Contains(pointArray[j])); } } } } if (resultRegionEmpty) { BRegion tempRegion(*testRegionA); tempRegion.IntersectWith(testRegionB); assert(RegionsAreEqual(&tempRegion, testRegionA)); } else { assert(!RegionsAreEqual(resultRegion, testRegionB)); for(int i = 0; i < resultRegion->CountRects(); i++) { BRect tempRect = resultRegion->RectAt(i); assert(resultRegion->Intersects(tempRect)); assert(testRegionA->Intersects(tempRect)); assert(!testRegionB->Intersects(tempRect)); BPoint *pointArray; int numPoints = GetPointsInRect(tempRect, &pointArray); for (int j = 0; j < numPoints; j++) { assert(resultRegion->Contains(pointArray[j])); assert(testRegionA->Contains(pointArray[j])); assert(!testRegionB->Contains(pointArray[j])); } } } }