SFML - Continuous Motion (Xander314?)

I'm trying to make a Zelda-ish RPG game. So far I'm just trying to get my sprite moving smoothly...
When I press the button, it moves once, waits for half a second, and then really starts moving...
This is the code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
#include <SFML/Graphics.hpp>
#include <SFML/Window.hpp>
#include <SFML/System.hpp>
#include "Game.h"
#include "Player.h"

const int WIDTH = 300;
const int HEIGHT = 220;

int main()
{
    Painter *p = new Painter();
    Game game(WIDTH, HEIGHT, p);
    Player player(p);
    sf::RenderWindow Window(sf::VideoMode(WIDTH, HEIGHT, 32), "SFML Sample Application");

    while (Window.IsOpened())
    {
        Window.Clear();
        float ElapsedTime = Window.GetFrameTime();
        float Framerate = 1.f / Window.GetFrameTime();
        sf::Event Event;
        while (Window.PollEvent(Event))
        {

            if(Event.Type == sf::Event::Closed)
                Window.Close();

            if (Window.GetInput().IsKeyDown(sf::Key::Left))  player.pSprite.Move(-3 * ElapsedTime, 0);
            if (Window.GetInput().IsKeyDown(sf::Key::Right)) player.pSprite.Move( 3 * ElapsedTime, 0);
            if (Window.GetInput().IsKeyDown(sf::Key::Up))    player.pSprite.Move(0, -3 * ElapsedTime);
            if (Window.GetInput().IsKeyDown(sf::Key::Down))  player.pSprite.Move(0,  3 * ElapsedTime);
        }


        for(int i = 0; i < game.map->grid.size(); i++)
            for(int j = 0; j < game.map->grid[i].size(); j++)
            {
                Window.Draw(game.p->grass(j*32, i*32));
                Window.Draw(game.map->grid[i][j]);
            }
        Window.Draw(player.pSprite);

        Window.Display();
    }

    return 0;
}
If I recall, the solution is to take the realtime input stuff (sf::Window::GetInput) out of the polled event loop.

And I'm flattered you think I'm so much better with SFML than I am ;)

[edit] Let me know if it works.
Last edited on
+1 to Xander314's solution. I'm sure that's the problem.
I assume because the movement code only gets processed when there is an event, and a keypress event is only dispatched every second or so with a depressed key. Sounds about right?
Sorry for the late reaction, but it indeed solved the problem! Thanks!
I have another question. For a tile-based RPG. Should I use free movement for my Hero or should I fix him to a tile? So far I think fixing him to a tile is the best way, and by far the easiest for collision detection etc.
One more thing: how should I go about scrolling?
Is sf::View the way to go?
Or should I keep track of my Hero's position, and than calculate all the necessary tiles to be drawn to fill the screen?

PS: I think I've started a project too difficult...
I have no idea how I should go about entering rooms, combat etc...
How do you mean "fix him to a tile"? I'm not sure how one would discretise movement to separate tiles. If you use sf::Collision collision can be done for you - you just pass two sprites to a function, either for box or sphere collision or whatever.

A view could work, but if you have a very large world, perhaps you won't want to load it all into memory at once.

For entering rooms - why not just make the rooms part of the tile background?

For combat, or talking, you might be able to use your collision dectector to decide whether you and the enemy/NPC is next to you. If so, then just have a key for attack or speak or whatever.

Hope this starts to clear up some of your problems ;) And don't be demoralised - I'm sure you're capable of this project :)
Wow wait is there a function sf::Collision ?
I didn't know that :P
And with fix him to a tile I mean no free movement, only movement from tile to tile...
What do you think would be the best choice?

EDIT: Can't seem to find sf::Collision anywhere.?
Last edited on
If you want a reasonably playable RPG, I wouldn't recommend jumping from tile to tile.

sf::Collision is not part of SFML, but someone has written it as an extra:
http://www.sfml-dev.org/wiki/en/sources/simple_collision_detection

I'm not sure of the license, but it probably says on that page.
i've tried that one already, but it comes with LOADS of errors and broken code...
At OP xander: why no (edit) acceleration?
Last edited on
@xander333 Failing sf::Collision, you could always write the collision code yourself. There are various topics to this effect on the SFML forums.

@ultifinitus
-3 * ElapsedTime
^ isn't this the velocity? Or were you suggesting non constant velocity?

NB: I am not OP xander.
Last edited on
I've written my own collision code, only to find out about this problem I had overlooked: I do not know in which tile my hero is! I can't calculate it since I only get coords relative to the window. How should I find in which tile my char is??

