0
\$\begingroup\$

I've got a little question about my gravity that isn't working and I can't find out why...

The issue is that the player just go upper but doesn't really 'jump' and doesn't come back on the ground. Plus, he can move like if he is on the ground while in the air but not like in a game like Mario...

It's like the condition about if I'm above or below a certain amount of Y position in the Move() method isn't seen I didn't really know how to use the acceleration though so it doesn't have any value, I'm so lost

Here is the code:

using System;
using SFML.Graphics;
using SFML.Window;
using SFML.System;

namespace ITI_First_Game
{
    public abstract class GameLoop
    {
        #region Fields

        public const int TARGET_FPS = 60;
        public const float TIME_UNTIL_UPDATE = 1f / TARGET_FPS;

        Clock _clock = new Clock();

        static Texture _backgroundTexture = new Texture("../Content/Bbackground.jpg");
        static Sprite _backgroundSprite;

        static Texture _mouseTexture = new Texture("../Content/mousesad.png");
        static Sprite _mouseSprite;

        static Texture _playerTexture = new Texture("../Content/playersprite.png");
        static Sprite _playerSprite;
        int _direction;
        //int _speed;
        int _animFrames;
        int _animStop;
        float deltaTime;

        float _velocityX = 0;
        float _velocityY = 0;
        float _accelerationX = 0;
        float _accelerationY = 0;
        float _gravity = 0;

        #endregion

        #region Properties

        public RenderWindow Window
        {
            get;
            protected set;
        }

        public GameTime GameTime
        {
            get;
            protected set;
        }

        public Color WindowClearColor
        {
            get;
            protected set;
        }

        #endregion

        protected GameLoop(uint windowWidth, uint windowHeight, string windowTitle, Color windowClearColor)
        {
            _backgroundTexture.Repeated = true;
            _backgroundSprite = new Sprite(_backgroundTexture);

            _mouseSprite = new Sprite(_mouseTexture);

            _playerSprite = new Sprite(_playerTexture);
            //_playerSprite.TextureRect = new IntRect(0, 0, 64, 96);
            _playerSprite.Position = new Vector2f(640, 580);
            //_speed = 400f;

            this.WindowClearColor = windowClearColor;
            this.Window = new RenderWindow(new VideoMode(windowWidth, windowHeight), windowTitle);
            this.GameTime = new GameTime();

            Window.Closed += WindowClosed;
            Window.SetFramerateLimit(60);

            Window.KeyPressed += WindowEscaping;
            //Window.KeyPressed += WindowPlayerMoved;

            Window.MouseMoved += MouseMoved;
            Window.MouseLeft += MouseLeft;
            Window.MouseEntered += MouseEntered;
            Window.MouseButtonReleased += WindowMouseButtonReleased;
        }

        public void Run() // Main method of the gameloop
        {
            LoadContent();
            Initialize();

            _animFrames = 0;
            _direction = 192;
            _animStop = 64;

            float totalTimeBeforeUpdate = 0f;
            float previousTimeElapsed;//= 0f;
            previousTimeElapsed = _clock.ElapsedTime.AsSeconds();
            deltaTime = 0f;
            float totalTimeElapsed = 0f;

            while (Window.IsOpen)
            {
                Window.DispatchEvents();

                totalTimeElapsed = _clock.ElapsedTime.AsSeconds();
                deltaTime = totalTimeElapsed - previousTimeElapsed;
                previousTimeElapsed = totalTimeElapsed;

                totalTimeBeforeUpdate += deltaTime;

                Move();

                if (totalTimeBeforeUpdate >= TIME_UNTIL_UPDATE)
                {
                    GameTime.Update(totalTimeBeforeUpdate, totalTimeElapsed);
                    totalTimeBeforeUpdate = 0f;

                    Update(GameTime);

                    Window.Clear(WindowClearColor);

                    _backgroundSprite.Draw(Window, RenderStates.Default);

                    _mouseSprite.Draw(Window, RenderStates.Default);

                    if (_animFrames == 4) _animFrames = 0;
                    _playerSprite.TextureRect = new IntRect(_animFrames * _animStop, _direction, 64, 96);
                    ++_animFrames;
                    _playerSprite.Draw(Window, RenderStates.Default);

                    Draw(GameTime);
                    Window.Display();
                }
            }
        }

        public abstract void LoadContent();
        public abstract void Initialize();
        public abstract void Update(GameTime gameTime);
        public abstract void Draw(GameTime gameTime);

