forum.boolean.name

forum.boolean.name (http://forum.boolean.name/index.php)
-   Blitz3D (http://forum.boolean.name/forumdisplay.php?f=45)
-   -   Отскок мяча (http://forum.boolean.name/showthread.php?t=17467)

Devilox 02.11.2012 16:40

Отскок мяча
 
День добрый!
Появилась идея реализовывать физические процессы в Blitz-е(т.к. хоть что-то получается на нём писать).
У меня есть мяч, который я запускаю. Как сделать проверку угла, под которым мяч врезается в стену?

H@NON 02.11.2012 17:25

Ответ: Отскок мяча
 
Делай проверку во время столкновения.
Цитата:

colEnt = EntityCollided(Model,coll_world)
If colEnt<>0 Then
For c% = 1 To CountCollisions(model)
nx# = nx + CollisionNX(Model,c)
ny# = ny + CollisionNY(Model,c)
nz# = nz + CollisionNZ(Model,c)
Next
nx = nx / n
ny = ny / n
nz = nz / n
VdotN# = VelX# * Nx + VelY# * Ny + Velz# * Nz
NFx# = -2.0 * Nx * VdotN
NFy# = -2.0 * Ny * VdotN
NFz# = -2.0 * Nz * VdotN
VelX# = VelX# + Nfx
Vely# = Vely# + Nfy
Velz# = Velz# + Nfz
End If
где VelX, velY, velZ - вектор скорости мяча

Devilox 03.11.2012 13:57

Ответ: Отскок мяча
 
Только вот вопрос: а что такое "n"?

H@NON 03.11.2012 14:59

Ответ: Отскок мяча
 
"n" это "с" )) неправильно указал я) "с" - это счетчик, ты в цикле складываешь все углы коллизии, а потом делишь на их количество, тем самым получаешь среднее арифметическое. Это нужно если коллизий будет больше одной.

DarkInside 03.11.2012 20:07

Ответ: Отскок мяча
 
эмм...а не проще брать координаты мяча при броске и координаты мяча при столкновении с объектом, а потом рассчитывать угол по этим координатам?



Вот как-то так..:rolleyes:

Devilox 05.11.2012 00:14

Ответ: Отскок мяча
 
Второй вариант не будет работать, т.к. если вращать стену вокруг точки соприкосновения с треугольником, угол альфа будет неизменен:)
По-моему, чтобы работало, надо стороне B быть перпендикулярной стене...:)

DarkInside 05.11.2012 04:42

Ответ: Отскок мяча
 
Берешь и складываешь полученный угол с углом, на который повёрнута стена относительно глобальных координат...чудеса?:-D
Цитата:

По-моему, чтобы работало, надо стороне B быть перпендикулярной стене
Нет, ты не понял идею...отрезок В перпендикулярен оси X, отрезок А перпендикулярен оси Y... И вообще их нет, это просто проекции осей Х и У для наглядного представления.

На первом рисунке шар ударяет в стену под углом 27 градусов, На рисунке 2 поворачиваем стену на 30 градусов, шар ударяет под углом 57 градусов...мистика;)

А отскакивать будет в первом случае на 63 грудуса, а во втором на (63 - 30*) = 33 градуса относительно проекции на ось У (отрезок В)
* - угол поворота стены


Devilox 05.11.2012 09:16

Ответ: Отскок мяча
 
Аааа, я понял... Это работает тогда, когда мы создаём стену в самом блитзе(у нас есть угол поворота стены), а если у нас целый уровень из стен, то ничего не получится...:) Или я ошибаюсь....
Я вчера весь вечер мозг ломал, как, не зная угла наклона стены и имея лишь одни координаты, расчитать угол...:-D

H@NON 05.11.2012 13:21

Ответ: Отскок мяча
 
берешь шарик и проверяешь его в цикле
For c% = 1 To CountCollisions(sharik)
colEnt = CollisionEntity(model,c)
nx# = CollisionNX(colEnt,c)
ny# = CollisionNY(colEnt,c)
nz# = CollisionNZ(colEnt,c)
Next
Это и будет вектор наклона стены. А из вектора наклона уже через стандартные команды блитца VectorPitch, VectorYaw находишь углы

Devilox 05.11.2012 14:08

Ответ: Отскок мяча
 
Вложений: 1
Какой-то странный отскок получился: вдоль плоскостей...:dontknow:

Devilox 05.11.2012 18:13

Ответ: Отскок мяча
 
Почему отскока в лобовую нет? :dontknow:

DarkInside 05.11.2012 22:36

Ответ: Отскок мяча
 
что-то ты тут намудрил с углами, я не знаток тригонометрии и опыта 3д кодинга у меня нет...

Когда меняешь вот это:
Код:

ex_bul\xspeed = ex_bul\xspeed + nfx
ex_bul\yspeed = ex_bul\yspeed + nfy
ex_bul\zspeed = ex_bul\zspeed + nfz

На вот это:
Код:

                       
ex_bul\zspeed = ex_bul\zspeed -0.1

то отскок вроде нормальный, если стрелять в ту стену, напротив которой появляешься.
Если стреляешь вбок стены, то надо ставить вот это:
Код:

                       
ex_bul\yspeed = ex_bul\yspeed -0.1

То есть nfx#, nfy# и nfz# примерно должны быть около -0.1, а у тебя они имеют какие-то странные значения во время столкновения они меняются от -0.0001 до 0.05.

А вообще возьми PhysX и не мучайся:)

Devilox 05.11.2012 23:09

Ответ: Отскок мяча
 
