Welcome, Guest. Please login or register. Did you miss your activation email?

Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.


Topics - wh1t3crayon

Pages: [1] 2
1
Graphics / Why is there a slight gap between my sf::ConvexShapes?
« on: November 24, 2015, 10:04:06 pm »
When creating a row of sf::ConvexShapes from data in a .txt file, there is a slight gap between each shape. If I create each shape with the same data inside the code itself, then there is no gap formed.
std::ifstream fin;
std::string str("levels/level" + std::to_string(levelNumber) + ".txt");
fin.open(str);
int yCounter = 0; //incr whenever file reads /n
if(fin.good()){
        while(!fin.eof()){
                std::string line;
                //this happens once per line, so whenever the while statement breaks, that means incr yCounter
                while(std::getline(fin, line)){
                        int xCounter = 0; //incr for each char, reset per line
                        for(int i = 0; i < line.length(); i++){
                                if(line[i] == 'w'){
                                        AddWall(xCounter, yCounter, tileSize);
                                }
                                xCounter++;
                        }
                        yCounter++;
                }
        }
}

void AddWall(int posX, int posY, int tileSize){
        objects.push_back(new Platform(posX, posY, tileSize));
}

Platform::Platform(int posX, int posY, int tileSize){
        shape.setPointCount(4);
        shape.setPoint(0, sf::Vector2f(posX, posY));
        shape.setPoint(1, sf::Vector2f(posX, posY + tileSize));
        shape.setPoint(2, sf::Vector2f(posX + tileSize, posY + tileSize));
        shape.setPoint(3, sf::Vector2f(posX + tileSize, posY));
        shape.setFillColor(sf::Color::White);
        shape.setPosition(posX * tileSize, posY * tileSize);
}

A screenshot of the gap is included. I know I can just add outlines to the shapes to solve this, but why is the problem happening in the first place?

2
Graphics / How to have a pointer to sf::Drawable in a base class?
« on: September 25, 2015, 02:14:07 am »
When running the code below I am getting the following runtime error:
Quote
Unhandled exception at 0x5E87CC6E (sfml-graphics-d-2.dll) in Project for SFML Web Problems.exe: 0xC0000005: Access violation reading location 0xCCCCCCD0.

// Project for SFML Web Problems.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "SFML\Graphics.hpp"
#include <deque>
#include <memory>

class WorldObject{
public:
        WorldObject(){ drawable = nullptr; }
        virtual ~WorldObject(){}

        sf::Drawable &GetDrawable(){
                return *drawable;
        }
protected:
        //accessing this pointer is invalid
        sf::Drawable *drawable;
};

class Entity : public WorldObject{
public:
        Entity(){
                sprite.setPosition(20, 20);
                sprite.setFillColor(sf::Color::White);
                sprite.setSize(sf::Vector2f(50, 50));

                drawable = &sprite;
        }
        virtual ~Entity(){}
private:
        sf::RectangleShape sprite;
};

class Holder{
public:
        Holder(){
                entities.push_back(Entity());
                objects.push_back(&entities[0]);       
        }
        ~Holder(){}

        std::deque<WorldObject*> &GetObjects(){
                return objects;
        }
        std::deque<Entity> &GetEntities(){
                return entities;
        }
private:
        std::deque<WorldObject*> objects;
        std::deque<Entity> entities;
};

int _tmain(int argc, _TCHAR* argv[])
{
        sf::RenderWindow window(sf::VideoMode(500, 500, 32), "Test");
        sf::Event ev;

        Holder holder;

        while(window.isOpen()){
                while(window.pollEvent(ev)){
                        if(ev.type == sf::Event::Closed){
                                window.close();
                        }
                }
                window.clear();
                for(unsigned int i= 0; i < holder.GetObjects().size(); i++){
                        //accessing sf::Drawable* throws error
                        window.draw(holder.GetObjects()[i]->GetDrawable());
                }
                window.display();
        }

        return 0;
}

 

My question is pretty straightforward. How do I make a pointer to sf::Drawable in a Base class so that in a Base container I can draw that drawable, be it a sf::Sprite, sf::RectangleShape, etc.?

3
General / Issue with using a ConvexShape's points like a VertexArray
« on: April 15, 2015, 06:23:26 am »
A while back I made a crude implementation of the Separating Axis Theorem, although I used the sf::VertexArray to represent an object. When adapting this to an actual project, I found that my objects on the screen were better off as sf::ConvexShapes, not VertexArrays. So I thought the adaptation for the SAT code would be straightforward, but it's not. The new SAT code using ConvexShapes always returns the overlaps of the shapes as zero. So somewhere in these two similar blocks of code, there is a bug that I seem to have missed when turning all the VertexArray code into ConvexShape code. Maybe all I need is a second pair of eyes, or maybe there's something between these two sf classes that I don't know about, but I'd appreciate it if somebody took the time to compare the two different code blocks. I'll post the before and after code.
The working SAT code, sf::VertexArray friendly:
// SFML Test.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "SFML\Graphics.hpp"

