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

Author Topic: Sprite can move diagonally [C++]  (Read 8090 times)

0 Members and 4 Guests are viewing this topic.

ulpa

  • Newbie
  • *
  • Posts: 2
    • View Profile
Sprite can move diagonally [C++]
« on: May 29, 2015, 02:33:36 pm »
Hello! I've a problem where my sprite can move diagonally upwards and not and it cannot move diagonally downwards. I don't want it to be able to move diagonally at all. I had diagonal movement before with some if statement with
if (sf::Keyboard::isKeyPressed(sf::Keyboard::W) && sf::Keyboard::isKeyPressed(sf::Keyboard::D) //move sprite
for everything. But I scrapped that idea because it was moving faster diagonally. Anyways here's my source. I uploaded it to pastebin to make it easier to read.
Also how do i print the location of the sprite?
http://pastebin.com/xZVi6LWg

Thanks in advance!

kitteh-warrior

  • Guest
Re: Sprite can move diagonally [C++]
« Reply #1 on: May 29, 2015, 02:47:58 pm »
The problem appears to be here. You are checking if the 'A' key is pressed, then only checking if the 'S' key is pressed if the 'A' key is not pressed. You are only checking if 'D' is pressed if the 'A' and 'S' keys are not pressed.

Edit: I forgot the important part (I should really proofread, then re-read the OP prior to posting the reply ;)): The reason you move diagonally upwards. You are always checking if 'W' or 'S' are pressed, and only checking if 'A' or 'D' are pressed if 'S' is not pressed. Replacing the "if" with "else if" on line 52 would bring you to the code I added at the bottom.

if (sf::Keyboard::isKeyPressed(sf::Keyboard::W)){//W
                sprit.move(0.0, -1);
                std::cout << "W\n";            
}//closeW
if (sf::Keyboard::isKeyPressed(sf::Keyboard::A)){//A
                sprit.move(-1, 0);
                std::cout << "A\n";
}//closeA
else if (sf::Keyboard::isKeyPressed(sf::Keyboard::S)){//S
                sprit.move(0, 1);
                std::cout << "S\n";
}//closeS
else if (sf::Keyboard::isKeyPressed(sf::Keyboard::D)){
                sprit.move(1, 0);
                std::cout << "D\n";
}

You shouldn't have the "else if"'s there, just "if"'s.

For printing the coordinates of the sprite, you could use:
std::cout << sprit.getPosition().x << ", " << sprit.getPosition().y << std::endl;

Edit: To avoid moving diagonally, you could use (see above for how this is slightly different than your code):

if(sf::Keyboard::isKeyPressed(sf::Keyboard::W)){ //W is pressed
        //moving up
}else if(sf::Keyboard::isKeyPressed(sf::Keyboard::S)){ //W is not pressed, S is pressed
        //moving down
}else if(sf::Keyboard::isKeyPressed(sf::Keyboard::A)){ //W and S not pressed, A is pressed
        //moving left
}else if(sf::Keyboard::isKeyPressed(sf::Keyboard::D)){ //W, S, and A not pressed, D pressed.
        //moving right
}

Keep in mind the order that you are checking these key pressed, because that determines which key overtakes another one. For example, using the above:
'D' is pressed, then 'W' is pressed -> moving up.
« Last Edit: May 29, 2015, 03:03:27 pm by kitteh-warrior »

DarkRoku12

  • Full Member
  • ***
  • Posts: 203
  • Lua coder.
    • View Profile
    • Email
Re: Sprite can move diagonally [C++]
« Reply #2 on: May 29, 2015, 03:53:02 pm »
you can use too :

// outside the loop

const int _left = 0 ;// (a)
const int _right = 3 ;// (d)  
const int _up = 22 ;// (w)
const int _down = 18 ;// (s)
// inside the game loop
if( event.type == Event::KeyPressed )
{
        switch( event.key.code )
       {
               case _right :
                    //code  
                   break ;
               case _left :
                    //code  
                   break ;
               case _up :
                    //code  
                   break ;
               case _down :
                    //code  
                   break ;
       }

}
 

with this you will evade the diagonal movement .
« Last Edit: May 29, 2015, 04:17:06 pm by DarkRoku »
I would like a spanish/latin community...
Problems building for Android? Look here

kitteh-warrior

  • Guest
Re: Sprite can move diagonally [C++]
« Reply #3 on: May 29, 2015, 04:25:52 pm »
you can use too :

[...omitted code...]

with this you will evade the diagonal movement .

