forum.boolean.name

forum.boolean.name (http://forum.boolean.name/index.php)
-   BlitzMax (http://forum.boolean.name/forumdisplay.php?f=104)
-   -   Вопрос-Ответ (для новичков BlitzMax) (http://forum.boolean.name/showthread.php?t=13756)

Платон Александрович 22.11.2011 13:50

Ответ: Вопрос-Ответ (для новичков BlitzMax)
 
Цитата:

Сообщение от Greymem (Сообщение 210620)
Сижу, читаю. Неужели всё придется делать через EVENT'ы и HOOK'и ?

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

Function ObjTest:Object()
        Print("Hello")
End Function

Function RunObj( Func:Object() )
    Func()
End Function

RunObj(ObjTest)


Greymem 22.11.2011 14:31

Ответ: Вопрос-Ответ (для новичков BlitzMax)
 
Благодарю

Кстати, моё незнание того, что объект можно передать как функцию, и так-же её и вызвать. Вовсе не даёт тебе право мне грубить.

Платон Александрович 22.11.2011 16:30

Ответ: Вопрос-Ответ (для новичков BlitzMax)
 

Цитата:

Сообщение от Greymem (Сообщение 210627)
Благодарю
Кстати, моё незнание того, что объект можно передать как функцию, и так-же её и вызвать. Вовсе не даёт тебе право мне грубить.

Что-что? Грубить? :-D Ты мне напомнил мою тещу, которая в каждом слове в ее адрес видит хамство, забавно так.
ЗЫ
И не объект передать как функцию, а указатель на функцию.

Greymem 23.11.2011 08:15

Ответ: Вопрос-Ответ (для новичков BlitzMax)
 

Цитата:

Сообщение от Платон Александрович (Сообщение 210665)
Что-что? Грубить? :-D Ты мне напомнил мою тещу, которая в каждом слове в ее адрес видит хамство, забавно так.
ЗЫ
И не объект передать как функцию, а указатель на функцию.


Не хотел? Ну вот и здорово. :)
Тёща наверное тоже видит (читает) только тогда когда достают постоянными указанием на кажется (указывающему) элементарные вещи, которые человек просто на просто ещё не практиковал.

Кстати "Тебе ж сказали как" фраза не годится, ибо мне не говорили как вызвать функцию, из функции в которую передан указатель

Так что быстренько помечаем всё оффтопом, дабы публике глаза не мазолить.


А за способ спасибо. Всё заработало.

Greymem 25.11.2011 16:23

Ответ: Вопрос-Ответ (для новичков BlitzMax)
 
Очередной трабл.

Пишу мини-ИИ для "баллистического бота" если можно так сказать
Суть в том, что он должен выстрелить снарядом в объект, но в точку в которой объекта ещё нет.

То есть должен просчитать траекторию движения цели, и выстрелить туда, где объект будет через t итераций (обновления объектов)

Вот что известно на входе:
Начальные координаты цели (X1,Y1)
Скорость цели (V1)
Направление движения цели (угол) (a1)

Начальные координаты бота (X2,Y2)
Скорость снаряда бота (V2)


Вот что нужно найти
Угол выстрела (a2)
Через сколько t они встретятся (t)

За одну итерацию координаты цели обновляются следующим образом
X1 = X1+(V1*Cos(a1))
Y1 = Y1+(V1*Sin(a1))
Выпущенный снаряд выходит из точки X2,Y2, и за одну итерацию обновляет свои координаты похожим образом используя скорость V2 и угол направления движения который мы должны найти a2


Снаряд летит только туда, куда его направили, никакие больше силы на снаряд не действует. А Бот стоит на месте.

Вариант решать перебором (начиная от 1 итерации и просчитывать столкнулись или нет - не подходит, так как сейчас именно так и делается и это не дело =))))

В принципе меня устроит только число t в данном случае. Буду знать t, буду знать угол.

В данный момент уже читаю и книгу по физике для комп. игр и краткий курс тригонометрии.
Но пожалуйста, помогите если кто знает.

Платон Александрович 25.11.2011 18:55

Ответ: Вопрос-Ответ (для новичков BlitzMax)
 
Цитата:

Сообщение от Greymem (Сообщение 211207)
Снаряд летит только туда, куда его направили, никакие больше силы на снаряд не действует. А Бот стоит на месте.

Это довольно просто
дистанция = | координаты_цели - координаты_бота |
время_полета_снаряда_по_прямой = дистанция / скорость_снаряда
упрежденные_координаты_цели = координаты_цели + скорость_цели * время_полета_снаряда_по_прямой

а если нужен именно угол, используй ATan2 с разностью упрежденных_координат_цели и координат_бота

Greymem 27.11.2011 10:46

