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.


Messages - MarcusM

Pages: [1]
1
General / Re: Store a made texture by the program for future use
« on: December 12, 2013, 01:31:32 pm »
As eXpl0it3r is suggesting, you should only "draw" the car once over to a texture/rendertexture, leaving you with only one for-loop to draw the car rather than a for-loop in every single frame.

2
Graphics / [FIXED] Create a block (using sf::RenderTexture) of tiles
« on: December 12, 2013, 08:45:42 am »
FIXED: Did some modifcations, here's the final result:
// TileBlock.cpp

#include "TileBlock.h"

#include <iostream>

FlxTileBlock::FlxTileBlock(int x, int y, unsigned int w, unsigned int h)
{
    m_texture.create(w, h);
    m_texture.clear(sf::Color(0, 0, 255));

    m_sprite.setPosition(x, y);

    active = false;
    immovable = true;

    width = w;
    height = h;
}
void FlxTileBlock::draw(sf::RenderTexture &rendertexture)
{
    rendertexture.draw(m_sprite);
}
void FlxTileBlock::loadTiles(sf::Image& tilesheet, unsigned int tilewidth, unsigned int tileheight)
{
    unsigned int total = tilesheet.getSize().x / tilewidth;

    unsigned int row = 0;
    unsigned int column;
    unsigned int destinationX;
    unsigned int destinationY = 0;
    unsigned int widthInTiles = width/tilewidth;
    unsigned int heightInTiles = height/tileheight;

    while (row < heightInTiles)
    {
        destinationX = 0;
        column = 0;
       
        while (column < widthInTiles)
        {
            int randomFrame = rand()%total;
           
            sf::Texture tempTexture;
            tempTexture.loadFromImage(tilesheet, sf::IntRect(randomFrame*tilewidth, 0, tilewidth, tileheight));

            sf::Sprite tempSprite(tempTexture);
            tempSprite.setPosition(destinationX, destinationY);

            m_texture.draw(tempSprite);

            destinationX += tilewidth;
            column++;
        }
        destinationY += tileheight;
        row++;
    }

    // update sprite
    m_texture.display();
    m_sprite.setTexture(m_texture.getTexture());
}



Hi there.

I am currently trying to create a block of tiles, when given the position, width, height and a tilesheet.

I am using a sf::RenderTexture so that I am able to create temporary textures and sprites and then draw them ontop of my RenderTexture. The RenderTexture is then used to create a sprite for my block.

However, when I draw it on top of my map, it's just black (the clearColor) as if nothing had been drawn on top of it. Is it because that sf::RenderTexture must keep a reference to the textures that were used on top of it?

Here's my current code:
// TileBlock.cpp

#include "TileBlock.h"

#include <iostream>

FlxTileBlock::FlxTileBlock(int x, int y, unsigned int w, unsigned int h)
{
    m_texture.create(w, h);
    m_texture.clear(sf::Color(0, 0, 0));

    m_sprite.setPosition(x, y);

    active = false;
    immovable = true;

    width = w;
    height = h;
}
void FlxTileBlock::draw(sf::RenderTexture &rendertexture)
{
    rendertexture.draw(m_sprite);
}
void FlxTileBlock::loadTiles(sf::Texture& tilesheet, unsigned int tilewidth, unsigned int tileheight)
{
    unsigned int total = tilesheet.getSize().x / tilewidth;

    // create temporary image from sf::Texture
    sf::Image image = tilesheet.copyToImage();

    unsigned int row = 0;
    unsigned int column;
    unsigned int destinationX;
    unsigned int destinationY;
    unsigned int widthInTiles = width/tilewidth;
    unsigned int heightInTiles = height/tileheight;

    while (row < heightInTiles)
    {
        destinationX = 0;
        column = 0;
       
        while (column < widthInTiles)
        {
            int randomFrame = rand()%total;
            randomFrame = 2;
           
            sf::Texture tempTexture;
            tempTexture.loadFromImage(image, sf::IntRect(randomFrame*tilewidth, 0, tilewidth, tileheight));

            sf::Sprite tempSprite(tempTexture);
            tempSprite.setPosition(destinationX, destinationY);

            m_texture.draw(tempSprite);

            std::cout << "drew something" << std::endl;

            destinationX += tilewidth;
            column++;
        }
        destinationY += tileheight;
        row++;
    }

    // update sprite
    m_texture.display();
    m_sprite.setTexture(m_texture.getTexture());
}

 

