Ok. im taring my hair out, and i cant take it anymore [grin]. im going to post my code and hopefully someone is nice enough to scan through it, and can maybe find my mistake. please note: this is the code for when i have a "render velocity" which i re-calculate each frame. i have not been doing this the whole time, its just the last thing that i tried. otherwise, i would just move my render position at my physical velocity x 1.2.
all of this code is used inside the Player class. first, let me say some members of the class.
xPos, yPos - this is my physical position
render_xpos, render_ypos - this is my render position
xVel, yVel - this is my physical velocity
render_xvel, render_yvel - this is my render positions velocity
current_dest_x/y - this is my destination, where i am moving towards, where the player clicked on
Collision_Mediator::Attempt_To_Move() - this received a Player instance, a time, and a velocity. it then tries to move that player at the given velocity * given time. this function can receive either seconds or milliseconds, and if it receives milliseconds, it turns it into seconds.
first, this is the function i call when i get a message from the server saying "ok, your good to move. this is your position, and this is the time". then i call this function sending it that data. basically, this function first sets my render position to my current physical position. then it sets my physical position to what the server says. then it jumps my physical position to make up for lost time.
void Player::Movement_Request_Accepted(Uint32 timestamp,float x,float y){ //DONT FORGET! OUR INTERPOLATED POSITION STARTS HERE, AT OUR CURRENT X/Y! if(!Math::Float_Equal(x,xPos) && !Math::Float_Equal(y,yPos)) { render_xpos = xPos; render_ypos = yPos; interpolating_render_position = true; } //set our new position (before making up for lost time) xPos = x; yPos = y; //// calculate slope xVel = current_dest_x - (xPos);//+(w/2)); yVel = current_dest_y - (yPos);//+(h/2)); //find the distance between the target the and shooter float diff = sqrt(xVel*xVel + yVel*yVel); // normalize and set velocity float invlen = 1.0f/diff;//((float)dy*dy + dx*dx); xVel *= (invlen*200); yVel *= (invlen*200); const Uint32 dt = RakNetGetTime() > timestamp ? RakNetGetTime() - timestamp : 0; //if there was a dt (this should always be true except rarely when there is 0 ping) if(dt > 0) { Collision_Mediator::Attempt_To_Move(this,dt,xVel,yVel); }//end if(dt > 0) render_xvel = xPos - render_xpos; render_yvel = yPos - render_ypos; float diff2 = sqrt(render_xvel*render_xvel + render_yvel*render_yvel); float invlen2 = 1.0f/diff2; render_xvel *= (invlen2*225); render_yvel *= (invlen2*225);}
then, each frame, i have a function called Player::Update() which i call. Player::Update() contains the following code, in this order:
first, i allow the player to click to move, and send the request to the server. here i also start moving at half my speed.
if( (systm->Get_Input().Mouse_Down(3) || systm->Get_Input().Mouse_Still_Down(3) ) && RakNetGetTime() - last_time_moved > MOVEMENT_DELAY && !waiting_for_movement_ack && !interpolating_render_position)// && !movement_todo.pending) { //mouse x/y int mx,my; SDL_GetMouseState(&mx,&my); //if they clicked on their view (e.g. not on the HUD) if(mx >= 0 && mx < VIEWWIDTH && my >=0 && my < VIEWHEIGHT) { if( !( Math::Float_Equal(xPos, mx+scroll_x) && Math::Float_Equal(yPos, my+scroll_y) ) ) { current_dest_x = mx + scroll_x; current_dest_y = my + scroll_y; // calculate slope xVel = current_dest_x - (xPos);//+(w/2)); yVel = current_dest_y - (yPos);//+(h/2)); //find the distance between the target the and shooter float diff = sqrt(xVel*xVel + yVel*yVel); // normalize and set velocity float invlen = 1.0f/diff;//((float)dy*dy + dx*dx); xVel *= (invlen*100); yVel *= (invlen*100); Network_Mediator::Send_Movement_Request(current_dest_x,current_dest_y);//(movement_todo.dest_x,movement_todo.dest_y); waiting_for_movement_ack = true; } last_time_moved = RakNetGetTime(); } }
next, i increment the render position to move closer to the physical position
(IF we are interpolating!). i also check to see if render has caught up to physical..
if(interpolating_render_position) { render_xvel = xPos - render_xpos; render_yvel = yPos - render_ypos; float diff = sqrt(render_xvel*render_xvel + render_yvel*render_yvel); float invlen = 1.0f/diff; render_xvel *= (invlen*225); render_yvel *= (invlen*225); float x_inc,y_inc; x_inc = (render_xvel * timer.Time_Passed); y_inc = (render_yvel * timer.Time_Passed); render_xpos += x_inc; render_ypos += y_inc; //now if our render position has caught up to our physical position float cntr_x = render_xpos;// + (w/2); float cntr_y = render_ypos;// + (h/2); //if( Math::Float_Equal( Point::Length( Point( xPos+(w/2),yPos+(h/2) ) - Point( render_xpos+(w/2),render_ypos+(h/2) ) ), 1.0f ) ) if(Point::Length(Point(xPos,yPos)-Point(render_xpos,render_ypos)) <= 1.0f)/* if(((cntr_x-xPos)*(xVel*1.2f) + (cntr_y-yPos)*(yVel*1.2f) ) >= 0.0f)*/ { //we stop interpolating, and snap our render position to our physical position interpolating_render_position = false; render_xpos = xPos; render_ypos = yPos; message->Add_To_Chat(player->Get_ID(),RakNetGetTime(),"RENDER == POS"); } } else { render_xpos = xPos; render_ypos = yPos; }
next, i do collision detection with the world and movement and last, i render using my render x/y position
Do_Collision_And_Movement();Render()
hopefully someone can spot out what im doing wrong.. thanks for any help!