Ответ: Вопрос-Ответ (для новичков BlitzMax)
 
Цитата:

Сообщение от Платон Александрович (Сообщение 211236)
Это довольно просто
дистанция = | координаты_цели - координаты_бота |
время_полета_снаряда_по_прямой = дистанция / скорость_снаряда
упрежденные_координаты_цели = координаты_цели + скорость_цели * время_полета_снаряда_по_прямой

а если нужен именно угол, используй ATan2 с разностью упрежденных_координат_цели и координат_бота

Спс, данные операции я итак сейчас проделываю, только если скорость цели=0. Тогда можно смело запускать снаряд туда, где цель сейчас и стоит. Там уже нам t ненужно, ибо все равно они столкнуться когданибудь.

Но если цель подвижна (с постоянной скоростью и углом направления) данный алгоритм уже не годится. Ибо сначала надо расчитать куда стрелять чтобы они столкнулись

Цитата:

Сообщение от Платон Александрович (Сообщение 211236)
упрежденные_координаты_цели = координаты_цели + скорость_цели * время_полета_снаряда_по_прямой

Опять таки время полёта в данном случае это время полета снаряда до той координаты где БЫЛА цель. А цель то перемещается. =(

Платон Александрович 27.11.2011 13:41

Ответ: Вопрос-Ответ (для новичков BlitzMax)
 
Greymem
вот такой итеративный алгоритм вроде работает:

1) расчетная_позиция = позиция_цели
2) дистанция = |расчетная_позиция - позиция_бота|
3) время_полета = дистанция / скорость_снаряда
4) упрежденная_позиция = позиция_цели + скорость_цели * время_полета

пункты 2,3,4 повторить несколько раз

некогда все грамотно расписывать, поэтому глянь эту говнодемку:)
при 5 итерациях ~60% попаданий, но это из-за того что цель отскакивает от стен, т.е. меняет направление когда выстрел уже произошел.

Код:

SuperStrict

Framework BRL.Blitz
Import BRL.Math
Import BRL.LinkedList
Import BRL.KeyCodes
Import BRL.GLMax2D

Type TBullet
       
        Field Link:TLink
       
        Field Force:Int
       
        Field PositionX:Float
        Field PositionY:Float
       
        Field DirectionX:Float
        Field DirectionY:Float
       
End Type

Const BulletSpeed:Float = 5

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 = 3

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 = Sqr(DeltaX * DeltaX + DeltaY * DeltaY)
                       
                        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.PositionX = BotPositionX
                Bullet.PositionY = BotPositionY
               
                Bullet.Force = 100
               
        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
               
                ' проверка на попадание в цель
               
                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


Greymem 28.11.2011 07:33

Ответ: Вопрос-Ответ (для новичков BlitzMax)
 
Найс, очень полезно и прикольно.

Не понятно только зачем нужен цикл. =)
Код:

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


Платон Александрович 28.11.2011 09:50

Ответ: Вопрос-Ответ (для новичков BlitzMax)
 
Цитата:

Сообщение от Greymem (Сообщение 211461)
Не понятно только зачем нужен цикл. =)

facepalm
ты хоть читаешь что я пишу или сразу код копипастишь?
Цитата:

вот такой итеративный алгоритм вроде работает:
Цитата:

пункты 2,3,4 повторить несколько раз
Каждый цикл увеличивает точность, поэтому нужно несколько раз повторить расчет. Может конечно есть нормальный алгоритм упреждения, но этот работает и пофиг :)

Цитата:

Сообщение от Greymem (Сообщение 211461)
Как сделать теже самые расчеты используя только одну переменную направления?

Это как? Для двумерного случая вектор направления и должен иметь две компоненты. А если тебе нужна инфа о направлении в одной переменной, то это есть ни что иное как угол :) А из угла вектор направления извлекается с помощью синуса и косинуса, вот так: X = Sin(Угол), Y = Cos(Угол) (или наоброт, зависит от осей координат)
Иначе говоря в коде расчета, перед циклом, был такой расчет скорости цели:
Код:

Local TargetVelocityX:Float = TargetDirectionX * TargetSpeed
Local TargetVelocityY:Float = TargetDirectionY * TargetSpeed

а будет такой
Код:

Local TargetVelocityX:Float = Sin(TargetAngle) * TargetSpeed
Local TargetVelocityY:Float = Cos(TargetAngle) * TargetSpeed

где TargetAngle угол направления движения цели

Цитата:

Сообщение от Greymem (Сообщение 211461)
Осталось заранее узнать координату в которой они столкнуться.
Можете помочь?

После цикла расчета переменные DeflexionX и DeflexionY как раз и будут содержать координаты цели где она столкнется с пулей.