sf::Vector2f Normalize(sf::Vector2f& input){
        if(sqrt(input.x * input.x + input.y * input.y) == 0){
        input.x = 1;
        return input;
    }
    float length = sqrt(input.x * input.x + input.y * input.y);

    input.x /= length;
    input.y /= length;
    return input;
}

sf::Vector2f GetNormalAxis(sf::VertexArray &shape, int index){
        sf::Vector2f vectorOne = shape[index].position;
    sf::Vector2f vectorTwo;
    if(index >= shape.getVertexCount() - 1)
        vectorTwo = shape[0].position;
    else
        vectorTwo = shape[index+1].position;

    sf::Vector2f normalAxis(-(vectorTwo.y - vectorOne.y), vectorTwo.x - vectorOne.x);
    normalAxis = Normalize(normalAxis);
    return normalAxis;
}

float DotProduct(sf::Vector2f &vectorOne, sf::Vector2f &vectorTwo){
    return vectorOne.x * vectorTwo.x + vectorOne.y * vectorTwo.y;
}

class WorldObject{
public:
        WorldObject(){}
        ~WorldObject(){}

        sf::VertexArray &GetOutline(){ return outline; }
private:
        sf::VertexArray outline;
};

class Projection{
public:
        Projection(sf::Vector2f &axis, sf::VertexArray &vertices){
                min = DotProduct(axis, vertices[0].position);
                max = min;

                for(int i = 1; i < vertices.getVertexCount(); i++){
                        float proj = DotProduct(axis, vertices[i].position);
                        if(proj < min){
                                min = proj;
                        }
                        else if(proj > max){
                                max = proj;
                        }
                }
        }
        ~Projection(){}

        float GetMin(){ return min; }
        float GetMax(){ return max; }

        float GetOverlap(Projection &projection){
                if(projection.GetMin() <= max && max <= projection.GetMax()){
                        return max - projection.GetMin();
                }
                else if(min <= projection.GetMax() && projection.GetMax() <= max){
                        return projection.GetMax() - min;
                }
                else{
                        return 0;
                }
        }
private:
        float min, max;
};

int _tmain(int argc, _TCHAR* argv[]){
        sf::RenderWindow window(sf::VideoMode(500, 500, 32), "Test");

        WorldObject object;
        WorldObject objectTwo;

        object.GetOutline().setPrimitiveType(sf::PrimitiveType::Triangles);
        object.GetOutline().append(sf::Vertex(sf::Vector2f(200, 180)));
        object.GetOutline().append(sf::Vertex(sf::Vector2f(10, 180)));
        object.GetOutline().append(sf::Vertex(sf::Vector2f(10, 240)));
        //object.GetOutline().append(sf::Vertex(sf::Vector2f(200, 240)));

        objectTwo.GetOutline().setPrimitiveType(sf::PrimitiveType::Quads);
        objectTwo.GetOutline().append(sf::Vertex(sf::Vector2f(20 + 80, 0)));
        objectTwo.GetOutline().append(sf::Vertex(sf::Vector2f(0 + 80, 0)));
        objectTwo.GetOutline().append(sf::Vertex(sf::Vector2f(0 + 80, 20)));
        objectTwo.GetOutline().append(sf::Vertex(sf::Vector2f(20 + 80, 20)));

        while(window.isOpen()){
                if(sf::Keyboard::isKeyPressed(sf::Keyboard::Escape)){
                        window.close();
                }
                if(sf::Keyboard::isKeyPressed(sf::Keyboard::Right)){
                        for(int i = 0; i < objectTwo.GetOutline().getVertexCount(); i++){
                                objectTwo.GetOutline()[i].position.x += .05;
                        }
                }
                if(sf::Keyboard::isKeyPressed(sf::Keyboard::Left)){
                        for(int i = 0; i < objectTwo.GetOutline().getVertexCount(); i++){
                                objectTwo.GetOutline()[i].position.x -= .05;
                        }
                }
                if(sf::Keyboard::isKeyPressed(sf::Keyboard::Down)){
                        for(int i = 0; i < objectTwo.GetOutline().getVertexCount(); i++){
                                objectTwo.GetOutline()[i].position.y += .05;
                        }
                }
                if(sf::Keyboard::isKeyPressed(sf::Keyboard::Up)){
                        for(int i = 0; i < objectTwo.GetOutline().getVertexCount(); i++){
                                objectTwo.GetOutline()[i].position.y -= .05;
                        }
                }

                if(sf::FloatRect(object.GetOutline().getBounds()).intersects(sf::FloatRect(objectTwo.GetOutline().getBounds()))){
                        std::vector<sf::Vector2f> axesOne;
                        std::vector<sf::Vector2f> axesTwo;
                        //for both shapes, get their axes
                        for(int i = 0; i < object.GetOutline().getVertexCount(); i++){
                                axesOne.push_back(GetNormalAxis(object.GetOutline(), i));
                        }
                        for(int i = 0; i < objectTwo.GetOutline().getVertexCount(); i++){
                                axesTwo.push_back(GetNormalAxis(objectTwo.GetOutline(), i));
                        }

                        //for both sets of axes
                        //project
                        float overlap = 50000000000;
                        sf::Vector2f smallestAxis;
               
                        for(int i = 0; i < axesOne.size(); i++){
                                Projection projectionOne(axesOne[i], object.GetOutline());
                                Projection projectionTwo(axesOne[i], objectTwo.GetOutline());

                                float o = projectionOne.GetOverlap(projectionTwo);
                                if(o == 0.f){
                                        //no overlap
                                }
                                if(o < overlap){
                                        overlap = o;
                                        smallestAxis = axesOne[i];
                                }
                        }

                        for(int i = 0; i < axesTwo.size(); i++){
                                Projection projectionOne(axesTwo[i], object.GetOutline());
                                Projection projectionTwo(axesTwo[i], objectTwo.GetOutline());

                                //but here, GetOverlap() actually returns a non zero number
                                float o = projectionOne.GetOverlap(projectionTwo);
                                if(o == 0.f){
                                        //no overlap
                                }
                                if(o < overlap){
                                        overlap = o;
                                        smallestAxis = axesTwo[i];
                                }
                        }

                        sf::Vector2f distance, aPos, bPos;
                        aPos = sf::Vector2f(object.GetOutline().getBounds().left + object.GetOutline().getBounds().width / 2, object.GetOutline().getBounds().top + object.GetOutline().getBounds().height / 2);
                        bPos = sf::Vector2f(objectTwo.GetOutline().getBounds().left + objectTwo.GetOutline().getBounds().width / 2, objectTwo.GetOutline().getBounds().top + objectTwo.GetOutline().getBounds().height / 2);
                        distance = aPos - bPos;

                        if(DotProduct(distance, smallestAxis) < 0.0f){
                                smallestAxis = -smallestAxis;
                        }
                       
                        for(int i = 0; i < objectTwo.GetOutline().getVertexCount(); i++){
                                objectTwo.GetOutline()[i].position -= (smallestAxis * overlap);
                        }
                }

                window.clear();
                window.draw(objectTwo.GetOutline());
                window.draw(object.GetOutline());
                window.display();
        }
        return 0;
}

 

