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

Author Topic: [SOLVED]Sf::View, putting player in the middle of screen  (Read 10257 times)

0 Members and 2 Guests are viewing this topic.

Sarbast

  • Newbie
  • *
  • Posts: 18
    • View Profile
[SOLVED]Sf::View, putting player in the middle of screen
« on: June 19, 2014, 12:03:06 am »
Hi
i want to put the player in the middle of the screen but i don't know
can someone tell me how to do it?
also when i move it to a side and then press another side its legs stop moving(fixed thanks for Ixrec)

sorry for my english

#ifdef SFML_STATIC
#pragma comment(lib, "glew.lib")
#pragma comment(lib, "freetype.lib")
#pragma comment(lib, "jpeg.lib")
#pragma comment(lib, "opengl32.lib")
#pragma comment(lib, "winmm.lib")
#pragma comment(lib, "gdi32.lib")  
#endif // SFML_STATIC


#include <SFML\Graphics.hpp>
#include <iostream>
#include <string>
#include <algorithm>
#include <ctime>
#include <cstdlib>

#pragma region Variables
sf::RenderWindow window;
sf::Texture Map;
sf::Sprite sMap;
sf::Clock MyClock;
sf::Event MyEvent;
sf::Vector2f position(800, 600);
sf::Texture Image;
sf::Sprite player;
sf::View MyView;
sf::Vector2i Place(1, 0);
sf::Vector2f MapPosition(position.x/2, position.y/2);
enum Direction{Down, Left, Right, Up};
float FrameSpeed = 500, SwitchFrame = 60, FrameCount = 0;
bool updateFrame = false;
#pragma endregion sf

int main()
{
        //Window
        window.create(sf::VideoMode(position.x, position.y), "My First SFML Game", sf::Style::Close);
        window.setPosition(sf::Vector2i(300, 50));
        window.setFramerateLimit(60);
        window.setKeyRepeatEnabled(false);

        //Texture Map
        if (!Map.loadFromFile("LOF-Map.png"))
                std::cout << "Couldn't Load The Map" << std::endl;

        //Texture player
        if (!Image.loadFromFile("Player.png"))
                std::cout << "Couldn't load the Image" << std::endl;
        Image.setSmooth(true);

        //Sprite Map
        sMap.setTexture(Map);

        //Sprite Player
        player.setTexture(Image);
        player.setPosition(sf::Vector2f(100, 100));

        //Game Loop
        while (window.isOpen())
        {

                //Event loop
                while (window.pollEvent(MyEvent))
                {
                       place.x = 1;
                        switch (MyEvent.type)
                        {
                        case sf::Event::Closed:
                                window.close();
                                break;
                        }

                }
                updateFrame = false;
                if (sf::Keyboard::isKeyPressed(sf::Keyboard::Down)){
                        updateFrame = true;
                        Place.y = Down;
                        player.move(0, 1);
                }
                else if (sf::Keyboard::isKeyPressed(sf::Keyboard::Left)){
                        updateFrame = true;
                        Place.y = Left;
                        player.move(-1, 0);
                }
                else if (sf::Keyboard::isKeyPressed(sf::Keyboard::Right)){
                        updateFrame = true;
                        Place.y = Right;
                        player.move(1, 0);
                }
                else if (sf::Keyboard::isKeyPressed(sf::Keyboard::Up)){
                        updateFrame = true;
                        Place.y = Up;
                        player.move(0, -1);
                }
       

                FrameCount += FrameSpeed * MyClock.restart().asSeconds();
                if (updateFrame == true){
                        if (FrameCount > SwitchFrame)
                        {
                                FrameCount = 0;
                                Place.x++;
                                if (Place.x * 32 >= Image.getSize().x)
                                        Place.x = 0;
                        }
                }
                if (player.getPosition().x<= 0)
                        player.setPosition(sf::Vector2f(0,player.getPosition().y));
                if (player.getPosition().y < 0)
                        player.setPosition(sf::Vector2f(player.getPosition().x, 0));

                //Display a block of the SpriteSheet
                player.setTextureRect(sf::IntRect(Place.x * 32, Place.y * 32, 32, 32));

                window.clear();
                window.setView(MyView);
                window.draw(sMap);
                window.draw(player);
                window.display();
        }
        return EXIT_SUCCESS;
}
« Last Edit: June 26, 2014, 01:55:13 pm by Sarbast »

Ixrec

  • Hero Member
  • *****
  • Posts: 1241
    • View Profile
    • Email
Re: Sf::View, putting player in the middle of screen
« Reply #1 on: June 19, 2014, 12:18:03 am »
I assume you're asking how to make the window follow the player using a view.  I think you can just do something like MyView.setCenter(player.getPosition()); every frame to achieve that.

