FPS jumping problem (changing gravity)

If you are a new Irrlicht Engine user, and have a newbie-question, this is the forum for you. You may also post general programming questions here.
Post Reply
SARIN
Posts: 139
Joined: Fri Oct 29, 2004 3:53 am

FPS jumping problem (changing gravity)

Post by SARIN »

i am using my own custom fps code for the collision system and gravity, but i am using the fps cam from irrlicht for basic movement. my collision works fine, but whenever i jump, the gravity will sometimes be correct, but other times the gravity will be slow and it will seem like i am floating.
anyone no what the problem is?

in the eventreceiver

Code: Select all

         if(event.EventType == EET_KEY_INPUT_EVENT && event.KeyInput.PressedDown == true &&
                       event.KeyInput.Key == KEY_SPACE && lvlcollision==true)
    {
        jump=1;
        jumping=true;
    }
in the mainloop

Code: Select all

     camrot=cam->getRotation();
     vector3df vector = cam->getPosition();
     vector=SideCollision(vector);
     vector=vector3df(vector.X,vector.Y+jump+3.5,vector.Z);
     vector3df groundlvl=LevelCollision(vector);
     if(lvlcollision==true) {vector.Y=groundlvl.Y+6.5;jump=0;}
     else if(lvlcollision==false) jump=jump-.01;
     cam->setPosition(vector3df(vector.X,vector.Y,vector.Z));
     player->node->setRotation(vector3df(0,camrot.Y,0));
     player->node->setPosition(vector3df(vector.X,vector.Y-6.5,vector.Z));
i have 2 external collision functions. the first is for checking collision with the graoun and the second is for collision with the sides and top of the player

Code: Select all

vector3df game::LevelCollision(vector3df pos) {
    if(jumping==true && jump>0) {return pos;}
    else {
    vector3df point=vector3df(0,0,0);
    line3d<f32> line;
    triangle3d<f32> tri;
    line.start=pos;
    line.end=vector3df(pos.X,pos.Y-7,pos.Z);
    if(sncl->getCollisionPoint(line,tris,point,tri)) {lvlcollision=true;jumping=false;}
    else {lvlcollision=false;}
    return point;}
}

vector3df game::SideCollision(vector3df pos) {
    vector3df point;
    line3d<f32> line;
    triangle3d<f32> tri;
    pos=vector3df(pos.X,pos.Y-3.5,pos.Z);
    for(int i=0;i<5;++i) {
    line.start=pos;
    if(i==0) {line.end=vector3df(pos.X+3,pos.Y,pos.Z);}
    else if(i==1) {line.end=vector3df(pos.X-3,pos.Y,pos.Z);}
    else if(i==2) {line.end=vector3df(pos.X,pos.Y,pos.Z+3);}
    else if(i==3) {line.end=vector3df(pos.X,pos.Y,pos.Z-3);}
    else if(i==4) {line.end=vector3df(pos.X,pos.Y+5,pos.Z);}
    if(sncl->getCollisionPoint(line,tris,point,tri)) {
    if(i==0) {pos.X=point.X-3;}
    else if(i==1) {pos.X=point.X+3;}
    else if(i==2) {pos.Z=point.Z-3;}
    else if(i==3) {pos.Z=point.Z+3;}
    else if(i==4) {pos.Y=point.Y-5;}
    }
    else {lvlcollision=false;}}
    return pos;
}
Guest

Post by Guest »

This bit:

Code: Select all

     vector=vector3df(vector.X,vector.Y+jump+3.5,vector.Z); 
     vector3df groundlvl=LevelCollision(vector); 
     if(lvlcollision==true) {vector.Y=groundlvl.Y+6.5;jump=0;} 
     else if(lvlcollision==false) jump=jump-.01;
Does not compensate for the frame rate.
You should make it something like:

Code: Select all

     vector=vector3df(vector.X,vector.Y+jump*frametime,vector.Z); 
     vector3df groundlvl=LevelCollision(vector); 
     if(lvlcollision==true) {vector.Y=groundlvl.Y+6.5;jump=0;} 
     else if(lvlcollision==false) jump=jump-.01*frametime;
