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

Author Topic: Simulating character movement - How do? [SOLVED]  (Read 10463 times)

0 Members and 1 Guest are viewing this topic.

AngelHoof

  • Newbie
  • *
  • Posts: 27
    • View Profile
Simulating character movement - How do? [SOLVED]
« on: July 21, 2011, 05:10:18 pm »
Hey!

So, I've managed to get together a blob that moves around the screen with the WASD keys, by this code:

Code: [Select]

const sf::Input& Input = Win.GetInput();
bool LeftKeyDown = Input.IsKeyDown(sf::Key::A);
bool RightKeyDown = Input.IsKeyDown(sf::Key::D);
bool UpKeyDown = Input.IsKeyDown(sf::Key::W);
bool DownKeyDown = Input.IsKeyDown(sf::Key::S);


And then later down the switch (Event.Type) this:
(Head is the sprite I want to control movement with)
Code: [Select]

case sf::Event::KeyPressed:
if (UpKeyDown)
Head.Move(0, -10);
if (DownKeyDown)
Head.Move(0, 10);
if (RightKeyDown)
Head.Move(10, 0);
if (LeftKeyDown)
Head.Move(-10, 0);


Now, this works to a degree, using the sf::Input i can press up and right  at the same time and it'll go diagonal. (Whereas i just had KeyPressed before)

However, upon pressing for example W (to go up) it moves one step (10 pixels) then stops for about half a second, then continues relatively smooth.

I guess I should use the clock somehow and decrease the Move to maybe 1 pixel per 0.1 seconds or something, so that I can get the smooth movement I want.

Just not sure how to go about this, any ideas?

Also, sorry if this is in the wrong section.

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6286
  • Thor Developer
    • View Profile
    • Bromeon
Simulating character movement - How do? [SOLVED]
« Reply #1 on: July 21, 2011, 05:19:24 pm »
Take the realtime inputs out of the event-handling loop.

sf::Event and sf::Input are two different mechanisms. The former reacts on one-time events (like key pressed), while the latter allows you to poll the current state of keyboard, mouse and joystick.
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

AngelHoof

  • Newbie
  • *
  • Posts: 27
    • View Profile
Simulating character movement - How do? [SOLVED]
« Reply #2 on: July 21, 2011, 05:35:06 pm »
:oops:

Oh my god, sorry about that!

Right okay, I'm at a loss right now aswell though, I figured I'd move my Input checking here:

Code: [Select]

