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

Author Topic: Creating sprites on whole/big map  (Read 3554 times)

0 Members and 1 Guest are viewing this topic.

Bogdan

  • Jr. Member
  • **
  • Posts: 91
    • View Profile
Creating sprites on whole/big map
« on: July 18, 2014, 08:11:26 pm »
Hi people,
I don't know for sure, if it's even a "window" related problem. If not, than you can freely move this thread to the right area.
It's about an issue, where sprites can only be created only inside the start screen, but if I move the view to other areas of the map, than it is not possible to create sprites there.
I've a suspicion that it's related to the coordinates, that are relative to the window.

In the tutorials I only see the cases, where you can get the relative mouse position in relation to the desktop (1) or in relation to the window (2). But how to get the "really" absolute position. I couln't find anything about it by searching the web and forum. I've only seen code for the both cases from above and/or completely outdated code. Any help is welcome :-)

I think it's this line, that is causing the problem:

newSprite.setPosition(sf::Mouse::getPosition(mMainWindow).x,sf::Mouse::getPosition(mMainWindow).y);

I've tried to even set this in relation to the my maprect or the boundrect, but it did't work.

The whole code:

#include <SFML/Graphics.hpp>
#include <iostream>
#include <list>

int main()
{
    sf::RectangleShape maprect;
    maprect.setSize(sf::Vector2f(1500, 400));
    maprect.setFillColor(sf::Color(0,00,255,255));
    maprect.setPosition(0, 0);

    sf::Sprite newSprite;

    sf::FloatRect mapbound = maprect.getGlobalBounds();

    sf::RenderWindow mMainWindow(sf::VideoMode(500, 400), "Map");
    mMainWindow.setFramerateLimit(60);
    sf::Texture unittexture;
    unittexture.loadFromFile("warrior.png");

    std::list<sf::Sprite> EnemyList;
    std::list<sf::Sprite>::iterator EnemyIt;

        sf::View view(sf::Vector2f(250, 200), sf::Vector2f(500, 400));  // center and size

    while (mMainWindow.isOpen())
    {
        sf::Event event;

        while (mMainWindow.pollEvent(event))
        {
            if (event.type == sf::Event::Closed)
            {
                mMainWindow.close();
            }
                        if((event.type == sf::Event::KeyPressed) && (event.key.code == sf::Keyboard::Right))
                                {
                                        view.move(+150, 0);
                                }
                        if((event.type == sf::Event::KeyPressed) && (event.key.code == sf::Keyboard::Left))                                                  
                                {
                                        view.move(-150, 0);
                                }
            if(event.type == sf::Event::MouseButtonPressed)
                if(event.mouseButton.button == sf::Mouse::Left)
                                       
                    if (maprect.getGlobalBounds().contains(mMainWindow.mapPixelToCoords(sf::Vector2i(event.mouseButton.x, event.mouseButton.y))))      
                    {
                        newSprite.setTexture(unittexture);
                        newSprite.setPosition(sf::Mouse::getPosition(mMainWindow).x,sf::Mouse::getPosition(mMainWindow).y);
                        EnemyList.push_back(newSprite);
                                                std::cout << "Mouse Pos" << sf::Mouse::getPosition(mMainWindow).x << ", " << sf::Mouse::getPosition(mMainWindow).y << std::endl;  // only relative to window
                    }
        }
                mMainWindow.draw(maprect);
                mMainWindow.setView(view);

        for(EnemyIt = EnemyList.begin();EnemyIt != EnemyList.end();EnemyIt++)
        {
            mMainWindow.draw(*EnemyIt);
        }

        mMainWindow.display();
        mMainWindow.clear(sf::Color(0, 200, 0, 255));
    }

    return 0;
}

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6276
  • Thor Developer
    • View Profile
    • Bromeon
Re: Creating sprites on whole/big map
« Reply #1 on: July 18, 2014, 08:31:03 pm »
You already retrieved the position with mapPixelToCoords(), why do you throw away the result?

Don't mix events and real-time input! This is something so many people do wrong, I recommend reading the corresponding tutorial sections again. It's even highlighted in red that you should read that part very carefully.
« Last Edit: July 18, 2014, 08:34:29 pm by Nexus »
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

Bogdan

  • Jr. Member
  • **
  • Posts: 91
    • View Profile
Re: Creating sprites on whole/big map
« Reply #2 on: July 18, 2014, 08:59:32 pm »
It worked! Thanks for your hint. As for the events/input mishmash I don't know it better at the moment, but will try to learn it asap.

Jesper Juhl

  • Hero Member
  • *****
  • Posts: 1405
    • View Profile
    • Email
Re: Creating sprites on whole/big map
« Reply #3 on: July 18, 2014, 11:30:50 pm »
A few random comments - not related to your problem since you already solved that, just some things I wanted to comment on:

#include <SFML/Graphics.hpp>
#include <iostream>
Why include "iostream"? I don't see any uses.

    sf::Texture unittexture;
    unittexture.loadFromFile("warrior.png");