Да, тут надо каким-то образом определять грань стены, тогда будет известен знак перед 0.1, не могу понять, как работает CollisionNX(NY, NZ) :-D
Я PhysX пробовал, но что-то в нём до конца не разобрался(видимо, я слишком ленивый :-D), вот и решил собственноручно описывать физические явления понятным для себя языком, но вот, из данного примера, видно, что не так уж всё и понятно :-D

Devilox 09.11.2012 16:44

Ответ: Отскок мяча
 
Ура!!! Получилось!!! Код, конечно, плохой, но он работает(движение по координатам и гравитация):
Код:

Global player
Global cam
Global pln
Global gun
Global pivo
Global cube

Global v# = 0.5
Global g# = 0.005

Graphics3D 800,600,32,1
SetBuffer BackBuffer()

Const TYPE_PLANE = 1
Const TYPE_SPHERES = 2

Type T_bullets
        Field ent
        Field old_x#
        Field old_y#
        Field old_z#
        Field xspeed#
        Field yspeed#
        Field zspeed#
        Field m%
End Type

player = CreateSphere()
EntityType player,TYPE_SPHERES

cam = CreateCamera(player)

gun = CreateCylinder()
ScaleEntity gun,0.2,0.5,0.2
EntityColor gun,200,50,50
EntityParent gun,cam
PositionEntity gun,1.2,-0.8,1
TurnEntity gun,90,0,0

pivo = CreatePivot()
EntityParent pivo,gun
PositionEntity pivo,0,1,0

pln = CreatePlane()
PositionEntity pln,0,-2,0
EntityColor pln,50,150,150
EntityType pln,TYPE_PLANE

cube1 = CreateCube()
EntityType cube1,TYPE_PLANE
EntityColor cube1,50,50,200
ScaleEntity cube1,2,2,1
PositionEntity cube1,0,-1,-5

cube2 = CreateCube()
EntityType cube2,TYPE_PLANE
EntityColor cube2,50,50,200
ScaleEntity cube2,2,2,1
PositionEntity cube2,0,-1,5

Collisions TYPE_SPHERES,TYPE_PLANE,2,1

HidePointer()

While Not KeyHit(1)

If MouseHit(1)
        CreateBullet()
EndIf

UpdateBullets()

If KeyDown(17) MoveEntity player,0,0,0.1
If KeyDown(31) MoveEntity player,0,0,-0.1
If KeyDown(30) MoveEntity player,-0.1,0,0
If KeyDown(32) MoveEntity player,0.1,0,0

TurnEntity player, 0, 0 -MouseXSpeed() * 0.1, 0
TurnEntity cam, MouseYSpeed() * 0.1, 0, 0                       
MoveMouse GraphicsWidth() / 2, GraphicsHeight() / 2
RotateEntity cam, EntityPitch#(cam), 0, 0

UpdateWorld()
RenderWorld()

Flip

Wend

End

;---------------------------------------------------;

Function CreateBullet.T_bullets()
        ex_bul.T_bullets = New T_bullets
        ex_bul\ent = CreateSphere(6,pivo)       
        ScaleEntity ex_bul\ent,0.2,0.2,0.2
        EntityParent ex_bul\ent,0
        RotateEntity ex_bul\ent,0,0,0
        EntityType ex_bul\ent,TYPE_SPHERES
        EntityRadius ex_bul\ent,0.2,0.2
       
        ex_bul\old_x = EntityX(ex_bul\ent)
        ex_bul\old_y = EntityY(ex_bul\ent)
        ex_bul\old_z = EntityZ(ex_bul\ent)
       
        ex_bul\xspeed = v * Cos(-EntityPitch#(cam)) * Sin(-EntityYaw#(player))
        ex_bul\yspeed = v * Sin(-EntityPitch#(cam))
        ex_bul\zspeed = v * Cos(-EntityPitch#(cam)) * Cos(EntityYaw#(player))
       
        ex_bul\m = 1
       
        Return ex_bul
End Function

Function UpdateBullets()
        Local ex_bul.T_bullets
       
        For ex_bul = Each T_bullets
       
        If ex_bul\m = 1               
                MoveEntity ex_bul\ent,ex_bul\xspeed,ex_bul\yspeed,ex_bul\zspeed
                ex_bul\yspeed = ex_bul\yspeed - g
        EndIf
                               
                If EntityCollided(ex_bul\ent,TYPE_PLANE)
                       
                        ex_bul\m = 0
                       
                        For c% = 1 To CountCollisions(ex_bul\ent)
                                nx# = CollisionNX(ex_bul\ent,c)
                                ny# = CollisionNY(ex_bul\ent,c)
                                nz# = CollisionNZ(ex_bul\ent,c)
                       
                                If nz <> 0
                                        If ex_bul\zspeed > 0
                                                ex_bul\zspeed = ex_bul\zspeed * nz
                                        Else
                                                ex_bul\zspeed = ex_bul\zspeed * (-nz)
                                        EndIf
                                EndIf
                               
                                If nx <> 0
                                        If ex_bul\xspeed > 0
                                                ex_bul\xspeed = ex_bul\xspeed * nx
                                        Else
                                                ex_bul\xspeed = ex_bul\xspeed * (-nx)
                                        EndIf
                                EndIf
                               
                                If ny <> 0
                                        If ex_bul\yspeed > 0
                                                ex_bul\yspeed = ex_bul\yspeed * ny
                                        Else
                                                ex_bul\yspeed = ex_bul\yspeed * (-ny)
                                        EndIf
                                EndIf

                                ex_bul\m  = 1
                        Next
                               
                EndIf
        Next
End Function



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

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