// TileBlock.h

#ifndef _TILEBLOCK_H_
#define _TILEBLOCK_H_

#include "stdafx.h"
#include "base.h"
#include "sys.h"

#include "Entities.h"

class FlxTileBlock
{
private:
    sf::RenderTexture m_texture;
    sf::Sprite m_sprite;

public:
    FlxTileBlock(int x, int y, unsigned int w, unsigned int h);

    int width;
    int height;

    bool active;
    bool immovable;

    void draw(sf::RenderWindow &window);
    void draw(sf::RenderTexture &rendertexture);

    void loadTiles(sf::Texture& tilesheet, unsigned int tilewidth=0, unsigned int tileheight=0);

};

#endif
 

3
Graphics / [Sprite] Modifying the bounds of a sprite
« on: November 19, 2013, 12:18:00 pm »
Hi there.

Is it possible to modify the FloatRect retrieved from a sprite by using sf::Sprite::getGlobalBounds?

I have a character sprite that uses a texture of 8x8px, but I want to edit it, so that the physical bounds of the sprite are 7x6px, rather than 8x8px, when checking for collisions against other sprites such as platformer tiles.

I can think of two ways of doing this:
  • Being able to modify the bounds of the sprite or
  • by modifying my collision detection code, so that instead of parsing the sf::Sprite of my objects, I should pass a custom sf::FloatRect which holds the collision detection bounds.

I would prefer the first method.

4
General / Re: Flipping the texture on an AnimatedSprite class
« on: October 18, 2013, 12:37:56 pm »
Ah cheers! Thanks for the explanation.

5
General / Re: Flipping the texture on an AnimatedSprite class
« on: October 18, 2013, 12:10:07 pm »
Try passing a negative number to setScale().

Tried implementing a AnimatedSprite::flipTexture() function:
void AnimatedSprite::flipTexture()
{
    setOrigin(getGlobalBounds().width/2, 0);
    setScale(-1.f,1.f);
    setOrigin(0, 0);
}

But I am having some trouble with the sprite changing position. Am I using the setOrigin correctly?

EDIT: This appears to work:
void AnimatedSprite::flipTexture()
{
    setOrigin(getGlobalBounds().width, 0);
    setScale(-1.f,1.f);
}

Will I face any problems with having a modified origin?

6
General / [SOLVED] Flipping the texture on an AnimatedSprite class
« on: October 18, 2013, 11:49:40 am »
Hi guys.

I am currently implementing spritesheets into my game rather than having static images moving around all over the places.
For this, I am using the source provided on the Github wiki: https://github.com/SFML/SFML/wiki/Source%3A-AnimatedSprite

It's working just fine, except I am having some trouble flipping the sprite when the character is moving in the opposite direction of the spritesheet.

I have a little trouble wrapping my head around how it should be done, as the AnimatedSprite class isn't inheriting from sf::Sprite, so that I can't do the simple:
// flip X
sprite.setTextureRect(sf::IntRect(width, 0, -width, height));

Has anyone implemented a such feature in their AnimatedSprite class? If so, how did you do it?

Thanks for your time.

7
I read you can't use list.erase() while iterating using a C++11 range loop, but how would I go about doing it then?
Use a conventional iterator loop like in good old times. You can even deduce the type with auto.

My game segfaults when using erase while iterating.
Assign the return value of erase() to the iterator, and make sure you don't increment the iterator in the cases where you erase.
Cheers once again! Works beautifully.

8
Instead of std::vector<std::unique_ptr<T>>, it would be easier to use a different container such as std::list<T> or std::deque<T>.

With C++11, you can deduce the type by replacing std::vector<...>::iterator with auto, or even better, use the range-based for loop:
for (Projectile& p : _projectileArray)
{
    p.update();
    CheckBulletCollision(p);
}

I've messed around with using a std::list rather than std::vector<std::unique_ptr...>>, and it works like a charm except in the cases when I need to remove items from the list.
I read you can't use list.erase() while iterating using a C++11 range loop, but how would I go about doing it then? My game segfaults when using erase while iterating.

9
You don't need to pass the smart pointer around, just pass around a reference to the smart pointer's object.

