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)

Черный крыс 11.03.2011 22:01

Ответ: Вопрос-Ответ (для новичков BlitzMax)
 
1) Типы внутри типов использовать МОЖНО., естественно, обьявить новый тип в теле другого типа никто вам не даст. А вот такая запись вполне допустима :

Код:

Type TCar
    Field _pos:Float
    Method Update()
        Type TTire
            field _x:Float
            Method Update()
                ...
            EndMethod
        EndType
    EndMethod
EndType

Тип TTire - временный, или по другому статичный.

2) Насчет статичных функций. Всегда считал, что с приходом методов они стали атавизмом. Ну нету таким функциям рационального использования и все тут! Единственное что они привносят - так это путаницу, и нечитабельность кода. Более того они не являются частью ООП. Многие новички любят делать такими функциями конструкторы и деструкторы, но вот только с точки зрения ООП - это все равно, что загнать себя в угол и кричать потом от безисходности и нечитабельности кода. Да и еще, статичные функци начинают "по настоящему" мешать, если речь идет о развитии и поддержке кода, так как они убивают само понятие "наследования" читай ООП.

3) Отсюда вывод -> Никаких функций в типах. Конструкторы и деструкторы можно легко сделать на методах.

Код:

Type TVector
    Field x:Float
    Field y:Float
 
    Method New() ' Дефолтный конструктор
        x=0 ; y=0
    EndMethod
 
    Method Create:TVector(x:Float = 0.0, y:Float = 0.0) ' Расширенный конструктор
        Self.x=x ; Self.y=y
        Return Self
    EndMethod
 
    Method Delete() ' Деструктор для GC
        Free()
    EndMethod
 
    Method Free() ' Принудительный деструктор
        x=Null ; y=Null
    EndMethod
EndType

Юзаем так :

Код:


Local v0:TVector = New TVector ' x=0 ; y=0
Local v1:TVector = New TVector.Create(10.0,15.0) ' x=10.0 ; y=15.0
 
v0 = Null ' Delete()
v1.Free()
v1 = Null

4) Как всем известно если вы в потомке обьявляете одноименный метод предка, то метод потомка заместит метод предка, а метод предка станет доступным через кейворд 'Super'. - В той же мере это относится и к полям, они тоже перекрываются и поля предка доступны через это же слово. Пример :

Код:

Type TParent
Field _value:String = "Parent field!"
EndType
 
Type TChild Extends TParent
Field _value:Int = 100
 
Method Test()
DebugLog(Super._value)
DebugLog(String(_value))
EndMethod
EndType

Догадайтесь с трех раз, что выведется на консоль?!

ЗЫ : Хотя, некоторые БМаксеры считают это небезопасным маневром в плане уборки мусора.

ПРАВКА : Насчет полей я был не прав. Их можно только переопределить.

JeanWinters 12.03.2011 09:05

Ответ: Вопрос-Ответ (для новичков BlitzMax)
 
А какой может быть практический смысл использования "типа в типе"? Или это просто разработчики языка не доглядели и теперь можно делать такой странный "хак"?..

SBJoker 12.03.2011 11:35

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

Черный крыс 12.03.2011 12:16

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

Вообще все типы, методы, функции, поля, переменные, константы - образуют собой дерево, которое заносится как я понимаю в стек (а может и по другому). И если допустим мы вызываем метод, тогда чем ближе какой-либо обьект лижет в ветке данного метода, тем быстрее произойдет поиск / вызов / операция.

Код:

Global value:Int = 100
 
Function Test()
    Local value:Int = 50
    DebugLog value
EndFunction
 
Function Test2()
    DebugLog value
EndFunction
 
Function Test3(value:Int)
    DebugLog value
EndFunction

Функция, метод или тип представляет собой что то вроде ветки. Быстрее всех выполнится функция Test3 самой медленной будет Test2.
В одно время Oxid высказывал свое мнение по этому поводу : если в функции обьявить локальную переменную и назвать ее коротким именем, то есть шанс что переменная занесется в регистр процессора для мнгновенного доступа.

