how do I get my sprite to move up and down once

Started by
67 comments, last by Tom Sloper 4 years, 6 months ago
13 minutes ago, Prototype said:

Do you want to make a finished game? Do you just want to muck around with openGL? Think about that, and then pick the tools that make it possible in the easiest way.

Well said. Phil, you've always said you want to work with the tools you learned before. This is a time when you need to adopt newer better tools.

-- Tom Sloper -- sloperama.com

Advertisement

 well I went to the bookstore with my code and traced out every line of code in the Update function which is called by the glutTimerFunc function. this is where my problem lies. what I want is that the positionY variable to count  up to 25.0f and then count back down to 0.0f. I am  also  using the velocityY variable to count up and down depending on where the positionY variable is located. I am also going to debug my code and see it is actually working. 

51 minutes ago, phil67rpg said:

 well I went to the bookstore with my code and traced out every line of code in the Update function which is called by the glutTimerFunc function. this is where my problem lies. what I want is that the positionY variable to count  up to 25.0f and then count back down to 0.0f. I am  also  using the velocityY variable to count up and down depending on where the positionY variable is located. I am also going to debug my code and see it is actually working. 

Phil you need to understand that you don't conduct a jump movement in a single frame... Depending on if you're using a variable time step or fixed you would find out how much time or how many ticks you would want the jump to take for a full cycle, then you do a part of that per update cycle while keeping track of where you are in your jump until you're either at the final stage or interrupted.

I have no idea why you don't just use a boolean when a jump button is pressed and in your update you begin your jump cycle and every tick after you update your position based on your algorithms for as long as your boolean returns true.

Your problem is that you don't understand how a Game Loop works and how Time Steps work. Research these and come back and explain in your own words what a Game Loop is and the different types of Time Steps and how they work. If you cannot do this then I would suggest sticking to Game Maker Studio or something more simple.

Also stop using GLUT for games.... Beyond simple prototypes it doesn't make sense to use it for anything requiring Update loops like this... If you're making a turn based game like a Card Game then you can get away with it.

Programmer and 3D Artist

On 10/2/2019 at 12:58 PM, Prototype said:

You're moving in the right direction, Phil

Agreed. This feels much better, with the start of logical groupings. Emphasis could be put back on managing state as @Prototype suggests with the onGround variable. One design here would be a controller(manager) for your objects that makes per frame pre-defined checks. Another design would be the object adjusts state based on it's own data (closer to what you seem to be trying to do).  As your game systems mature, it becomes a mix.  Although I understand that, case in point is currently a logic error, I though it might be positive to lean the discussion to overall design first instead of our pattern of one little piece missing. I also like that @phil67rpg is trying to make better descriptions. During your posts, spend some more time on expressing your things as @Rutin suggests. A lot more words. Don't worry if what you write is wrong. I think that would do two things. One, you may answer your own question in the process of trying to describe it completely (at which point the programmer in you can bloom) or the other, where we'll see where you are failing quicker.

With that said, the glut thing...I can understand the draw to this being also from the era. A few great frameworks (like the old F. Luna stuff) used it and probably survived time to be picked up again and again. I didn't because I was anti-everything back then :) but have tried more than a handful of the options. GLFW I liked, but I timed it against a raw OGL startup and doing input handling with the same ~80,000 vertices or so test (hmp...something) and it was measurably working harder (~15-20+%) somewhere in GLFW. Easy to get up and going with. SFML was okay, I'm not sure I gave it a fair chance. Currently I'm using SDL which is interesting if you like gluing together libraries as I do. Those are my C++ choices. For C#, I reach for monogame or Unity for fun. GoDot is the next on my list but runs funny on my (much) older system, so that fun is waiting for an upgrade.  

edit;p I thought I might add one last thing...perhaps you might consider tracking your distance off the ground and doing a hard reaction/reset crossing zero..that might be interesting info. Also when i jump, all I do is give my object thing an impulse. (in whatever direction) fire it. forget it. All my dynamic objects, all the time, have a downward attraction. The fight then becomes when you are on the ground (falling through or wiggle with extreme purpose :D or better yet, do nothing at all)

Then again...a dozen more approaches are valid. 

 


if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN && 
    key_jump == false && onGround == true) // <-- and allow this state
{
	// fire the jump impulse action here and forget it

	key_jump = true; 
}

 

I am reading up on game loops and timing steps I see that gaming algorithms  have been around for quite some time. I am learning about timing and frames.