The use of the event is ideal for typical development, but in this case the OP is constantly moving the object depending if the keys are pressed at the time of the update. Even with the key press repeating enabled, the code would not give the desired result. Although, that way is much better for most circumstances.

For example, at 60FPS, the sprite will move 60 pixels in 1 second. With the event handling method, it depends on the system configuration (time prior to start key repeating, or the key repeating event in general).

Hapax

  • Hero Member
  • *****
  • Posts: 3379
  • My number of posts is shown in hexadecimal.
    • View Profile
    • Links
Re: Sprite can move diagonally [C++]
« Reply #4 on: May 29, 2015, 04:26:40 pm »
If the only reason you don't want diagonal movement is because it travels quicker, you can multiply both directions by 0.7 (approx.).
Here is an example of how I used that in my entry to this month's game jam. It also shows a more accurate number to multiply by.  ;D
Selba Ward -SFML drawables
Cheese Map -Drawable Layered Tile Map
Kairos -Timing Library
Grambol
 *Hapaxia Links*

DarkRoku12

  • Full Member
  • ***
  • Posts: 203
  • Lua coder.
    • View Profile
    • Email
Re: Sprite can move diagonally [C++]
« Reply #5 on: May 29, 2015, 04:31:01 pm »

For example, at 60FPS, the sprite will move 60 pixels in 1 second. With the event handling method, it depends on the system configuration (time prior to start key repeating, or the key repeating event in general).

Yes, but you can use to the mathematics for the fast moving.

You want to move 5 pixels per frame. you do this:

float move = 5/60. Simply

And when the keys are released the sprite won't move. becuase the "move code" will be inside the "cases"
« Last Edit: May 29, 2015, 04:33:19 pm by DarkRoku »
I would like a spanish/latin community...
Problems building for Android? Look here

kitteh-warrior

  • Guest
Re: Sprite can move diagonally [C++]
« Reply #6 on: May 29, 2015, 04:38:30 pm »
Yes, but you can use to the mathematics for the fast moving.

You want to move 5 pixels per frame. you do this:

float move = 5/60. Simply

This doesn't work with event triggering, though. If you are constantly checking the state of the keyboard with each update, it would work. The key pressed event is not triggered unless the key was pressed, or the key-repeat was triggered.

Lets say that if the event is triggered for the 'W' key:
User presses key -> Change Position -> Draw -> Game Loop -> Event is Not Triggered at Every Iteration of the Game Loop (thus not always changing position) -> Draw -> Game Loop -> [...]

To have the object move for every iteration of the game loop, you would need to have variable of some sort to store which direction you are moving in, and if there is motion or not. You would also need to accommodate for the key release event, so that you stop moving within the game loop.

To show what I mean by this:

//within the game loop, where renderWindow = your render window.
sf::Event evt;
while(renderWindow.pollEvents(evt)){
        if((evt.type == sf::Event::KeyPressed) && (evt.key.code == sf::Keyboard::W)){
                std::cout << "Key pressed event" << std::endl;
                //the CLI window should only say "Key Pressed Event" when the event is triggered, not while the key is down.
        }
}

if(sf::Keyboard::isKeyPressed(sf::Keyboard::W)){
        std::cout << "Key is currently down" << std::endl;
        //the CLI window should only say "Key is currently down" while the key is currently being pressed.
}
« Last Edit: May 29, 2015, 04:52:21 pm by kitteh-warrior »

DarkRoku12

  • Full Member
  • ***
  • Posts: 203
  • Lua coder.
    • View Profile
    • Email
Re: Sprite can move diagonally [C++]
« Reply #7 on: May 29, 2015, 05:36:33 pm »

//within the game loop, where renderWindow = your render window.
sf::Event evt;
while(renderWindow.pollEvents(evt)){
        if((evt.type == sf::Event::KeyPressed) && (evt.key.code == sf::Keyboard::W)){
                std::cout << "Key pressed event" << std::endl;
                //the CLI window should only say "Key Pressed Event" when the event is triggered, not while the key is down.
        }
}

if(sf::Keyboard::isKeyPressed(sf::Keyboard::W)){
        std::cout << "Key is currently down" << std::endl;
        //the CLI window should only say "Key is currently down" while the key is currently being pressed.
}

I already test your code and when i press the "W" key the console print "Key is currently down" each frame while the key is down. (i only press W one and left it pressed)

Test code:


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