And the new, not working SAT code, uses sf::ConvexShape in place of the VertexArray. That's the only change.
// SFML Test.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "SFML\Graphics.hpp"

sf::Vector2f Normalize(sf::Vector2f& input){
        if(sqrt(input.x * input.x + input.y * input.y) == 0){
        input.x = 1;
        return input;
    }
    float length = sqrt(input.x * input.x + input.y * input.y);

    input.x /= length;
    input.y /= length;
    return input;
}

sf::Vector2f GetNormalAxis(sf::ConvexShape &shape, int index){
        sf::Vector2f vectorOne = shape.getPoint(index);
    sf::Vector2f vectorTwo;
        if(index >= shape.getPointCount() - 1)
                vectorTwo = shape.getPoint(0);
    else
                vectorTwo = shape.getPoint(index + 1);

    sf::Vector2f normalAxis(-(vectorTwo.y - vectorOne.y), vectorTwo.x - vectorOne.x);
    normalAxis = Normalize(normalAxis);
    return normalAxis;
}

float DotProduct(sf::Vector2f &vectorOne, sf::Vector2f &vectorTwo){
    return vectorOne.x * vectorTwo.x + vectorOne.y * vectorTwo.y;
}

class WorldObject{
public:
        WorldObject(){}
        ~WorldObject(){}

        sf::ConvexShape &GetShape(){ return shape; }
private:
        //this is the only major change, a vertex array to a convex shape
        sf::ConvexShape shape;
};

class Projection{
public:
        Projection(sf::Vector2f &axis, sf::ConvexShape &shape){
                min = DotProduct(axis, shape.getPoint(0));
                max = min;

                for(int i = 1; i < shape.getPointCount(); i++){
                        float proj = DotProduct(axis, shape.getPoint(i));
                        if(proj < min){
                                min = proj;
                        }
                        else if(proj > max){
                                max = proj;
                        }
                }
        }
        ~Projection(){}

        float GetMin(){ return min; }
        float GetMax(){ return max; }

        float GetOverlap(Projection &projection){
                if(projection.GetMin() <= max && max <= projection.GetMax()){
                        return max - projection.GetMin();
                }
                else if(min <= projection.GetMax() && projection.GetMax() <= max){
                        return projection.GetMax() - min;
                }
                else{
                        return 0;
                }
        }
private:
        float min, max;
};