You can get the frame time (in milliseconds, so multiply by 1000) in the OnPostRender function. I would suggest putting this sort of physics stuff into the OnPostRender function for your own FPS class.
SARIN
Posts: 139
Joined: Fri Oct 29, 2004 3:53 am

Post by SARIN »

hmmm, that is wat im now trying to do, but it is now very choppy (the movement, as i am using a custom camera now, the jumping wont even work right) whenever i press forward it only moves a bit every 2 seconds or so. a possible reason is that time isless than an integer 1, but i think that that would require a frame rate of over 1000, and its only showing at 80-158.my code for getting the time

in the event reciever

Code: Select all

    if(event.EventType == EET_KEY_INPUT_EVENT && event.KeyInput.PressedDown == true &&
                       event.KeyInput.Key == KEY_KEY_W)
    {
        camspeed.X=500*sin(camrot.Y)*time/1000;
        camspeed.Z=500*cos(camrot.Y)*time/1000;
        moving=true;
    }
in the main loop

Code: Select all

time=device->getTimer()->getTime()-lasttime;
if(lvlcollision==false) camspeed.Y=camspeed.Y-.0003*time/1000;
lasttime=device->getTimer()->getTime();
[code]

is there something wrong with the time multiplication?
thx
Guest

Post by Guest »

Well, actually... you're doing some perfectly sensible things here:
multiplying by 500 and dividing by 1000.

Thing is, those are integers. When you combine integers with floats, the result is an integer, not a float.
So what I expect to be calculated is something like:
500*0*0/1000 - which is likely to be 0

Try writing your constants as 500.0 and 1000.0

Also, I doubt that the event receiver handles continuous keypresses.
More likely, you're "jumping" forward every time the user presses a key.
You only get an event when something changes. Look in the FAQ forum for the keys[] stuff - you're likely more interested in setting the speed (or acceleration) depending on whether the key is currently being depressed.
SARIN
Posts: 139
Joined: Fri Oct 29, 2004 3:53 am

Post by SARIN »

yay working! my problem wast that i was calling the beginscene in between, like this

Code: Select all

time=device->getTimer()->getTime()-lasttime;
driver->beginScene();
driver->endScene();
lasttime=device->getTimer()->getTime();
it is now like

Code: Select all

time=device->getTimer()->getTime()-lasttime;
lasttime=device->getTimer()->getTime();
driver->beginScene();
driver->endScene();
thx
VeneX
Posts: 228
Joined: Sun Nov 30, 2003 3:32 pm
Location: The Netherlands
Contact:

Post by VeneX »

I trie to let the camera jump in the techdemo.
At the eventhandling of the spacebar I added:

Code: Select all

if(!jump)
		{	collider->setGravity(core::vector3df(0, 0.1f,0));
			timeForJumpScene = 500;
			jumpStartTime = device->getTimer()->getTime();
			jump = true;
		}
and in the main loop I added:

Code: Select all

u32 now = device->getTimer()->getTime();
			if (now - jumpStartTime > timeForJumpScene && jump);
			{	collider->setGravity(core::vector3df(0, -9.81f, 0));
				jump = false;
			}
However, If I press the spacebar, the camera starts floating, it seems it 'falls' floating to the lowest area of the level but no way it's going to jump :?
When I just change all that to: collider->setGravity(core::vector3df(0, 0.1f,0)); it really begins to fly so what's wrong?
Visit my website @ www.venex.be
Plethora project will be added to the site
AMD AthlonXP 2600+, 512MB DDR, Radeon M10 (mobile 9600) PRO 64MB, WinXP
VeneX
Posts: 228
Joined: Sun Nov 30, 2003 3:32 pm
Location: The Netherlands
Contact:

Post by VeneX »

no one is using like this, or having an idea how it should work?
Visit my website @ www.venex.be
Plethora project will be added to the site
AMD AthlonXP 2600+, 512MB DDR, Radeon M10 (mobile 9600) PRO 64MB, WinXP
Post Reply