SFML community forums

Help => General => Topic started by: smiaro on December 29, 2013, 07:20:32 pm

Title: Problem with collision SFML 2.0
Post by: smiaro on December 29, 2013, 07:20:32 pm
Hello, here is my player and level class code. First cpp files, then .h. I try to make simple collision but this doesn't work. Why?;> Help me pls. My character ignores collisions and just go and jump through sprites :( You can ignore CollisonRight, CollisionLeft. I want to use Collision method because I think collision check is good.
HEEELP :)

Player.cpp
#include <SFML/Graphics.hpp>
#include "Player.h"
#include "Level.h"


void Player::Draw(sf::RenderWindow & gameWindow)
{
        const float gravity = 0.9;
        int groundHeight = 368;
        sf::Vector2f velocity(sf::Vector2f(0, 0));
        float moveSpeed = 2.0f;
        float jumpSpeed = 10.0f;

        Level level;

        enum Direction { Down,Left, Right, Up }; //{0,1}
        sf::Vector2i source(1, Down);

        gameWindow.setKeyRepeatEnabled(false);

        sf::Texture playerImage;
        playerImage.loadFromFile("C:/Users/Marcin/Desktop/Teddies/Release/Images/player.png");
        sf::Sprite player(playerImage);
        player.setPosition(0, 50);

        while (gameWindow.isOpen()) {
                sf::Event event;
                while (gameWindow.pollEvent(event)) {
                        if (level.Collision(level.cabinets) || level.Collision(level.microwaves) || level.Collision(level.boxs) || level.Collision(level.fridges) || level.Collision(level.ovens) || level.Collision(level.chairs) || level.Collision(level.tables)) {
                                velocity.x = 0;
                                velocity.y = 0;
                        }
                        else if (sf::Keyboard::isKeyPressed(sf::Keyboard::Right))
                        {
                                source.y = Right;
                                velocity.x = +moveSpeed;
                        }
                        else if (sf::Keyboard::isKeyPressed(sf::Keyboard::Left))
                        {
                                source.y = Left;
                                velocity.x = -moveSpeed;
                        }
                        else
                        {
                                source.y = Down;
                                velocity.x = 0;
                        }
                        if (sf::Keyboard::isKeyPressed(sf::Keyboard::Space))
                                velocity.y = -jumpSpeed;
                        if (event.key.code == sf::Keyboard::Escape)
                                return;
                        break; 
                }

                player.move(velocity.x, velocity.y);
                if (player.getPosition().y < groundHeight || velocity.y < 0)
                {
                        velocity.y += gravity;
                }
                else
                {
                        player.setPosition(player.getPosition().x, groundHeight - player.getScale().y);
                        velocity.y = 0;
                }

                source.x++;
                if (source.x * 32 >= playerImage.getSize().x)
                        source.x = 0;

                player.setTextureRect(sf::IntRect(source.x * 32, source.y * 32, 32, 32));
                level.Draw(gameWindow);
                gameWindow.draw(player);
                gameWindow.display();
                gameWindow.clear();
        }

}

 

Level.cpp
#include <SFML/Graphics.hpp>
#include <SFML/Audio.hpp>
#include "Level.h"
#include "Player.h"

void Level::Load1(sf::RenderWindow& gameWindow) {
        Player player;
        Counts(gameWindow);
        Draw(gameWindow);
        player.Draw(gameWindow);
}