int _tmain(int argc, _TCHAR* argv[]){
        sf::RenderWindow window(sf::VideoMode(500, 500, 32), "Test");

        WorldObject object;
        WorldObject objectTwo;

        object.GetShape().setPointCount(3);
        object.GetShape().setPoint(0, sf::Vector2f(200, 180));
        object.GetShape().setPoint(1, sf::Vector2f(10, 180));
        object.GetShape().setPoint(2, sf::Vector2f(10, 240));
        object.GetShape().setFillColor(sf::Color::White);

        objectTwo.GetShape().setPointCount(4);
        objectTwo.GetShape().setPoint(0, sf::Vector2f(100, 0));
        objectTwo.GetShape().setPoint(1, sf::Vector2f(80, 0));
        objectTwo.GetShape().setPoint(2, sf::Vector2f(80, 20));
        objectTwo.GetShape().setPoint(3, sf::Vector2f(100, 20));
        objectTwo.GetShape().setFillColor(sf::Color::White);

        while(window.isOpen()){
                if(sf::Keyboard::isKeyPressed(sf::Keyboard::Escape)){
                        window.close();
                }
                if(sf::Keyboard::isKeyPressed(sf::Keyboard::Right)){
                        objectTwo.GetShape().move(.05, 0);
                }
                if(sf::Keyboard::isKeyPressed(sf::Keyboard::Left)){
                        objectTwo.GetShape().move(-.05, 0);
                }
                if(sf::Keyboard::isKeyPressed(sf::Keyboard::Down)){
                        objectTwo.GetShape().move(0, .05);
                }
                if(sf::Keyboard::isKeyPressed(sf::Keyboard::Up)){
                        objectTwo.GetShape().move(0, -.05);
                }

                if(sf::FloatRect(object.GetShape().getGlobalBounds()).intersects(sf::FloatRect(objectTwo.GetShape().getGlobalBounds()))){
                        std::vector<sf::Vector2f> axesOne;
                        std::vector<sf::Vector2f> axesTwo;

                        //for both shapes, get their axes
                        for(int i = 0; i < object.GetShape().getPointCount(); i++){
                                axesOne.push_back(GetNormalAxis(object.GetShape(), i));
                        }
                        for(int i = 0; i < objectTwo.GetShape().getPointCount(); i++){
                                axesTwo.push_back(GetNormalAxis(objectTwo.GetShape(), i));
                        }

                        //for both sets of axes
                        //project
                        float overlap = 50000000000;
                        sf::Vector2f smallestAxis;
               
                        for(int i = 0; i < axesOne.size(); i++){
                                Projection projectionOne(axesOne[i], object.GetShape());
                                Projection projectionTwo(axesOne[i], objectTwo.GetShape());

                                float o = projectionOne.GetOverlap(projectionTwo);
                                if(o == 0.f){
                                        //no overlap
                                }
                                if(o < overlap){
                                        overlap = o;
                                        smallestAxis = axesOne[i];
                                }
                        }

                        for(int i = 0; i < axesTwo.size(); i++){
                                Projection projectionOne(axesTwo[i], object.GetShape());
                                Projection projectionTwo(axesTwo[i], objectTwo.GetShape());

                                //GetOverlap() always returns 0. Why?
                                float o = projectionOne.GetOverlap(projectionTwo);
                                if(o == 0.f){
                                        //no overlap
                                }
                                if(o < overlap){
                                        overlap = o;
                                        smallestAxis = axesTwo[i];
                                }
                        }

                        sf::Vector2f distance, aPos, bPos;
                        aPos = sf::Vector2f(object.GetShape().getGlobalBounds().left + object.GetShape().getGlobalBounds().width / 2, object.GetShape().getGlobalBounds().top + object.GetShape().getGlobalBounds().height / 2);
                        bPos = sf::Vector2f(objectTwo.GetShape().getGlobalBounds().left + objectTwo.GetShape().getGlobalBounds().width / 2, objectTwo.GetShape().getGlobalBounds().top + objectTwo.GetShape().getGlobalBounds().height / 2);
                        distance = aPos - bPos;

                        if(DotProduct(distance, smallestAxis) < 0.0f){
                                smallestAxis = -smallestAxis;
                        }

                        objectTwo.GetShape().move(-smallestAxis * overlap);
                }

                window.clear();
                window.draw(objectTwo.GetShape());
                window.draw(object.GetShape());
                window.display();
        }

        return 0;
}

 

So the second block of code should also prevent the two shapes from colliding, but nothing happens because I found out that the GetOverlap() function always returns 0.

4
General / How to react to a collision (wall-sliding)?
« on: February 23, 2015, 10:46:26 pm »
I'm working out the basics oof the Seperating Axis Theorem, and using this code I found http://en.sfml-dev.org/forums/index.php?topic=12063.0 I was able to create this little program that works fine, in the respect that it simply returns whether the two objects collide. My question is, what do I do next to set the two objects apart from each other, but in the shortest distance possible. Most tutorials say "project one shape onto the axis of shortest distance between the two shapes" but I'm not sure how to do that code-wise. Here is the working program
// SFML Test.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "SFML\Graphics.hpp"
#include <iostream>