while (Win.IsOpened())
{
const sf::Input& Input = Win.GetInput();
bool LeftKeyDown = Input.IsKeyDown(sf::Key::A);
bool RightKeyDown = Input.IsKeyDown(sf::Key::D);
bool UpKeyDown = Input.IsKeyDown(sf::Key::W);
bool DownKeyDown = Input.IsKeyDown(sf::Key::S);

while ()
{
Head.Move(-10, 0);
}


I was thinking this would work, but apparently it doesn't. Infact, it actually freezes the program.
Code: [Select]

while (LeftKeyDown)
{
Head.Move(-10, 0);
}


However, I'm not sure where to go from here to check the Realtime Input, any advice?

Blublop

  • Newbie
  • *
  • Posts: 13
    • View Profile
Simulating character movement - How do? [SOLVED]
« Reply #3 on: July 21, 2011, 05:42:20 pm »
It's your while loop what indicates the crash.
Image when you click A , your variable "leftkeydown" is set to TRUE.
Then if you reach the while loop the programm gets stuck because the condition is always true.

To solve your problem just replace the while loop by a single if condition

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
Simulating character movement - How do? [SOLVED]
« Reply #4 on: July 21, 2011, 06:31:18 pm »
Quote
it actually freezes the program

You still need an event loop (even an empty one) to keep the window responsive.
Laurent Gomila - SFML developer

AngelHoof

  • Newbie
  • *
  • Posts: 27
    • View Profile
Simulating character movement - How do? [SOLVED]
« Reply #5 on: July 21, 2011, 09:09:54 pm »
Ah, Okay, Thanks Laurent! So I made it into if expressions again and moved it into the PollEvent loop.

It seems to work differently... But, still a delay before movement when actually starting to press the key.

So, this is the current state:

Code: [Select]

while (Win.IsOpened())
{
const sf::Input& Input = Win.GetInput();
bool LeftKeyDown = Input.IsKeyDown(sf::Key::A);
bool RightKeyDown = Input.IsKeyDown(sf::Key::D);
bool UpKeyDown = Input.IsKeyDown(sf::Key::W);
bool DownKeyDown = Input.IsKeyDown(sf::Key::S);


sf::Clock WinTime;
float Timer = WinTime.GetElapsedTime();


sf::Event Happen;
while (Win.PollEvent(Happen))
{
if (LeftKeyDown)
Head.Move(-10, 0);
if (RightKeyDown)
Head.Move(10, 0);
if (UpKeyDown)
Head.Move(0, -10);
if (DownKeyDown)
Head.Move(0, 10);


And then it moves onto the event switch for closing the window and whatnot...


So, uh... The clock is completely unused.  
I'm still not sure where to go from here to get the smooth movement I want  :)

Disch

  • Full Member
  • ***
  • Posts: 220
    • View Profile
Simulating character movement - How do? [SOLVED]
« Reply #6 on: July 22, 2011, 02:25:03 am »
Whether or not the key is down has nothing to do with events.  So take that out of your event loop.

You want something like this:

Code: [Select]

while(game_running)
{
  while( events )
  {
    // check the events
    //   the only event you're probably interested in is the Close
    //   event
   
    //  you do NOT want key events
  }

  // now that you're outside the event loop, see what keys are down

  // move object based on whatever keys are down

  //  draw / display
}

AngelHoof

  • Newbie
  • *
  • Posts: 27
    • View Profile
Simulating character movement - How do? [SOLVED]
« Reply #7 on: July 22, 2011, 11:57:30 am »
Hmm, okay.

Code: [Select]

while (Win.IsOpened())
{
const sf::Input& Input = Win.GetInput();
bool LeftKeyDown = Input.IsKeyDown(sf::Key::A);
bool RightKeyDown = Input.IsKeyDown(sf::Key::D);
bool UpKeyDown = Input.IsKeyDown(sf::Key::W);
bool DownKeyDown = Input.IsKeyDown(sf::Key::S);


sf::Clock WinTime;
float Timer = WinTime.GetElapsedTime();


sf::Event Happen;
while (Win.PollEvent(Happen))
{
switch (Happen.Type)
{
case sf::Event::Closed:
Win.Close();
break;
case sf::Event::KeyPressed:
if (Happen.Key.Code == sf::Key::Escape)
Win.Close();
break;
default:
break;
}
}

if (LeftKeyDown)
Head.Move(-0.1, 0);
if (RightKeyDown)
Head.Move(0.1, 0);
if (UpKeyDown)
Head.Move(0, -0.1);
if (DownKeyDown)
Head.Move(0, 0.1);

Win.Clear();
Win.Draw(Head);
Win.Display();

}
}


So that's what I've got then, and pressing any key just removes the sprite, although the window is still responsive.


Edit: Changed the (move's) to 1's instead of 10's, and it's now moving around REALLY fast???

This is slightly confusing.

Edit2: Changed it to 0.1 movements instead, and it's working perfectly now!

So uh... Nice, I guess  :)

G.

  • Hero Member
  • *****
  • Posts: 1592
    • View Profile
Simulating character movement - How do? [SOLVED]
« Reply #8 on: July 22, 2011, 12:53:43 pm »
When your movement is inside the event loop, it is run only when your even is processed, which isn't every frame. (probably depends on the key repeat delay) Now it runs every frame, hence the faster speed.

AngelHoof

  • Newbie
  • *
  • Posts: 27
    • View Profile
Simulating character movement - How do? [SOLVED]
« Reply #9 on: July 22, 2011, 01:03:41 pm »
Ah, thank you G.!

Disch

  • Full Member
  • ***
  • Posts: 220
    • View Profile
Simulating character movement - How do? [SOLVED]
« Reply #10 on: July 22, 2011, 04:46:20 pm »
You might also want to set a framerate limit so that the speed at which your player moves does not depend on the speed of the user's computer.

If you set the FPS limit to 60, and he's moving at 1 pixel per frame, then he'll move 60 pixels per second.

AngelHoof

  • Newbie
  • *
  • Posts: 27
    • View Profile
Simulating character movement - How do? [SOLVED]
« Reply #11 on: July 22, 2011, 04:52:38 pm »
Ah, that's great advice, more control over movement  :)

Disch, as in, disch from cplusplus?

Disch

  • Full Member
  • ***
  • Posts: 220
    • View Profile
Simulating character movement - How do? [SOLVED]
« Reply #12 on: July 22, 2011, 06:03:24 pm »
Yes I am the same Disch from the cplusplus.com forums.  :)