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

Author Topic: View problems  (Read 9980 times)

0 Members and 4 Guests are viewing this topic.

Yelnats

  • Newbie
  • *
  • Posts: 27
    • View Profile
View problems
« on: April 09, 2011, 05:06:55 am »
I have been using a view to display the screen of my game, and then there would be a GUI at the bottom. My problem right now is actually grasping what the view functions do. Does setcenter() move the view itself i.e. move the screen inside the actual window, or move everything in the screen but the window stays? Basically, imagine a window on a computer monitor. Does set center move the window, or the monitor itself? (monitor = view, window = things in view).

Also, how can I go about making a camera that follows the player? Do I use set center, or what? I have one that isn't working very well, but the character is able to be rendered outside of the view's co ordinates. This might be because I am using setcenter() and if it is, what should I use instead.

Thanks in advance, and if you need clarifications, I will try as hard as I can.

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
View problems
« Reply #1 on: April 09, 2011, 09:34:22 am »
Every function of sf::View transforms the view itself, views can't move other entities of the 2D world. So SetCenter moves the view, so that it sees a different part of the world. Views are similar to 2D cameras.
Laurent Gomila - SFML developer

Yelnats

  • Newbie
  • *
  • Posts: 27
    • View Profile
View problems
« Reply #2 on: April 09, 2011, 06:32:00 pm »
Oh ok thanks I get it now.

Yelnats

  • Newbie
  • *
  • Posts: 27
    • View Profile
View problems
« Reply #3 on: April 10, 2011, 02:32:21 am »
Ok, I have run into even more troubles. I have a view that is meant to follow the character and stop when it hits the edge of the map. The character is set to the position 320, 460 and the camera's center is 320, 360. Why doesn't the camera/view display the character? I used setview() before drawing the character.

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
View problems
« Reply #4 on: April 10, 2011, 10:01:28 am »
Quote
Why doesn't the camera/view display the character?

How could we know? ;)
Please give more details, or show the relevant code.
Laurent Gomila - SFML developer

Yelnats

  • Newbie
  • *
  • Posts: 27
    • View Profile
View problems
« Reply #5 on: April 10, 2011, 09:00:31 pm »
Yeah sorry about that, it was pretty stupid to ask without any info. Here is the move view code
Code: [Select]
void cmainchar::moveview(cmap * maps){
//fix this
//then remove safety checks on tiles (not needed anymore)
if(teleport){
spawn = true;
fall = 0.f;
jump = 0.f;
maps->changemap(this, spawn);
teleport = false;
}
int setx, sety;
int x = you.GetPosition().x + 20;
int y = you.GetPosition().y + 20;
//posx and posy is the size of the map. it is multiplied by 40 due to the size of the tiles (40 by 40)
if (x < 320)
setx = 320;

else if (x> maps->posx * 40 - 320)
setx = maps->posx *40 - 320;

else
setx = x;

if (y < 200)
sety = 200;

else if (y > maps->posy * 40 - 200)
sety = maps->posy * 40 - 200;

else
sety = y;

View.SetCenter(setx, sety);
std::cout << you.GetPosition().y << " " << View.GetCenter().y - 200 << " " << View.GetSize().y << std::endl;
}

The character is 40 by 60 pixels, and the view is 640 by 400 on the coordinates 0,0. I use App.SetView(View) before drawing the character, although I am unsure of what that does exactly(this is probably the error, but I am unsure, so if you can explain what exactly it does, I would appreciate it). The cout gives this information:Ypostion 460 YviewTop 120 YviewSize 400. So there is no reason why the character isn't in view. There is a GUI obscuring the bottom of the screen that is 80 pixels high and 640 long. The character resides on the bottom of the screen, his feet touching the bottom. So the character's actual position is 580.

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
View problems
« Reply #6 on: April 10, 2011, 09:43:56 pm »
Hmm... it's hard to tell. Could you write a complete and minimal code that reproduces the problem?
Laurent Gomila - SFML developer

Yelnats

  • Newbie
  • *
  • Posts: 27
    • View Profile