class Object : public sf::Drawable, public sf::Transformable{
public:
    Object() : shape( sf::TrianglesStrip, 6 ), verts( 4 ){
                //so this would create a sword (kind of) but other objects would instantiate these points as they see fit
        shape[0].position = sf::Vector2f(80, 100);
        shape[1].position = sf::Vector2f(80, 20);
        shape[2].position = sf::Vector2f(100, 100);
        shape[3].position = sf::Vector2f(100, 20);
        shape[4].position = sf::Vector2f(90, 10);
        shape[5].position = sf::Vector2f(80, 20);
    }
    sf::VertexArray& getShape()
                {return shape;}
private:
        virtual void draw(sf::RenderTarget& target, sf::RenderStates states) const
    {
        states.transform *= getTransform();
        target.draw( shape, states);
        for( int i = 0; i < verts.size(); i++ )
        {
            target.draw( verts[i], states);
        }
    }

        //each 2d shape will be made of various points, whether it is a simple square or a shape like a sword
    sf::VertexArray shape;
        //I think this is just for decoration, nothing required
    std::vector<sf::CircleShape> verts;
};

sf::Vector2f normalize( sf::Vector2f& input )
{
    if( sqrt(input.x*input.x + input.y*input.y) == 0 )
    {
        input.x = 1;
        return input;
    }
    float length = sqrt(input.x*input.x + input.y*input.y);

    input.x /= length;
    input.y /= length;
    return input;
}

sf::Vector2f getNormalAxis( sf::VertexArray& shape, int index )
{
    sf::Vector2f vector1 = shape[index].position;
    sf::Vector2f vector2;
    if( index >= shape.getVertexCount() - 1 )
        vector2 = shape[0].position;
    else
        vector2 = shape[index+1].position;

    sf::Vector2f normalAxis( -(vector2.y - vector1.y), vector2.x - vector1.x );
    normalAxis = normalize( normalAxis );
    return normalAxis;
}

float dotProduct( sf::Vector2f& vector1, sf::Vector2f& vector2 )
{
    return vector1.x*vector2.x + vector1.y*vector2.y;
}

bool sat( Object& shape1, Object& shape2 )
{
    sf::Vector2f vectorOffset( shape1.getPosition().x - shape2.getPosition().x, shape1.getPosition().y - shape2.getPosition().y );

    for( int i = 0; i < shape1.getShape().getVertexCount(); i++ )
    {
        sf::Vector2f axis = getNormalAxis( shape1.getShape(), i );

        float min1 = dotProduct( axis, shape1.getShape()[0].position );
        float max1 = min1;

        for( int j = 1; j < shape1.getShape().getVertexCount(); j++ )
        {
            float testNum = dotProduct( axis, shape1.getShape()[j].position );
            if( testNum < min1 )
                min1 = testNum;
            if( testNum > max1 )
                max1 = testNum;
        }

        float min2 = dotProduct( axis, shape2.getShape()[0].position );
        float max2 = min2;

        for( int j = 1; j < shape2.getShape().getVertexCount(); j++ )
        {
            float testNum = dotProduct( axis, shape2.getShape()[j].position );
            if( testNum < min2 )
                min2 = testNum;
            if( testNum > max2 )
                max2 = testNum;
        }

        float offset = dotProduct( axis, vectorOffset );
        min1 += offset;
        max1 += offset;

        float test1 = min1 - max2;
        float test2 = min2 - max1;

        if( test1 > 0 || test2 > 0 )
            return 0;
    }
    return 1;
}

int _tmain(int argc, _TCHAR* argv[]){
        sf::RenderWindow window(sf::VideoMode(500, 500, 32), "Test");

        Object object;
        Object objectTwo;

        objectTwo.getShape().resize(4);

        while(window.isOpen()){
                if(sf::Keyboard::isKeyPressed(sf::Keyboard::Escape)){
                        window.close();
                }
                if(sf::Keyboard::isKeyPressed(sf::Keyboard::Right)){
                        for(int i = 0; i < objectTwo.getShape().getVertexCount(); i++){
                                objectTwo.getShape()[i].position.x += .05;
                        }
                }
                if(sf::Keyboard::isKeyPressed(sf::Keyboard::Left)){
                        for(int i = 0; i < objectTwo.getShape().getVertexCount(); i++){
                                objectTwo.getShape()[i].position.x -= .05;
                        }
                }
                if(sf::Keyboard::isKeyPressed(sf::Keyboard::Down)){
                        for(int i = 0; i < objectTwo.getShape().getVertexCount(); i++){
                                objectTwo.getShape()[i].position.y += .05;
                        }
                }
                if(sf::Keyboard::isKeyPressed(sf::Keyboard::Up)){
                        for(int i = 0; i < objectTwo.getShape().getVertexCount(); i++){
                                objectTwo.getShape()[i].position.y -= .05;
                        }
                }

                /*you may want to change this if you don't like your console being flooded with outputs*/
                std::cout << sat(object, objectTwo);

                window.clear();
                window.draw(objectTwo);
                window.draw(object);
                window.display();
        }

        return 0;
}

 

