Найс, очень полезно и прикольно.
Не понятно только зачем нужен цикл. =)
For Local ComputingPass:Int = 1 To 5
Но при его отсутствии пули летят не в центр цели =) и иногда пролетают мимо
Мистика =)
К сожалению в данном примере направление X и Y довольно сильно различаются.
Как сделать те-же самые расчеты используя только одну переменную направления? - Сделано
Как установить угол выстрела на координату я уже знаю
Осталось заранее узнать координату в которой они столкнуться. - Сделано.
Вот переделал на использование одного поля "Direction" для пули
Правда подлагивает, подёргивает (интересно из-за чего?)
Но вроде работает, ХЗ, может ещё что неправильно, посмотрите плиз.

SuperStrict
Framework BRL.Blitz
Import BRL.Math
Import BRL.LinkedList
Import BRL.KeyCodes
Import brl.GLMax2D
Function GetRange:Int(x1:Int, x2:Int, y1:Int, y2:Int)
Return Sqr(((x1 - x2) ^ 2) + ((y1 - y2) ^ 2)) ;
End Function
Function Strike_Angle:Double(x0:Double, y0:Double, x1:Double, y1:Double)
Return ATan2(y1 - y0, x1 - x0) ;
End Function
Type TBullet
Field Link:TLink
Field Force:Int
Field PositionX:Float
Field PositionY:Float
'= = ОРИГИНАЛЬНЫЙ КОД = =
'Field DirectionX:Float
'Field DirectionY:Float
' = = = = = = = = = = = =
Field Direction:Float;
End Type
Const BulletSpeed:Float = 4
Local Bullets:TList = CreateList()
Local TargetPositionX:Float = 100
Local TargetPositionY:Float = 100
Local TargetDirectionX:Float = Sin(45)
Local TargetDirectionY:Float = Cos(45)
Const TargetSpeed:Float = 1
Local BotPositionX:Float = 400
Local BotPositionY:Float = 300
Local TicksCount:Int = 0
Local ShootTick:Int = 0
Local ShotsCount:Int = 0
Local HitsCount:Int = 0
Graphics(800, 600)
Repeat
TicksCount :+ 1
' движение цели
TargetPositionX :+ TargetDirectionX * TargetSpeed
TargetPositionY :+ TargetDirectionY * TargetSpeed
' отскок от стен
If TargetPositionX < 0 Then
TargetPositionX = 0
TargetDirectionX = -TargetDirectionX
End If
If TargetPositionX >= 800 Then
TargetPositionX = 800 - 1
TargetDirectionX = -TargetDirectionX
End If
If TargetPositionY < 0 Then
TargetPositionY = 0
TargetDirectionY = -TargetDirectionY
End If
If TargetPositionY >= 600 Then
TargetPositionY = 600 - 1
TargetDirectionY = -TargetDirectionY
End If
' стрельба
If TicksCount >= ShootTick Then
ShootTick = TicksCount + 10
ShotsCount :+ 1
' расчет упреждения
Local DeflexionX:Float = TargetPositionX
Local DeflexionY:Float = TargetPositionY
Local TargetVelocityX:Float = TargetDirectionX * TargetSpeed
Local TargetVelocityY:Float = TargetDirectionY * TargetSpeed
For Local ComputingPass:Int = 1 To 5
' = = = = = = = = = = ОРИГИНАЛЬНЫЙ КОД = = = = = =
'Local DeltaX:Float = (DeflexionX - BotPositionX)
'Local DeltaY:Float = (DeflexionY - BotPositionY)
' = = = = = = = = = = = = = = = = = = = = = = = =
Local Distance:Float = GetRange(BotPositionX, TargetPositionX, BotPositionY, TargetPositionY)
Local Time:Float = Distance / BulletSpeed
DeflexionX = TargetPositionX + TargetVelocityX * Time
DeflexionY = TargetPositionY + TargetVelocityY * Time
Next
' выстрел
Local Bullet:TBullet = New TBullet
Bullet.Link = Bullets.AddLast(Bullet)
' = = = = = = = = = = ОРИГИНАЛЬНЫЙ КОД = = = = = = = = = = = =
'Local DeltaX:Float = DeflexionX - BotPositionX
'Local DeltaY:Float = DeflexionY - BotPositionY
'Local Distance:Float = Sqr(DeltaX * DeltaX + DeltaY * DeltaY)
'Bullet.DirectionX = DeltaX / Distance
'Bullet.DirectionY = DeltaY / Distance
' = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
Bullet.Direction = Strike_Angle(BotPositionX, BotPositionY, DeflexionX, DeflexionY)
Bullet.PositionX = BotPositionX
Bullet.PositionY = BotPositionY
Bullet.Force = 500
End If
' обновление пуль
For Local Bullet:TBullet = EachIn Bullets
If Bullet.Force <= 0 Then
Bullet.Link.Remove()
Continue
End If
' полет
Bullet.Force :- 1
' = = = = = = = = = = ОРИГИНАЛЬНЫЙ КОД = = = = = = = = = = = =
'Bullet.PositionX :+ Bullet.DirectionX * BulletSpeed
'Bullet.PositionY :+ Bullet.DirectionY * BulletSpeed
' = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
Bullet.PositionX:+BulletSpeed * Cos(Bullet.Direction) ;
Bullet.PositionY:+BulletSpeed * Sin(Bullet.Direction) ;
' проверка на попадание в цель
Local DeltaX:Float = TargetPositionX - Bullet.PositionX
Local DeltaY:Float = TargetPositionY - Bullet.PositionY
Local Distance:Float = Sqr(DeltaX * DeltaX + DeltaY * DeltaY)
If Distance <= 8 Then
HitsCount :+ 1
Bullet.Link.Remove()
End If
Next
' отрисовка
Cls()
SetColor(0, 255, 0)
DrawOval(BotPositionX - 8, BotPositionY - 8, 16, 16)
SetColor(255, 0, 0)
DrawOval(TargetPositionX - 8, TargetPositionY - 8, 16, 16)
SetColor(255, 255, 0)
For Local Bullet:TBullet = EachIn Bullets
DrawOval(Bullet.PositionX - 3, Bullet.PositionY - 3, 6, 6)
Next
SetColor(255, 255, 255)
DrawText(String.FromInt(HitsCount * 100 / ShotsCount) + "%", 10, 10)
Flip()
Until KeyDown(KEY_ESCAPE)
End