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 - thePyro_13

Pages: [1] 2 3 ... 11
1
Feature requests / Re: std::exit()
« on: August 14, 2022, 06:27:04 am »
The only crash I experienced was due to a dependency between sharedContext and contextDestroyCallbacks.

Since both are static they are only accessed from within GLContext.cpp the issue can be resolved by putting those two into a static struct and manually destructing the sharedContext first:
static struct SharedContextStruct {
            ~SharedContextStruct() noexcept
            {
                sharedContext.reset();
            }

            std::unique_ptr<ContextType> sharedContext;
            ContextDestroyCallbacks contextDestroyCallbacks;
        } sharedContextData;
This doesn't change any of the other interactions with these objects, except to add the member access, but will ensure that sharedContext is always destroyed before contextDestroyCallbacks.

EDIT: There shouldn't be any risk of accessing already destroyed objects through this, since those objects destructors should have removed them from the calback list.

2
Feature requests / std::exit()
« on: August 09, 2022, 06:18:08 am »
Currently sfml will cause a crash(MSVC2022) if std::exit is called after using any of the SFML Graphics objects.

In the debugger the crash appears in GLContext.cpp:752 when calling the elements in contextDestroyCallbacks.
This is because std::exit will skip destruction of stack objects, but will still call static global objects destructors.
I think this is during the destructor of the global shared context.

This might be fixed by sticking the static global objects into a static global struct together, so that the callback list won't be destroyed before the shared context. SFML could also register a function to clear the shared context before the static objects are destroyed using std::atexit.

I've moved to using std::quick_exit, but I think it would be worth it to get std::exit working with SFML.

3
General discussions / Dynamic Split Screen
« on: March 12, 2014, 11:27:02 am »
Here's a quick bit of example code on what I call Dynamic Split Screens, this is the effect I first encountered in one of the newer Lego Star Wars games.