Для глобальной функции приоритет приблизительно таков : аргументы->локальные переменные->глобальные переменные.

Для метода : аргументы->поля->локальные переменные->глобальные переменные внутри типа->глобальные переменные.

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

А если рассматривать целиком весь БМакс, то он весь состоит из чунков (порций кода), - отсюда его модульность.
По идее глобальную функцию (и не только ее) можно вызвать класически : DrawImage(image,x,y,0)
А можно явно указать с какого чунка вызвать функцию : brl.max2d.DrawImage(image,x,y), в той же степени это относится ко всему остальному.
Хотя на самом деле компилятор на стадии формирования кода все вызовы приводит ко второму виду.

Для пытливых - можно пойти еще дальше : brl.max2d.TImage(image).Frame(0).Draw(...) - но это уже черезчур =)

Nerd 01.05.2011 21:41

Ответ: Вопрос-Ответ (для новичков BlitzMax)
 
Запускаю блицмакс, а он выдает ошибку "Unable to determine BlitzMax version. Please, reinstall BlitzMax to repair this problem". Это че за хрень?

baton4ik 01.05.2011 23:39

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

Nerd 02.05.2011 00:01

Ответ: Вопрос-Ответ (для новичков BlitzMax)
 
Спасибо, кэп. Переустановил, то же самое.

FireOwl 03.05.2011 15:21

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

Nerd 03.05.2011 20:43

Ответ: Вопрос-Ответ (для новичков BlitzMax)
 
К сожалению, да. Поставил Blide, заработало.

Nerd 18.06.2011 15:37

Ответ: Вопрос-Ответ (для новичков BlitzMax)
 
Есть List, в нём несколько int. Проходим по нему For..Each'ем - MAV - пишет, что индекс цикла (который, естественно, тоже int) должен быть объектом. Разве Int это не тип?
Цитата:

Error: " EachIn index variable must be an object"

Randomize 19.06.2011 21:36

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

Сообщение от Nerd96 (Сообщение 192106)
Есть List, в нём несколько int. Проходим по нему For..Each'ем - MAV - пишет, что индекс цикла (который, естественно, тоже int) должен быть объектом. Разве Int это не тип?

Int, Float, Double, Byte в лист не засунуть.
А вот String пожалуйста. Можешь делать так:
Код:

Local str:String
str[0] = 100500 'твоё число
List.AddLast(str)

Потом извлекать:
Local number:Int = Int(List.ValueAtIndex(0)[0])


NitE 09.07.2011 02:35

Ответ: Вопрос-Ответ (для новичков BlitzMax)
 
У меня есть тип и несколько экземпляров. Мне известно значение поля одного из экземпляров. Как мне получить этот экземпляр?

baton4ik 09.07.2011 03:31

Ответ: Вопрос-Ответ (для новичков BlitzMax)
 
Заноси экземпляры в список, а потом пробегись по нему, проверяя значение поля.

NitE 09.07.2011 04:51

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

Как такое сделать без перебора ? Вообще возможно-ли ?

АПД: То что мне известно значение поля значит - что оно у меня уже в переменной.

moka 09.07.2011 17:54

Ответ: Вопрос-Ответ (для новичков BlitzMax)
 
Хз если есть что-то подобное хаш таблицам. Но если в полях есть уникальные данные, то можно сделать хаш таблицу, и использовать значение как индекс. Но это не подойдёт во многих случаях..

pavyf 11.08.2011 16:21

Ответ: Вопрос-Ответ (для новичков BlitzMax)
 
Как в BLide приделать иконку к exe'шнику?

baton4ik 11.08.2011 16:41

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

Сообщение от pavyf (Сообщение 198742)
Как в BLide приделать иконку к exe'шнику?

Blide тут ни при чём.
Создаёшь файл ресурсов с иконкой (for example "projecticon.o")
И пишешь в начале кода:
Код:

?Win32
Import "projecticon.o"
?

Как создавать файл ресурсов - гугли.


