SFML community forums

Help => Graphics => Topic started by: bladelock on September 26, 2011, 11:18:47 am

Title: How to simulate Mario Jump? (moving the sprite in mid-air)
Post by: bladelock on September 26, 2011, 11:18:47 am
Greetings

Okay, i made this chunk of code that makes the sprite "jump". I havn't really learned anything about manipulating the FPS of a program, so it might explain how i formulated my jump sequence.


I managed to make the sprite "jump" when I press the "Up" button; however, I'm not sure how to make the sprite move horizontally while in mid-air like how mario manages to move horizontally before touching the ground.

Here is part of my code.

Code: [Select]
while(Window.IsOpened())
{

while(Window.GetEvent(Event))
{

if((Event.Type == Event.KeyPressed) && (Event.Key.Code == Key::Up))
{
for(int c = 0; c < 240; c++)
{
Sprite.Move(0, -1.0);
Window.Clear();
Window.Draw(Sprite);
Window.Display();
}

for(int c = 240; c > 0; c--)
{
Sprite.Move(0, 1.0);
Window.Clear();
Window.Draw(Sprite);
Window.Display();
}

}



}
while(Window.GetEvent(Event))
{
if(Event.Type == Event.Closed)
{
Window.Close();
}
else if((Event.Type == Event.KeyPressed) && (Event.Key.Code == Key::Left))
{

Sprite.Move(-10.0, 0);
Window.Clear();
Window.Draw(Sprite);
Window.Display();

}
else if((Event.Type == Event.KeyPressed) && (Event.Key.Code == Key::Right))
{

Sprite.Move(10.0,0);
Window.Clear();
Window.Draw(Sprite);
Window.Display();

}



}



}




Cheers.
Title: How to simulate Mario Jump? (moving the sprite in mid-air)
Post by: sbroadfoot90 on September 27, 2011, 12:33:54 am
I explain the structure of the game loop here

http://www.sfml-dev.org/forum/viewtopic.php?p=39048

Unfortunately in your code, while it will still run, in each game loop, you allow for one jump. One game loop is essentially one frame, so the jump should span over many game loops. You want something like this

Code: [Select]
while(Window.GetEvent(Event)) {
   if( user pressed up ) {
      MarioJumping = true;
   }
}

if (MarioJumping) {
   put some logic in here including things like

   if (left key is being pressed) {
      move mario left a bit
   }

   if (mario hit the ground) {
      MarioJumping = false;
   }
}


Eventually you'll want to move everything into a class so the above code will turn into something like

Code: [Select]
while(Window.GetEvent(Event)) {
   if( user pressed up ) {
      Mario.Jump();
   }
}

Mario.Update();

Window.Clear();
Mario.Draw(Window);
Window.Display();


with the class looking something like this

Code: [Select]
class Mario {
public:
   void Jump();
   void Draw(sf::RenderWindow &Window);
   void Update();
private:
   sf::Sprite Sprite;
   bool IsJumping;
};

void Mario::Jump() {
   IsJumping = true;
}

void Mario::Update() {
   if(IsJumping) {
      same jumping logic as above
   }
   
   some more updating logic
}
Title: How to simulate Mario Jump? (moving the sprite in mid-air)
Post by: bladelock on September 27, 2011, 11:24:19 am
Title: How to simulate Mario Jump? (moving the sprite in mid-air)
Post by: bladelock on September 27, 2011, 01:34:12 pm
Quote from: "sbroadfoot90"
I explain the structure of the game loop here

http://www.sfml-dev.org/forum/viewtopic.php?p=39048

Unfortunately in your code, while it will still run, in each game loop, you allow for one jump. One game loop is essentially one frame, so the jump should span over many game loops. You want something like this

Code: [Select]
while(Window.GetEvent(Event)) {
   if( user pressed up ) {
      MarioJumping = true;
   }
}

if (MarioJumping) {
   put some logic in here including things like

   if (left key is being pressed) {
      move mario left a bit
   }

   if (mario hit the ground) {
      MarioJumping = false;
   }
}


Eventually you'll want to move everything into a class so the above code will turn into something like

Code: [Select]
while(Window.GetEvent(Event)) {
   if( user pressed up ) {
      Mario.Jump();
   }
}

Mario.Update();

Window.Clear();
Mario.Draw(Window);
Window.Display();


with the class looking something like this

Code: [Select]
class Mario {
public:
   void Jump();
   void Draw(sf::RenderWindow &Window);
   void Update();
private:
   sf::Sprite Sprite;
   bool IsJumping;
};

void Mario::Jump() {
   IsJumping = true;
}

void Mario::Update() {
   if(IsJumping) {
      same jumping logic as above
   }
   
   some more updating logic
}


trying it out at the moment.

This is hard!!! I'm already getting screwed by some syntax error  



What if I try to make SFML detect whether the user is pressing two keys at once, how will the code look like?

Thanks
Title: How to simulate Mario Jump? (moving the sprite in mid-air)
Post by: sbroadfoot90 on September 28, 2011, 01:16:49 am
There are two different methods for detecting keyboard input. When the first time the key is pressed, an KeyPressed event gets sent to the event stack. Similarly when the key is released, a KeyReleased event gets sent to the event stack.

