Дэвелопер
Регистрация: 17.01.2007
Сообщений: 1,552
Написано 351 полезных сообщений (для 774 пользователей)
|
Ответ: Как я делал перемещение физического игрока и все работает
многие почему-то не могут сделать нормального перемещения для игрока. Специально для них привожу код.
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
|