UPD: лол, не глянул на твой ник. Я иконку уже приделал, зайди в скайп, всё обсудим.

Rzone 24.08.2011 13:32

Ответ: Вопрос-Ответ (для новичков BlitzMax)
 
Можно ли сделать функцию чтоб возвращала тип по параметру поля, но без перебора?

Reks888 24.08.2011 13:59

Ответ: Вопрос-Ответ (для новичков BlitzMax)
 
Разве что ты как-то их категоризируешь.
Тогда перебора меньше будет.
Ничего стандартного без перебора нет(Хотя про TList не уверен, можно в его сорцах посмотреть)

Greymem 08.11.2011 13:43

Ответ: Вопрос-Ответ (для новичков BlitzMax)
 
Здравствуйте. Когда то очень давно попадался пример кода
Обыскивающий файлы в папках и подпапки в папках. Потерялся :(

Как получить список имен файлов в определенной папке?

ВОПРОС СНЯТ. Нашёл информацию тут: http://en.wikibooks.org/wiki/BlitzMa...em/File_system

P.S. Прошу оставить данное сообщение для возможности поиска

Greymem 09.11.2011 13:42

Ответ: Вопрос-Ответ (для новичков BlitzMax)
 
Не могу понять как обработать ошибку с помощью

try
throw
Catch
Except

У меня где-то в коде в фоновом потоке выполняется неведомая хрень.
___Добавлено: Причем если выполнять код в однопоточном режиме то всё нормально.
Программа тут-же вылетает с "EXCEPTION ACCESS VIOLATION"
"Зрительный" поиск ошибок в коде не помог. =)

Хотелось бы разделить код на участки с "попыткой" и писать в лог каждый НЕЗАВЕРШЕННЫЙ из-за ошибок участок, но при этом чтобы программа продолжала работать.

Randomize 09.11.2011 14:16

Ответ: Вопрос-Ответ (для новичков BlitzMax)
 
http://ruseller.com/lessons.php?rub=37&id=1277
http://ruseller.com/lessons.php?rub=37&id=1279
Не BlitzMax, но смысл try...catch секций мне удалось понять только из этой статьи.

Greymem 09.11.2011 14:29

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

Сообщение от Randomize (Сообщение 209009)
http://ruseller.com/lessons.php?rub=37&id=1277
http://ruseller.com/lessons.php?rub=37&id=1279
Не BlitzMax, но смысл try...catch секций мне удалось понять только из этой статьи.

А есть примеры нормального кода с использованием "попытки" в BlitzMax ?
Например отрисовка NULL объекта?

moka 09.11.2011 14:37

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

Сообщение от Greymem (Сообщение 209010)
А есть примеры нормального кода с использованием "попытки" в BlitzMax ?
Например отрисовка NULL объекта?

Если обращение происходит в отдельную библиотеку, то скорее всего он не будет сама обрабатывать ошибку, и также не будет выбрасывать throw, но учитывая сложность устройства многих библиотек, тебе словить ошибку также не удастся (не факт).

Greymem 09.11.2011 14:39

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

Сообщение от MoKa (Сообщение 209012)
Если обращение происходит в отдельную библиотеку, то скорее всего он не будет сама обрабатывать ошибку, и также не будет выбрасывать throw, но учитывая сложность устройства многих библиотек, тебе словить ошибку также не удастся (не факт).

Не используя отдельную библиотеку. Всё стандартно, mad2d и лоадеры изображений.
Можно пример в студию?

moka 09.11.2011 14:45

Ответ: Вопрос-Ответ (для новичков BlitzMax)
 
http://en.wikibooks.org/wiki/BlitzMa...age/Exceptions

Greymem 09.11.2011 14:48

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

Сообщение от MoKa (Сообщение 209014)

Это я тоже читал

Вот такая байда например работать не хочет при билде релиза.
В однопоточном Debug Mod работает. В многопоточном не работает.

Local Image:TImage;
Try
DrawImage(Image, 0, 0, 0) ;
Catch ex:Object
Print ex.ToString()
End Try

Greymem 10.11.2011 12:08

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

