forum.boolean.name

forum.boolean.name (http://forum.boolean.name/index.php)
-   3D-программирование (http://forum.boolean.name/forumdisplay.php?f=12)
-   -   Искуственный интеллект (http://forum.boolean.name/showthread.php?t=17810)

burovalex 29.01.2013 08:55

Искуственный интеллект
 
Вложений: 1
Доброго времени уважаемые буленчане!

Хочу реализовать ИИ на движке Блитц3Д+Ксорс+Физикс.
Помогите обойти грабли, на которые вы сами наступали при такой реализации.

Хотелось бы реализовать как на рисунке справа.
Сложно ли это будет сделать?
Стоит ли маршрут просчитывать динамически в реалтайме, либо строить вейпоинты?
Если вейпоинты, то где их удобнее хранить, в самом типе ИИ либо в отдельном массиве?
Для прогнозирования встречи с препятствием что лучше использовать, Pick,Collided(Xors'a), RayCast(PhysX'a)?

DarkInside 29.01.2013 11:49

Ответ: Искуственный интеллект
 
Кури A* - самое простое для новичка
http://ru.wikipedia.org/wiki/%D0%90%...D0%BA%D0%B0_A*

Или если хочешь повозиться с матрицами, то волновой аглогитм
http://ru.wikipedia.org/wiki/%D0%92%...B8%D1%82%D0%BC

burovalex 29.01.2013 12:09

Ответ: Искуственный интеллект
 
Ребят, можно без всякого научного бреда?
Может в математике это эффективно, но если ты начнешь проверять как в вики каждую точку на пересечение с объектом в 3д мире - комп загнётся от таких А-звезд и волновых эффектов.

А вообще такие методы у меня изображены на левом рисунке.
По сути я могу спокойно двигать ncp пока он не упрётся в стену -> если упёрся повернуть в сторону -> пройти прямо -> поворачиваться к цели -> упёрся -> ....
Работать будет Намного быстрее

Raion 29.01.2013 12:23

Ответ: Искуственный интеллект
 
Ну тогда используй точки перемещения. Самый простой и быстрый вариант.Только персонажи будут бегать по одной линии следования. Или тебе нужна готовая библиотека поиска пути.

burovalex 29.01.2013 12:28

Ответ: Искуственный интеллект
 
Да хоть что-нибудь чтоб оттолкнуться..

Как понимать Точки перемещения??

Gector 29.01.2013 12:44

Ответ: Искуственный интеллект
 
Цитата:

Сообщение от burovalex (Сообщение 251036)
Работать будет Намного быстрее

Не будет. Пик будет жрать не так уж и мало ресурсов.
Кстати можно было и поискать по форуму. Астар на блице.

burovalex 29.01.2013 13:01

Ответ: Искуственный интеллект
 
Ну и что, астар.. Ты понимаешь какой в методе принцип складывается. Что для блитца на такой метод надо кучу ентити создать и проверять между ними расстояние, а теперь добавь туда еще и препятствия и получится попа!

H@NON 29.01.2013 13:09

Ответ: Искуственный интеллект
 
тебе для вейпоинта(точки перемещения) нужны лишь координаты, никакие ентити тут не нужны

burovalex 29.01.2013 13:21

Ответ: Искуственный интеллект
 
Вложений: 1
Давайте я попробую пример сделать, на основе (если помните по информатике проходили) типа метод пузырька или чтото вроде того
Хочу попробывать так, как на рисунке в аттаче

Но для этого надо будет добавлять чтото типа графов

Подскажите только плиз как в тип добавлять подтипы?
Т.е. маленький пример, я пойму, просто не хочется гуглить с моим мертвым интернетом..

jimon 29.01.2013 13:29

Ответ: Искуственный интеллект
 
burovalex
в кваке третей поиск пути был через пространственных граф параллелепипедов которые задавали объемы в которых мог свободно гулять персонаж, а связи между объемами - это как персонаж должен перейти (например прыжок или присесть)

отсюда боты из третей кваки работали на любой карте, и это не тормозило в 1999, почему более простой алгоритм (Astar) будет тормозить у тебя в 2013 ?
а то что ты показал в первом посте на левой и правой карте это всего лишь как персонаж идет по найденому пути, достаточно идти по квадратному пути с простой кубической интерполяцией и получишь то что на правой части картинки

ps. алгоритмы поиска пути всегда работают на графах, в том числе и Astar, то что он в статьях для блица ищет по 2д массиву - просто абстракция чтобы упростить понимание

burovalex 29.01.2013 14:25

Ответ: Искуственный интеллект
 
Наверное надо было уточнить, что мой мир динамичный - с растущими деревьями, и меняющимися препядствиями. Вот теперь представь выросший небольшой лесок, надо обойти деревья. Как в кваке со статичной картой такое не проканает, ну точнее надо будет постоянно обновлятьих, да и придется всё таки создавать ентити кучу.
А мне то надо сделать так, чтобы встретил зверушку, она шугнулась, и начала строить себе маршрут отступления.

burovalex 29.01.2013 14:43

Ответ: Искуственный интеллект
 
Вот у меня сейчас терраин 64х64 и это так - средненький островок.
Использую я конечно 30-40% суши, НО я сейчас тестил этот пример Астар
и он выдал время обработки 4 мс - вот теперь прикинь что будет допустим 5 шуганутых зверюшек - и комп повесится

вот исходник со встроенным Астаром

Код:

Graphics3D 1024, 768, 32, 2
SetBuffer BackBuffer()


;        Create navigation grid
Local rows=64
Local cols=64
       
Dim Graph.NAV_Node(rows, cols)

For col=0 To cols-1
        For row=0 To rows-1
                Graph(col, row)=NAV_CreateNode(col*10, 0, row*10)
               
                ;Swap pivot with cube to make node visible
                FreeEntity Graph(col, row)\Pivot
                Graph(col, row)\Pivot=CreateCube()
                PositionEntity Graph(col, row)\Pivot, col*10+Rnd(-2, 2), 0, row*10+Rnd(-2, 2)
        Next
Next

;        Connect nodes
For col=0 To cols-1
        For row=0 To rows-2
                NAV_Connect(Graph(col, row), Graph(col, row+1))
        Next
Next
       
For row=0 To rows-1
        For col=0 To cols-2
                NAV_Connect(Graph(col, row), Graph(col+1, row))
        Next
Next

;        Set camera
Camera=CreateCamera()
PositionEntity Camera, rows*10/2, rows*10, cols*10/2
TurnEntity Camera, 90, 0, 0

;        Pick source and destination nodes

Src.NAV_Node=Graph(0, 0)
Dst.NAV_Node=Graph(rows-1, cols-1)

EntityColor Src\Pivot, 0, 0, 255
EntityColor Dst\Pivot, 255, 0, 0

;        Get search time

time1=MilliSecs()
NAV_FindPath(Src, Dst)
time2=MilliSecs()

P.NAV_Node=Dst\Parent

While P<>Null
        EntityColor P\Pivot, 255, 0, 0
        P=P\Parent
Wend

While Not KeyHit(1)
        UpdateWorld
        RenderWorld
        Text 20, 20, "time: "+(time2-time1)
        Flip
Wend
End

;        NAVIGATION

Type NAV_Node
        Field Pivot
        Field Disabled
        Field Parent.NAV_Node                        ; for path building
        Field F#, G#, H#
       
        Field FirstLink.NAV_Link
        Field LastLink.NAV_Link
End Type

Type NAV_Link
        Field Node.NAV_Node
        Field Distance#
       
        Field PrevLink.NAV_Link
        Field NextLink.NAV_Link
End Type

Type NAV_OpenedNode
        Field Node.NAV_Node
End Type

Type NAV_ClosedNode
        Field Node.NAV_Node
End Type

Type NAV_Path
        Field StartNode.NAV_PathNode
End Type

Type NAV_PathNode
        Field Node.NAV_Node
       
        Field NextNode.NAV_PathNode
End Type

Function NAV_CreateNode.NAV_Node(X#, Y#, Z#)
        Local Node.NAV_Node=New NAV_Node
        Node\Pivot=CreatePivot()
        PositionEntity Node\Pivot, X, Y, Z
        Return Node
End Function

Function NAV_AddLink(NodeA.NAV_Node, NodeB.NAV_Node)
        Local Link.NAV_Link=New NAV_Link
        Link\Distance=EntityDistance(NodeA\Pivot, NodeB\Pivot)
        Link\Node=NodeB
       
        If NodeA\LastLink<>Null
                Link\PrevLink=NodeA\LastLink
                NodeA\LastLink\NextLink=Link
                NodeA\LastLink=Link
        Else
                NodeA\FirstLink=Link
                NodeA\LastLink=Link
        EndIf
End Function

Function NAV_Connect(NodeA.NAV_Node, NodeB.NAV_Node)
        NAV_AddLink(NodeA, NodeB)
        NAV_AddLink(NodeB, NodeA)
End Function

Function NAV_Heuristic#(Node.NAV_Node, DstNode.NAV_Node)
        Local X#=Abs(EntityX(DstNode\Pivot, True)-EntityX(Node\Pivot, True))
        Local Y#=Abs(EntityY(DstNode\Pivot, True)-EntityY(Node\Pivot, True))
        Local Z#=Abs(EntityZ(DstNode\Pivot, True)-EntityZ(Node\Pivot, True))
       
        Return (X+Y+Z)
End Function

Function NAV_AddToOpened(Node.NAV_Node)
        Local Opened.NAV_OpenedNode
        Local L.NAV_OpenedNode
        Local R.NAV_OpenedNode
       
        L=First NAV_OpenedNode
       
        If L<>Null
                If Node\F<=L\Node\F
                        Opened=New NAV_OpenedNode
                        Opened\Node=Node
                        Insert Opened Before L
                        Return
                EndIf
        Else
                Opened=New NAV_OpenedNode
                Opened\Node=Node
                Return
        EndIf
       
        Repeat
                R=After L
                If R=Null Then Exit
               
                If Node\F>=L\Node\F And Node\F<=R\Node\F
                        Opened=New NAV_OpenedNode
                        Opened\Node=Node
                        Insert Opened Before R
                        Return
                EndIf
                L=R
        Forever
       
        Opened=New NAV_OpenedNode
        Opened\Node=Node
       
End Function

Function NAV_AddToClosed(Node.NAV_Node)
        Local Closed.NAV_ClosedNode
        Local L.NAV_ClosedNode
        Local R.NAV_ClosedNode
       
        L=First NAV_ClosedNode
       
        If L<>Null
                If Node\F<=L\Node\F
                        Closed=New NAV_ClosedNode
                        Closed\Node=Node
                        Insert Closed Before L
                        Return
                EndIf
        Else
                Closed=New NAV_ClosedNode
                Closed\Node=Node
                Return
        EndIf
       
        Repeat
                R=After L
                If R=Null Then Exit
               
                If Node\F>=L\Node\F And Node\F<=R\Node\F
                        Closed=New NAV_ClosedNode
                        Closed\Node=Node
                        Insert Closed Before R
                        Return
                EndIf
                L=R
        Forever
       
        Closed=New NAV_ClosedNode
        Closed\Node=Node
End Function

Function NAV_SortNode(Opened.NAV_OpenedNode)

        Local Node.NAV_Node=Opened\Node
        Delete Opened
       
        Local L.NAV_OpenedNode
        Local R.NAV_OpenedNode
       
        L=First NAV_OpenedNode
       
        If L<>Null
                If Node\F<=L\Node\F
                        Opened=New NAV_OpenedNode
                        Opened\Node=Node
                        Insert Opened Before L
                        Return
                EndIf
        Else
                Opened=New NAV_OpenedNode
                Opened\Node=Node
                Return
        EndIf
               
        Repeat
                R=After L
                If R=Null Then Exit
                       
                If Node\F>=L\Node\F And Node\F<=R\Node\F
                        Opened=New NAV_OpenedNode
                        Opened\Node=Node
                        Insert Opened Before R
                        Return
                EndIf
                L=R
        Forever
       
        Opened=New NAV_OpenedNode
        Opened\Node=Node
       
End Function

Function NAV_IsOpened.NAV_OpenedNode(Node.NAV_Node)
        For Opened.NAV_OpenedNode=Each NAV_OpenedNode
                If Opened\Node=Node Then Return Opened
                If Opened\Node\F>Node\F Then Return Null
        Next
End Function

Function NAV_IsClosed(Node.NAV_Node)
        For Closed.NAV_ClosedNode=Each NAV_ClosedNode
                If Closed\Node=Node Then Return True
                If Closed\Node\F>Node\F Then Return
        Next
End Function

Function NAV_FindPath.NAV_Path(SrcNode.NAV_Node, DstNode.NAV_Node)
        Local Node.NAV_Node
        Local Link.NAV_Link
        Local LinkNode.NAV_Node
        Local Opened.NAV_OpenedNode
        Local Closed.NAV_ClosedNode
       
        NAV_AddToOpened(SrcNode)
       
        Local Fail
       
        Repeat
                Opened=First NAV_OpenedNode
               
                If Opened=Null
                        Fail=True
                        Exit
                EndIf
               
                Node=Opened\Node
                Link=Node\FirstLink
               
                Delete Opened
                NAV_AddToClosed(Node)
               
                While Link<>Null
                       
                        LinkNode=Link\Node
                        If LinkNode\Disabled=False
                                If NAV_IsClosed(LinkNode)=False
                                        Local G=Node\G+Link\Distance
                                       
                                        If LinkNode=DstNode
                                                LinkNode\Parent=Node
                                                Exit
                                        EndIf
                                       
                                        Local OpenedLinkNode.NAV_OpenedNode=NAV_IsOpened(LinkNode)
                                       
                                        If OpenedLinkNode=Null
                                                LinkNode\Parent=Node
                                                LinkNode\G=G
                                                LinkNode\H=NAV_Heuristic(LinkNode, DstNode)
                                                LinkNode\F=LinkNode\G+LinkNode\H
                                                NAV_AddToOpened(LinkNode)
                                        Else
                                                If G<LinkNode\G
                                                        LinkNode\Parent=Node
                                                        LinkNode\G=G
                                                        LinkNode\F=LinkNode\G+LinkNode\H
                                                        NAV_SortNode(OpenedLinkNode)
                                                EndIf
                                        EndIf
                                EndIf
                        EndIf
                       
                        Link=Link\NextLink
                Wend
               
                If LinkNode=DstNode Then Exit
        Forever
       
        If Fail=False
                Local Parent.NAV_Node=DstNode
               
                If Parent=Null Then RuntimeError ""
               
                Local PathNode.NAV_PathNode=New NAV_PathNode
                PathNode\Node=Parent
               
                Local NextNode.NAV_PathNode=PathNode
               
                Repeat
                        Parent=Parent\Parent
                        PathNode=New NAV_PathNode
                        PathNode\Node=Parent
                        PathNode\NextNode=NextNode
                        NextNode=PathNode
                Until Parent=SrcNode
               
                Local Path.NAV_Path=New NAV_Path
                Path\StartNode=PathNode
               
                Delete Each NAV_OpenedNode
                Delete Each NAV_ClosedNode
               
                Return Path                                                                ; Finally return path
        Else
                Delete Each NAV_OpenedNode                                ; ...Or null
                Delete Each NAV_ClosedNode
        EndIf
End Function

Function NAV_NearestNode.NAV_Node(Entity)
        Local MinDistance#=10^38
        Local NearestNode.NAV_Node
       
        For Node.NAV_Node=Each NAV_Node
                If Node\Disabled
                        Local Distance#=EntityDistance(Entity, Node\Pivot)
                        If Distance<MinDistance
                                MinDistance=Distance
                                NearestNode=Node
                        EndIf
                EndIf
        Next
       
        Return NearestNode
End Function

Function NAV_DeletePath(Path.NAV_Path)
        Local PathNode.NAV_PathNode=Path\StartNode
        Local NextPathNode.NAV_PathNode
       
        While PathNode<>Null
                NextPathNode=PathNode\NextNode
                Delete PathNode
                PathNode=NextPathNode
        Wend
       
        Delete Path
End Function

Function NAV_Clear()
        For Node.NAV_Node=Each NAV_Node
                FreeEntity Node\Pivot
                Delete Node
        Next
       
        Delete Each NAV_Link
        Delete Each NAV_Path
        Delete Each NAV_PathNode
End Function


burovalex 29.01.2013 14:57

Ответ: Искуственный интеллект
 
Так на вопросы и не ответили

Цитата:

Если вейпоинты, то где их удобнее хранить, в самом типе ИИ либо в отдельном массиве?
Для прогнозирования встречи с препятствием что лучше использовать, Pick,Collided(Xors'a), RayCast(PhysX'a)?
Цитата:

Подскажите только плиз как в тип добавлять подтипы?
Т.е. маленький пример, я пойму, просто не хочется гуглить с моим мертвым интернетом..

DarkInside 29.01.2013 15:12

Ответ: Искуственный интеллект
 
Цитата:

Сообщение от burovalex (Сообщение 251036)
Ребят, можно без всякого научного бреда

Уважаемый, этот "научный бред" широко применяется на практике и неоднократно обсуждался на форуме

http://forum.boolean.name/showpost.p...50&postcount=2

Как уже сказали, если тебе нужно примитивное перемещение по вейпойнтам, тогда о каком "искусственном интеллекте" идет речь?

SBJoker 29.01.2013 15:40

Ответ: Искуственный интеллект
 
В играх типа Doom3 и прочих, нафигация монстров по коридорам и игре вобщем сделана вейпоинтами, с поиском пути по ним и прочее.
А микро-перемещения реализуются уже анализом положения преград по близости.
Подскочить к игроку например, или окружить его, поползать по стенам.

burovalex 29.01.2013 15:53

Ответ: Искуственный интеллект
 
Не обижайтесь, но с вами говоришь как со стенкой, вам одно, вы другое.
Может я чтото не понимаю...
У меня нет коридоров, чтобы поставить две точки одну в начале, другую в конце. У меня остров, ростут пальмы, т.е. появляются преграды. У меня изначально не неда никаких вейпоинтов.
Понимаю когда есть помещение, надо нцп знать где есть проход а где нет. У меня то наоборот, надо знать где нельзя пройти.

Ребят, ну подскажите ответы на вопросы ниже, я не могу гуглить, у меня скорость 32 кб/сек. - не издевайтесь )

Цитата:

Для прогнозирования встречи с препятствием что лучше использовать, Pick,Collided(Xors'a), RayCast(PhysX'a)?

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

MiXaeL 29.01.2013 16:19

Ответ: Искуственный интеллект
 
Не осилил весь код, некогда, мне хватило Dim. Перепиши на куче (а лучше посмотри готовый пример), и получишь ускорение на несколько порядков.
Я сам писал a* через массив, вышло ооочень медленно. Типа того, что на карте 512х512 был поиск несколько секунд.

burovalex 29.01.2013 16:37

Ответ: Искуственный интеллект
 
Цитата:

Сообщение от burovalex (Сообщение 251060)
Не обижайтесь, но с вами говоришь как со стенкой, вам одно, вы другое.
Может я чтото не понимаю...

Ребят, ну подскажите ответы на вопросы ниже, я не могу гуглить, у меня скорость 32 кб/сек. - не издевайтесь )

Цитата:

Для прогнозирования встречи с препятствием что лучше использовать, Pick,Collided(Xors'a), RayCast(PhysX'a)?

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

...

MiXaeL 29.01.2013 16:47

Ответ: Искуственный интеллект
 
Тебе ответили - A* с выделением памяти на куче.
Не хочешь делать нормально, бери Пик, Коллизии, делай тесты. А потом я нарисую тебе пример, на котором твое прогнозирование загонит бота в тупик или цикл.

burovalex 29.01.2013 17:07

Ответ: Искуственный интеллект
 
ок ;)
Да я не против пользоваться таким методом, но мне кажется для начинающего должно быть чтото попроще...

И не понял что означает выделение памяти на куче

Блин, мне так и не подсказали как в типе сделать подтип.
Чтобы к нцп добавлять вейпоинты.

MiXaeL 29.01.2013 17:38

Ответ: Искуственный интеллект
 
Кучи, это читать в хелпе про Heap. Блитц у меня не стоит уже лет 7, так что точнее не скажу. Кстати, вспомнил про еще более классную штуку, к тому же совсем свежую: http://habrahabr.ru/post/162915/
Подтипов тут нет честных, не могу найти правильную ссылку, импер подскажет.

Platon 29.01.2013 17:59

Ответ: Искуственный интеллект
 
burovalex
Не тупи, у тебя есть карта растительности - юзай ее для построения графа для поиска пути Астаром или волновым методом. Точнее ты можешь по этой карте построить регулярную сетку ( массив ) на которой будут отмечаться проходимые и непроходимые участки ( да, можно риалтайм ), а чтобы не тормозило на больших картах - выпрямляй руки, учи матчасть или юзай уже готовые реализации алгоритмов поиска пути :)