View problems
« Reply #7 on: April 11, 2011, 01:32:42 am »
Here, I tried. The problem is that the view stops following you when you get close to the bottom, but you can hit the bottom (where there would be a 80 pixels high GUI)
Code: [Select]
#include <SFML/Graphics.hpp>
#include <iostream>

sf::RenderWindow App(sf::VideoMode(640, 480, 32), "Fail");

sf::View View(sf::FloatRect(0,0,640,400));

void moveview(const sf::Sprite & you){
//fix this
//then remove safety checks on tiles (not needed anymore)

int setx, sety;
int x = you.GetPosition().x + 20;
int y = you.GetPosition().y + 20;

if (x < 320)
setx = 320;

else if (x> 18 * 40 - 320)
setx = 18 * 40 - 320;

else
setx = x;

if (y < 200)
sety = 200;

else if (y > 14 * 40 - 200)
sety = 14 * 40 - 200;

else
sety = y;

View.SetCenter(setx, sety);
}

int main(){
sf::Image ibackground;
ibackground.LoadFromFile("background.png");
sf::Sprite background;
background.SetImage(ibackground);
sf::Image itest;
itest.LoadFromFile("image.png");
sf::Sprite test;
test.SetImage(itest);
while (App.IsOpened()){
sf::Event Event;
        while (App.GetEvent(Event)){
            if (Event.Type == sf::Event::Closed)
                App.Close();
        }
if (App.GetInput().IsKeyDown(sf::Key::A))
test.Move(-100.f * App.GetFrameTime(), 0);

if (App.GetInput().IsKeyDown(sf::Key::D))
test.Move(100.f * App.GetFrameTime(), 0);

if (App.GetInput().IsKeyDown(sf::Key::W))
test.Move(0, -100.f * App.GetFrameTime());

if (App.GetInput().IsKeyDown(sf::Key::S))
test.Move(0, 100.f * App.GetFrameTime());

if(test.GetPosition().x < 0)
test.SetPosition(0, test.GetPosition().y);

if(test.GetPosition().x + test.GetSize().x >18 *40)
test.SetPosition(18 * 40  - test.GetSize().x, test.GetPosition().y);

if(test.GetPosition().y < 0)
test.SetPosition(test.GetPosition().x, 0);

if(test.GetPosition().y + test.GetSize().y >14 *40)
test.SetPosition(test.GetPosition().x , 14 * 40 - test.GetSize().y);

moveview(test);
App.Clear();
App.SetView(View);
App.Draw(background);
App.Draw(test);
App.Display();
}
return 0;
}

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
View problems
« Reply #8 on: April 11, 2011, 08:09:56 am »
I tried your code and everything looks ok. The view follows the player and stops at the borders of the background. So what's wrong actually?
Laurent Gomila - SFML developer

Yelnats

  • Newbie
  • *
  • Posts: 27
    • View Profile
View problems
« Reply #9 on: April 11, 2011, 10:22:14 pm »
Basically the player overshoots 80 pixels in the Y axis direction (which is where a GUI will reside, basically obscuring the player). So he should stop moving at position x,400 and so should the view, instead of x,480. Also, can you explain what exactly change view does? Does it alter the co ordinates, converts them, or what? My idea is it gets the position of the view, and then subtracts that from the item being drawn.

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
View problems
« Reply #10 on: April 11, 2011, 10:38:38 pm »
Ok I see. There are too many "magic" numbers in your code, it's hard to tell which line is wrong. But basically there's nothing wrong in how you use SFML, it's probably just a wrong formula.

Quote
Also, can you explain what exactly change view does? Does it alter the co ordinates, converts them, or what? My idea is it gets the position of the view, and then subtracts that from the item being drawn.

Before being drawn, the geometry of each object is transformed by the view: offseted by the view's position, rotated by the view's rotation, etc... (using a single 4x4 matrix).
Laurent Gomila - SFML developer

Yelnats

  • Newbie
  • *
  • Posts: 27
    • View Profile
View problems
« Reply #11 on: April 11, 2011, 11:00:05 pm »
Ah ok thanks. Let me change the magic numbers (if I understand it correctly)
Code: [Select]
#include <SFML/Graphics.hpp>
#include <iostream>

const int xscreensize = 720;
const int yscreensize = 560;