SBJoker 10.11.2011 13:27

Ответ: Вопрос-Ответ (для новичков BlitzMax)
 
ну что тут можно посоветовать.. тебе точно многопоточное необходимо?
*Для справки, ты же вкурсе что разруливать потоки нужно самому да? Простое включение многопоточности не сделает приложение таковым.

Greymem 10.11.2011 14:21

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

Сообщение от SBJoker (Сообщение 209144)
ну что тут можно посоветовать.. тебе точно многопоточное необходимо?
*Для справки, ты же вкурсе что разруливать потоки нужно самому да? Простое включение многопоточности не сделает приложение таковым.

Да я в курсе.
У меня есть основной игровой цикл
И задача в фоне которая создает объект для обработки в главном цикле.

Долго объяснять.

Вот всё бы нормально... до тех пор пока главный цикл не обратиться к "недосозданному" в фоне объекту. Или когда главный цикл попытается удалить этот объект

Я даже при создании и удалении блокирую один и тот-же мутекс. Всё равно где-то ошибка.

Теперь мне как обработать попытку в главном цикле и как обработать попытку в фоне?

Ибо ошибка EXCEPTION_ACCESS_VIOLATION

Greymem 10.11.2011 14:52

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

При длительной симуляции обязательно произойдёт ошибко.

Как обработать это всё попыткой? Так как главный цикл не знает какое действие выполняется прямо сейчас в фоне и наоборот.

Типа получилось удалить - ок, не получилось то просто PRINT чегонибудь Но чтобы прога не останавливалась.

Надеюсь я понятно выражаюсь, и вы сможете мне помочь. Спасибо заранее.

Код:

Type TCustomType
        Field X:Int;
        Field Y:Int;
        Field Text:String;
       
        Function Add(X:Int, I:Int, Text:String, Source:String = " ")
        Local NewData:TCustomType = New TCustomType;
                NewData.X = X;
                NewData.Y = Y;
                NewData.Text = Text;
                ObjList.AddLast(NewData) ;
                Print(String(MilliSecs()) + Source + X + " " + Y + Text) ;
        End Function
       
        Method Destroy()
                ObjList.Remove(Self) ;
                X = Null;
                Y = Null;
                Text = Null;
                GCCollect;
        End Method
End Type

Function AddOrDestroy:Object(Obj:Object = Null)
Local LObj:TCustomType;

SeedRnd(MilliSecs() / Rand(1, 20)) ;
TCustomType.Add(Rand(1, 200), Rand(1, 200), "t " + String(Rand(1, 200)), " Thread ") ;
Delay(Rand(5, 10)) ;

For LObj = EachIn ObjList
        LObj.Destroy() ;
Next
SeedRnd(MilliSecs() / Rand(1, 15)) ;

'Delay(Rand(5, 10)) ;
End Function

Global ObjList:TList = New TList;
Global ObjGenerator:TThread = New TThread;

SeedRnd(MilliSecs()) ;

While Not KeyDown(KEY_ESCAPE)
Local LObj:TCustomType;
Local I:Int;
       
        If Not ObjGenerator.Running() Then ObjGenerator = CreateThread(AddOrDestroy, Null)
       
        For I = 1 To Rand(1, 15)
                SeedRnd(MilliSecs() / Rand(1, 20)) ;
                TCustomType.Add(Rand(1, 200), Rand(1, 200), "t " + String(Rand(1, 200))) ;
        Next
       
        For LObj = EachIn ObjList
                LObj.Destroy() ;
        Next
       
        For LObj = EachIn ObjList
                Print(LObj.X);
        Next

Wend


