forum.boolean.name

forum.boolean.name (http://forum.boolean.name/index.php)
-   Xors3D (http://forum.boolean.name/forumdisplay.php?f=126)
-   -   Как я делал перемещение физического игрока и все работает (http://forum.boolean.name/showthread.php?t=15449)

pozitiffcat 08.09.2011 10:14

Как я делал перемещение физического игрока и все работает
 
Код:

xEntityAddCapsuleShape(camera,20,5,5) ;//тут примерные значения с ними у вас может и не работать
xEntitySetFriction(camera,0) ;
xEntitySetAngularFactor(camera,0,1.0,0) ;
xEntityDisableSleeping(camera);
while(не выход из цикла)/тут сами понимаете как надо
{
...
//чтобы ходить юзаешь не moveEntity
int spx = xMouseXSpeed();
int spy = xMouseYSpeed();
xMouseMove(xGraphicsWidth()/2, xGraphicsHeight()/2);
xTurnEntity(camera, spy,-spx,0);
xRotateEntity(camera, xEntityPitch(camera), xEntityYaw(camera),0);
xEntitySetLinearVelocity(camera,0,0,0);//перемещение
xEntitySetAngularVelocity(camera,0,0,0);//вращение
float y = xEntityYaw(camera, true);
//нажатие вперед
xEntitySetLinearVelocity(camera,-10*sin(y*3.14/180),0,10*cos(y*3.14/180));
//нажатие вниз
xEntitySetLinearVelocity(camera,10*sin(y*3.14/180),0,-10*cos(y*3.14/180));
//нажатие влево
float velx = xEntityGetLinearVelocityX(camera);//нужно если мы идем вперед или назад
float velz=xEntiyGetLinearVelocityZ(camera);//нужно если мы идем вперед или назад
xEntitySetLinearVelocity(camera,velx+(-10*cos(y*3.14/180)),0,velz+(-10*sin(y*3.14/180)));
//нажатие вправо
float velx = xEntityGetLinearVelocityX(camera);//нужно если мы идем вперед или назад
float velz=xEntiyGetLinearVelocityZ(camera);//нужно если мы идем вперед или назад
xEntitySetLinearVelocity(camera,velx+(10*cos(y*3.14/180)),0,velz+(10*sin(y*3.14/180)));
//гравитация
float velx = xEntityGetLinearVelocityX(camera);//нужно если мы идем вперед или назад
float velz=xEntiyGetLinearVelocityZ(camera);//нужно если мы идем вперед или назад
xEntitySetLinearVelocity(camera,velx,-9,velz);


Colossus 08.09.2011 15:04

Ответ: Как я делал перемещение физического игрока и все работает
 
распиши все в функции для удобства )

moka 08.09.2011 15:41

Ответ: Как я делал перемещение физического игрока и все работает
 
Тупо код не очень информативно. Лучше всего сперва описать в письменном виде, какова логика и что ты реализуешь в коде, затем уже реализовывать.

dsd 08.09.2011 15:58

Ответ: Как я делал перемещение физического игрока и все работает
 
А не проще было из локальных координат камеры тформить вектор перемещения и xEntitySetLinearVelocity(camera,xtformedX(),xTForm edY()-9,xTformedZ()); а?

pozitiffcat 09.09.2011 08:13

Ответ: Как я делал перемещение физического игрока и все работает
 
хз привых по старинке, в каком то движке на Delphi лет 5 назад писал, перемещение вычислял синусом и косинусом
А так код будет понятен для тех кто боле менее шарит в ксорсе, если нет, то этот код ему незачем вообще пусть доростет.
Код:

xEntitySetLinearVelocity(camera,10*sin(y*3.14/180),0,-10*cos(y*3.14/180));
это вычисление "скорости" физического объекта для x и z осей относительно угла поворота y

Medan 23.09.2011 19:36

Ответ: Как я делал перемещение физического игрока и все работает
 
Это не может работать. Как объект будет двигаться, если
Y получит 0 из функции xEntityYaw

pozitiffcat 23.09.2011 19:39

Ответ: Как я делал перемещение физического игрока и все работает
 
косинус нуля единица, что означает движение по оси Z вперед!

H@NON 06.10.2011 15:47

Ответ: Как я делал перемещение физического игрока и все работает
 
многие почему-то не могут сделать нормального перемещения для игрока. Специально для них привожу код.

Код:

Function AddHero(x#,y#,z#,yaw#=0)
    H.HeroT = New HeroT
    H\model = xCreateCube()
    xScaleMesh H\model, 1, 2, 0.5
    H\mass = 50
    H\radius = 1.0
    H\height = 2
    ;создаем физическую оболочку в виде капсулы
    xEntityAddCapsuleShape(H\model, H\mass, H\radius, H\height)
    ;делаем слегка трение модельке
    xEntitySetFriction(H\model,0.5)
    ;запрещаем поворачиваться модельке кроме оси Y
    xEntitySetAngularFactor(H\model, 0, 1.0, 0)
    ;убираем инерцию поворота, чтобы моделька подчинялась только нашему контролю
    xEntitySetDamping(H\model, 0, 1)
   
    xPositionEntity H\model, x, y, z
    xRotateEntity H\model, 0, yaw, 0
    ;Вспомогательный пивот для расчетов. Мне так удобнее
    helpPivot = xCreateCube(H\model)
    xScaleMesh helpPivot, 2, 0.1, 2
End Function

Function ControlHero()
    Local smoothYaw# = 0.5            ;смягчающий коэффициент поворота
    Local moveForce# = 1000            ;усилие для движения
    Local maxJump# = 50                ;максимальная скорость прыжка
    Local maxSpeed# = 20                ;макс скорость перемещения
    Local moveX#, moveZ#, jump#
    Local collCnt, collNum
    Local InGround = False                        ;указывает на земле ли моделька
    Local nx#,ny#,nz#, collEnt, nCount
    Local dYaw#
   
    collCnt = xEntityCountContacts(H\model)
   
    ;Если коллизия произошла
    If collCnt > 0 Then
        For collNum = 0 To collCnt-1
            ;Если коллизия произошла с ногами
            If xEntityGetContactY(H\model, collNum) < xEntityY(H\model,1) - H\height*0.5 Then
                ;моделька на земле
                InGround = True
                ;расчет вектора наклона земли под моделькой
                collEnt = xEntityGetContact(H\model, collNum)
                nx = nx + xEntityGetContactNX#(collEnt, collNum)
                ny = ny + xEntityGetContactNY#(collEnt, collNum)
                nz = nz + xEntityGetContactNZ#(collEnt, collNum)
                nCount = nCount + 1
            EndIf
        Next
        nx = nx / nCount
        ny = ny / nCount
        nz = nz / nCount
    EndIf
   
    ;поворот модельки мышкой
    H\Yaw = H\Yaw-mxs*smoothYaw
    xRotateEntity H\model, 0, H\Yaw, 0
   
    If InGround Then
        ;вырубаем гравитацию. Так меньше глюков
        xEntitySetGravity(H\model, 0, 0, 0)
       
        ;Если двигаемся по диагонали то уменьшить равномерно силы
        If (kdRight - kdLeft)<>0 And (kdUp - kdDown)<>0 Then maxSpeed = maxSpeed * 0.75
       
        ;сила перемещения модельки
        moveX = (kdRight - kdLeft) * (maxSpeed - Abs(xEntityGetLinearVelocityX(H\model, False))) * moveForce
        moveZ = (kdUp - kdDown) * (maxSpeed - Abs(xEntityGetLinearVelocityZ(H\model, False))) * moveForce
       
        ;поворачиваем пивот параллельно земли под моделькой
        xAlignToVector helpPivot, nx, ny, nz, 2
        dYaw = AngleDiff(xEntityYaw(helpPivot,1), xEntityYaw(H\model,1))
        xTurnEntity helpPivot, 0, dYaw, 0
        If Abs(xEntityPitch(helpPivot,1)) > 45 Then
            xRotateEntity helpPivot, 45*Sgn(xEntityPitch(helpPivot,1)), xEntityYaw(helpPivot,1), xEntityRoll(helpPivot,1), True
            xEntitySetGravity(H\model, 0, -20, 0)
        EndIf
        If Abs(xEntityRoll(helpPivot,1)) > 45 Then
            xRotateEntity helpPivot, xEntityPitch(helpPivot,1), xEntityYaw(helpPivot,1), 45*Sgn(xEntityRoll(helpPivot,1))
            xEntitySetGravity(H\model, 0, -20, 0)
        EndIf
       
        xTformVector moveX, 0, moveZ, helpPivot, 0
       
        ;применяем силы перемещения на модельку
        xEntityApplyCentralForce(H\model, xTFormedX(), 0, xTFormedZ(), True)
        ;если хотим прыгать - прыгаем
        If khSpace Then xEntitySetLinearVelocity(H\model, xEntityGetLinearVelocityX(H\model), maxJump, xEntityGetLinearVelocityZ(H\model))
       
        ;торможение модельки если не хотим идти
        If moveX = 0  Then xEntityApplyCentralForce(H\model, -xEntityGetLinearVelocityX(H\model, False)*moveForce, 0, 0, False)
        If moveZ = 0 Then xEntityApplyCentralForce(H\model, 0, 0, -xEntityGetLinearVelocityZ(H\model, False)*moveForce, False)
    Else
        ;снова включаем гравитацию модельке
        xEntitySetGravity(H\model, 0, -100, 0)
       
        ;это чтобы слегка контролировать движение в воздухе для казуальности
        moveX = (kdRight - kdLeft) * (maxSpeed - Abs(xEntityGetLinearVelocityX(H\model, False))) * moveForce * 0.1
        moveZ = (kdUp - kdDown) * (maxSpeed - Abs(xEntityGetLinearVelocityZ(H\model, False))) * moveForce * 0.1
        xEntityApplyCentralForce(H\model, moveX, 0, moveZ, False)
    EndIf
End Function


CRASHER 10.10.2011 02:33

Ответ: Как я делал перемещение физического игрока и все работает
 
Ну чтож ты?) Вроде делишся, а вот тип не дописал, и функции AngleDiff нет. С типом то я справился а как же функция?) Допиши пожалст))

