Показать сообщение отдельно
Старый 02.09.2012, 18:38   #3
Platon
Знающий
 
Регистрация: 04.08.2006
Адрес: Россия
Сообщений: 297
Написано 39 полезных сообщений
(для 70 пользователей)
Ответ: Приближение/удаление камеры

для вращения используй аккумуляцию углов и последующее ограничение Pitch угла, примерно так ( возможно где-то косяк со знаками, не проверял ):
; расчитываем смещение мыши с учетом чувствительности
Local MouseDeltaX# = MouseXSpeed() * MouseSensitivityX
Local MouseDeltaY# = MouseYSpeed() * MouseSensitivityY

; блокируем мышь в центре экрана
MoveMouse( ScreenCenterX, ScreenCenterY )

; аккумулируем угол вращения тела
PlayerBodyYaw = PlayerBodyYaw - MouseDeltaX

; вращаем тело
RotateEntity( PlayerBody, 0, PlayerBodyYaw, 0 )

; аккумулируем угол наклона камеры
PlayerCameraPitch = PlayerCameraPitch - MouseDeltaY

; ограничиваем его
If PlayerCameraPitch < MinPlayerCameraPitch Then PlayerCameraPitch = MinPlayerCameraPitch
If PlayerCameraPitch > MaxPlayerCameraPitch Then PlayerCameraPitch = MaxPlayerCameraPitch

; вращаем пивот камеры
RotateEntity( PlayerCamera, PlayerCameraPitch, 0, 0 )
для движения, как минимум, определение направления и его нормализация ( чтобы по диагонали скорость не была выше ), примерно так:
; вектор направления ( только оси X и Z, если перс не умеет летать :) )
Local PlayerBodyViewingDirX# = GetMatElement( PlayerBody, 2, 0 )
Local PlayerBodyViewingDirZ# = GetMatElement( PlayerBody, 2, 1 )

; вектор движения
Local PlayerBodyMovingDirX# = 0
Local PlayerBodyMovingDirZ# = 0

; вперед ( вектор движения +  вектор направления )
If KeyDown( 17 ) Then
	PlayerBodyMovingDirX = PlayerBodyMovingDirX + PlayerBodyViewingDirX
	PlayerBodyMovingDirZ = PlayerBodyMovingDirZ + PlayerBodyViewingDirZ
End If

; назад ( вектор движения +  -вектор направления )
If KeyDown( 31 ) Then
	PlayerBodyMovingDirX = PlayerBodyMovingDirX - PlayerBodyViewingDirX
	PlayerBodyMovingDirZ = PlayerBodyMovingDirZ - PlayerBodyViewingDirZ
End If

; вправо ( вектор движения +  перпендикуляр к вектору направления )
If KeyDown( 30 ) Then
	PlayerBodyMovingDirX = PlayerBodyMovingDirX + PlayerBodyViewingDirZ
	PlayerBodyMovingDirZ = PlayerBodyMovingDirZ - PlayerBodyViewingDirX
End If

; влево ( вектор движения + -перпендикуляр к вектору направления )
If KeyDown( 32 ) Then
	PlayerBodyMovingDirX = PlayerBodyMovingDirX - PlayerBodyViewingDirZ
	PlayerBodyMovingDirZ = PlayerBodyMovingDirZ + PlayerBodyViewingDirX
End If

; квадрат длины вектора движения
Local PlayerBodyMovingDirDot# = PlayerBodyMovingDirX * PlayerBodyMovingDirX + PlayerBodyMovingDirZ * PlayerBodyMovingDirZ

; если больше единицы, значит движение дагональное, нормализуем
If PlayerBodyMovingDirDot > 1.0 Then
	
	Local PlayerBodyMovingDirInvLen# = 1.0 / Sqr( PlayerBodyMovingDirDot )
	
	PlayerBodyMovingDirX = PlayerBodyMovingDirX * PlayerBodyMovingDirInvLen
	PlayerBodyMovingDirZ = PlayerBodyMovingDirZ * PlayerBodyMovingDirInvLen
	
End If

; двигаем тело по вектору движения
TranslateEntity( PlayerBody, PlayerBodyMoveDirX, 0, PlayerBodyMoveDirZ )
ну и можно потом аккумуляцию скорости, инерцию, трение, гравитацию, прыжок и т.д. таким же образом, манипулируя векторами.

по ограничению приближения - да просто по смене Z мышки считай квадрат дистанции от камеры до ее пивота, и соответственно двигай\не двигай камеру.

по коду косячки
- SetBuffer BackBuffer() для 3д режима делать не нужно ( конечно если ты не менял буфер ) т.к. по умолчанию стоит BackBuffer.
- UpdateWorld логичнее делать перед RenderWorld
- убери Collisions из цикла, CameraClsColor тоже непонятно что там делает
- control да и вообще любые действия над сценой логичнее делать перед UpdateWorld и RenderWorld
(Offline)
 
Ответить с цитированием
Эти 2 пользователя(ей) сказали Спасибо Platon за это полезное сообщение:
St_AnGer (04.09.2012), tirarex (03.09.2012)