Just by looking at your code, i don't know how often key precesses are processed. Likely while the timer is used to wait for the next update, the keys may be processed multiple times, which makes it hard to imagine what's going on. (Here logging to a text file can give better understanding than using the debugger.)

To get rid of such issues and doubts, you could use your own tracking of input, and process the resulting events in your update to sync all this, e.g. like so (I don't understand the need for EndJump, so it's no longer used here):

 


bool onGround = false;
bool key_jump = false;

void StartJump()
{
	if (onGround)
	{
		velocityY = -12.0f;
		onGround = false;
	}
}

void EndJump()
{
	if (velocityY < -6.0f)
	{
		velocityY = -6.0f;
	}
}

void Update()
{
    if (key_jump) StartJump();
                          
	velocityY += gravity;
	positionY += velocityY;
	positionX += velocityX;
	if (positionY > 25.0f)
	{
		positionY = 0.0f;
		velocityY = 0.0f;
		onGround = false;
	}
}

void Loop(int val)
{
	Update();
	drawSprite();
	glutPostRedisplay();
	glutTimerFunc(33, Loop, 0);
}

void mouseClicks(int button, int state, int x, int y)
{
	if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN)
	{
		//StartJump();
    	key_jump = true;
	}
	if (button == GLUT_LEFT_BUTTON && state == GLUT_UP)
	{
		//EndJump();
      	key_jump = false;
	}
}

void handleKeypress(unsigned char key, int x, int y)
{
	switch (key)
	{
	case 27:
		exit(0);
		break;
	case 32:
		Loop(0);
		break;

 

If this works, there is still a problem: If the user presses the key only for a short duration, the bool might be set AND unset BEFORE the update is called, so it misses the desired jump. This could be fixed in many ways, for example by sing multiple flags to track both button down and button up events seperately. 

1 hour ago, JoeJ said:

if (positionY > 25.0f) { positionY = 0.0f;

Spotted a bug, must be either

if(y>25) y=25

or 

if(y>0) y=0 

?

thanks joe, I am have changed my code, it  jumps up to 25.0f and  stays there, I will work on it some more.


bool onGround = false;
bool key_jump = false;

void StartJump()
{
	if (onGround)
	{
		velocityY = -12.0f;
		onGround = false;
	}
}

void EndJump()
{
	if (velocityY < -6.0f)
	{
		velocityY = -6.0f;
	}
}

void Update()
{
	if (key_jump)
		StartJump();
		velocityY += gravity;
		positionY += velocityY;
		positionX += velocityX;
		if (positionY > 25.0f)
		{
			positionY = 25.0f;
			velocityY = 0.0f;
			onGround = false;
		}
}

void Loop(int val)
{
	Update();
	drawSprite();
	glutPostRedisplay();
	glutTimerFunc(33, Loop, 0);
}

void mouseClicks(int button, int state, int x, int y)
{
	if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN)
	{
		key_jump=true;
	}
	if (button == GLUT_LEFT_BUTTON && state == GLUT_UP)
	{
		key_jump=false;
	}
}

void handleKeypress(unsigned char key, int x, int y)
{
	switch (key)
	{
	case 27:
		exit(0);
		break;
	case 32:
		Loop(0);
		break;

 

Don't call Loop() when the spacebar is pressed, this function is called repetitively by glutTimerFunc.

Right now you are starting a new jump over and over when key_jump is true, you only want to call that when a jump starts. Note that your forgot the braces on your if(key_jump) clause. Also, you don't need a dedicated action to stop jumping, this condition will automatically be met when you hit the ground.

I reworked your code a little to reflect these changes.


bool onGround = false;


void StartJump()
{
    if (onGround)
    {
        velocityY = -12.0f;
        onGround = false;
    }
}


void Update()
{
    velocityY += gravity;
    positionY += velocityY;
    positionX += velocityX;
    if (positionY > 25.0f)
    {
        positionY = 25.0f;
        velocityY = 0.0f;
        onGround = true;
    }
}

void Loop()
{
    Update();
    drawSprite();
    glutPostRedisplay();
    glutTimerFunc(33, Loop, 0);
}

void mouseClicks(int button, int state, int x, int y)
{
    if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN)
    {
        StartJump();
    }
}

void handleKeypress(unsigned char key, int x, int y)
{
    switch (key)
    {
        case 27:
            exit(0);
            break;
        }
    }
}

 

This topic is closed to new replies.

Advertisement