So if the moving square runs into the complex shape, how would I reset the square just outside of the other shape? References to this code would be nice, but a link to a good tutorial on this would work just as well, thanks.

5
I'm working on a grid to speed up collision detection, and the way I have this set up is that a GridSquare class holds a std::vector of all the objects that are within that specific grid square (determined by using a sf::FloatRect::intersects()). Here is what I mean by this class:
class GridSquare{
public:
        GridSquare(float x, float y, float px, float py); //position.x, position.y, width, height,
        ~GridSquare();

        sf::RectangleShape &GetVisual();
        sf::FloatRect &GetGridSquare();

        void AddStationaryObject(sf::Transformable &object);
        void AddMovableObject(sf::Transformable &object);

        std::vector<sf::Transformable> &GetStationaryObjects();
        std::vector<sf::Transformable> &GetMovableObjects();
        std::vector<sf::Transformable> &GetGridObjects();
private:
//so in the gameloop I'll check for what objects intersect this float rect, and...
        sf::FloatRect gridSquare;
//...add these objects to the respective vectors below
        //stationary objects hold walls and such, movable objects would be player and projectiles
        std::vector<sf::Transformable> stationaryObjects_, movableObjects_, gridObjects_;
};

The issue is that sf::RenderWindow::draw() does not take a sf::Transformable as a parameter, so when I declare the vectors above as "std::vector<sf::Transformable>" and try to loop through the vector and draw the objects, this compiler error is thrown:
Quote
IntelliSense: no instance of overloaded function "sf::RenderWindow::draw" matches the argument list
            argument types are: (sf::Transformable)
            object type is: sf::RenderWindow   c:\Users\jordan\Documents\Visual Studio 2012\Projects\SFML Test\SFML Test\SFML Test.cpp   20
Here is a small code example to see for yourself:
int _tmain(int argc, _TCHAR* argv[]){
        sf::RenderWindow window;
        window.create(sf::VideoMode(500, 500, 32), "Test");
        //a vector of sf::Transformable, can't be drawn on screen because a transformable isn't a drawable
        std::vector<sf::Transformable> objectsToDraw;
        objectsToDraw.push_back(sf::RectangleShape(sf::Vector2f(20, 20)));

        while(window.isOpen()){
                //just calling the draw function here, no need to worry about updating because nothing is being updated
                window.clear();
                window.draw(objectsToDraw[0]); //throws an error that draw() doesn't take an argument of sf::Transformable
                window.display();
        }

        return 0;
}

So, the ideal fix would be to declare those std::vectors as std::vector<sf::Drawable>, that way their objects can be drawn, right? Well, that throws a different error:
Quote
Error   2   error C2259: 'sf::Drawable' : cannot instantiate abstract class   c:\program files (x86)\microsoft visual studio 11.0\vc\include\xmemory0   617

Again, a small code example:
#include "stdafx.h"
#include "SFML\Graphics.hpp"

int _tmain(int argc, _TCHAR* argv[]){
        sf::RenderWindow window;
        window.create(sf::VideoMode(500, 500, 32), "Test");
        //a vector of sf::Drawable, throws an error that the abstract class can't be instantiated
        std::vector<sf::Drawable> objectsToDraw;
        objectsToDraw.push_back(sf::RectangleShape(sf::Vector2f(20, 20)));

        while(window.isOpen()){
                //just calling the draw function here, no need to worry about updating because nothing is being updated
                window.clear();
                //window.draw(objectsToDraw[0]); //the error isn't thrown here, but above when the vector is declared
                window.display();
        }

        return 0;
}

I don't understand this error. I just want a std::vector that will hold all types of sfml drawable objects, which I can then iterate through and draw all the objects on screen. Any suggestions?

6
Graphics / SFML Texture only showing up as a black box?
« on: December 08, 2014, 02:31:03 pm »
I've heard of the white box issue, but why is only a black box rendering where my sprite is? My code was working fine until I gave the sprite its own class, then it stopped responding to all setPositions()'s and is only showing a 10*10 black box (the texture is 10*10 as well). Here is the new code I tried to implement
Flashlight::Flashlight(){
        light.setOrigin(light.getGlobalBounds().width / 4, light.getGlobalBounds().height / 2);
        light.setPosition(250, 250);
        light.setTexture(imgr.GetImage("images/light.png"));
}
light light is a class sprite. I set their velocites like this:
        if(sf::Keyboard::isKeyPressed(sf::Keyboard::Left)){
                flashlight.AddVelocity(sf::Vector2f(-1, 0));
        }