        private void Move()
        {
            _gravity = 5000;

            if (_playerSprite.Position.Y < 580) _velocityY += _gravity;
            else if (_playerSprite.Position.Y > 580) _playerSprite.Position = new Vector2f(_playerSprite.Position.X, 580);

            _velocityX += _accelerationX;
            _velocityY += _accelerationY;

            if (Keyboard.IsKeyPressed(Keyboard.Key.Space))
            {
                _animStop = 0;
                _velocityY = -100;
                _playerSprite.Position += new Vector2f(0f, _velocityY * deltaTime);
                Console.WriteLine(_playerSprite.Position);
            }

            if (Keyboard.IsKeyPressed(Keyboard.Key.Q))
            {
                _direction = 96;
                _animStop = 64;
                _velocityX = -500;
                _playerSprite.Position += new Vector2f(_velocityX * deltaTime, 0f);
            }

            else if (Keyboard.IsKeyPressed(Keyboard.Key.D))
            {
                _direction = 192;
                _animStop = 64;
                _velocityX = 500;
                _playerSprite.Position += new Vector2f(_velocityX * deltaTime, 0f);
            }
            else _animStop = 0;

            /*if (_playerSprite.Position.X >= 960) _backgroundSprite.TextureRect = new IntRect(new Vector2i((int)_playerSprite.Position.X % (int)_backgroundSprite.Texture.Size.X, 0), new Vector2i(1280, 720));
            else if (_playerSprite.Position.X < 320) _backgroundSprite.TextureRect = new IntRect(new Vector2i((int)_playerSprite.Position.X % (int)_backgroundSprite.Texture.Size.X, 0), new Vector2i(1280, 720));*/

            /*if (_playerSprite.Position.X < 0) _playerSprite.Position = new Vector2f(0, _playerSprite.Position.Y);
            else if (_playerSprite.Position.X > 1220) _playerSprite.Position = new Vector2f(1220, _playerSprite.Position.Y);*/
        }

        private void WindowClosed(object sender, EventArgs e)
        {
            Window.Close();
        }

        private void WindowEscaping(object sender, KeyEventArgs e)
        {
            if (e.Code == Keyboard.Key.Escape) Window.Close();
        }

        private void MouseLeft(object sender, EventArgs e)
        {
            Window.SetMouseCursorVisible(true);
        }

        private void MouseEntered(object sender, EventArgs e)
        {
            Window.SetMouseCursorVisible(false);
        }

        private void MouseMoved(object sender, MouseMoveEventArgs e)
        {
            _mouseSprite.Position = new Vector2f(e.X, e.Y);
        }

        private void WindowMouseButtonReleased(object sender, MouseButtonEventArgs e)
        {
            //if (e.Button == Mouse.Button.Left) _playerSprite.Position = new Vector2f(e.X, e.Y);
        }

    }
}

For those who prefer Hastebin, this is one: https://hastebin.com/ligerarigo.cs

\$\endgroup\$
-1
\$\begingroup\$

Here's a quick block of pseudo-code that could help you, with the comments.

Basically, the gravity is your acceleration, it modifies the velocity every frame, and the velocity modifies the position.

A jump is an impulse that modifies the velocity once (you have to make sure to not apply it every frame).

const gravity = 5000 // this should not change during the execution of your game

_accelerationY = gravity // Assuming that the 0,0 is at the top left of the screen 

// As frames go by, the acceleration will increase, having the character falling faster and 
// faster.

// Manage your input first (this will override the gravity.
if ( _spaceReleasedLastFrame && spaceDownThisFrame )
{
  // give  impulse
  _velocityY = -30000 // This high value is to scale with your gravity
  // Again, as frames go by, the gravity will revert the effect of this jump, slowing the 
  // speed the character is going in the up direction, then making it go down.

  _spaceReleasedLastFrame = False // Make sure we don't spam the jump
}
else if ( !spaceDownThisFrame )
{
  _spaceReleasedLastFrame = True
}

_velocityY += _accelerationY // Change the velocity based on the acceleration (gravity)
_positionY += _velocityY


// When you reach the floor, make sure you don't get through, and set the velocity to 0 in
// case you find another force
if ( _positionY > 580 )
{
  _velocityY = 0
  _positionY = 580
} 

Keep in mind that it's been a while since I worked on something like this so there might be a small issue here or there.

You'll eventually need a flag that sets when you jump, and resets when the character touches the ground to prevent double/triple/quadruple/etcuple jump.


On a side note, you seem to be working on a 60 FPS basis, and you seem to Update your game with the frame time (it's unclear now what GameTime does), but this does not apply to your Move method. You might want to pass the deltaT to the Move method and base your calculations on that. You'll have an easier time to wrap you head around x-pixels-per-second than x-pixels-per-variable-frame.

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ Thanks for your help. Actually, I don't really know how to make a difference between what is done normally and what is done every frame. I'm actually working on a 60 FPS basis, yep. The deltaTime is already passed to the Move method to make the calculation with the speed, to be able to make the character move at the same speed whether the FPS are at 60 or 10. I'll try that tomorrow, thanks! \$\endgroup\$ – Tanguy Epifanic Mar 15 '18 at 20:09
  • \$\begingroup\$ Actually, I added the gravity as you wrote it but I can't really add the _spaceReleased and _spaceDown method, I don't know how to make the difference in the code between the actual frame and the last frame... EDIT: I didn't use the _velocityY += _gravity in the character position, that's why my character wasn't going down. Furthermore, that condition was entered as well as the one about the Space Key Pressed (and not released!), so he was 'going down' and going up at the same time. \$\endgroup\$ – Tanguy Epifanic Mar 16 '18 at 9:10

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.