void Level::Draw(sf::RenderWindow& gameWindow) {
        sf::Texture cabinet,bg,microwave,fridge,table,oven,box, chair;
        cabinet.loadFromFile("C:/Users/Marcin/Desktop/Teddies/Release/Images/cabinet.png");
        bg.loadFromFile("C:/Users/Marcin/Desktop/Teddies/Release/Images/bg.png");
        microwave.loadFromFile("C:/Users/Marcin/Desktop/Teddies/Release/Images/microwave.png");
        fridge.loadFromFile("C:/Users/Marcin/Desktop/Teddies/Release/Images/fridge.png");
        table.loadFromFile("C:/Users/Marcin/Desktop/Teddies/Release/Images/table.png");
        oven.loadFromFile("C:/Users/Marcin/Desktop/Teddies/Release/Images/oven.png");
        box.loadFromFile("C:/Users/Marcin/Desktop/Teddies/Release/Images/box.png");
        chair.loadFromFile("C:/Users/Marcin/Desktop/Teddies/Release/Images/chair.png");
        sf::Sprite cabinets(cabinet);
        sf::Sprite bgs(bg);
        sf::Sprite microwaves(microwave);
        sf::Sprite fridges(fridge);
        sf::Sprite tables(table);
        sf::Sprite ovens(oven);
        sf::Sprite boxs(box);
        sf::Sprite chairs(chair);
        bgs.setPosition(0, 0);
        cabinets.setPosition(0, 405);
        fridges.setPosition(137, 295);
        tables.setPosition(262, 395);
        microwaves.setPosition(30, 367);
        ovens.setPosition(489, 355);
        boxs.setPosition(658, 455);
        chairs.setPosition(285, 350);
        gameWindow.draw(bgs);
        gameWindow.draw(cabinets);
        gameWindow.draw(microwaves);
        gameWindow.draw(fridges);
        gameWindow.draw(chairs);
        gameWindow.draw(tables);
        gameWindow.draw(ovens);
        gameWindow.draw(boxs);
}

void Level::Counts(sf::RenderWindow& gameWindow) {

        sf::SoundBuffer buffer,buffer2,buffer3,buffer4;
        buffer.loadFromFile("C:/Users/Marcin/Desktop/Teddies/Release/Sources/three.wav");
        sf::Sound sound,sound2,sound3,sound4;
        sound.setBuffer(buffer);
        sound.setVolume(50);

        sf::Texture three, two, one, start,bg;
        three.loadFromFile("C:/Users/Marcin/Desktop/Teddies/Release/Images/3.png");
        two.loadFromFile("C:/Users/Marcin/Desktop/Teddies/Release/Images/2.png");
        one.loadFromFile("C:/Users/Marcin/Desktop/Teddies/Release/Images/1.png");
        start.loadFromFile("C:/Users/Marcin/Desktop/Teddies/Release/Images/start.png");
        bg.loadFromFile("C:/Users/Marcin/Desktop/Teddies/Release/Images/bg.png");

        sf::Sprite threes(three);
        sf::Sprite twos(two);
        sf::Sprite ones(one);
        sf::Sprite starts(start);
        sf::Sprite bgs(bg);

        bgs.setPosition(0, 0);
        threes.setPosition(350, 240);
        twos.setPosition(350, 240);
        ones.setPosition(350, 240);
        starts.setPosition(340, 240);

        threes.setScale(0.4, 0.4);
        twos.setScale(0.4, 0.4);
        ones.setScale(0.4, 0.4);
        starts.setScale(0.4, 0.4);

        gameWindow.clear();
        gameWindow.draw(bgs);
        gameWindow.draw(threes);
        gameWindow.display();
        sound.play();
        sf::sleep(sf::seconds(1));

        gameWindow.clear();
        gameWindow.draw(bgs);
        gameWindow.draw(twos);
        gameWindow.display();
        buffer2.loadFromFile("C:/Users/Marcin/Desktop/Teddies/Release/Sources/two.wav");
        sound2.setBuffer(buffer2);
        sound2.setVolume(50);
        sound2.play();
        sf::sleep(sf::seconds(1));

        gameWindow.clear();
        gameWindow.draw(bgs);
        gameWindow.draw(ones);
        gameWindow.display();
        buffer3.loadFromFile("C:/Users/Marcin/Desktop/Teddies/Release/Sources/one.wav");
        sound3.setBuffer(buffer3);
        sound3.setVolume(50);
        sound3.play();
        sf::sleep(sf::seconds(1));

        gameWindow.clear();
        gameWindow.draw(bgs);
        gameWindow.draw(starts);
        gameWindow.display();
        buffer4.loadFromFile("C:/Users/Marcin/Desktop/Teddies/Release/Sources/go.wav");
        sound4.setBuffer(buffer4);
        sound4.setVolume(50);
        sound4.play();
        sf::sleep(sf::seconds(1));

        gameWindow.clear();
        //gameWindow.draw(ones);
        //gameWindow.draw(starts);
}