I was inspired to give this a shot after reading this post about non axis aligned viewports.
I had already written this post but managed to lose it(I compulsively hit refresh :(). So please tell me if their is anything I missed or should explain in more detail. :(

The goal is to smoothly split and re-merge the two split views based on player locations.
This provides a good middle ground between games that don't use split screens at all(like Super Smash Bro.'s) and games that use static split rectangles, like most console games.

We don't want to split into predefined rectangles, because this can disorient players when their avatar jumps to the opposite side of the screen, we also want to avoid the same problem when re-merging the views.

The solution is to have the two views dynamically generated based on the players relative positions to one another. Also we make sure that the views can cleanly rotate around one other if the players end up circling one another.

This explanation is much worse than my original one, so here's a video showing it off:


Finally, here's the code:
I use SFML for most of the work, and Thor for some vector maths.
The map.png I'm using is just a big image of the world from the original Legend of Zelda.
//===============================================================
// Dynamic Split Screen Example for SFML(http://sfml-dev.org/)
//
// The code in this file was developed by Steven Pilkington.
// More information about this example can be
// found on my blog(http://cyangames.wordpress.com/)
//
// I'm putting this in the public domain, so have fun with it.
//
//                                                                                              Date: 12/03/2014
//===============================================================

#include "SFML/Graphics.hpp"

#include "Thor/Vectors.hpp"

//Set the window resolution.
const int WIDTH = 800;
const int HEIGHT = 600;

//Ditermine if the views should be split based on the difference between both players positions.
bool shouldSplit(sf::Vector2f position1, sf::Vector2f position2);

//Calculate the camera position for the object at position1, moving the camera in the direction of position2.
sf::Vector2f viewPosition(sf::Vector2f position1, sf::Vector2f position2);

int main()
{
        //Create window.
        sf::RenderWindow window;
        window.create(sf::VideoMode(WIDTH, HEIGHT), "Dynamic Split Screen");

        //Create two player sprites.
        sf::Vector2f playerSize(10, 10);
        sf::RectangleShape p1(playerSize), p2(playerSize);

        p1.setFillColor(sf::Color::Blue);
        p2.setFillColor(sf::Color::Red);

        //Multiply our movements by this to control player movement speed.
        const float PLAYERSPEED = .1f;

        //Create background.
        //We're using a big image of the origional Legend of Zelda game world as our background.
        sf::Texture mapTex;
        mapTex.loadFromFile("map.png");
        sf::Sprite map(mapTex);
        //Move the background sprite so that the world origin is somewhere in the middle of the map.
        map.setPosition(-sf::Vector2f(map.getLocalBounds().width / 2.f, map.getLocalBounds().height / 2.f));

        //Create our views.
        //One for each player, player ones view is also used for both players when the views are merged.
        sf::View p1View = window.getView();
        sf::View p2View = window.getView();

        //View movement speed.
        const float VIEWSPEED = .2f;

        //Rendertexture is used to render player twos view of the world.
        sf::RenderTexture p2Tex;
        p2Tex.create(WIDTH, HEIGHT);
        sf::Sprite p2Sprite;

       

        //We use a large rectangle to draw the devider between the two camaras in slit screen mode.
        //We also use this to blend the two views together.
        sf::RectangleShape eraser;
        eraser.setOutlineColor(sf::Color::Black);
        eraser.setFillColor(sf::Color::Transparent);
        eraser.setOutlineThickness(2);
        eraser.setSize(sf::Vector2f(WIDTH*2, HEIGHT*2));

        //Start main loop.
        while(window.isOpen())
        {
                //Handle events.
                sf::Event e;
                if(window.pollEvent(e))
                {
                        if(e.type == sf::Event::Closed)
                                window.close();
                }

                //User controls.
                sf::Vector2f move;
                //Player one input.
                if(sf::Keyboard::isKeyPressed(sf::Keyboard::W))
                        move.y += -1;

                if(sf::Keyboard::isKeyPressed(sf::Keyboard::S))
                        move.y += 1;

                if(sf::Keyboard::isKeyPressed(sf::Keyboard::A))
                        move.x += -1;

                if(sf::Keyboard::isKeyPressed(sf::Keyboard::D))
                        move.x += 1;

                p1.move(move * PLAYERSPEED);

                //Reset the move vector.
                move = sf::Vector2f();
                //Player two input.
                if(sf::Keyboard::isKeyPressed(sf::Keyboard::Up))
                        move.y += -1;

                if(sf::Keyboard::isKeyPressed(sf::Keyboard::Down))
                        move.y += 1;

                if(sf::Keyboard::isKeyPressed(sf::Keyboard::Left))
                        move.x += -1;

                if(sf::Keyboard::isKeyPressed(sf::Keyboard::Right))
                        move.x += 1;

                p2.move(move * PLAYERSPEED);

                //Now we need do decide if we split our views.
                bool singleView = true;
                //Ideal position is the location that the camera wants to be in.
                sf::Vector2f idealPos;
       
                if(shouldSplit(p1.getPosition(), p2.getPosition()))
                {                      
                        //We want to split, so we calculate the ideal position for each camera using viewPosition().
                        singleView = false;
                        idealPos = viewPosition(p1.getPosition(), p2.getPosition());
                        p1View.move( (idealPos - p1View.getCenter()) * VIEWSPEED);

                        idealPos = viewPosition(p2.getPosition(), p1.getPosition());
                        p2View.move( (idealPos - p2View.getCenter()) * VIEWSPEED);
                }
                else
                {
                        //If we don't want a split view, then the ideal position is the halfway
                        //point between both players.
                        idealPos = (p1.getPosition() + p2.getPosition()) / 2.f;
                        p1View.move( (idealPos - p1View.getCenter()) * VIEWSPEED);
                        //Set player twos cameras to the same as player ones, this will avoid an jump if the cameras split again
                        //far away from where they last merged.
                        p2View.setCenter(p1View.getCenter());
                }

                //Draw everything from player ones point of view.
                window.clear();
                window.setView(p1View);
                window.draw(map);
                window.draw(p1);
                window.draw(p2);

                //If we're splitting the views then we'll do the same for player twos view.
                if(!singleView)
                {
                        //Draw all our normal stuff from players twos point of view.
                        p2Tex.clear();
                        p2Tex.setView(p2View);
                        p2Tex.draw(map);
                        p2Tex.draw(p1);
                        p2Tex.draw(p2);

                        //Now calculate where to place our rectangle to properly divide the screen.
                        //We start in the centre of the window.
                        eraser.setPosition(window.mapPixelToCoords(sf::Vector2i(WIDTH/2, HEIGHT/2), p2View));
                        //Then we calcuate a vector representing the line that will split the two views.
                        //This line is perpendicular to the line between both players.
                        sf::Vector2f angle = thor::perpendicularVector(p1.getPosition() - p2.getPosition());
                        thor::setLength(angle, static_cast<float>(HEIGHT));
                        //Move the rectangle along this line so that it will stretch across the entire screen.
                        eraser.move(angle);
                        //Rotate the rectangle so that it covers the side of the screen that we want to be blended with player ones view.
                        eraser.setRotation(-(thor::signedAngle(angle, sf::Vector2f(1, 1)) + 135));

                        //Draw the rectangle to our rendertexture using BlendMode None.
                        p2Tex.draw(eraser, sf::BlendMode::BlendNone);
                        p2Tex.display();

                        //Assign the tecture to a sprite.
                        p2Sprite.setTexture(p2Tex.getTexture());
                        //Draw it over the origin so that our rectangle math works out properly.
                        window.setView(window.getDefaultView());
                        //Draw it to the window.
                        window.draw(p2Sprite);
                }

                window.display();
        }


        return EXIT_SUCCESS;
}

bool shouldSplit(sf::Vector2f position1, sf::Vector2f position2)
{
        //If the two positions are more than a half of the average of the screens
        //width and height then we'll split.
        sf::Vector2f dist = position1 - position2;
        if(thor::length(dist) > (WIDTH + HEIGHT) / 4)
                return true;

        return false;
}

sf::Vector2f viewPosition(sf::Vector2f position1, sf::Vector2f position2)
{
        //Our camera position is currently set to keep the player within a circular area of the screen.
        //It would probably be better to convert this to instead keep them within a elliptical area.
        sf::Vector2f out = position1;

        //MAX_DISTANCE will keep position1 on the screen, reguardless of how far away it is from position2.
        const float MAX_DISTANCE = (WIDTH + HEIGHT) / 5;
        //this is the ideal position, the halfway point between both players, the camera will gravitate towards this position
        //so that things meet up nicely when the views merge.
        sf::Vector2f direction = (position2 - position1) / 2.f;

        //Use MAX_DISTANCE to trim our direction vector if it is too long,
        //eg. If it would put position1 off the edge of the screen.
        if(thor::length(direction) > MAX_DISTANCE)
                thor::setLength(direction, MAX_DISTANCE);

        return out + direction;
}

This should work as a good starting point for someone who wants to add this technique to their own project. Theirs are fair bit of cleaning up and improving to do, mostly the player positions should be constrained to an ellipsis rather than a circle, currently the players can end up far too close to the screen edge.

I'll be putting this up on my blog and the SFML wiki as as well, probably tomorrow or the day after.

Criticism welcome(especially when it comes to my maths), If anyone can think of any small features like this that they'd like to see in an example then tell me, I'll give it a shot.

4
I prefer music without lyrics when working on something. So I tend to listen to soundtracks. Currently I listen to the Bastion soundtrack while programming.

5
If I remember correctly (and according to the wikipedia page), XInput is basically only for XBox 360 controllers.

It's encouraged by Microsoft for all controllers(though hasn't been adopted) and games(some newer games seem to support Xinput controllers much better than DirectInput ones). It seems like some of the newer Logitech controllers use both Xinput and DirectInput(with some kind of physical switch to change between them).