A little error handling probably wouldn't hurt.

         if((event.type == sf::Event::KeyPressed) && (event.key.code == sf::Keyboard::Right))
            {
               view.move(+150, 0);
            }
         if((event.type == sf::Event::KeyPressed) && (event.key.code == sf::Keyboard::Left))                                                 
            {
               view.move(-150, 0);
            }
            if(event.type == sf::Event::MouseButtonPressed)
                if(event.mouseButton.button == sf::Mouse::Left)
Not that it really matters from a performance perspective but it still seems bizare to me that apparently you expect that an sf::Event can be multiple types at once.  Why don't you use
if (event.type == foo) { ... } else if (event.type == bar) { ... }
?
Ohh and some consistent indenting probably wouldn't hurt either (check out ClangFormat.
               
        for(EnemyIt = EnemyList.begin();EnemyIt != EnemyList.end();EnemyIt++)
        {
            mMainWindow.draw(*EnemyIt);
        }
Why not simply
for (auto& enemy : EnemyList) { mMainWindow.draw(enemy); }
?
And if you insist on using C++03 style code, then at least use "++EnemyIt" rather than "EnemyIt++" - the prefix operator is never slower than the postfix one (but potentially faster), so always prefer to use prefix unless you need postfix.

Mörkö

  • Jr. Member
  • **
  • Posts: 96
    • View Profile
Re: Creating sprites on whole/big map
« Reply #4 on: July 19, 2014, 02:04:46 am »
Can someone explain to me why this doesn't cause a green screen:

mMainWindow.display();
mMainWindow.clear(sf::Color(0, 200, 0, 255));

I was surprised when I tried it in my own code and everything just looked normal. I would expect it to just.. clear the screen.

G.

  • Hero Member
  • *****
  • Posts: 1559
    • View Profile
Re: Creating sprites on whole/big map
« Reply #5 on: July 19, 2014, 02:16:41 am »
Do you draw something on your green screen? Something like a map, a huge blue rectangle, or something else?
clear indeed clears the screen with the specified color, but if you draw cover your whole screen with something else before your next display you won't see it.

Bogdan

  • Jr. Member
  • **
  • Posts: 91
    • View Profile
Re: Creating sprites on whole/big map
« Reply #6 on: July 19, 2014, 11:09:52 am »

for (auto& unitsprite: EnemyList) { mMainWindow.draw(unitsprite); }

As we know it doesn't work with "enemy". But what to choose instead for replacement? I thought "unitsprite" was an element of the container.Btw: .I'm using VS 2010.

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6276
  • Thor Developer
    • View Profile
    • Bromeon
Re: Creating sprites on whole/big map
« Reply #7 on: July 19, 2014, 11:19:36 am »
I'm using VS 2010.
Visual Studio 2010 does not support the range-based for loop.

You have to use iterators, or AURORA_FOREACH, which emulates range-based for:
AURORA_FOREACH(sf::Sprite& s, EnemyList)
{
    ...
}
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

Hapax

  • Hero Member
  • *****
  • Posts: 3058
  • My number of posts is shown in hexadecimal.
    • View Profile
Re: Creating sprites on whole/big map
« Reply #8 on: July 19, 2014, 03:15:35 pm »
mMainWindow.display();
mMainWindow.clear(sf::Color(0, 200, 0, 255));
I have to ask: why are you using display() before clear()?
Selba Ward - SFML drawables
Kairos - Timing Library
Rectangular Boundary Collision - Rectangular SAT Collision

@Hapaxiation - Hapaxia on Twitter

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
Re: Creating sprites on whole/big map
« Reply #9 on: July 19, 2014, 04:20:08 pm »
Unroll a typical main loop:

- clear
- draw
- display
- clear
- draw
- display
...

Now unroll his loop:


- display
- clear
- draw
- display
- clear
- draw
...

You see, moving "display" from the end of the loop to the beginning doesn't make much difference, the result is the same ;)
Laurent Gomila - SFML developer

Hapax

  • Hero Member
  • *****
  • Posts: 3058
  • My number of posts is shown in hexadecimal.
    • View Profile
Re: Creating sprites on whole/big map
« Reply #10 on: July 19, 2014, 04:23:15 pm »
Ah, good point. I suppose it doesn't matter so much. Just looks like the frame would be behind maybe, but I see that it wouldn't stop the window from clearing. My bad. Still not sure why someone would purposefully do it  :P
Selba Ward - SFML drawables
Kairos - Timing Library
Rectangular Boundary Collision - Rectangular SAT Collision

@Hapaxiation - Hapaxia on Twitter

Bogdan

  • Jr. Member
  • **
  • Posts: 91
    • View Profile
Re: Creating sprites on whole/big map
« Reply #11 on: July 23, 2014, 08:34:37 pm »
It wasn't on purpose, I simply didn't care about it or did't even see it :-)
But now I've changed it to a normal order. (for future posts)