//DODANE DLA SPROBOWANIA KOLIZJI
bool Level::CollisionLeft(sf::Sprite x)
{
        Player p;
        if (x.getPosition().x < p.player.getPosition().x + p.player.getGlobalBounds().width)
                return true;
        return false;
}

bool Level::CollisionRight(sf::Sprite x)
{
        Player p;
        if (x.getPosition().x + x.getGlobalBounds().width >  p.player.getPosition().x)
                return true;
        return false;
}

bool Level::CollisionBottom(sf::Sprite x)
{
        Player p;
        if (x.getPosition().y > p.player.getPosition().y + p.player.getGlobalBounds().width)
                return true;
        return false;
}

bool Level::Collision(sf::Sprite x)
{
        Player p;
        float x1 = p.player.getPosition().x;
        float x2 = x.getPosition().x;
        float y1 = p.player.getPosition().y;
        float y2 = x.getPosition().y;
        float w1 = p.player.getGlobalBounds().width;
        float w2 = x.getGlobalBounds().width;
        float h1 = p.player.getGlobalBounds().height;
        float h2 = x.getGlobalBounds().height;

        return(((x1 - (w1 / 2) < x2 + (w2 / 2)) && (x2 + (w2 / 2) > x1 - (w1 / 2))) && ((x2 - (w2 / 2) < x1 + (w1 / 2)) && (x1 + (w1 / 2) > x2 - (w2 / 2))) && ((y1 - (h1 / 2) < y2 + (h2 / 2)) && (y2 + (h2 / 2) > y1 - (h1 / 2))) && ((y2 - (h2 / 2) < y1 + (h1 / 2)) && (y1 + (h1 / 2) > y2 - (h2 / 2))));
}

////

 

Level.h
#pragma once
class Level
{
public:
        void Load1(sf::RenderWindow& gameWindow);
        void Draw(sf::RenderWindow& gameWindow);
        void Counts(sf::RenderWindow& gameWindow);


        //DODANE DLA SPROBOWANIA KOLIZJI
        sf::Sprite cabinets;
        sf::Sprite microwaves;
        sf::Sprite fridges;
        sf::Sprite tables;
        sf::Sprite ovens;
        sf::Sprite boxs;
        sf::Sprite chairs;

        bool CollisionLeft(sf::Sprite x);
        bool CollisionRight(sf::Sprite x);
        bool CollisionBottom(sf::Sprite x);
        bool Collision(sf::Sprite x);
        ////
};
 

Player.h
#pragma once
class Player
{
public:
        void Draw(sf::RenderWindow& gameWindow);
        bool BoundingBoxTest(const sf::Sprite& Object1, const sf::Sprite& Object2);
       
        //DODANE DLA SPROBOWANIA KOLIZJI
        sf::Sprite player;
        ////
};
 
Title: Re: Problem with collision SFML 2.0
Post by: zsbzsb on December 30, 2013, 12:36:04 am
Seriously, learn to use your debugger and step through code. You should be able to easily see the problem...

Anyways, here is a hint

return(((x1 - (w1 / 2) < x2 + (w2 / 2)) && (x2 + (w2 / 2) > x1 - (w1 / 2))) && ((x2 - (w2 / 2) < x1 + (w1 / 2)) && (x1 + (w1 / 2) > x2 - (w2 / 2))) && ((y1 - (h1 / 2) < y2 + (h2 / 2)) && (y2 + (h2 / 2) > y1 - (h1 / 2))) && ((y2 - (h2 / 2) < y1 + (h1 / 2)) && (y1 + (h1 / 2) > y2 - (h2 / 2))));

First you should break this up, this is way to long for one line and very error prone (in fact you really can't put that logic all in one boolean expression anyways). Second, let's translate this to english and see if you can see the problem.

Quote
if someleft < otherleft AND someright > otherright AND sometop < othertop AND somebottom > otherbottom ect... return true
ELSE return false

Third, maybe read SFML documentation to make your life easier (http://www.sfml-dev.org/documentation/2.1/classsf_1_1Rect.php#a566740c8f58e01bb052266f47e7e1011).
Title: Re: Problem with collision SFML 2.0
Post by: didii on December 30, 2013, 12:45:10 am
Fifth: use a minimal example code to display your problem. Remove all that is unnecessary to your problem. In most cases, this process already reveals what is wrong.