Greymem 28.11.2011 10:11

Ответ: Вопрос-Ответ (для новичков BlitzMax)
 
А какая гарантия того, что на 5-ом шаге цикла расчеты будут точнее чем на 3-ем?

Код уже готов, вверху.
Можете глянуть, что не так?

Greymem 28.11.2011 10:16

Ответ: Вопрос-Ответ (для новичков BlitzMax)
 
И еще, при

Const TargetSpeed:Float = 3
и скажем
Const BulletSpeed:Float = 4

Снаряд пулю уже не догонит, хотя мы меняли только скорость цели.
Снаряд должен подстраиваться под цель по-идее

Платон Александрович 28.11.2011 10:22

Ответ: Вопрос-Ответ (для новичков BlitzMax)
 
Цитата:

Сообщение от Greymem (Сообщение 211475)
А какая гарантия того, что на 5-ом шаге цикла расчеты будут точнее чем на 3-ем?

Ну проверь точность с разной скоростью цели и пуль.
Вообще чем выше скорость пули относительно скорости цели, тем меньше итераций потребуется.
Цитата:

Сообщение от Greymem (Сообщение 211475)
Можете глянуть, что не так?

Вот здесь неверно
Цитата:

GetRange(BotPositionX, TargetPositionX, BotPositionY, TargetPositionY)
Надо не TargetPosition брать, а Deflexion, т.к. я уже говорил что алгоритм итеративный - следующая итерация берет расчет с предыдущей, а у тебя все итерации считают сначала.

Greymem 28.11.2011 10:39

Ответ: Вопрос-Ответ (для новичков BlitzMax)
 
Цитата:

Сообщение от Платон Александрович (Сообщение 211478)
Надо не TargetPosition брать, а Deflexion, т.к. я уже говорил что алгоритм итеративный - следующая итерация берет расчет с предыдущей, а у тебя все итерации считают сначала.

Готово, так, теперь пули вроде как цель догоняют (разумеется за исключением тех случаев, когда цель вот-вот отскочит или уже отскочила)

Что-то ещё упустили?

Greymem 28.11.2011 12:25

Ответ: Вопрос-Ответ (для новичков BlitzMax)
 
Вот что получилось, на случай, если кому-нибудь понадобится

Код:

SuperStrict

Framework BRL.Blitz
Import brl.Math
Import brl.basic
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 PositionX:Float
        Field PositionY:Float
       
        '= = ОРИГИНАЛЬНЫЙ КОД = =
        'Field DirectionX:Float
        'Field DirectionY:Float
        ' = = = = = = = = = = = =
       
        Field Direction:Float;
       
End Type

Global BulletSpeed:Float = 1

Local Bullets:TList = CreateList()

Local TargetPositionX:Float = 100
Local TargetPositionY:Float = 100

Local TargetDirectionX:Float = Sin(45)
Local TargetDirectionY:Float = Cos(45)

Global 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
        If KeyDown(KEY_UP) Then
                BulletSpeed:+0.1
        ElseIf KeyDown(KEY_DOWN) And BulletSpeed > 0 Then
                BulletSpeed:-0.1
        ElseIf KeyDown(KEY_LEFT) And TargetSpeed > 0 Then
                TargetSpeed:-0.1
        ElseIf KeyDown(KEY_RIGHT)
                TargetSpeed:+0.1
        End If
       
       
        ' движение цели
       
        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 Bullets.Count() = 0 And 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, DeflexionX, BotPositionY, DeflexionY)
                        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
               
        End If
       
        ' обновление пуль
       
        For Local Bullet:TBullet = EachIn Bullets
               
               
                'If Bullet.Force <= 0 Or Bullet.PositionX + 8 > GraphicsWidth() Or Bullet.PositionX + 8 < 0 Or Bullet.PositionY + 8 > GraphicsHeight() Or Bullet.PositionY + 8 < 0
                If Bullet.PositionX + 8 > GraphicsWidth() Or Bullet.PositionX + 8 < 0 Or Bullet.PositionY + 8 > GraphicsHeight() Or Bullet.PositionY + 8 < 0
       
                        Bullet.Link.Remove()
                        Continue
                       
                End If
               
                ' полет
               
                ' = = = = = = = = = = ОРИГИНАЛЬНЫЙ КОД = = = = =  = = = = = = =
                '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(111, 111, 111) ;
        DrawText("[UP] - Increase bullet speed, [DOWN] - Decrease bullet speed", 40, 5) ;
        DrawText("Bullet speed: " + BulletSpeed, 600, 5) ;
        DrawText("[left] - Increase target speed, [right] - Decrease target speed", 40, 20) ;
        DrawText("Target speed: " + TargetSpeed, 600, 20) ;
        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



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

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