I am making some collision and it sort of works but it's not working as good as it should, its hard to explain but if you run the code you'll see what i mean.
Collision
//Get collision.
if(rectToMove.intersects(redBlockSprite.getGlobalBounds()))
{
if(velocity.x < 0 && position.x < redBlockSprite.getPosition().x + redBlockSprite.getGlobalBounds().width)
{
cout << "Touched Right side" << endl;
position.x = redBlockSprite.getPosition().x + characterSprite.getGlobalBounds().width;
}
if(velocity.y > 0 && position.y > redBlockSprite.getPosition().y - redBlockSprite.getGlobalBounds().height)
{
cout << "Touched Top" << endl;
position.y = redBlockSprite.getPosition().y - characterSprite.getGlobalBounds().height;
}
if(velocity.x > 0 && position.x > redBlockSprite.getPosition().x - redBlockSprite.getGlobalBounds().width)
{
cout << "Touched Left Side" << endl;
position.x = redBlockSprite.getPosition().x - characterSprite.getGlobalBounds().width;
}
if(velocity.y < 0 && position.y < redBlockSprite.getPosition().y + redBlockSprite.getGlobalBounds().height)
{
cout << "Touched Bottom" << endl;
position.y = redBlockSprite.getPosition().y + characterSprite.getGlobalBounds().height;
}
}
Complete Code
#include <iostream>
#include <math.h>
#include <SFML/Graphics.hpp>
using namespace std;
int main()
{
sf::Vector2f position;
sf::Vector2f velocity;
float maxspeed = 4.0f;
float accel = 4.5f;
float decel = 0.01f;
bool vSyncEnabled = true;
//Setup Window and Framerate
sf::RenderWindow window(sf::VideoMode(800, 600), "Bounding Box (Collision)");
window.setFramerateLimit(60);
window.setVerticalSyncEnabled(vSyncEnabled);
//Load Texture
sf::Texture character;
if(!character.loadFromFile("Resources/Textures/triangle.png"))
{
cout << "Error loading resource 'triangle.png'" << endl;
}
else
{
cout << "triangle.png texture loaded" << endl;
}
//Set Sprite for Character Object
sf::Sprite characterSprite;
characterSprite.setTexture(character);
characterSprite.setOrigin(sf::Vector2f(0, 0));
characterSprite.setPosition(400, 300);
//Load Red Block Texture
sf::Texture redBlock;
if(!redBlock.loadFromFile("Resources/Textures/RedBlock.png"))
{
cout << "Error loading 'RedBlock.png" << endl;
}
else
{
cout << "RedBlock.png texture loaded" << endl;
}
//Set Sprite for Red Block Object
sf::Sprite redBlockSprite;
redBlockSprite.setTexture(redBlock);
redBlockSprite.setOrigin(sf::Vector2f(0, 0));
redBlockSprite.setPosition(200, 200);
while(window.isOpen())
{
window.clear(sf::Color::White);
window.draw(characterSprite);
window.draw(redBlockSprite);
sf::Event event;
while(window.pollEvent(event))
{
switch(event.type)
{
case sf::Event::Closed:
{
window.close();
}
break;
//Dont stretch the window contents when its resized
case sf::Event::Resized:
{
sf::FloatRect visibleArea(0, 0, event.size.width, event.size.height);
window.setView(sf::View(visibleArea));
}
break;
}
}
//WASD Movement
if(sf::Keyboard::isKeyPressed(sf::Keyboard::A))
{
velocity.x -= accel;
}
else if(sf::Keyboard::isKeyPressed(sf::Keyboard::D))
{
velocity.x += accel;
}
else
{
velocity.x *= decel;
}
if(sf::Keyboard::isKeyPressed(sf::Keyboard::W))
{
velocity.y -= accel;
}
else if(sf::Keyboard::isKeyPressed(sf::Keyboard::S))
{
velocity.y += accel;
}
else
{
velocity.y *= decel;
}
//Make sure the sprite isn't going too fast
if(velocity.x < -maxspeed) velocity.x = -maxspeed;
if(velocity.x > maxspeed) velocity.x = maxspeed;
if(velocity.y < -maxspeed) velocity.y = -maxspeed;
if(velocity.y > maxspeed) velocity.y = maxspeed;
//Update sprite position and move sprite
position += velocity;
//Get the window's size
sf::Vector2u currWSize = window.getSize();
if(position.x <= 0)
{
position.x = 0;
}
if(position.y <= 0)
{
position.y = 0;
}
if(position.x >= currWSize.x - characterSprite.getGlobalBounds().width)
{
position.x = currWSize.x - characterSprite.getGlobalBounds().width;
}
if(position.y >= currWSize.y - characterSprite.getGlobalBounds().height)
{
position.y = currWSize.y - characterSprite.getGlobalBounds().height;
}
sf::FloatRect rectToMove(position, {characterSprite.getGlobalBounds().width, characterSprite.getGlobalBounds().width});
//Get collision.
if(rectToMove.intersects(redBlockSprite.getGlobalBounds()))
{
if(velocity.x < 0 && position.x < redBlockSprite.getPosition().x + redBlockSprite.getGlobalBounds().width)
{
cout << "Touched Right side" << endl;
position.x = redBlockSprite.getPosition().x + characterSprite.getGlobalBounds().width;
}
if(velocity.y > 0 && position.y > redBlockSprite.getPosition().y - redBlockSprite.getGlobalBounds().height)
{
cout << "Touched Top" << endl;
position.y = redBlockSprite.getPosition().y - characterSprite.getGlobalBounds().height;
}
if(velocity.x > 0 && position.x > redBlockSprite.getPosition().x - redBlockSprite.getGlobalBounds().width)
{
cout << "Touched Left Side" << endl;
position.x = redBlockSprite.getPosition().x - characterSprite.getGlobalBounds().width;
}
if(velocity.y < 0 && position.y < redBlockSprite.getPosition().y + redBlockSprite.getGlobalBounds().height)
{
cout << "Touched Bottom" << endl;
position.y = redBlockSprite.getPosition().y + characterSprite.getGlobalBounds().height;
}
}
characterSprite.setPosition(position);
velocity *= decel;
window.display();
}
return 0;
}
Hi,
You are not computing redBlockSprite sides coordinates properly.
For example, if you want to know the left side x coordinate, it is redBlockSprite.getPosition().x (assuming its origin is (0,0)).
Then, when setting position, there are still issues with sides coordinates for the bottom and right cases.
For example, if you want the left side of the characterSprite to be on the right side of the redBlockSprite, you want that :
position.x // character left side
= redBlockSprite.getPosition().x + redBlockSprite.getGlobalBounds().width; // redBlock right side
This kind of formulas are easy to find with a diagram, so take a paper an a pencil, it will be obvious.