Добавлено:
В этом примере при операциях с листом если вставить LockMutex,UnlockMutex
Всё работает без ошибок. В моём коде - нет. =( Пока не разобрался почему.

Но обработчик попытки мне всё равно нужен

Randomize 10.11.2011 16:22

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


Код:

Function Add(X:Int, I:Int, Text:String, Source:String = " ")
        Local NewData:TCustomType = New TCustomType;
                NewData.X = X;
                NewData.Y = Y;

Параметр I в конструкторе ошибочен - внутри конструктора Y остаётся вновь созданной нетронутой переменной с нулём.

Код:

While Not KeyDown(KEY_ESCAPE)
Local LObj:TCustomType;
Local I:Int;

Опрашивать клавиатуру нечем. Окна то нет.

Код:

        Method Destroy()
                ObjList.Remove(Self) ;
                X = Null;
                Y = Null;
                Text = Null;
                GCCollect;
        End Method

Я понимаю стремление всё контролировать, но обнулять переменные не надо. Это сделает Garbage collector сам. Всё кроме ObjList.Remove(Self) и GCCollect можно убрать из деструктора.


Написал семпл:
Код:

SuperStrict
Framework brl.basic
Import brl.glmax2d
Import brl.random
Import brl.threads

Type TTest
        Field x:Float, y:Float, z:Float
EndType

Function MySexyThread:Object(obj:Object)
                Local tst:TTest
                Try
                        tst.x = 7
                        tst.y = 8
                Catch e:Object
                        Print "Gotcha! " + e.ToString()
                EndTry
EndFunction


Global SexyThread:TThread = New TThread

SeedRnd(MilliSecs())


Local endtime:Int = MilliSecs() + (1000 * 60)
While (MilliSecs() < endtime)
        If Not SexyThread.Running() Then SexyThread = CreateThread(MySexyThread, Null)
        Delay(1)
Wend

Работает как положено. На протяжении минуты плюёт экскепты.
Твой код с указанными выше правками тоже работает.

Код:

SuperStrict
Framework brl.basic
Import brl.glmax2d
Import brl.random
Import brl.threads

Local img:TImage

Try
        DrawImage(img, 10, 10)
Catch e:Object
        Print "Wft? " + e.ToString()
End Try

Тоже вполне работает.

Greymem 11.11.2011 09:20

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

Function Add(X:Int, I:Int, Text:String, Source:String = " ")
должен быть Y вместо I

Код:

While Not KeyDown(KEY_ESCAPE)
Хотел графику сделать, но потом передумал.

Ошибка вызванная операциями в основном и фоновом потоке никак не связана с моими маленькими погрешностями.


Попытка, Исключения указанные тобой при во втором примере работают только в DebugMod и в однопоточном режиме.

За первый спасибо. Работает =)))
Странно, но у меня тоже самое не пахало =)

Вообщем доразобрался. Всем спасибо

Greymem 11.11.2011 09:38

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

Целесообразно ли использовать в каждом графическом объекте TLink на Image вместо самого TImage если в системе много объектов с одинаковым изображением?

?

Randomize 11.11.2011 20:46

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

Сообщение от Greymem (Сообщение 209232)
Новый вопрос

Целесообразно ли использовать в каждом графическом объекте TLink на Image вместо самого TImage если в системе много объектов с одинаковым изображением?

?

Нет, не целесообразно. Сам TImage является указателем на загруженное изображение/пиксмапу.

JeanWinters 13.11.2011 18:49

Ответ: Вопрос-Ответ (для новичков BlitzMax)
 
Где можно скачать новую версию blitzmax ?

SBJoker 13.11.2011 21:59

Ответ: Вопрос-Ответ (для новичков BlitzMax)
 
Ты это серьёзно?
http://forum.boolean.name/showthread.php?t=15661

Greymem 22.11.2011 07:44

Ответ: Вопрос-Ответ (для новичков BlitzMax)
 
Подскажите пожалуйста, как вызывать из функции другую функцию, если название второй было передано в первой.
К примеру, как это делает функция CreateThread() ?

Исправьте плиз код, чтобы из функции RunObj можно было вызвать любую другую, которая идет в параметре к данной функции.

Код:

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

Function RunObj(ObjName:Object)
?????
End Function


RunObj(ObjTest) ;


baton4ik 22.11.2011 10:56

Ответ: Вопрос-Ответ (для новичков BlitzMax)
 
