void MainState::Update() { // Moves the player in the specified direction if (m_PlayerDirState[kPlayerDirLeft]) { m_Player->TranslateBy(Vec2(-5.0, 0.0)); } else if (m_PlayerDirState[kPlayerDirRight]) { m_Player->TranslateBy(Vec2(5.0, 0.0)); } else if (m_PlayerDirState[kPlayerDirUp]) { m_Player->TranslateBy(Vec2(0.0, -5.0)); } else if (m_PlayerDirState[kPlayerDirDown]) { m_Player->TranslateBy(Vec2(0.0, 5.0)); } for (int i = 0; i < m_ProjectileArray.GetSize(); ++i) { Rect screenRect = m_EnginePtr->GetScene()->GetScreenRect(); Projectile* projectile = m_ProjectileArray[i]; Vec2 pos = projectile->GetWorldPosition(); if (pos.GetX() < screenRect.GetX() || pos.GetX() > (screenRect.GetX() + screenRect.GetW()) || pos.GetY() < screenRect.GetY() || pos.GetY() > (screenRect.GetY() + screenRect.GetH())) { LOG_PRINT("removed"); } } }
/** * Returns true if the given box is directly above the ground */ bool MovementMap::IsOnGround(const Rect box) { // Checks the lower limit if (!IsZero(box.Center().GetX(), box.GetY()+box.GetH()+1)) return true; // Checks the lower-right limit if (!IsZero(box.GetX()+box.GetW(), box.GetY()+box.GetH()+1)) return true; // Checks the lower-left limit if (!IsZero(box.GetX(), box.GetY()+box.GetH()+1)) return true; return false; }
/** * Corrects the box position relative to a given tileBox * and the previous position of the box. */ void MovementMap::CorrectCollision(Rect& box, Rect tileBox) { if (!Collision::IsColliding(box, tileBox, 0, 0)) return; // If the previous position was to the left of the tile if (previousPos.GetX()+previousPos.GetW() <= tileBox.GetX()) box.MoveRect(tileBox.GetX() - (box.GetX()+box.GetW()), 0); // If the previous position was to the right of the tile else if (previousPos.GetX() >= tileBox.GetX()+tileBox.GetW()) box.MoveRect((tileBox.GetX()+tileBox.GetW()) - box.GetX(), 0); // If the previous position was below the tile else if (previousPos.GetY() > tileBox.GetY()) box.MoveRect(0, tileBox.GetY()+tileBox.GetH() - box.GetY()); // If the previous position was above the tile else box.MoveRect(0, tileBox.GetY()-(box.GetY()+box.GetH())); }
Vec2 CollisionDetector::AABBToAABB(const Rect& rect1, const Rect& rect2) { // Prevents false collision if either rects has no width and height if ((rect1.GetW() == 0 && rect1.GetH() == 0) || (rect2.GetW() == 0 && rect2.GetH() == 0)) { return Vec2(0.0, 0.0); } Vec2 min1(rect1.GetX(), rect1.GetY()); Vec2 max1(rect1.GetX() + rect1.GetW(), rect1.GetY() + rect1.GetH()); Vec2 min2(rect2.GetX(), rect2.GetY()); Vec2 max2(rect2.GetX() + rect2.GetW(), rect2.GetY() + rect2.GetH()); if ((max1.GetX() < min2.GetX()) || (max1.GetY() < min2.GetY())) { return Vec2(0.0, 0.0); } if ((max2.GetX() < min1.GetX()) || (max2.GetY() < min1.GetY())) { return Vec2(0.0, 0.0); } // Potential resolution offsets double negX = max1.GetX() - min2.GetX(); double posX = max2.GetX() - min1.GetX(); double negY = max1.GetY() - min2.GetY(); double posY = max2.GetY() - min1.GetY(); // Returns the component vector that needs the least offset to resolve the collision if (negX <= posX && negX <= negY && negX <= posY) { return Vec2(-negX, 0.0); } else if (posX <= negY && posX <= posY) { return Vec2(posX, 0.0); } else if (negY <= posY) { return Vec2(0.0, -negY); } else { return Vec2(0.0, posY); } return Vec2(0.0, 0.0); }
void WidgetTableWidget::UpdateTableImpl() { SettlerMap::Iterator iter = _settlers.Begin(); for (; !!iter; ++iter) { Rect clientrect = ClientRect( iter.Key().x, iter.Key().y ); Rect boundrect = iter.Value()._settler->GetBoundingRect(); Rect area = boundrect.Align( clientrect, iter.Value()._alignment ) ; Widget *p_child = iter.Value()._settler; DirtyLock guard_dirty(p_child); p_child->SetPosition( Pos( area.GetX(), area.GetY() ) ); } SetDimensions( GetWidth(), GetHeight() ); }
bool Hud::DrawPoints(float alpha) { Rect rect = mTextRect; Uint32 temp = gpStory->GetPoints() * gpPlayer->GetLives(); Uint16 size = mFont.mSize; string text; bool ret; /* Draw background */ mScreenRect.Draw(mScreenColor, alpha); /* Generate string */ text = str(format("Points X Life") ); rect.SetY(rect.GetY() + size); /* Draw string */ ret = DrawString(text, mTextColor, rect, true); if (!ret) return false; /* Generate string */ text = str(format("%d X %d = %d") % gpStory->GetPoints() % gpPlayer->GetLives() % temp ); rect.SetY(rect.GetY() - size); /* Draw string */ ret = DrawString(text, mTextColor, rect, true); if (!ret) return false; /* Generate string */ text = str(format("Total score: %03d") % gpPlayer->GetScore()); rect.SetY(rect.GetY() - size); /* Draw string */ ret = DrawString(text, mTextColor, rect, true); if (!ret) return false; return true; }
/*! Place self inside parents-client area. * Proportions are rect.{x|y|w|h} / base.{x|y|x|y}. * If base.{x|y}==0 then position and size in {X|Y} direction will be preserved. */ void Widget::Place ( const Rect &rect, const Pos &base) { Rect client_area = GetParent()->GetClientRect( this); Rect my_rect = GetBoundingRect() + GetPosition(); double x = my_rect.GetX(); double y = my_rect.GetY(); double w = my_rect.GetW(); double h = my_rect.GetH(); if ( base.x > 0) { x = as_double( client_area.GetW() * rect.GetX() ) / as_double( base.x ); } if ( base.y > 0) { y = as_double( client_area.GetH() * rect.GetY() ) / as_double( base.y ); } if ( base.x > 0) { w = as_double( client_area.GetW() * rect.GetW() ) / as_double( base.x ); } if ( base.y > 0) { h = as_double( client_area.GetH() * rect.GetH() ) / as_double( base.y ); } SetPosition( client_area.GetPos() + Pos( std::floor(x), std::floor(y) )); Resize( std::ceil(w), std::ceil(h) ); }
bool WidgetTableWidget::Insert( int column, int row, Widget *client, int align_flg ) { Rect::Alignment align = Rect::Alignment(align_flg); if ( column < GetNumColumns() && row < GetNumRows() && !Settled( column, row) ) { Rect area = client->GetBoundingRect().Align( ClientRect( column, row), align ) ; Cell cell; cell._alignment = align; cell._settler = client; _settlers.Insert( Pos(column,row), cell); _placement.Insert( client, Pos(column,row) ); HubWidget::Insert( client, area.GetX(), area.GetY() ); return true; } else { assert(!"No such column or row"); return false; } }
/** * Returns a vector of Rects corresponding to the tiles * that are colliding with the given box */ std::vector<Rect> MovementMap::GetCollidingTiles(const Rect& box) { std::vector<Rect> collidingTiles; // Check the upper point if (!IsZero(box.GetX()+box.GetW()/2, box.GetY())) collidingTiles.push_back(TileToRect(box.GetX(), box.GetY())); // Check the right point if (!IsZero(box.GetX()+box.GetW(), box.GetY()+box.GetH()/2)) collidingTiles.push_back(TileToRect(box.GetX()+box.GetW(), box.GetY())); // Check the left point if (!IsZero(box.GetX(), box.GetY()+box.GetH()/2)) collidingTiles.push_back(TileToRect(box.GetX(), box.GetY()+box.GetH())); // Check the lower point if (!IsZero(box.GetX()+box.GetW()/2, box.GetY()+box.GetH())) collidingTiles.push_back(TileToRect(box.GetX()+box.GetW(), box.GetY()+box.GetH())); // for (int i = 0; i < collidingTiles.size(); i++) // { // std::cout << std::endl; // std::cout << "(" << collidingTiles[i].GetX() << "," << collidingTiles[i].GetY() << ")" << std::endl; // std::cout << "Width: " << collidingTiles[i].GetW() << " Height: " << collidingTiles[i].GetH() << std::endl; // } return collidingTiles; }
// Methos allocates space for widget void Widget::SetBoundingRect( const Rect &r ) { Rect previous = _bound; _bound = r; bool anything_changed=false; if ( GetEnvironment() ) { _parent->SetDirty( previous | _bound ); } if ( _bound.GetX() != previous.GetX() || _bound.GetY() != previous.GetY() ) { OnReposition.Send_1( Pos( _bound.GetX(), _bound.GetY() )); anything_changed=true; } if ( _bound.GetW() != previous.GetW() || _bound.GetH() != previous.GetH() ) { OnResize.Send_2( _bound.GetW(), _bound.GetH() ); anything_changed=true; } if ( anything_changed ) NotifyAncestors(true); }
/** * This method uses the new position of the given object, * its previous position and the map to determine whether * the object is colliding with the walls */ bool MovementMap::IsColliding(const Rect box) { // // Checks the center // if (!IsZero(box.Center().GetX(), box.Center().GetY())) return true; // Checks the above limit if (!IsZero(box.GetX()+box.GetW()/2, box.GetY())) return true; // Checks the right limit if (!IsZero(box.GetX() + box.GetW(), box.GetY() + box.GetH()/2)) return true; // Checks the left limit if (!IsZero(box.GetX(), box.GetY()+box.GetH()/2)) return true; // Checks the upper-right limit if (!IsZero(box.GetX()+box.GetW(), box.GetY())) return true; // Checks the upper-left limit if (!IsZero(box.GetX(), box.GetY())) return true; // Checks the lower limit if (!IsZero(box.Center().GetX(), box.Center().GetY() + box.GetH()/2)) return true; // Checks the lower-right limit if (!IsZero(box.GetX()+box.GetW(), box.GetY()+box.GetH())) return true; // Checks the lower-left limit if (!IsZero(box.GetX(), box.GetY()+box.GetH())) return true; return false; // return IsCollidingWithGround(box); }
Vec2 CollisionDetector::LineToAABB(const Vec2& linePt, const Vec2& lineDir, const Rect& rect) { // Prevents false collision if either rects has no width and height if (rect.GetW() == 0 && rect.GetH() == 0) { return Vec2(0.0, 0.0); } Vec2 linePt1 = linePt; Vec2 linePt2 = linePt + lineDir; Vec2 rectPtArray[] = { Vec2(rect.GetX(), rect.GetY()), Vec2(rect.GetX() + rect.GetW(), rect.GetY()), Vec2(rect.GetX() + rect.GetW(), rect.GetY() + rect.GetH()), Vec2(rect.GetX(), rect.GetY() + rect.GetH()) }; double currentDirMag = 1.0f; // Current direction vector magnitude // Test intersection for all four line segments of the rectangle for (int i = 0; i < 4; ++i) { // i is the index of the first point, j the second // set j to 0 if i equals 3 int j = (i < 3) ? (i + 1) : 0; Vec2 rectPt1 = rectPtArray[i]; Vec2 rectPt2 = rectPtArray[j]; double sNumer = ( (linePt1.GetY() - rectPt1.GetY()) * (rectPt2.GetX() - rectPt1.GetX()) ) - ( (linePt1.GetX() - rectPt1.GetX()) * (rectPt2.GetY() - rectPt1.GetY()) ); double sDenom = ( (linePt2.GetX() - linePt1.GetX()) * (rectPt2.GetY() - rectPt1.GetY()) ) - ( (linePt2.GetY() - linePt1.GetY()) * (rectPt2.GetX() - rectPt1.GetX()) ); double tNumer = ( (linePt1.GetY() - rectPt1.GetY()) * (linePt2.GetX() - linePt1.GetX()) ) - ( (linePt1.GetX() - rectPt1.GetX()) * (linePt2.GetY() - linePt1.GetY()) ); double tDenom = ( (linePt2.GetX() - linePt1.GetX()) * (rectPt2.GetY() - rectPt1.GetY()) ) - ( (linePt2.GetY() - linePt1.GetY()) * (rectPt2.GetX() - rectPt1.GetX()) ); double s = sNumer / sDenom; double t = tNumer / tDenom; // Lines intersect if s and t are in range [0,1] if ((s >= 0.0 && s <= 1.0) && (t >= 0.0 && t <= 1.0)) { currentDirMag = t < currentDirMag ? s : currentDirMag; } } if (currentDirMag == 1.0) { return Vec2(0.0, 0.0); } else { return Vec2(linePt + (lineDir * currentDirMag)); } }
bool Hud::DrawString(string text, SDL_Color color, Rect rect, bool center) { /* Render string */ return mFont.Render(color, text, rect.GetX(), rect.GetY(), center); }