Some other issues:
- Don't use global variables without a good reason.  All of those variables should be declared inside main() so they have a clear scope and non-undefined initialization order.
- It's better to keep the list of libraries in your build files (makefiles, IDE project configuration) rather than your code files.
- In your switch() statement for events, the default case should never get called (it's not like SFML will produce an "empty" event every frame), but your code seems to assume that it will get called if there is no event.  Maybe this is related to your bug?
- With event handling, it's generally best to avoid any game logic (moving the player, deciding if this is an "updateFrame", etc) until after you've checked all the events and keyboard inputs.  Event/input processing logic should remain separate from actual game logic.

Minor comments:
- I believe sf::Vector2f MapPosition(position.x/2, position.y/2); could just be sf::Vector2f MapPosition(position/2);
- I believe player.setPosition(sf::Vector2f(100, 100)); could just be player.setPosition(100, 100);
- FrameCount, FrameSpeed and SwitchFrame are somewhat confusing variable names, since they seem to be used to control the player's animation rather than, say, implement a fixed timestep (which is what it looked like they were doing at first glance).  Some better names might be PlayerMovement, PlayerSpeed and MovementThreshhold.
- "Place" also isn't a great name for that variable.
« Last Edit: June 19, 2014, 12:30:25 am by Ixrec »

Sarbast

  • Newbie
  • *
  • Posts: 18
    • View Profile
Re: Sf::View, putting player in the middle of screen
« Reply #2 on: June 19, 2014, 12:31:55 am »
Thanks for the answer but setCenter() not really working fine for my code it changes position of the map and puts left above in the middle of the screen

and thanks for the tips they were so helpful

Ixrec

  • Hero Member
  • *****
  • Posts: 1241
    • View Profile
    • Email
Re: Sf::View, putting player in the middle of screen
« Reply #3 on: June 19, 2014, 01:03:33 am »
Thanks for the answer but setCenter() not really working fine for my code it changes position of the map and puts left above in the middle of the screen

I assumed you would want the map/world to move around if the camera is following the player, since that's what most games do.  If you want something different, you're going to need to explain to us what you want instead before we can help you implement it.

Try to give an example with the exact positions and sizes you think everything has, screenshots of what you currently see, the exact code you ran to get it (don't just describe the change, show exact code), and a sketch of what you wanted to see instead.
« Last Edit: June 19, 2014, 01:07:37 am by Ixrec »

Sarbast

  • Newbie
  • *
  • Posts: 18
    • View Profile
Re: Sf::View, putting player in the middle of screen
« Reply #4 on: June 19, 2014, 01:18:09 am »
that's what i want like other games
I just want the camera follow where the player goes


Ixrec

  • Hero Member
  • *****
  • Posts: 1241
    • View Profile
    • Email
Re: Sf::View, putting player in the middle of screen
« Reply #5 on: June 19, 2014, 07:52:33 am »
That screenshot by itself doesn't tell us what the problem is.  There's a reason I tried to list what information we need from you.

Sarbast

  • Newbie
  • *
  • Posts: 18
    • View Profile
Re: Sf::View, putting player in the middle of screen
« Reply #6 on: June 20, 2014, 02:03:42 pm »
I meant screen scrolling, while the player goes left/right of the screen the map goes opposite it and camera always shows the Player. i can't explain better than that  :(

btw i found out how to do that i followed a youtube video i don't know if thats a right way to do that.
if you understood my question and have better way to do that please tell me how?

//Screen Scroling
                MapPosition.x = player.getPosition().x + 16 - (position.x / 2);
                MapPosition.y = player.getPosition().y + 16 - (position.y / 2);
               
                if (MapPosition.x < 0)
                        MapPosition.x = 0;
                if (MapPosition.y < 0)
                        MapPosition.y = 0;

                MyView.reset(sf::FloatRect(MapPosition.x, MapPosition.y, position.x, position.y));

now i got into this problem


Language was always obstacle for me to learn programming there isn't a single book about programming in my language :(

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: Sf::View, putting player in the middle of screen
« Reply #7 on: June 20, 2014, 02:39:44 pm »
view.setCenter(player.getPosition());
?
Laurent Gomila - SFML developer

Sarbast

  • Newbie
  • *
  • Posts: 18
    • View Profile
Re: Sf::View, putting player in the middle of screen
« Reply #8 on: June 20, 2014, 03:03:15 pm »
Thats what i got after putting
MyView.SetCenter(player.getPosition())

i don't know how to remove the black sides


dabbertorres

  • Hero Member
  • *****
  • Posts: 505
    • View Profile
    • website/blog
Re: Sf::View, putting player in the middle of screen
« Reply #9 on: June 20, 2014, 04:58:10 pm »
That will take some logic taking into concern the position of the player relative to the edge of the map.

Fitzy

  • Newbie
  • *
  • Posts: 15
    • View Profile
    • Email
Re: Sf::View, putting player in the middle of screen
« Reply #10 on: June 21, 2014, 09:54:07 pm »
To remove that black around the map, you need to set it so sf::View doesn't follow the player once the bounds of the map image has been reached, once the player moves past the sf::View X or Y center AND the map bounds are not reached, set the new center on the player and move with the player but only move the view across the X or Y axis depending on the map's bounds.

Think of the player pushing invisible walls when he moves, these walls are bound to the far left, right, top and bottom of the screen and there are little walls around the player, those little walls are attached to the big walls.

Now when you move the player, the small walls push the big walls which the sf::View is attached too, once the map bounds has been reached on the negative X axis, the wall on the left side of the player is destroyed, unable to move the big wall on the far left side of the screen, thus, the sf::View no longer moves on the negative X axis untill the player moves in the positive X axis then the camera moves and all walls are reset.

No idea if that made sense to anyone but I tried to explain what I meant :P