sf::RenderWindow App(sf::VideoMode(640, 480, 32), "Fail");

sf::View View(sf::FloatRect(0,0,640,400));

void moveview(const sf::Sprite & you){
//fix this
//then remove safety checks on tiles (not needed anymore)

int setx, sety;
int x = you.GetPosition().x + 20;
int y = you.GetPosition().y + 20;

if (x < View.GetSize().x / 2)
setx = View.GetSize().x / 2;

else if (x> xscreensize - View.GetSize().x / 2)
setx = xscreensize - View.GetSize().x / 2;

else
setx = x;

if (y < View.GetSize().y / 2)
sety = View.GetSize().y / 2;

else if (y > yscreensize - View.GetSize().y / 2)
sety = yscreensize - View.GetSize().y / 2;

else
sety = y;

View.SetCenter(setx, sety);
}

int main(){
sf::Image ibackground;
ibackground.LoadFromFile("background.png");
sf::Sprite background;
background.SetImage(ibackground);
sf::Image itest;
itest.LoadFromFile("image.png");
sf::Sprite test;
test.SetImage(itest);
while (App.IsOpened()){
sf::Event Event;
        while (App.GetEvent(Event)){
            if (Event.Type == sf::Event::Closed)
                App.Close();
        }
if (App.GetInput().IsKeyDown(sf::Key::A))
test.Move(-100.f * App.GetFrameTime(), 0);

if (App.GetInput().IsKeyDown(sf::Key::D))
test.Move(100.f * App.GetFrameTime(), 0);

if (App.GetInput().IsKeyDown(sf::Key::W))
test.Move(0, -100.f * App.GetFrameTime());

if (App.GetInput().IsKeyDown(sf::Key::S))
test.Move(0, 100.f * App.GetFrameTime());

if(test.GetPosition().x < 0)
test.SetPosition(0, test.GetPosition().y);

if(test.GetPosition().x + test.GetSize().x >xscreensize)
test.SetPosition(xscreensize - test.GetSize().x, test.GetPosition().y);

if(test.GetPosition().y < 0)
test.SetPosition(test.GetPosition().x, 0);

if(test.GetPosition().y + test.GetSize().y > yscreensize)
test.SetPosition(test.GetPosition().x , yscreensize - test.GetSize().y);

moveview(test);
App.Clear();
App.SetView(View);
App.Draw(background);
App.Draw(test);
App.Display();
}
return 0;
}


Just to make sure I get views, if I draw a sprite with SetView() changed, it will get that view's position and subtract it from the sprite, and then draw it? I'm only talking about the position, not rotation and stuff. Also does a view affect a sprite's origin?

Wizzard

  • Full Member
  • ***
  • Posts: 213
    • View Profile
View problems
« Reply #12 on: April 12, 2011, 12:04:13 am »
I'm not sure what the problem is. I put your code into a SFML 2 project and it works fine with a background image that is 720x560 and a character that is 32x32.

Quote from: "Yelnats"
Just to make sure I get views, if I draw a sprite with SetView() changed, it will get that view's position and subtract it from the sprite, and then draw it? I'm only talking about the position, not rotation and stuff. Also does a view affect a sprite's origin?

Every transformation (movement, rotation, scale/zoom) that is applied to the drawable being drawn and the currently set view affects the final result on the screen.

However, changing a view's origin does not affect a sprite's origin when you use the get acessor function.

Yelnats

  • Newbie
  • *
  • Posts: 27
    • View Profile
View problems
« Reply #13 on: April 12, 2011, 12:14:49 am »
Basically, I want there to be 80 pixels of room after you can't move anymore, so that the background will be 80 pixels above the edge of the screen after you hit it, which is where the GUI would be.

Wizzard

  • Full Member
  • ***
  • Posts: 213
    • View Profile
View problems
« Reply #14 on: April 12, 2011, 01:31:12 am »
I still don't get it. Is the GUI and background contained in the same image?

If you're just trying to add padding at the top (or bottom) so that there is room for a GUI,
make the view able to move 80 pixels above (or below) where it can now. You don't have anything in your code that indicates 80 pixels.

 

anything