Also, for the tiles, how should I go about naming them? with an enumeration?
Last edited on
I do not know in which tile my hero is!


Have a variable that keeps track of your hero's position.

Also, for the tiles, how should I go about naming them? with an enumeration?


Be as generic as possible -- it makes it easier in the long run.

I actually made a big post about this earlier. See here:

http://cplusplus.com/forum/general/42924/

He was using HGE as his lib instead of SFML, but you should get the idea.
Okay, I decided to make it easier for myself and not use scrolling.
So it's going to be room-based :)
Let's see how that turns out!
Currently working on the collision code.
And very helpful post, Disch!

EDIT: having a hell of a hard time getting the collision right...
Damn, why is this so much harder than when I coded the collision for my pong and breakout game :S
I keep getting SEGMENTATION faults LOL.
Last edited on
YESSS YES YES YES YESSS.
Lol I love the feeling when I finally get something right :D
It took me 2 hours to find out I had typed [y][x-1] instead of [y-1][x]
God I'm happy now :P
Ah well, I bet the next problem will arise within two minutes xD
Okay the next problem has arisen ^^
How should I manage buildings and other big sprites?
Cut them into small sprites of 32x32?

EDIT: I think I'm not building my map right...
This is how I make it:
Read data in from a text file into a vector.
I add the correct tile by using a switch statement.
Like this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
Map::Map(Painter* p, int tileWidth_, int tileHeight_, string fileName)
{
    ifstream file;
    file.open(fileName.c_str());
    int width, height, type;
    tileWidth = tileWidth_;
    tileHeight = tileHeight_;


    file>>width;
    file>>height;

    for(int i = 0; i < height; i++)
    {
        vector<Tile> temp;
        grid.push_back(temp);

        std::cout<<"\n";

        for(int j = 0; j < width; j++)
        {
            file>>type;
            std::cout<<type<<" ";
            switch(type)
            {
                case 0:
                        grid[i].push_back(Tile(p->grass(j*tileHeight, i*tileHeight), true));
                        break;
                case 1:
                        grid[i].push_back(Tile(p->tree(j*tileHeight, i*tileHeight), false));
                        break;
                case 2:
                        grid[i].push_back(Tile(p->player(j*tileHeight, i*tileHeight), false));
                        break;
            }
        }
    }
}


"p" is my "painter".
p->tree(int xpos, int ypos) returns a tree sprite positioned at (xpos, ypos).
second parameter for the tile is if it's walkable or not.
Is this a good way?
Last edited on
That method could still work for drawing large sprites (Should this topic be marked completed and a new one started?). To use this for large sprites you would need to break them up and draw them something like this:
1
2
3
4
5
6
//*Your Code Here*//
case 3: 
            grid[i].push_back(Tile(p->House_Top_Left(j*tileHeight, i*tileHeight), false));
case 4: 
            grid[i].push_back(Tile(p->House_Top_Center(j*tileHeight, i*tileHeight), false));
//*Etc...*// 


Although like Disch mentioned earlier you may want to use more generic names or your switch case could get out of control as your game expands.
What do you mean by more generic names?
Is "grass, tree or rock" not generic enough?
And I'll start a new thread for my next problem regarding this game :)
Is "grass, tree or rock" not generic enough?


They're not.

Basically, you shouldn't have any names. All of it should be dynamic. You code shouldn't know whether or not it has grass/trees/rocks/whatever. It should just know that it has tiles.

See this post:

http://cplusplus.com/forum/general/42924/#msg232049

Last edited on
For your tiles, you could stop hard coding, use an image manager, and have relative file names for each tile. for instance.

In Your Map File:
1
2
3
<0,0,"resources\\brick.png",1(),0,0><0,1,"resources\\resources\\brick.png",1(),0,0>
//x,y,file,collision layer,movability,special flag
//movability has additional optional params scrolling position and direction 


Then have your image manager use a map with pointers to images and when you reference a file name that hasn't been used yet, make a new image and load it from memory.

As far as scrolling goes. It's horrifically easy. What I did was make a map class that holds all of my sprites on a certain layer, and it has the ability to check collisions, notify objects of collisions, and move it's own camera offset. Since it displays all of my sprites, it has the ability to offset every single sprite by (-xpos,-ypos)

My favorite new feature of my new game engine is my "scene" class, it holds a map of objects, and it grabs input from the user, and objects can register for any event from the operating system, then respond based on however they've overloaded their receiveevent() method. It's amazing for my button class, and great for my player class. I'm going to add events from objects, so that other objects can respond to events from other objects =]
Topic archived. No new replies allowed.