Change

void Engine::CheckBulletCollision(std::unique_ptr<Projectile> projectile, int i)
...
CheckBulletCollision(_projectileArray[i], i)
 

To

void Engine::CheckBulletCollision(Projectile& projectile, int i)
...
CheckBulletCollision(*_projectileArray[i], i)
Sorry for the double-posting, but just to be sure that I understood what happened. Could you explain to me why the other sprites suddenly turned white when erasing a BulletPistol() from the std::vector array?

10
You don't need to pass the smart pointer around, just pass around a reference to the smart pointer's object.

Change

void Engine::CheckBulletCollision(std::unique_ptr<Projectile> projectile, int i)
...
CheckBulletCollision(_projectileArray[i], i)
 

To

void Engine::CheckBulletCollision(Projectile& projectile, int i)
...
CheckBulletCollision(*_projectileArray[i], i)

The textures are now working perfectly. Thanks for your help!

11
I assume that this now means that the array, _projectileArray, now holds pointers to the BulletPistol class rather than a BulletPistol class itself. Is this correct?

Yes, and since you are using a smart pointer you do not need to worry about memory leaks, the smart pointer will automatically delete the BulletPistol class when it goes out of memory.

Quote
If so, how would the push_back look?

_projectileArray.push_back(std::unique_ptr<Projectile>(new BulletPistol(...)));

Thanks for all your help and guidance!

I am having some trouble in my CheckBulletCollision function, which deletes the bullets if they collide.
Is my iteration over the std::vector array wrong now?

Source:
...
void Engine::Update()
{
    sf::Vector2i mousePos = SYS_MousePos(window);
    Player.update(window.mapPixelToCoords(mousePos));

    // update bullets
    for (int i = _projectileArray.size() - 1; i >= 0; --i)
    {
        _projectileArray[i]->update();
        CheckBulletCollision(_projectileArray[i], i);
    }

    // update camera position
    UpdateCamera();

}
...
void Engine::CheckBulletCollision(std::unique_ptr<Projectile> projectile, int i)
{
    // left
    if (projectile->getPosition().x < window.mapPixelToCoords(sf::Vector2i(0, 0)).x)
    {
        _projectileArray.erase(_projectileArray.begin() + i);
        return;
    }
    // right
    if (projectile->getPosition().x > window.mapPixelToCoords(sf::Vector2i(SYS_WIDTH, 0)).x)
    {
        _projectileArray.erase(_projectileArray.begin() + i);
        return;
    }
    // up
    if (projectile->getPosition().y < window.mapPixelToCoords(sf::Vector2i(0, 0)).y)
    {
        _projectileArray.erase(_projectileArray.begin() + i);
        return;
    }
    // down
    if (projectile->getPosition().y > window.mapPixelToCoords(sf::Vector2i(0, SYS_HEIGHT)).y)
    {
        _projectileArray.erase(_projectileArray.begin() + i);
        return;
    }
}
 

Here's the error, which I just can't seem to figure out:
Code: [Select]
$ make all && ./main.x64
g++ -std=c++11 -Wno-switch -Iinclude -c cpp/game.cpp
cpp/game.cpp: In member function ‘void Engine::Update()’:
cpp/game.cpp:121:52: error: use of deleted function ‘std::unique_ptr<_Tp, _Dp>::unique_ptr(const std::unique_ptr<_Tp, _Dp>&) [with _Tp = Projectile; _Dp = std::default_delete<Projectile>]’
         CheckBulletCollision(_projectileArray[i], i);
                                                    ^
In file included from /usr/include/c++/4.8.1/memory:81:0,
                 from cpp/stdafx.h:17,
                 from cpp/game.cpp:2:
/usr/include/c++/4.8.1/bits/unique_ptr.h:273:7: error: declared here
       unique_ptr(const unique_ptr&) = delete;
       ^
In file included from cpp/game.cpp:6:0:
cpp/game.h:22:10: error:   initializing argument 1 of ‘void Engine::CheckBulletCollision(std::unique_ptr<Projectile>, int)’
     void CheckBulletCollision(std::unique_ptr<Projectile> projectile, int i);
          ^
make: *** [game.o] Error 1

12
Just to be sure, you suggest to use a std::unique_ptr rather than std::vector?

