I have a four FloatRects, that anwser for sprite animation frames collision directions, i initialize it for each frame in Animation.h
ColPointDivide its a integer that equals 10, i use it that the edges do not intersect (up-right,up-left,etc...)
i.e i want to create a FloatRect (Collision box) that little offseting from top to bottom Y points, trying deny edges intersecting
*leftRect = FloatRect(
0,
R.height / ColPointDivide,
R.width / 2,
R.height - R.height / ColPointDivide
);
*upRect = FloatRect(R.width / ColPointDivide,
0,
R.width - R.width / ColPointDivide,
R.height / 2);
*rightRect = FloatRect(R.width / 2, R.height / ColPointDivide, R.width / 2, R.height - R.height / ColPointDivide);
*downRect = FloatRect(R.width / ColPointDivide, R.height / 2, R.width - R.width / ColPointDivide, R.height / 2);
In code when i want to check collision, i trying this:
(mtv its a SAT mtv, that contains collision depth, like 0,1)
(curColRect its an array vector of FloatRects with size 4, i calling i needed direction, and current animation frame)
for each (Block bl in m_engine->MapBlocks)
{
FloatRect blrect = bl.sprite.getLocalBounds();
//auto B = bl.sprite.getLocalBounds();
//RectangleShape colupshape(Vector2f(curAnim.Col_up.width,curAnim.Col_up.height));
//colupshape.setPosition(curAnim.Col_up.left, curAnim.Col_up.top);
// m_engine->AddSprite(&colupshape, 0);
Vector2f mtv;
if (m_engine->m_math.sat_test(bl.sprite, kidspr, &mtv))
{
FloatRect mtvrect(mtv.x, mtv.y, blrect.width-mtv.x, blrect.height-mtv.y);
// coutMTV(mtv);
if (!passed[ColPoint::up])
{
if (mtvrect.intersects(curColRect[ColPoint::up].at(curf)))
{
setPos(
Vector2f(
kidentity->GetX(), bl.sprite.getPosition().y - kidentity->anim.getSprite()->getOrigin().y
));
colUP = true;
passed[ColPoint::up] = true;
}
}
// and that for each direction...
I also setting false all booleans to false above, and its method calling with gameloop some often like drawing, under i setting booleans that wasnt colliding to false
(under code)
if (!passed[cp::left])
{
colLEFT = false;
}
if (!passed[cp::right])
{
colRIGHT = false;
}
if (!passed[cp::up])
{
colUP = false;
}
if (!passed[cp::down])
{
colDOWN = false;
//cout << "not col down" << endl;
}
(above code)
void kid::control()
{
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Left))
{
kidentity->anim.flip(true);
}
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Right))
{
kidentity->anim.flip(false);
}
/*grounded = false;
colUP = false;
colDOWN = false;
colLEFT = false;
colRIGHT = false;*/
static bool passed[4];
passed[ColPoint::left] = false;
passed[ColPoint::right] = false;
passed[ColPoint::up] = false;
passed[ColPoint::down] = false;
colDOWN = false;
colLEFT = false;
colUP = false;
colRIGHT = false;
vector<FloatRect> curColRect[4];
curColRect[0].reserve(0);
curColRect[1].reserve(0);
curColRect[2].reserve(0);
curColRect[3].reserve(0);
int animnum = anim.GetAnimNum(anim.currentAnim);
//auto CurrentAnim = anim.animList[anim.currentAnim];
//cout << animnum;
int curf = anim.animList[anim.currentAnim].currentFrame;
if (!anim.isFlip())
{
//int f = anim.animList[anim.currentAnim].currentFrame;
curColRect[0] = anim.animList[anim.currentAnim].ColRect[0];
curColRect[1] = anim.animList[anim.currentAnim].ColRect[1];
curColRect[2] = anim.animList[anim.currentAnim].ColRect[2];
curColRect[3] = anim.animList[anim.currentAnim].ColRect[3];
}
else
{
//cout << "FLIP" << endl;
//int f = anim.animList[anim.currentAnim].currentFrame;
curColRect[0] = anim.animList[anim.currentAnim].ColRectFlip[0];
curColRect[1] = anim.animList[anim.currentAnim].ColRectFlip[1];
curColRect[2] = anim.animList[anim.currentAnim].ColRectFlip[2];
curColRect[3] = anim.animList[anim.currentAnim].ColRectFlip[3];
}
Sprite kidspr = *kidentity->anim.getSprite();
So, when my sprite with animation collides to a block by up, ALL booleans that anwser for collision (colDOWN,colLEFT,colRIGHT,colUP) are true, but collision was by up point...
I also trying use CurColRect[point][curf].contains(mtv), but this work veery strange, when collision by up, all collision booleans are false, only colLEFT are true, idk why
Please help me, idk what is wrong
I also dont want to use Box2d for its objectives
I use SFML 2.4.2
sat_test method:
bool Iwmo::Math::sat_test(const sf::Sprite &sp1, const sf::Sprite &sp2, sf::Vector2f *out_mtv) {
const sf::FloatRect &rectSp1 = sp1.getGlobalBounds();
const sf::FloatRect &rectSp2 = sp2.getGlobalBounds();
float proj_x, proj_y, overlap_x, overlap_y;
// test overlap in x axis
proj_x = std::max(rectSp1.left + rectSp1.width, rectSp2.left + rectSp2.width) - std::min(rectSp1.left, rectSp2.left);
if (proj_x < rectSp1.width + rectSp2.width) {
if (out_mtv) {
// calculate mtv in x
overlap_x = rectSp1.width + rectSp2.width - proj_x;
}
// test overlap in y axis
proj_y = std::max(rectSp1.top + rectSp1.height, rectSp2.top + rectSp2.height) - std::min(rectSp1.top, rectSp2.top);
if (proj_y < rectSp1.height + rectSp2.height) {
if (out_mtv) {
// calculate mtv in y
overlap_y = rectSp1.height + rectSp2.height - proj_y;
out_mtv->x = out_mtv->y = 0;
// choose minimun overlap
if (overlap_x < overlap_y) {
out_mtv->x = overlap_x * (rectSp1.left < rectSp2.left ? -1 : 1);
}
else {
out_mtv->y = overlap_y * (rectSp1.top < rectSp2.top ? -1 : 1);
}
}
return true;
}
}
return false;
}