А ты посмотри как CreateThread() сделан:
Код:

Function Create:TThread( entry:Object( data:Object),data:Object )

Greymem 22.11.2011 12:52

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

Сообщение от baton4ik (Сообщение 210612)
А ты посмотри как CreateThread() сделан:
Код:

Function Create:TThread( entry:Object( data:Object),data:Object )

Спс, Кэп.
Это я уже посмотрел

Теперь как вызвать этот самый entry ?

Greymem 22.11.2011 13:10

Ответ: Вопрос-Ответ (для новичков BlitzMax)
 
Сижу, читаю. Неужели всё придется делать через EVENT'ы и HOOK'и ?

Платон Александрович 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


Greymem 30.11.2011 09:56

Ответ: Вопрос-Ответ (для новичков BlitzMax)
 
Вопрос по геометрии:
http://forum.boolean.name/showthread...751#post211751

Решение найдено
Код:

Function RotateAroundOrigin(X:Float Var, Y:Float Var, ox:Float, oy:Float, a:Int)
        Local DX:Float = X - ox
        Local DY:Float = Y - oy
        Local angdiff:Float = ATan2(DX, DY)
        Local dist:Float = Sqr(DX * DX + DY * DY)
        Local s:Float = Sin(a + angdiff)
        Local c:Float = Cos(a + angdiff)
        Local tx:Float = (dist * s)
        Local ty:Float = (dist * c)
        x = tx + ox
        y = ty + oy
        Return
End Function

Graphics 800, 600

Global oX:Float = 400
Global oY:Float = 300

Global offsetx:Int = 10;
Global Offsety:Int = 20;
Global rX:Float = oX + offsetx
Global rY:Float = oY + Offsety
Global a:Float = 1

While Not KeyHit(KEY_ESCAPE)
        RotateAroundOrigin(rX, rY, ox, oy, a)
        Plot rX, rY
        Plot ox, oy
       
        If KeyHit(KEY_RIGHT)
                ox:+100;
                rX:Float = ox + offsetx
                rY:Float = oy + Offsety
        ElseIf KeyHit(KEY_LEFT)
                ox:-100;
                rX:Float = ox + offsetx
                rY:Float = oy + Offsety
        ElseIf KeyHit(KEY_UP)
                offsetx:+10;
                Offsety:+10;
                rX:Float = ox + offsetx
                rY:Float = oy + Offsety
        ElseIf KeyHit(KEY_DOWN)
                offsetx:-10;
                Offsety:-10;
                rX:Float = ox + offsetx
                rY:Float = oy + Offsety
        EndIf;
       
       
       
        Flip
Wend
End

Источник http://www.blitzbasic.com/Community/...hp?topic=88294
Но немножко переделал под изменение координат опорной точки

SBJoker 30.11.2011 10:58

Ответ: Вопрос-Ответ (для новичков BlitzMax)
 
Это есть в стандартном функционале.

Greymem 30.11.2011 11:00

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

Сообщение от SBJoker (Сообщение 211754)
Это есть в стандартном функционале.

Хммм... и как называется функция?

Dzirt 30.11.2011 14:03

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

Atan2()

Greymem 30.11.2011 14:30

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

Сообщение от Dzirt (Сообщение 211759)
Тему не читай, а сами знаете что....

Atan2()

Ваш речевой оборот убивает клетки моего мозга.
Уточните, что вы хотели этим всем сказать?

SBJoker 30.11.2011 15:04

Ответ: Вопрос-Ответ (для новичков BlitzMax)
 
Я уже вам ответил: http://forum.boolean.name/showpost.p...3&postcount=17

dimanche13 30.11.2011 15:39

Ответ: Вопрос-Ответ (для новичков BlitzMax)
 
Сдается мне, ему не нужны намеки, ему нужен код.

Greymem 30.11.2011 15:42

Ответ: Вопрос-Ответ (для новичков BlitzMax)
 
Нетъ и еще раз нетъ =)
Кое до чего я могу дойти сам
Брать SetImageHandle и задавать xy с минусом?


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

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