No, use a std::unique_ptr<BulletPistol> with a std::vector<T>. So in the end you have std::vector<std::unique_ptr<BulletPistol>>.

In my engine I have changed
std::vector<Projectile> _projectileArray
to now
std::vector<std::unique_ptr<Projectile>> _projectileArray;
.

I assume that this now means that the array, _projectileArray, now holds pointers to the BulletPistol class rather than a BulletPistol class itself. Is this correct?

If so, how would the push_back look?

13
Quote
You have a couple things going.

_projectileArray.push_back(newBullet);

When you store your class in the array like that you are actually copying the BulletPistol class into the array (and thus when the array/vector is resized your copying your BulletPistol class again). Use a std::unique_ptr<BulletPistol> instead with your array to avoid copying.
Just to be sure, you suggest to use a std::unique_ptr rather than std::vector?

Quote
And you should reread the tutorial on textures and pay close attention to the end about minimizing your textures. You are loading a new texture for every BulletPistol instance when you should already have it loaded and be reusing the same texture.

That is most certainly on my todo-list. Just wanted to get something up on the screen ASAP.

14
Hi guys.

I am having some trouble with sprites turning white (not starting out as white).

I have an array of bullets (an array of BulletPistol()) and they are initialized just fine with a texture. Problem occurs when my collision detecting erases an array entry, the other bullets turn white - so it seems that they lose reference to my texture. Why does this occur, when every single bullet should (well, they should atleast) have their own reference to the texture?

The bullets are erased using the erase() command and are added to the array like so:
BulletPistol newBullet(Player.getHandPosition(), Player.getHandRotation());
_projectileArray.push_back(newBullet);

I worry that I have messed up in my class structures.

Here are some of the classes I use:
class PhysicalObject
{
protected:
    sf::Texture _image;
    sf::Sprite _sprite;

public:
    float xVel;
    float yVel;
    float speed;

    PhysicalObject();
    PhysicalObject(const PhysicalObject& other) : _image(other._image), _sprite(other._sprite), xVel(other.xVel), yVel(other.yVel)
    {
        _sprite.setTexture(_image);

    };
    virtual ~PhysicalObject();

    virtual void update();
    virtual void draw(sf::RenderWindow &window);
    sf::Vector2f getPosition();
    float getRotation();
};

//-----------------------------------------------------------------------------
class Projectile : public PhysicalObject
{
public:
    Projectile();
    Projectile(const Projectile& other) : PhysicalObject(other) {};
    virtual ~Projectile();

    bool isDead;
    int pushBack;
    float angle;
    void die();
};

//-----------------------------------------------------------------------------

class BulletPistol : public Projectile
{
public:
    BulletPistol(sf::Vector2f position, float angle);
    BulletPistol(const BulletPistol& other) : Projectile(other) {};
    ~BulletPistol();

private:
};

PhysicalObject::PhysicalObject()
{
    speed = 0.f;
    xVel = 0.f;
    yVel = 0.f;
}
PhysicalObject::~PhysicalObject()
{

}
void PhysicalObject::update()
{
    _sprite.move(xVel, yVel);
}
void PhysicalObject::draw(sf::RenderWindow &window)
{
    window.draw(_sprite);
}
sf::Vector2f PhysicalObject::getPosition()
{
    return _sprite.getPosition();
}
float PhysicalObject::getRotation()
{
    return _sprite.getRotation();
}

//-----------------------------------------------------------------------------
Projectile::Projectile()
{
    pushBack = 2;
    isDead = false;
}
Projectile::~Projectile()
{
}
void Projectile::die()
{
    isDead = true;
}

//-----------------------------------------------------------------------------
BulletPistol::BulletPistol(sf::Vector2f position, float angle)
{
    // general
    _image.loadFromFile("resources/bullet_rpg.png");
    _image.setSmooth(true);
    _sprite.setTexture(_image);
    _sprite.setOrigin(_image.getSize().x/2, _image.getSize().y/2);
    _sprite.setPosition(position);
    _sprite.setRotation(angle + 180);

    // specifications
    speed = 20.0;

    // start moving
    angle -= 180;
    xVel = cos(angle*PI/180) * speed;
    yVel = sin(angle*PI/180) * speed;
}
BulletPistol::~BulletPistol()
{
   
}
 

Pages: [1]
anything