void solveBrickBallCollision(Brick& mBrick, Ball& mBall) noexcept { if(!isIntersecting(mBrick, mBall)) return; // Invece di distruggere immediatemente il mattoncino, // decrementiamo prima la sua "vita". --mBrick.requiredHits; if(mBrick.requiredHits <= 0) mBrick.destroyed = true; auto overlapLeft(mBall.right() - mBrick.left()); auto overlapRight(mBrick.right() - mBall.left()); auto overlapTop(mBall.bottom() - mBrick.top()); auto overlapBottom(mBrick.bottom() - mBall.top()); auto bFromLeft(std::abs(overlapLeft) < std::abs(overlapRight)); auto bFromTop(std::abs(overlapTop) < std::abs(overlapBottom)); auto minOverlapX(bFromLeft ? overlapLeft : overlapRight); auto minOverlapY(bFromTop ? overlapTop : overlapBottom); if(std::abs(minOverlapX) < std::abs(minOverlapY)) mBall.velocity.x = std::abs(mBall.velocity.x) * (bFromLeft ? -1.f : 1.f); else mBall.velocity.y = std::abs(mBall.velocity.y) * (bFromTop ? -1.f : 1.f); }
static void solveBrickBallCollision(Brick& mBrick, Ball& mBall) noexcept { if (!isIntersecting(mBrick, mBall)) return; // Instead of immediately destroying the brick upon collision, // we decrease and check its required hits first. --mBrick.requiredHits; if (mBrick.requiredHits <= 0) mBrick.destroyed = true; float overlapLeft{mBall.right() - mBrick.left()}; float overlapRight{mBrick.right() - mBall.left()}; float overlapTop{mBall.bottom() - mBrick.top()}; float overlapBottom{mBrick.bottom() - mBall.top()}; bool ballFromLeft(std::abs(overlapLeft) < std::abs(overlapRight)); bool ballFromTop(std::abs(overlapTop) < std::abs(overlapBottom)); float minOverlapX{ballFromLeft ? overlapLeft : overlapRight}; float minOverlapY{ballFromTop ? overlapTop : overlapBottom}; if (std::abs(minOverlapX) < std::abs(minOverlapY)) mBall.velocity.x = ballFromLeft ? -Ball::defVelocity : Ball::defVelocity; else mBall.velocity.y = ballFromTop ? -Ball::defVelocity : Ball::defVelocity; }
void solvePaddleBallCollision(const Paddle& mPaddle, Ball& mBall) noexcept { if(!isIntersecting(mPaddle, mBall)) return; mBall.velocity.y = -Ball::defVelocity; mBall.velocity.x = mBall.x() < mPaddle.x() ? -Ball::defVelocity : Ball::defVelocity; }
void Game::testCollision(Paddle& mPaddle, Ball& mBall) { if (!isIntersecting(mPaddle, mBall)) return; mBall.velocity.y = -ballVelocity; if (mPaddle.velocity.x == -paddleVelocity && mBall.velocity.x == ballVelocity) mBall.velocity.x = -ballVelocity; else if (mPaddle.velocity.x == paddleVelocity && mBall.velocity.x == -ballVelocity) mBall.velocity.x = ballVelocity; }
int GameUI::update(core::Siika2D *siika, Boss *boss) { if (ushiko.health < heartCount) changeTexture(heartIcons[ushiko.health], siika, "ui_heart_hurt.png",glm::vec2(64,64)); else if (ushiko.health > heartCount) changeTexture(heartIcons[ushiko.health - 1], siika, "ui_heart_pink.png", glm::vec2(64, 64)); heartCount = ushiko.health; if (boss != nullptr && boss->bossHealth != bossHeartCount) { changeTexture(bossHeartIcons[boss->bossHealth], siika, "ui_bosslifebar_hearthurt.png", glm::vec2(64, 64)); bossHeartCount = boss->bossHealth; } if (boss == nullptr) { std::stringstream pointsText; pointsText << ushiko.pointsAmount << "/" << levelPoints; pointsTextUI->setText(pointsText.str()); } glm::vec2 touchPosition = glm::vec2(0, 0); if (inputTimer.getElapsedTime(SECONDS) > 0.5) { for (int i = 0; i < siika->_input->touchPositionsActive(); i++) touchPosition = siika->_input->touchPosition(i)._positionStart; if (isIntersecting(touchPosition, pauseButton->getComponent<misc::TransformComponent>()->getPosition())) { inputTimer.reset(); if (lastState == RESUME) { changeTexture(pauseButton, siika, "ui_playbutton.png", glm::vec2(128,128)); shade->setPosition(glm::vec2(0, 0)); lastState = PAUSE; return PAUSE; } else { changeTexture(pauseButton, siika, "ui_pausebutton.png", glm::vec2(128, 128)); shade->setPosition(glm::vec2(0, siika->_graphicsContext->getDisplaySize().y)); lastState = RESUME; return RESUME; } } } return DEFAULT; }
void solvePaddleBallCollision(const Paddle& mPaddle, Ball& mBall) noexcept { if(!isIntersecting(mPaddle, mBall)) return; auto newY(mPaddle.top() - mBall.shape.getRadius() * 2.f); mBall.shape.setPosition(mBall.x(), newY); auto paddleBallDiff(mBall.x() - mPaddle.x()); auto posFactor(paddleBallDiff / mPaddle.width()); auto velFactor(mPaddle.velocity.x * 0.05f); sf::Vector2f collisionVec{posFactor + velFactor, -2.f}; mBall.velocity = getReflected(mBall.velocity, getNormalized(collisionVec)); }
// Now, let's also define a function that will executed every game // frame. This function will check if a paddle and a ball are // colliding, and if they are it will resolve the collision by // making the ball go upwards and in the direction opposite to the // collision. void solvePaddleBallCollision(const Paddle& mPaddle, Ball& mBall) noexcept { // If there's no intersection, exit the function. if(!isIntersecting(mPaddle, mBall)) return; // Otherwise let's "push" the ball upwards. mBall.velocity.y = -Ball::defVelocity; // And let's direct it dependently on the position where the // paddle was hit. // If the ball's center was to the left of the paddle's center, // the ball will move towards the left. Otherwise, it will move // towards the right. // {Info: ball vs paddle collision} mBall.velocity.x = mBall.x() < mPaddle.x() ? -Ball::defVelocity : Ball::defVelocity; }
void Game::testCollision(Brick& mBrick, Ball& mBall) { if (!isIntersecting(mBrick, mBall)) return; mBrick.destroyed = true; float overLapLeft{ mBall.right() - mBrick.left() }; float overLapRight{ mBrick.right() - mBall.left() }; float overLapTop{ mBall.bottom() - mBrick.top() }; float overLapBottom{ mBrick.bottom() - mBall.top() }; bool ballFromLeft(abs(overLapLeft) < abs(overLapRight)); bool ballFromTop(abs(overLapTop) < abs(overLapBottom)); float minOverlapX{ ballFromLeft ? overLapLeft : overLapRight }; float minOverlapY{ ballFromTop ? overLapTop : overLapBottom }; if (abs(minOverlapX) < abs(minOverlapY)) mBall.velocity.x = ballFromLeft ? -ballVelocity : ballVelocity; else mBall.velocity.y = ballFromTop ? -ballVelocity : ballVelocity; }
void solveBrickBallCollision(Brick& mBrick, Ball& mBall) noexcept { if(!isIntersecting(mBrick, mBall)) return; mBrick.destroyed = true; auto overlapLeft(mBall.right() - mBrick.left()); auto overlapRight(mBrick.right() - mBall.left()); auto overlapTop(mBall.bottom() - mBrick.top()); auto overlapBottom(mBrick.bottom() - mBall.top()); auto bFromLeft(std::abs(overlapLeft) < std::abs(overlapRight)); auto bFromTop(std::abs(overlapTop) < std::abs(overlapBottom)); auto minOverlapX(bFromLeft ? overlapLeft : overlapRight); auto minOverlapY(bFromTop ? overlapTop : overlapBottom); if(std::abs(minOverlapX) < std::abs(minOverlapY)) mBall.velocity.x = std::abs(mBall.velocity.x) * (bFromLeft ? -1.f : 1.f); else mBall.velocity.y = std::abs(mBall.velocity.y) * (bFromTop ? -1.f : 1.f); }
void solveBrickBallCollision(Brick& mBrick, Ball& mBall) noexcept { if(!isIntersecting(mBrick, mBall)) return; mBrick.destroyed = true; float overlapLeft{mBall.right() - mBrick.left()}; float overlapRight{mBrick.right() - mBall.left()}; float overlapTop{mBall.bottom() - mBrick.top()}; float overlapBottom{mBrick.bottom() - mBall.top()}; bool ballFromLeft(std::abs(overlapLeft) < std::abs(overlapRight)); bool ballFromTop(std::abs(overlapTop) < std::abs(overlapBottom)); float minOverlapX{ballFromLeft ? overlapLeft : overlapRight}; float minOverlapY{ballFromTop ? overlapTop : overlapBottom}; if(std::abs(minOverlapX) < std::abs(minOverlapY)) mBall.velocity.x = ballFromLeft ? -Ball::defVelocity : Ball::defVelocity; else mBall.velocity.y = ballFromTop ? -Ball::defVelocity : Ball::defVelocity; }
void BbqGeoRefdTerrainRenderer<HeightType, HeightDeltaType, TextureType >::render( BbqTerrNode *rootNode, const BbqRenderOptions &options ) { _oStatistics.nodeCount = 0; _oStatistics.triangleCount = 0; traversalStack_.push_back(rootNode); // activate the shader: // glUseProgramObjectARB( terrainShader_.getProgramHandle() ); // terrainShader_.activate(options.pDrawEnv); // fprintf(stderr, "Frame start\n"); while(!traversalStack_.empty()) { BbqTerrNode *node = traversalStack_.back(); assert(node); traversalStack_.pop_back(); #ifdef GV_CHECK // cull this node->. if( options.enableFrustumCulling && !isIntersecting( options.frustum, node->boundingBox ) ) { // not visible at all _oStatistics.culledNodeCount++; continue; } #endif const Real32 detailFactor = options.screenSpaceError; //todo: i need to use the distance to Pnt3f bboxCenter; Vec3f dist; node->boundingBox.getCenter(bboxCenter); /* fprintf(stderr, "%d %f %f %f\n", node->id, bboxCenter[0], bboxCenter[1], bboxCenter[2]); */ dist = options.viewerpos - bboxCenter; const float distance = osgMax(dist.length(), 0.001f); // const float distance = osgMax( // getMagnitude( options.frustum.getPosition() - // node->boundingBox.getCenter() ), 0.001f ); //// todo: instead of the size of the node, use the maximum error bound Vec3f bboxSize; node->boundingBox.getSize(bboxSize); // const float nodeSize = node->boundingBox.getSize().x; const float nodeSize = bboxSize.x(); // const float fovY = options.frustum.getFovY(); const float fovY = options.fovy; const float screenResolution = float( options.screenSize.y() ) / fovY; #if 0 //Unused const float nodeError = screenResolution * ( ( nodeSize / float( _oDatabaseInfo.heightTileSize ) ) / distance ); const float objectSpaceHeightError = float( node->maxHeightError ) / 32767.0f * _oDatabaseInfo.heightScale + _oDatabaseInfo.heightOffset; // 65535.0f * _oDatabaseInfo.heightScale + _oDatabaseInfo.heightOffset; const float screenSpaceHeightError = ( objectSpaceHeightError / distance ) * screenResolution; const float screenFactor = float( options.screenSize.y() ) / ( 2.0f * tanf( fovY / 2.0f ) ); const float screenSpaceHeightError2 = ( objectSpaceHeightError / distance ) * screenFactor; const float switchDistance2 = ( objectSpaceHeightError / detailFactor ) * screenFactor; #endif // todo: geomorphing geht noch nicht richtig... Vec3f disp = options.viewerpos - bboxCenter; // options.frustum.getPosition() - node->boundingBox.getCenter(); // Vec3f extent = node->boundingBox.getSize(); Vec3f extent; node->boundingBox.getSize(extent); disp[0] = osgMax( 0.0f, fabsf( disp.x() ) - extent.x() ); disp[1] = osgMax( 0.0f, fabsf( disp.y() ) - extent.y() ); disp[2] = osgMax( 0.0f, fabsf( disp.z() ) - extent.z() ); // disp.y = 0; // for debugging // float d = 0; // d = osgSqrt( dot( disp, disp ) ); // d = osgSqrt( disp.dot(disp) ); // float // const float tan_half_FOV = tanf(0.5f * horizontal_FOV_degrees // * (float) M_PI / 180.0f); // // const float K = screen_width_pixels / tan_half_FOV; // // distance_LODmax is the distance below which we need to be // // at the maximum LOD. It's used in compute_lod(), which is // // called by the chunks during update(). // m_distance_LODmax = ; // return fmax(1, d / (objectSpaceHeightError / detailFactor) * K); //} //float switchDistance2 = ( objectSpaceHeightError / detailFactor ) * //screenFactor; //float switchDistance = ( objectSpaceHeightError / detailFactor ) * //screenFactor; float switchDistance = ( nodeSize / float( _oDatabaseInfo.heightTileSize ) ) / detailFactor * screenResolution; float geomorphStartDistance = switchDistance + 145.0f; //const bool hasEnoughDetail = nodeError < detailFactor; /* fprintf(stderr, "%f | %f\n", distance, geomorphStartDistance); */ if( node->isLeafNode() || distance > geomorphStartDistance ) { // render the node: #ifndef GV_TEST Inherited::setGeoMorphingFactor( node ); #else _oTerrainShader.setUniform( "geoMorphFactor", options.geoMorphFactor ); #endif renderNodeVbo( node, options.showSkirts, options ); if( options.showBoundingBoxes ) { glColor3f( 0, 0, 1 ); this->renderBoundingBox( node->boundingBox, options ); } if( options.showSwitchDistance ) { // Pnt3f bboxCenter; node->boundingBox.getCenter(bboxCenter); glColor3f( 0, 1, 0 ); Inherited::renderSphere(bboxCenter , switchDistance, options ); } } else { // compute the geomorphing factor: //const float innerSwitchDistance = switchDistance - //switchDistance / 4.0f; node->geoMorphingFactor = clamp( 1.0f - ( switchDistance - distance ) / ( geomorphStartDistance - switchDistance ), 0.0f, 1.0f ); //node->geoMorphingFactor = 1.0f; // push the child nodes: // todo: push the nearest child last.. (to get a rough front to // back rendering order) static int order[ 4 ] = { 0, 1, 2, 3 }; //static float dist[ 4 ]; //if( options.sortChildren ) //{ // for( int i = 0; i < 4; ++i ) // { // dist[ i ] = getMagnitude( node->children[ i //]->boundingBox.getCenter() - options.frustum.getPosition() ); // for( int j = 0; j < i; ++j ) // { // if( dist[ i ] < // } // } //} traversalStack_.push_back( node->children[ order[ 0 ] ] ); traversalStack_.push_back( node->children[ order[ 1 ] ] ); traversalStack_.push_back( node->children[ order[ 2 ] ] ); traversalStack_.push_back( node->children[ order[ 3 ] ] ); } } glColor3f(1.f, 0.f, 0.f); glBegin(GL_QUADS); { glVertex3f(rootNode->boundingBox.getMin().x(), 0.f, rootNode->boundingBox.getMin().z()); glVertex3f(rootNode->boundingBox.getMax().x(), 0.f, rootNode->boundingBox.getMin().z()); glVertex3f(rootNode->boundingBox.getMax().x(), 0.f, rootNode->boundingBox.getMax().z()); glVertex3f(rootNode->boundingBox.getMin().x(), 0.f, rootNode->boundingBox.getMax().z()); } glEnd(); static bool dumpBox = false; if(dumpBox == false) { fprintf(stderr, "%f %f | %f %f\n", rootNode->boundingBox.getMin().x(), rootNode->boundingBox.getMin().z(), rootNode->boundingBox.getMax().x(), rootNode->boundingBox.getMax().z()); dumpBox = true; } // glUseProgramObjectARB( 0 ); // _oTerrainShader.deactivate(options.pDrawEnv); }