However, if you want to track whether a certain key is being pressed at the moment, it's a bit tricky to keep track of these events. Instead the way to test if a key is being pressed right now, you can use the function sf::Input::IsKeyDown(key). So to test if the user is pressing two keys, say up and left, you can go

Code: [Select]
if(IsKeyDown(up) && IsKeyDown(left))

I wouldn't try the OO approach until you understand sfml a bit better.

What is your syntax error saying? Obviously I'm only writing in pseudocode, so don't copy and paste what I've been typing directly into your code.
Title: How to simulate Mario Jump? (moving the sprite in mid-air)
Post by: bladelock on September 28, 2011, 11:59:04 am
Quote from: "sbroadfoot90"
There are two different methods for detecting keyboard input. When the first time the key is pressed, an KeyPressed event gets sent to the event stack. Similarly when the key is released, a KeyReleased event gets sent to the event stack.

However, if you want to track whether a certain key is being pressed at the moment, it's a bit tricky to keep track of these events. Instead the way to test if a key is being pressed right now, you can use the function sf::Input::IsKeyDown(key). So to test if the user is pressing two keys, say up and left, you can go

Code: [Select]
if(IsKeyDown(up) && IsKeyDown(left))

I wouldn't try the OO approach until you understand sfml a bit better.

What is your syntax error saying? Obviously I'm only writing in pseudocode, so don't copy and paste what I've been typing directly into your code.


It tried the Input::IsKeyDown() function, this is what I got



Here is my Code
Code: [Select]
while(Window.IsOpened())
{

if(Input::IsKeyDown(Up))
{
Sprite.Move(0, -10.0);
Window.Clear();
Window.Draw(Sprite);
Window.Display();
}



while(Window.GetEvent(Event))
{
if(Event.Type == Event.Closed)
{
Window.Close();
}
else if((Event.Type == Event.KeyPressed) && (Event.Key.Code == Key::Left))
{

Sprite.Move(-10.0, 0);
Window.Clear();
Window.Draw(Sprite);
Window.Display();

}
else if((Event.Type == Event.KeyPressed) && (Event.Key.Code == Key::Right))
{

Sprite.Move(10.0,0);
Window.Clear();
Window.Draw(Sprite);
Window.Display();

}



}



}


Then it says...
Code: [Select]
main.cpp(38): error C2065: 'Up' : undeclared identifier

I checked the SFML Website, and I included <SFML\Window\Input.hpp>

And I added "Up" since it said here that the keycode for the up arrow is "Up"
http://www.sfml-dev.org/documentation/1.6/namespacesf_1_1Key.php#ad32ed01d3448273340bd25af5cdd9c81

How should I fix this?



EDIT: Now i've tried replaceing "Up" with
Code: [Select]
Key::Up
now it gives
Code: [Select]
main.cpp(38): error C2352: 'sf::Input::IsKeyDown' : illegal call of non-static member function

How do I do this?

Thanks for the help so far also.
Title: How to simulate Mario Jump? (moving the sprite in mid-air)
Post by: Laurent on September 28, 2011, 12:01:48 pm
This enum is in the namespace sf::Key.

Code: [Select]
if(Input::IsKeyDown(sf::Key::Up))
Title: How to simulate Mario Jump? (moving the sprite in mid-air)
Post by: bladelock on September 28, 2011, 12:22:07 pm
Quote from: "Laurent"
This enum is in the namespace sf::Key.

Code: [Select]
if(Input::IsKeyDown(sf::Key::Up))


Sir Laurent, I have tried adding the if condition you suggested; however, I end up getting this

Code: [Select]
main.cpp(39): error C2352: 'sf::Input::IsKeyDown' : illegal call of non-static member function


What have I done?
Title: How to simulate Mario Jump? (moving the sprite in mid-air)
Post by: Nexus on September 28, 2011, 12:28:42 pm
As the error message says, IsKeyDown() is not static, so you need an object to call it.

You can access the sf::Input object of a window with sf::RenderWindow's method GetInput(). Call the IsKeyDown() method on this object, using the . operator.
Title: How to simulate Mario Jump? (moving the sprite in mid-air)
Post by: bladelock on September 28, 2011, 01:58:09 pm
Quote from: "Nexus"
As the error message says, IsKeyDown() is not static, so you need an object to call it.

You can access the sf::Input object of a window with sf::RenderWindow's method GetInput(). Call the IsKeyDown() method on this object, using the . operator.


I googled your suggestion, I found this link.
http://www.youtube.com/watch?v=G1_OstExZAk

I learned that since I would have to call it w/ an object. I called IsKeyDown using Window.GetInput()

Resulting to something like

if(Window.GetInput().IsKeydDown(sf::Key::Up))

Thank you!


Now, to the main question, with this method, how can I then simulate the Jump, allowing the player to move a bit while in mid-air?
Title: How to simulate Mario Jump? (moving the sprite in mid-air)
Post by: sbroadfoot90 on September 29, 2011, 09:40:16 am
Already answered this in my first reply.