H@NON 10.10.2011 02:41

Ответ: Как я делал перемещение физического игрока и все работает
 
не стоит стопроцентно юзать мой код, он скорее на логику, как вариант реализации.
Функция вот :
Цитата:

Function AngleDiff#(angle1#,angle2#)
Return ((angle2 - angle1) Mod 360 + 540) Mod 360 - 180
End Function

CRASHER 10.10.2011 02:51

Ответ: Как я делал перемещение физического игрока и все работает
 
О,благодарю)) Слушай, я так понимаю ты просто набросал его или откудо то перекинул. Просто странно. Ты ссылаешся на тип HeroT через H. Хотя в функции ControlHero() нет хендла типа. Мне пришлось залить его туда, это верно, или же я чего то не понял?

.Squid 10.10.2011 03:09

Ответ: Как я делал перемещение физического игрока и все работает
 
Цитата:

Сообщение от H@NON (Сообщение 205255)
Function AngleDiff#(angle1#,angle2#)
Return ((angle2 - angle1) Mod 360 + 540) Mod 360 - 180
End Function

WTF?

H@NON 10.10.2011 12:06

Ответ: Как я делал перемещение физического игрока и все работает
 
Цитата:

Сообщение от CRASHER (Сообщение 205256)
О,благодарю)) Слушай, я так понимаю ты просто набросал его или откудо то перекинул. Просто странно. Ты ссылаешся на тип HeroT через H. Хотя в функции ControlHero() нет хендла типа. Мне пришлось залить его туда, это верно, или же я чего то не понял?

Тупо сделал глобальной переменную H.HeroT.

Цитата:

Function AngleDiff#(angle1#,angle2#)
Return ((angle2 - angle1) Mod 360 + 540) Mod 360 - 180
End Function
так нада) чтоб никто не догадалсо )

CRASHER 10.10.2011 14:41

Ответ: Как я делал перемещение физического игрока и все работает
 
H@NON, расскажи пожалуйсто зачем нам xTurnEntity для helpPivot ?

H@NON 10.10.2011 15:27

Ответ: Как я делал перемещение физического игрока и все работает
 
Пивот нужен лишь чтобы положить его параллельно земли под игроком. А поворачиваем его, чтобы пивот смотрел туда же куда и игрок.


Часовой пояс GMT +4, время: 09:39.

vBulletin® Version 3.6.5.
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Перевод: zCarot