I was doing a bit of reading into this and found this on MSDN(http://msdn.microsoft.com/en-us/library/windows/desktop/hh405052(v=vs.85).aspx). It looks like the Flight stick mapping does separate the triggers into two axis(Z and Rz). This might lead to a workable solution for full 360 controller support on Windows.

6
General discussions / Re: A new logo for SFML
« on: March 31, 2013, 08:44:16 am »
Maybe rather than an actual arrow, a stylised arrow(such as those used to represent vectors) would be more appropriate, as it can be seen as an arrow, but is also a much more simplistic icon.

7
SFML projects / Re: The Wanderer
« on: March 31, 2013, 08:31:25 am »
This is looking pretty good, I'd like to see a video of it action too please. :D

To those having .dll problems, the dll you cite is part of the visual C++ runtime 1012(if I remember the version numbers correctly). It can be correctly installed using this installer http://www.microsoft.com/en-au/download/details.aspx?id=30679

8
Graphics / Re: Changing the Hue of a Sprite
« on: February 01, 2013, 03:57:46 am »
Try using something like this HSL colour class(from the sfml github wiki)

getColour() from the sprite, convert it into a HSL colour object, modify the hue, and then convert it back.

The github code comes with functions to convert back and forth between HSL colour objects and sfml colour objects.

9
Try separating the animation choice from the actual input. A possible way to do this is by choosing the animation based on the delta movement from the previous frame(or maybe a fractional second ago).

This way you should still trigger the correct animation even if you move perfectly horizontal or vertical for a single frame.

10
SFML projects / Re: Thor 2.0
« on: January 14, 2013, 10:41:18 am »
So I've been hooking as much of my game up with thor::Action as possible over the past few days and have run into an issue.

When subscribing joystick buttons, we provide the joystick ID and the button. However, the joystick axis movement seems like it can only be subscribed with the JoyMoved Event. I had hoped that I'd be able to subscribe specific axis from specific joysticks, but this doesn't appear to be possible with the current thor::Action API.

This isn't a problem with MouseMove events, as their can only be one logical mouse cursor, but that isn't the case with joysticks and their axis.

Is a more specific subscription available for joystick axis? Or does Thor not currently provide anything like this?

11
Window / Re: Key combinations in SFML
« on: January 11, 2013, 03:36:45 pm »
If i understand your question correctly then you should use the input classes for this rather than the event based ones.

Assuming you're on 2.0, this can be done by querying sf::Mouse and sf::Keyboard. Use sf::Input for 1.6.

Pseudocode for SFML2:
if(sf::Mouse::isButtonPressed(sf::Mouse::Left) && sf::Keyboard::isKeyPressed(sf::Keyboard::LShift))
    //Do stuff

Pseudocode for SFML1.6:
const sf::Input &input = window.GetInput();
if(input.IsMouseButtonDown(sf::Mouse::Left) && input.IsKeyDown(sf::Key::LShift))
    //Do stuff

As things get more complex using something like thor::Action might be a better solution.

12
General / Re: How To Get Rid Of CMD?
« on: January 04, 2013, 04:53:39 am »
Presuming you're on Windows. Set your projects Subsystem from 'Console' to 'Windows'. You'll also need to link against SFML main if you do this.

13
Window / Re: Make window hidden when created
« on: December 18, 2012, 06:21:25 am »
You probably don't need to hide it like this in the first place.

Create the window at twice the size and then apply an sf::View with the size that you want your game to be.

Example:
int windowScale = 2;
int windowSize = 256;
sf::RenderWindow window(sf::VideoMode(windowSize*windowScale, windowSize*windowScale), "Resize test");
//window resolution is 1060x1060
sf::View gameView;
gameView.setSize(windowSize, windowSize);

window.setView(gameView);
//display resolution is now 256x256
//window is still 1060x1060 pixels large

//...rest of code

14
Window / Re: Can't make Joystick work
« on: December 10, 2012, 07:10:03 am »
You have the same problem as you did before. GetInput is a non-static member function. You need to call GetInput on an actual instance of sf::Window.

15
Graphics / Re: Multiple textures vs bigger single texture
« on: December 04, 2012, 03:33:24 am »
The consensus seems to be one sprite per entity with Sprite::setTextureRect to speicify different animation frames(all the frames for a single entity must be in a single texture though).

See thor's Animator class for an easy way to automate this.

Pages: [1] 2 3 ... 11
anything