Napisałem bardzo prosty silnik fizyczny do obsługi ruchu gracza i kolizji w grze typu FPS.
Chciałbym wiedzieć w jaki sposób najlepiej obsługiwać szybkość świata silnika fizycznego.

Próbowałem stworzyć metodę Entity::update(float ticks), która "przeskakiwałaby" odpowiednią wielkość przyśpieszenia (ogólnie zmiany prędkości) oraz liczbę "metrów" o jakie zostałby przeniesiony gracz przy jej wywołaniu, tak, że przy podaniu liczby jej wywołań na sekundę float ticks, ciągle, niezależnie od ich liczby fizyka miałaby stałą prędkość.

physics.h

#ifndef PHYSICS_H
#define PHYSICS_H

#define WIN32_LEAN_AND_MEAN

#include <windows.h>

class Entity
{
public:
    bool collidable;
    bool dynamic;

    double posx, posy, posz;
    float velx, vely, velz;
    float gravity;
    float acceleration;
    float brakes;
    float resistance;
    float maxFallSpeed;

    Entity(void);
    ~Entity(void){}
    void accelerate(float ax, float ay, float az);
    void brake(float bx, float by, float bz);
    void update(float elapsed);
    bool collided(Entity body);
};

class Animal : public Entity
{
public:
    float walkSpeed;
    float runSpeed;

    Animal(bool = true, bool = true);
    ~Animal(void){}
};

#endif

physics.cpp

#include <iostream>
#include "physics.h"

Entity::Entity(void)
{
    posx = 0, posy = 0, posz = 0;
    velx = 0, vely = 0, velz = 0;
    gravity = 9.80665;
    acceleration = 0.2;
    brakes = 2.0;
    resistance = 2.0;
    maxFallSpeed = 90.0;
}

void Entity::accelerate(float ax, float ay, float az)
{
    velx += ax;

    vely += ay;

    velz += az;
}

void Entity::brake(float bx, float by, float bz)
{
    //X AXIS BRAKING
    if(velx > 0 && bx < velx)
        velx -= bx;
    else if(velx < 0 && bx > velx)
        velx += bx;
    else
        velx = 0;
    //Y AXIS BRAKING
    if(vely > 0 && by < vely)
        vely -= by;

    else if(vely < 0 && by > vely)
        vely += by;
    else
        vely = 0;
    //Z AXIS BRAKING
    if(velz > 0 && bz < velz)
        velz -= bz;
    else if(velz < 0 && bz > velz)
        velz += bz;
    else
        velz = 0;
}

void Entity::update(float ticks)
{
    if(dynamic)
    { //Tutaj wiem co jest źle, tylko to zostawiłem, może pomoże mnie zrozumieć (co chcę zrobić)
        //Tutaj prędkość jest dodawana do pozycji przed ukończeniem jej zwiększania i prędkość grawitacji tak samo(prędkość może być zwiększana co sekundę, ale to by nie było płynne, po za tym jeżeli dam to co 1 ms, to fizyka będzie spowolniona, gdy ktoś nie będzie uruchamiał update() co najmniej 1000 razy na sekundę  (potrzebuję czegoś by tego wszystkiego  uniknąć)
        if(vely < maxFallSpeed)
            accelerate(0, -gravity/ticks, 0); //GRAVITY ACCELERATION

        brake(resistance/ticks, resistance/ticks, resistance/ticks); //AIR RESISTANCE (SIMPLE)

        posx += velx/ticks; //APPLYING POSITION
        posy += vely/ticks; //-||-
        posz += velz/ticks; //-||-
    }
}

Animal::Animal(bool d, bool c)
{
    collidable = c;
    dynamic = d;
    walkSpeed = 0.8;
    runSpeed = 2.3;
};

int main()
{
    float TICKS_PER_SECOND = 64;
    DWORD timer = GetTickCount();
    DWORD t = GetTickCount(); //Timer do wyłączania aplikacji
    Animal body(true, true);
                    //body.accelerate(0.0, 0.0, 1);
    while(GetTickCount() < t+6000) //Uruchamiam aplikację tylko na sześć sekund
    {
        if(GetTickCount() > timer + (1000/TICKS_PER_SECOND))
        {
            timer = GetTickCount();
            if(GetAsyncKeyState(VK_SPACE) & 1 && body.velz < body.runSpeed)body.accelerate(0.0, 0.0, 1);
            body.update(TICKS_PER_SECOND);
            std::cout<<body.posx<<", "<<body.posy<<", "<<body.posz<<"\n";
        }
    }
    return 0;
}

W jaki sposób to zaimplementować, żeby działało?

Prosiłbym także o podanie jakiegoś tutorialu na temat wykrywania kolizji ścian (nie mogą być to sześcienne bounding box'y, muszę wykrywać kolizję z terenem, może być nawet w 2d).