RegIon 29.01.2013 18:10

Ответ: Искуственный интеллект
 
Как-то скачал сборку примеров на Блитце, там как раз было 2 с А* алгоритмом. Только я не могу найти(

burovalex 29.01.2013 19:20

Ответ: Искуственный интеллект
 
Ну даже, чтобы пользоваться Астаром, надо научиться пользоваться подтипами. С чем у меня пока проблемы, вкурить не могу..

Цитата:

Type npc
Field entity
Field target
Field wp.waypoints
End Type

Type waypoints
Field x#,y#,z#
End Type

Function CreateNPC()
npc.npc=New npc
End Function

Function NewTarget()
For npc.npc.wp=Each npc.waipoints
;а здесь чтото не правильно, я хотел пройтись по типу waypoints в типе npc
Next
End Function

tormoz 29.01.2013 19:24

Ответ: Искуственный интеллект
 
Оченно рекомендую библу Дипломата:

http://forum.boolean.name/showthread...080#post251080

Юзал для стратегии и шутера - работает отменно и с статикой и динамикой. сотня юнитов шустренько шныряет по уровню с узкими коридорами, не сталкиваясь и не застревая.

Nex 29.01.2013 22:33

Ответ: Искуственный интеллект
 
Можно использовать волновой алгоритм. Это наверно самый простой поиск пути в плане реализации.
http://pmg.org.ru/ai/path.htm

tirarex 29.01.2013 22:48

Ответ: Искуственный интеллект
 
Вот для свой игрушки тоже ищу нахождение пути только вот мне нужно сделать нахождение по вей поинтам

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


еслть ли такие библиотеки работающие по вышеописанному принципу

tormoz 29.01.2013 23:03

Ответ: Искуственный интеллект
 
Цитата:

Сообщение от tirarex (Сообщение 251095)
в варианте tormoz,а таковых точек не заметил но увидел что надо показывать где стены а на большой карте с кучей домов и разных интерьеров таковой возможности нет


еслть ли такие библиотеки работающие по вышеописанному принципу

Ты не понимаешь как работает пп.
Твоя задача передать в длл сетку проходимости.
Разбиваешь уровень на клетки со стороной в одного юнита. Заполняешь массив по проходимости. Передаешь в пп. Все.
Заполнять сетку можно заранее, например нарисовать битмап проходимости, где пиксель -клетка сетки, или получить в коде, пикая уровень по сетке, дифференцируя по высоте\имени и тп.
Дополнить карту можно самими юнитами в динамике.
Далее передаешь начальную и конечную точку пути
пп возвращает координаты вейпойнтов по которым двигается юнит (в формате сетки).
см. примеры в архиве.

jimon 29.01.2013 23:25

Ответ: Искуственный интеллект
 
ну сетка это всего лишь частный случай графа, где каждый узел связан с еще 4 (или 9 чтобы ходили по диагонали) узлами, не вижу проблем брать за граф карту вейпоинтов, просто кто будет учить дискретную математику для этого ? все ищут простого решения, геймдевелоперы блин

tormoz 29.01.2013 23:48

Ответ: Искуственный интеллект
 
Цитата:

Сообщение от jimon (Сообщение 251099)
ну сетка это всего лишь частный случай графа, где каждый узел связан с еще 4 (или 9 чтобы ходили по диагонали) узлами, не вижу проблем брать за граф карту вейпоинтов, просто кто будет учить дискретную математику для этого ? все ищут простого решения, геймдевелоперы блин

Сомневаюсь что велосипедный пп для отдельной игры как-то повлияет на общий результат. Думаю что наоборот - пока девелопер сушит мозг над 100500-ым велосипедом, плавно подойдет старость...:-D

tirarex 29.01.2013 23:56

Ответ: Искуственный интеллект
 
Конкретного ответа нет :(
пойду гуглить дальше

burovalex 30.01.2013 07:33

Ответ: Искуственный интеллект
 
Цитата:

Сообщение от burovalex (Сообщение 251079)
Ну даже, чтобы пользоваться Астаром, надо научиться пользоваться подтипами.
Код:

Type npc
 Field entity
 Field target
 Field wp.waypoints
 End Type

 Type waypoints
 Field x#,y#,z#
 End Type

 Function CreateNPC()
 npc.npc=New npc
 End Function

 Function NewTarget()
For npc.npc.wp=Each npc.waipoints
;а здесь чтото не правильно, я хотел пройтись по типу waypoints в типе npc
 Next
 End Function

С чем у меня пока проблемы, вкурить не могу..

Блин, ну подскажите как пройтись по типу waipoints в типе npc

burovalex 30.01.2013 11:04

Ответ: Искуственный интеллект
 
Чет я не понял, с трудом разобрался, так что получается.
Если в типе добавить еще один тип - то у них всё равно связи не будет?? 0_о

Получается в любом случае придётся проходить по всему списку и делать выборку?

Platon 30.01.2013 12:07

Ответ: Искуственный интеллект
 
Цитата:

Сообщение от burovalex (Сообщение 251162)
Чет я не понял, с трудом разобрался, так что получается.
Если в типе добавить еще один тип - то у них всё равно связи не будет?? 0_о

Получается в любом случае придётся проходить по всему списку и делать выборку?

Может ты все-таки в справку заглянешь? В блиц-бейсике для структурных типов Type создается один глобальный список, поэтому обьявляя там поле с таким типом, ты будешь иметь лишь указатель (ссылка) на экземпляр, а все создаваемые оператором New экземпляры будут автоматически помещаться в этот глобальный список. Поэтому надо делать свой список, т.е. в твоем случае тип Waypoints должен иметь ссылку на следующий в списке, а тип npc иметь ссылку на начало списка. Гугли односвязный и\или двусвязный список чтобы понять как его строить. По сути список - та же очередь в действительности, где каждый элемент помнит того кто впереди него ( за кем занял ), и того кто позади ( кто за ним занял ). К слову в BlitzMax, который уже ближе к "взрослым" ЯП, есть такой механизм. По-моему тебе стоит бросить блиц-бейсик и юзать блиц-макс, к тому-же, раз ты юзаешь Xors3D, юзать его из BlitzMax будет правильно, все-таки блиц-бейсик намертво связан с блиц3д, и юзать один движок из другого - извращение, имхо.

ЗЫ
вот примерно как можно очередь сделать

Код:


; элемент очереди
Type Element
       
        ; сзади по очереди
        Field BackElement.Element
       
        ; впереди по очереди
        Field FrontElement.Element
       
End Type

; очередь
Type Queue
       
        ; первый в очереди
        Field FirstElement.Element
       
        ; последний в очереди
        Field LastElement.Element
       
End Type

;
; функция входа в очередь
;
Function EnterQueue ( Queue.Queue, Element.Element )
       
        ;
        ; спрашиваешь кто последний
        ;
        If Queue\LastElement <> Null Then
               
                ;
                ; последний запоминает что ты за ним занял
                ;
                Queue\LastElement\BackElement = Element
               
                ;
                ; раз ты последний, за тобой никого нет
                ;
                Element\BackElement = Null
               
                ;
                ; запоминаешь того, кто перед тобой
                ;
                Element\FrontElement = Queue\LastElement
               
        ;
        ; последнего нет - нет и очереди
        ;
        Else
               
                ;
                ; раз очереди нет, ты первый в очереди
                ;
                Queue\FirstElement = Element
               
        End If       
       
        ;
        ; занял очередь, теперь ты последний в очереди
        ;
        Queue\LastElement = Element
       
End Function

;
; функция выхода из очереди
;
Function LeaveQueue ( Queue.Queue, Element.Element )
       
        ;
        ; сзади тебя кто-то есть, ты не последний в очереди
        ;
        If Element\BackElement <> Null Then
               
                ;
                ; сообщаешь тому, кто занимал за тобой, что он теперь стоит
                ; за тем, кто впереди нас
                ;
                Element\BackElement\FrontElement = Element\FrontElement
               
        ;       
        ; сзади тебя никого нет, ты последний в очереди
        ;
        Else
               
                ;
                ; сообщаешь тому, кто впереди нас, что он становится последним
                ; в очереди
                ;
                Queue\LastElement = Element\FrontElement
               
        End If
       
        ;
        ; впереди тебя кто-то есть, ты не первый в очереди
        ;
        If Element\FrontElement <> Null Then
               
                ;
                ; сообщаешь тому, за кем ты занимал,
                ; что за ним теперь не ты, а тот, кто занимал за тобой
                ;
                Element\FrontElement\BackElement = Element\BackElement
       
        ;       
        ; впереди тебя никого нет, ты первый в очереди
        ;
        Else
               
                ;
                ; сообщаешь тому, кто сзади тебя, что он теперь первый в очереди
                ;
                Queue\FirstElement = Element\BackElement
               
        End If
       
End Function


burovalex 30.01.2013 16:24

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

А блитц я не брошу пока не закончу с проектом. Переделывать муторно, т.к. моя версия пока стабильна, не буду пока ее трогать.

З.Ы. Как говорит мой батя, "НЕ ТРОГАЙ НАЛАЖЕННО РАБОТАЮЩИЙ МЕХАНИЗМ" - блин, правда правд )


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

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