int main()
{

   RenderWindow window( VideoMode( 600 , 600 ) , "mywindow" ) ;


    while( window.isOpen() )
    {
        Event e ;

       while( window.pollEvent( e ) )
       {

            switch( e.type )
            {
                case Event::Closed :
                     window.close() ;
            }
            if((e.type == sf::Event::KeyPressed) && (e.key.code == sf::Keyboard::W)){
                std::cout << "Key pressed event" << std::endl;
                //the CLI window should only say "Key Pressed Event" when the event is triggered, not while the      key is down.
            }

       }

        window.clear() ;
        window.display() ;

    }

        return 0;
}

 

See the attachment.
« Last Edit: May 29, 2015, 05:42:46 pm by DarkRoku »
I would like a spanish/latin community...
Problems building for Android? Look here

kitteh-warrior

  • Guest
Re: Sprite can move diagonally [C++]
« Reply #8 on: May 29, 2015, 05:49:24 pm »
I already test your code and when i press the "W" key the console print "Key is currently down" each frame while the key is down. (i only press W one and left it pressed)

You didn't test all of the code.
//within the game loop, where renderWindow = your render window.
sf::Event evt;
while(renderWindow.pollEvents(evt)){
        if((evt.type == sf::Event::KeyPressed) && (evt.key.code == sf::Keyboard::W)){
                std::cout << "Key pressed event" << std::endl;
                //the CLI window should only say "Key Pressed Event" when the event is triggered, not while the key is down.
        }
}

if(sf::Keyboard::isKeyPressed(sf::Keyboard::W)){
        std::cout << "Key is currently down" << std::endl;
        //the CLI window should only say "Key is currently down" while the key is currently being pressed.
}

This was to show you that "Key is currently down" would appear more than "Key pressed event" does.

Insert the following into your game loop (just before the "window.clear()" and "window.draw()" calls), and it will display "Key is currently down" quite a few times, even if you just tap it.
if(sf::Keyboard::isKeyPressed(sf::Keyboard::W)){
        std::cout << "Key is currently down" << std::endl;
        //the CLI window should only say "Key is currently down" while the key is currently being pressed.
}

DarkRoku12

  • Full Member
  • ***
  • Posts: 203
  • Lua coder.
    • View Profile
    • Email
Re: Sprite can move diagonally [C++]
« Reply #9 on: May 29, 2015, 06:18:59 pm »

This was to show you that "Key is currently down" would appear more than "Key pressed event" does.


Yes, all will depend on the precision that the programmers wants.
I would like a spanish/latin community...
Problems building for Android? Look here

kitteh-warrior

  • Guest
Re: Sprite can move diagonally [C++]
« Reply #10 on: May 29, 2015, 06:48:50 pm »
Yes, all will depend on the precision that the programmers wants.

This has nothing to do with precision, more so the frequency of updating. If you use events for this case, then the sprite will move as you press the key, pause for a part of a second, then continue moving as the key is being held down. This would look very choppy.

DarkRoku12

  • Full Member
  • ***
  • Posts: 203
  • Lua coder.
    • View Profile
    • Email
Re: Sprite can move diagonally [C++]
« Reply #11 on: May 29, 2015, 07:08:38 pm »
This has nothing to do with precision

The precision is very important too. (I'm not disparaging the update rate, is important too).

When you play , Sport Games , Shooters Games , Car games ... the precision is VERY important.
In RPG not so much but in harcore games without precision finish them will be IMPOSSIBLE.

SFML have several key events options/triggers , it's up to the programmers use what she/he consider.

I would like a spanish/latin community...
Problems building for Android? Look here

kitteh-warrior

  • Guest
Re: Sprite can move diagonally [C++]
« Reply #12 on: May 29, 2015, 07:22:55 pm »
The precision is very important too. (I'm not disparaging the update rate, is important too).

I am not saying that precision is not important. I am saying that for the OP's problem would be more easily solved with checking the state of the keyboard rather than wait for an event to occur, while keeping consistency with the original syntactical format that they followed, then stated some reasons as to why it would be done that way.

Anyway, this is getting rather off topic.

ulpa

  • Newbie
  • *
  • Posts: 2
    • View Profile
Re: Sprite can move diagonally [C++]
« Reply #13 on: June 01, 2015, 09:39:20 am »
-snip-
Thank you, that solved my problem.
-snip-
I used this before, but I found a problem with that, if you move around the mouse while pressing for example "D" the sprite will move around faster because of the Event loop triggering more times when the mouse is moving, hence why I am using this way instead. Although your system seems more advanced, since I only used something simple.