//and

void Flashlight::AddVelocity(sf::Vector2f increment){
        velocityX += increment.x;
        velocityY += increment.y;
}

//return functions
sf::Vector2f &Flashlight::GetVelocity(){
        if(velocityX >= MAX_FLASHLIGHT_VELOCITY.x){
                velocityX = MAX_FLASHLIGHT_VELOCITY.x;
        }
        if(velocityY >= MAX_FLASHLIGHT_VELOCITY.y){
                velocityY = MAX_FLASHLIGHT_VELOCITY.y;
        }
        return sf::Vector2f(velocityX, velocityY);
}

sf::Sprite Flashlight::GetLight(){
        return light;
}

//and move the sprite, which is also not working
void Engine::Update(float interpolation){
        if(CollisionTest() == false){
                flashlight.GetLight().move(flashlight.GetVelocity().x * interpolation * .8, flashlight.GetVelocity().y * interpolation * .8);
                flashlight.GetShader().setPosition(flashlight.GetLight().getPosition());
        }
}
 
Where flashlight is an object of my new class I created.
That's everything related to my new code. I'm not sure why the sprite is now unresponsive, but any help would be appreciated.

7
Graphics / Stuck in event loop when using Event::MouseMoved
« on: November 20, 2014, 06:47:01 pm »
I'm trying to use relative mouse movement to move a sprite around the screen, but I'm having trouble. The sprite doesn't move until I move the mouse completely off the screen, but only because this movement breaks the loop of Event::MouseMoved. Here is the event code:
while(window.pollEvent(event)){
                if(event.type == sf::Event::Closed){
                        window.close();
                }
                if(event.type == sf::Event::MouseMoved){
                        sf::Vector2f mouseOffsetOrigin = static_cast<sf::Vector2f>(sf::Mouse::getPosition(window));
                        float mouseOffsetX, mouseOffsetY;
                        mouseOffsetX = sf::Mouse::getPosition(window).x - mouseOffsetOrigin.x;
                        mouseOffsetY = sf::Mouse::getPosition(window).y - mouseOffsetOrigin.y;
//flashlight is a sprite
                        board.GetFlashlight().move(mouseOffsetX, mouseOffsetY);
//keep the mouse in the center of the screen
                        sf::Mouse::setPosition(sf::Vector2i(SCREEN_WIDTH / 2, SCREEN_HEIGHT / 2), window);
                }
                if(event.key.code == sf::Keyboard::Escape){
                        window.close();
                }

The code is pretty simple I think, but it's not working properly because the event loop never breaks out.

8
Graphics / How to see if there is a clear path between two sprites?
« on: November 18, 2014, 10:49:42 pm »
So let's say I have two objects and a bunch of walls or other obstructions on screen. What would be a way to see if the two objects (sprites, cursor and a sprite, etc) have a clear, unobstructed line of sight to each other (like the line of sight feature in Heroscape if there are any fans out there :P)? I tried extending a sf::FloatRect from one object to the next, and seeing if that collided with any of the wall objects, but you can't rotate floatrect objects so that won't work. Any other ideas?

9
Graphics / Help drawing sf::Text accurately on screen
« on: November 13, 2014, 06:22:57 pm »
Yes this has been discussed before, but from the hours I've spent searching I've never seen it solved. Basically, I'm trying to position a text object directly in the center of the screen, but it appears to be off by several pixels on both axels. Here is the basic code:
sf::Text text;
text.setString("sf text test");
//set origin to physical center of text
text.setOrigin(text.getGlobalBounds().left + (text.getGlobalBounds().width / 2), text.getGlobalBounds().top + (text.getGlobalBounds().height / 2));
//screen is 500 * 500, so this is the center of screen
text.setPosition(250, 250);
 
Yet the linked image is what happens on screen. Adding 20 pixels on the x value and 4 pixels on the y value seems to account for this shift perfectly. I've concluded that this is because there is a hidden, much larger bounding box around the text that is the result of getGlobalBounds(), so how do I account for this hidden variable?

10
Graphics / Does sf::Text render dashes?
« on: November 12, 2014, 02:25:50 pm »
I'm trying to make a graphical representation of an Emily Dickinson poem, which is full of dashes in its lines. I open a text file with the poem and read from it, copying the lines into sf::text objects, but when displayed the dashes just appear as empty boxes. Any suggestions?

11
Graphics / Crash when trying to draw sf::Text?
« on: October 23, 2014, 05:21:27 am »
My code was working fine when I was drawing RectangleShapes from a vector, but then I tried doing the same thing with sf::Text and got the error "Unhandled exception at 0x5E7FBA72 (sfml-graphics-d-2.dll) in Dickinson Project.exe: 0xC0000005: Access violation reading location 0x00000004." I'm not sure what's wrong, as the dll's can't be linked incorrectly since the other sfml objects were drawing fine. Here is the problem code:
void Engine::Render(){
        window.clear(sf::Color::Black);
        window.draw(board.GetWalls()[0].GetWallShape());
//comment the next line out, and program runs fine
    window.draw(board.GetTexts()[0].GetText());
        window.display();
}

Here is the Text class:

#include "stdafx.h"
#include "SFML\Graphics.hpp"

class Text{
public:
        Text(std::string str, float posx, float posy, float rotation, int size, sf::Color color);
        ~Text();

        sf::Text GetText();
private:
        sf::Text text;
        sf::Font font;
};


#include "stdafx.h"
#include "Text.h"

Text::Text(std::string str, float posx, float posy, float rotation, int size, sf::Color color){
        font.loadFromFile("fonts/arial.ttf");
        text.setFont(font);
        text.setString(str);
        text.setPosition(posx, posy);
        text.setCharacterSize(size);
        text.setRotation(rotation);
        text.setColor(color);
}

Text::~Text(){

}

sf::Text Text::GetText(){
        return text;
}

In another program I have, similar code displays sf::Texts just fine, so what could be the issue?


12
Graphics / Drawing a "flashlight texture" around mouse position?
« on: October 22, 2014, 06:33:28 am »
I'm working on a project for class and I'm trying to design a maze, and the mouse will be your character, but the character has a limited sight distance so I want only the surrounding 50-100 pixels to be drawn from the point of the cursor. Are there any tutorials somebody can point me to/is this even possible?

13
Graphics / Problem with VertexArray declaration?
« on: October 07, 2014, 03:24:34 am »
In the tutorial for sf:VertexArrays, this line of code is given as an example declaration:
sf::VertexArray quad(sf::Quads, 4);
However, when I copy and paste this into my own project, like so:
struct Tetromino{
   std::string filename;
   sf::VertexArray quad(sf::Quads, 4);
   // write a constructor taking a string and four vertices
   Tetromino(std::string filename, sf::VertexArray squares);
   ~Tetromino();
};
 
I get the error "constant sf::Quads is not a type name". Why is this happening? Is this a bug or error in the documentation?

14
Graphics / Rotating a sprite is causing some really weird bugs
« on: October 02, 2014, 05:56:14 pm »
I'm trying to implement rotation into my tetris clone and it is going terribly. Basically, when I try and set the tetrimino's sprite's origin to its center so I can rotate it without changing the position any, the sprite moves a lot farther on the screen that it should. Like it moves by tens of pixels each time. Here is the rotate function:
void GamePiece::RotateLeft(){
        if(originCount != 10){
                bool rotate = true;
                int newx, newy;
                sf::Vector2f origin(pieceRectangles_[0].getPosition().x + originCount, pieceRectangles_[0].getPosition().y + originCount);
                for(int i = 0; i < 4; i++){
                        newx = (origin.x + origin.y - pieceRectangles_[i].getPosition().y - 10);
                        newy = (pieceRectangles_[i].getPosition().x + origin.y - origin.x);

                        sf::RectangleShape temp = pieceRectangles_[i];
                        temp.setPosition(newx, newy);
                        sf::FloatRect fr = temp.getGlobalBounds();

                        for(int j = 0; j < levelCollisions.size(); j++){
                                if(fr.intersects(levelCollisions[j])){
                                        rotate = false;
                                }
                        }
                }
                if(rotate == true){
                        for(int i = 0; i < 4; i++){
                                newx = (origin.x + origin.y - pieceRectangles_[i].getPosition().y - 10);
                                newy = (pieceRectangles_[i].getPosition().x + origin.y - origin.x);
                                pieceRectangles_[i].setPosition(newx, newy);
                        }
                        pieceShape.setOrigin(pieceShape.getPosition().x + pieceShape.getGlobalBounds().width / 2, pieceShape.getPosition().y + pieceShape.getGlobalBounds                                                       ().height / 2);
                        pieceShape.rotate(90);
                        pieceShape.setOrigin(pieceShape.getPosition());
                }
        }
}

The first half with the for loops and such is the part that rotates all the individual squares which I use for collision detection. This part works perfectly (I have their color set to blue so I can see where they are moving versus the new position of the actual sprite). The problem starts at pieceShape.setOrigin(). I'm trying to set the sprite's origin to its center so I can rotate it smoothly, but the sprite spirals out from where it should have been, with increasing distance everytime.

15
Graphics / SFML 2.1 Vertex Example/Tutorial?
« on: September 22, 2014, 08:07:13 pm »
Correct me if I am wrong, but I can design an oddly shaped sprite myself by creating and storing a series of sf::vertex's, right? For instance, if I wanted to get the bounds of a sprite that's not a rectange shape, like a tetrimino that's not a square piece, I could set some sf::vertex's on the tetrimino's actual vertex's and call it a sprite, correct? The documentation is sort of weak on examples, so can somebody provide a more detailed explanation of how to use sf::vertex to create bounds for objects?

Pages: [1] 2
anything