Dynamic Obstacles
DYNAMIC OBSTACLES:
https://www.youtube.com/watch?v=8BZ_3gua5Bs
In PandAI, use it via:
addDynamicObstacle(NodePath obstacle);
The code for this tutorial:
1# This tutorial provides an example of creating a character and having it walk
2# around using PandAI and dynamic obstacle pathfinding
3
4from direct.showbase.ShowBase import ShowBase
5from panda3d.core import *
6from direct.showbase.DirectObject import DirectObject
7from direct.interval.IntervalGlobal import *
8from direct.task import Task
9from direct.actor.Actor import Actor
10import random
11import sys
12import os
13from direct.gui.DirectGui import *
14from direct.gui.OnscreenText import OnscreenText
15
16from panda3d.ai import *
17
18base = ShowBase()
19
20speed = 0.2
21turnspeed = 3.5
22
23# Figure out what directory this program is in.
24MYDIR = os.path.abspath(sys.path[0])
25MYDIR = Filename.fromOsSpecific(MYDIR).getFullpath()
26
27font = loader.loadFont("cmss12")
28
29
30# Function to put instructions on the screen.
31def addInstructions(pos, msg):
32 return OnscreenText(text=msg, style=1, fg=(1, 1, 1, 1), font=font,
33 pos=(-1.3, pos), align=TextNode.ALeft, scale=.05)
34
35
36# Function to put title on the screen.
37def addTitle(text):
38 return OnscreenText(text=text, style=1, fg=(1, 1, 1, 1), font=font,
39 pos=(1.3, -0.95), align=TextNode.ARight, scale=.07)
40
41
42class World(DirectObject):
43
44 def __init__(self):
45
46 self.keyMap = {"left": 0, "right": 0, "forward": 0}
47
48 #base.disableMouse()
49 base.cam.setPosHpr(0, -210, 135, 0, 327, 0)
50 self.done = []
51 for i in range(4):
52 self.done.append(False)
53 self.toggle = False
54 self.firstTime = False
55
56 addTitle("Pandai Tutorial: Dynamic Avoidance of Moving Obstacles")
57 addInstructions(0.95, "[ESC]: Quit")
58 addInstructions(0.90, "[Arrow Keys]: Move the blue Ralph")
59 addInstructions(0.85, "Try and move the blue Ralph in the path of the "
60 "other Ralphs")
61
62 self.loadModels()
63 self.setAI()
64
65 def loadModels(self):
66
67 self.environ1 = loader.loadModel("models/skydome")
68 self.environ1.reparentTo(render)
69 self.environ1.setPos(0, 0, 0)
70 self.environ1.setScale(1)
71
72 self.environ2 = loader.loadModel("models/skydome")
73 self.environ2.reparentTo(render)
74 self.environ2.setP(180)
75 self.environ2.setH(270)
76 self.environ2.setScale(1)
77
78 self.environ = loader.loadModel("models/plane_demo1")
79 self.environ.reparentTo(render)
80 self.environ.setPos(0, 0, 0)
81
82 self.Target = Actor("models/ralph",
83 {"run": "models/ralph-run",
84 "walk": "models/ralph-walk"})
85 self.Target.setColor(0, 0, 1)
86 self.Target.setPos(60, -60, 0)
87 self.Target.setScale(2)
88 self.Target.reparentTo(render)
89 self.Target.loop("run")
90 self.Targetforward = NodePath("Targetforward")
91 self.Targetforward.setPos(0, -1, 0)
92 self.Targetforward.reparentTo(self.Target)
93
94 # Create the main character, Ralph
95 self.ralph = []
96 self.positions = []
97 self.positions_new = []
98 for i in range(4):
99 self.ralph.append(Actor("models/ralph",
100 {"run": "models/ralph-run",
101 "walk": "models/ralph-walk"}))
102 self.ralph[i].reparentTo(render)
103 self.ralph[i].setScale(2)
104
105 self.positions.append(NodePath(str(i)))
106 self.positions_new.append(NodePath(str(i)))
107 if i < 2:
108 self.ralph[i].setPos(Point3(-61, -34 + (i * 40), 0))
109 else:
110 self.ralph[i].setPos(Point3(61, -34 + ((i - 2) * 40), 0))
111
112 self.positions.append(NodePath(str(i)))
113 self.positions_new.append(NodePath(str(i)))
114
115 self.positions[0].setPos(Point3(-61, -34 + ((0) * 40), 0))
116 self.positions[1].setPos(Point3(-53, -34 + ((1) * 40), 0))
117 self.positions[2].setPos(Point3(53, -44 + ((0) * 40), 0))
118 self.positions[3].setPos(Point3(61, -24 + ((1) * 40), 0))
119
120 self.positions_new[0].setPos(Point3(61, -44 + ((0) * 40), 0))
121 self.positions_new[1].setPos(Point3(53, -44 + ((1) * 40), 0))
122 self.positions_new[2].setPos(Point3(-53, -24 + ((0) * 40), 0))
123 self.positions_new[3].setPos(Point3(-61, -24 + ((1) * 40), 0))
124
125 def setAI(self):
126 # Creating AI World
127 self.AIworld = AIWorld(render)
128
129 #self.accept("enter", self.setMove)
130 # Movement
131 self.accept("arrow_left", self.setKey, ["left", 1])
132 self.accept("arrow_right", self.setKey, ["right", 1])
133 self.accept("arrow_up", self.setKey, ["forward", 1])
134 self.accept("arrow_left-up", self.setKey, ["left", 0])
135 self.accept("arrow_right-up", self.setKey, ["right", 0])
136 self.accept("arrow_up-up", self.setKey, ["forward", 0])
137
138 self.AIchar = []
139 self.AIbehaviors = []
140 for i in range(4):
141 maxForce = 25 - (5 * random.random())
142 char = AICharacter("ralph", self.ralph[i], 60, 0.05, maxForce)
143 self.AIchar.append(char)
144 self.AIworld.addAiChar(char)
145 self.AIbehaviors.append(char.getAiBehaviors())
146 self.AIbehaviors[i].initPathFind("models/navmesh.csv")
147
148 # AI World update
149 taskMgr.add(self.AIUpdate, "AIUpdate")
150
151 taskMgr.add(self.Mover, "mover")
152
153 self.setMove(1)
154
155 def setMove(self, type):
156 if type == 1:
157 for i in range(4):
158 if i == 0:
159 self.AIbehaviors[i].pathFindTo(self.positions_new[0], "addPath")
160 self.AIbehaviors[i].addDynamicObstacle(self.ralph[2])
161 if i == 1:
162 self.AIbehaviors[i].pathFindTo(self.positions_new[1], "addPath")
163 self.AIbehaviors[i].addDynamicObstacle(self.ralph[3])
164 if i == 2:
165 self.AIbehaviors[i].pathFindTo(self.positions_new[2], "addPath")
166 if i == 3:
167 self.AIbehaviors[i].pathFindTo(self.positions_new[3], "addPath")
168 if self.firstTime is False:
169 self.AIbehaviors[i].addDynamicObstacle(self.Target)
170 self.ralph[i].loop("run")
171
172 self.firstTime = True
173
174 if type == 2:
175 for i in range(4):
176 if i == 0:
177 self.AIbehaviors[i].pathFindTo(self.positions[0], "addPath")
178 if i == 1:
179 self.AIbehaviors[i].pathFindTo(self.positions[1], "addPath")
180 if i == 2:
181 self.AIbehaviors[i].pathFindTo(self.positions[2], "addPath")
182 if i == 3:
183 self.AIbehaviors[i].pathFindTo(self.positions[3], "addPath")
184
185 self.ralph[i].loop("run")
186
187 # To update the AIWorld
188 def AIUpdate(self, task):
189 self.AIworld.update()
190 for i in range(4):
191 status = self.AIbehaviors[i].behaviorStatus("pursue")
192 if status == "done" or status == "paused":
193 self.done[i] = True
194
195 j = 0
196 for i in range(4):
197 if self.done[i] is True:
198 j += 1
199
200 if j == 4:
201 self.toggle = not self.toggle
202 if self.toggle is True:
203 self.setMove(2)
204 else:
205 self.setMove(1)
206 for i in range(4):
207 self.done[i] = False
208
209 return Task.cont
210
211 def setKey(self, key, value):
212 self.keyMap[key] = value
213
214 def Mover(self, task):
215 startPos = self.Target.getPos()
216
217 if self.keyMap["left"] != 0:
218 self.Target.setH(self.Target.getH() + turnspeed)
219 if self.keyMap["right"] != 0:
220 self.Target.setH(self.Target.getH() - turnspeed)
221 if self.keyMap["forward"] != 0:
222 forwardvector = self.Targetforward.getPos(render) - startPos
223 self.Target.setPos(startPos + forwardvector * speed)
224
225 return Task.cont
226
227
228w = World()
229base.run()
The full working demo can be downloaded at: