Posted By

ozkriff on 07/23/08


Tagged


Versions (?)

with shad.001


 / Published in: Python
 

  1. import direct.directbase.DirectStart
  2. from pandac.PandaModules import *
  3. from pandac.PandaModules import CollisionTraverser,CollisionNode
  4. from pandac.PandaModules import CollisionHandlerQueue,CollisionRay
  5. from pandac.PandaModules import Filename,GeomNode
  6. from pandac.PandaModules import PandaNode,NodePath,Camera,TextNode
  7. from pandac.PandaModules import Vec3,Vec4,BitMask32
  8. from direct.gui.OnscreenText import OnscreenText
  9. from direct.actor.Actor import Actor
  10. from direct.task.Task import Task
  11. from direct.showbase.DirectObject import DirectObject
  12. import random, sys, os, math
  13.  
  14. SPEED = 0.5
  15.  
  16. # Figure out what directory this program is in.
  17. MYDIR=os.path.abspath(sys.path[0])
  18. MYDIR=Filename.fromOsSpecific(MYDIR).getFullpath()
  19.  
  20. # Function to put instructions on the screen.
  21. def addInstructions(pos, msg):
  22. return OnscreenText(text=msg, style=1, fg=(1,1,1,1),
  23. pos=(-1.3, pos), align=TextNode.ALeft, scale = .05,mayChange=True)
  24.  
  25. # Function to put title on the screen.
  26. def addTitle(text):
  27. return OnscreenText(text=text, style=1, fg=(1,1,1,1),
  28. pos=(1.3,-0.95), align=TextNode.ARight, scale = .07)
  29.  
  30. class World(DirectObject):
  31.  
  32. def __init__(self):
  33.  
  34.  
  35.  
  36.  
  37.  
  38. self.onCollisionText = OnscreenText(
  39. text="",
  40. style=1, fg=(1,1,1,1), pos=(-1.3, 0.15),
  41. align=TextNode.ALeft, scale = .05)
  42.  
  43. self.keyMap = {"left":0, "right":0, "forward":0, "shift":0, "control":0,"alt":0}
  44. base.win.setClearColor(Vec4(0,0,0,1))
  45.  
  46. self.picker = CollisionTraverser()
  47. self.queue = CollisionHandlerQueue()
  48.  
  49. # Post the instructions
  50.  
  51. self.title = addTitle("Panda3D Tutorial: Roaming Ralph (Walking on Uneven Terrain)")
  52. self.inst1 = addInstructions(0.95, "[ESC]: Quit")
  53. self.inst2 = addInstructions(0.90, "[Left Arrow]: Rotate Ralph Left")
  54. self.inst3 = addInstructions(0.85, "[Right Arrow]: Rotate Ralph Right")
  55. self.inst4 = addInstructions(0.80, "[Up Arrow]: Run Ralph Forward")
  56. self.inst5 = addInstructions(0.75, "[Down Arrow]: Home")
  57. self.inst10 = addInstructions(0.60, "!!!")
  58. self.inst11 = addInstructions(0.50, "...")
  59. self.inst30 = addInstructions(0.10, " ")
  60.  
  61. self.loadPicker()
  62.  
  63. self.environ = loader.loadModel("models/world")
  64. self.environ.reparentTo(render)
  65. self.environ.setPos(0,0,0)
  66.  
  67. # Create the main character, Ralph
  68.  
  69. ralphStartPos = self.environ.find("**/start_point").getPos()
  70. self.ralph = Actor("models/ralph",
  71. {"run":"models/ralph-run",
  72. "walk":"models/ralph-walk"})
  73. self.ralph.reparentTo(render)
  74. self.ralph.setScale(.2)
  75. self.ralph.setPos(ralphStartPos)
  76. self.ralph.setTag('pickable', 'R')
  77.  
  78. # Create a floater object. We use the "floater" as a temporary
  79. # variable in a variety of calculations.
  80.  
  81. self.floater = NodePath(PandaNode("floater"))
  82. self.floater.reparentTo(render)
  83.  
  84. # Accept the control keys for movement and rotation
  85.  
  86. self.accept("escape", sys.exit)
  87. self.accept("arrow_left", self.setKey, ["left",1])
  88. self.accept("arrow_right", self.setKey, ["right",1])
  89. self.accept("arrow_up", self.setKey, ["forward",1])
  90. self.accept("arrow_left-up", self.setKey, ["left",0])
  91. self.accept("arrow_right-up", self.setKey, ["right",0])
  92. self.accept("arrow_up-up", self.setKey, ["forward",0])
  93. self.accept("arrow_down", self.Home)
  94.  
  95. self.accept("mouse1", self.collisionCheck,[1])
  96. self.accept("mouse3", self.collisionCheck,[2])
  97. self.accept("mouse2", self.collisionCheck,[3])
  98.  
  99. taskMgr.add(self.move,"moveTask")
  100. #~ taskMgr.add(self.cam,"camTask")
  101.  
  102. # Set up the camera
  103.  
  104. base.disableMouse()
  105. base.camera.setPos(self.ralph.getX(),self.ralph.getY()+10,8)
  106.  
  107. # Game state variables
  108. self.prevtime = 0
  109. self.isMoving = False
  110.  
  111. # We will detect the height of the terrain by creating a collision
  112. # ray and casting it downward toward the terrain. One ray will
  113. # start above ralph's head, and the other will start above the camera.
  114. # A ray may hit the terrain, or it may hit a rock or a tree. If it
  115. # hits the terrain, we can detect the height. If it hits anything
  116. # else, we rule that the move is illegal.
  117.  
  118. self.cTrav = CollisionTraverser()
  119.  
  120. self.ralphGroundRay = CollisionRay()
  121. self.ralphGroundRay.setOrigin(0,0,1000)
  122. self.ralphGroundRay.setDirection(0,0,-1)
  123. self.ralphGroundCol = CollisionNode('ralphRay')
  124. self.ralphGroundCol.addSolid(self.ralphGroundRay)
  125. self.ralphGroundCol.setFromCollideMask(BitMask32.bit(0))
  126. self.ralphGroundCol.setIntoCollideMask(BitMask32.allOff())
  127. self.ralphGroundColNp = self.ralph.attachNewNode(self.ralphGroundCol)
  128. self.ralphGroundHandler = CollisionHandlerQueue()
  129. self.cTrav.addCollider(self.ralphGroundColNp, self.ralphGroundHandler)
  130.  
  131. # Uncomment this line to see the collision rays
  132. #self.ralphGroundColNp.show()
  133.  
  134. #Uncomment this line to show a visual representation of the
  135. #collisions occuring
  136. #self.cTrav.showCollisions(render)
  137.  
  138.  
  139. #=======================LIGHTS/SHADOWS=====================#
  140.  
  141.  
  142. #load s light=========================
  143.  
  144. plight = PointLight('plight')
  145. plight.setColor(VBase4(1, 1, 1, 1))
  146. plnp = render.attachNewNode(plight)
  147. plnp.setPos(-107, 25, 10)
  148. render.setLight(plnp)
  149.  
  150. #~ =============================
  151.  
  152.  
  153.  
  154. #Records the state of the arrow keys
  155. def setKey(self, key, value):
  156. self.keyMap[key] = value
  157.  
  158. #teleport ralph
  159. def teleport(self, pos):
  160. self.ralph.setPos(pos)
  161.  
  162. #the same
  163. def move2(self, pos):
  164. self.ralph.setPos(pos)
  165.  
  166. def loadPicker(self):
  167. #attach a CollisionRay node to the camera
  168. self.pickerNode = CollisionNode('mouseRay')
  169. self.pickerNP = camera.attachNewNode(self.pickerNode)
  170. self.pickerNode.setFromCollideMask(GeomNode.getDefaultCollideMask())
  171. self.pickerRay = CollisionRay()
  172. self.pickerNode.addSolid(self.pickerRay)
  173. self.pickerNP.show()
  174.  
  175. #add collision node (fromObject) to the traverser
  176. self.picker.addCollider(self.pickerNP, self.queue)
  177. self.picker.showCollisions(render)
  178.  
  179. if base.mouseWatcherNode.hasMouse():
  180. #get the mouse position
  181. mpos = base.mouseWatcherNode.getMouse()
  182. #aim the collision ray
  183. self.pickerRay.setFromLens(base.camNode, mpos.getX(), mpos.getY())
  184. self.inst30.destroy()
  185. self.inst30 = addInstructions(-0.50, str(mpos.getX())+" "+str(mpos.getY()))
  186. #fire the ray and record, in the queue, any collisions
  187. self.picker.traverse(render)
  188.  
  189. if self.queue.getNumEntries() > 0:
  190. if self.queue.getNumEntries() == 1:
  191. self.mytext = "A collision with: _ " \
  192. + str(self.queue.getEntry(0).getIntoNodePath()) +" at point of: _ " \
  193. + str(self.queue.getEntry(0).getInteriorPoint(self.queue.getEntry(0).getIntoNodePath()))
  194. else:
  195. #organize the collisions from first hit to second...
  196. self.queue.sortEntries()
  197. #output the name of the node paths the ray collided with
  198. self.mytext = "A collision occured first with " \
  199. + str(self.queue.getEntry(0).getIntoNodePath()) \
  200. + " and then with " + str(self.queue.getEntry(1).getIntoNodePath())
  201.  
  202.  
  203. self.onCollisionText.setText(self.mytext)
  204.  
  205.  
  206. def collisionCheck(self,but):
  207. if base.mouseWatcherNode.hasMouse():
  208. #get the mouse position
  209. mpos = base.mouseWatcherNode.getMouse()
  210. #aim the collision ray
  211. self.pickerRay.setFromLens(base.camNode, mpos.getX(), mpos.getY())
  212. self.inst30.destroy()
  213. self.inst30 = addInstructions(-0.50, str(mpos.getX())+" "+str(mpos.getY()))
  214. #fire the ray and record, in the queue, any collisions
  215. self.picker.traverse(render)
  216.  
  217. if self.queue.getNumEntries() > 0:
  218. if self.queue.getNumEntries() == 1:
  219. self.mytext = "A collision with: _ " \
  220. + str(self.queue.getEntry(0).getIntoNodePath()) +" at point of: _ " \
  221. + str(self.queue.getEntry(0).getInteriorPoint(self.queue.getEntry(0).getIntoNodePath()))
  222. else:
  223. #organize the collisions from first hit to second...
  224. self.queue.sortEntries()
  225. #output the name of the node paths the ray collided with
  226. self.mytext = "A collision occured first with " \
  227. + str(self.queue.getEntry(0).getIntoNodePath()) \
  228. + " and then with " + str(self.queue.getEntry(1).getIntoNodePath())
  229.  
  230.  
  231. if but ==1:
  232. #self.teleport(self.queue.getEntry(0).getInteriorPoint(self.queue.getEntry(0).getIntoNodePath()))
  233. self.moveTo = self.queue.getEntry(0).getInteriorPoint(self.queue.getEntry(0).getIntoNodePath())
  234. self.ralph.loop("run")
  235.  
  236. if but ==2:
  237. self.move2(self.queue.getEntry(0).getInteriorPoint(self.queue.getEntry(0).getIntoNodePath()))
  238.  
  239. self.onCollisionText.setText(self.mytext)
  240.  
  241.  
  242. # Accepts arrow keys to move either the player or the menu cursor,
  243. # Also deals with grid checking and collision detection
  244.  
  245. #~ def cam(self, task):
  246. #~ if base.mouseWatcherNode.hasMouse():
  247. #~ #get the mouse position
  248. #~ xwpos = base.mouseWatcherNode.getMouse()
  249. #~
  250. #~ if xwpos.getX() > 0.9:
  251. #~ base.camera.setPos(camera.getX()-0.15 ,camera.getY(),10)
  252. #~ if xwpos.getX() < -0.9:
  253. #~ base.camera.setPos(camera.getX()+0.15 ,camera.getY(),10)
  254. #~ if xwpos.getY() > 0.9:
  255. #~ base.camera.setPos(camera.getX() ,camera.getY()-0.15,10)
  256. #~ if xwpos.getY() < -0.9:
  257. #~ base.camera.setPos(camera.getX() ,camera.getY()+0.15,10)
  258.  
  259. #~(base.win.movePointer(0, base.win.getXSize()/2, base.win.getYSize()/2))
  260. #~ return Task.cont
  261.  
  262.  
  263. def move(self, task):
  264. #time saving
  265. elapsed = task.time - self.prevtime
  266.  
  267. # save ralph's initial position so that we can restore it,
  268. # in case he falls off the map or runs into something.
  269.  
  270. startpos = self.ralph.getPos()
  271.  
  272. # If a move-key is pressed, move ralph in the specified direction.
  273.  
  274. if (self.keyMap["left"]!=0):
  275. self.ralph.setH(self.ralph.getH() + elapsed*300)
  276. if (self.keyMap["right"]!=0):
  277. self.ralph.setH(self.ralph.getH() - elapsed*300)
  278. if (self.keyMap["forward"]!=0):
  279. backward = self.ralph.getNetTransform().getMat().getRow3(1)
  280. backward.setZ(0)
  281. backward.normalize()
  282. self.ralph.setPos(self.ralph.getPos() - backward*(elapsed*5))
  283.  
  284. #mose moving =) thanks InternZero
  285. if hasattr(self, "moveTo"):
  286. self.ralph.lookAt(self.moveTo)
  287. self.ralph.setH(self.ralph, 180)
  288. backward = self.ralph.getNetTransform().getMat().getRow3(1)
  289. backward.setZ(0)
  290. backward.normalize()
  291. self.ralph.setPos(self.ralph.getPos() - backward*(elapsed*5))
  292.  
  293. #stop when reash the destination point
  294. if self.ralph.getPos(render).almostEqual(self.moveTo, 0.05):
  295. #~ print "Comparison:", self.ralph.getPos(render), self.moveTo
  296. self.ralph.setPos(self.moveTo)
  297. self.isMoving = False
  298. self.ralph.pose("walk",5)
  299. backward = self.ralph.getNetTransform().getMat().getRow3(1)
  300. backward.setZ(0)
  301. backward.normalize()
  302. del self.moveTo
  303.  
  304. # If ralph is moving, loop the run animation.
  305. # If he is standing still, stop the animation.
  306.  
  307. if (self.keyMap["forward"]!=0) or (self.keyMap["left"]!=0) or (self.keyMap["right"]!=0):
  308. if self.isMoving is False:
  309. self.ralph.loop("run")
  310. self.isMoving = True
  311. else:
  312. if self.isMoving:
  313. self.ralph.stop()
  314. self.ralph.pose("walk",5)
  315. self.isMoving = False
  316.  
  317. # Now check for collisions.
  318.  
  319. self.cTrav.traverse(render)
  320.  
  321. # Adjust ralph's Z coordinate. If ralph's ray hit terrain,
  322. # update his Z. If it hit anything else, or didn't hit anything, put
  323. # him back where he was last frame.
  324.  
  325. entries = []
  326. for i in range(self.ralphGroundHandler.getNumEntries()):
  327. entry = self.ralphGroundHandler.getEntry(i)
  328. entries.append(entry)
  329. entries.sort(lambda x,y: cmp(y.getSurfacePoint(render).getZ(),
  330. x.getSurfacePoint(render).getZ()))
  331. if (len(entries)>0) and (entries[0].getIntoNode().getName() == "terrain"):
  332. self.ralph.setZ(entries[0].getSurfacePoint(render).getZ())
  333. else:
  334. self.ralph.setPos(startpos)
  335.  
  336.  
  337. #camera look at
  338. self.floater.setPos(self.ralph.getPos())
  339. self.floater.setZ(self.ralph.getZ() + 2.0)
  340. base.camera.lookAt(self.floater)
  341.  
  342. self.inst10.destroy()
  343. self.inst10 = addInstructions(0.55, str(self.ralph.getPos)+"(ralph position):")
  344.  
  345. self.inst11.destroy()
  346. self.inst11 = addInstructions(0.50, str(self.ralph.getPos()))
  347.  
  348.  
  349. # Store the task time and continue.
  350. self.prevtime = task.time
  351. return Task.cont
  352.  
  353.  
  354. def Home(self):
  355. ralphStartPos = self.environ.find("**/start_point").getPos()
  356. self.ralph.setPos(ralphStartPos)
  357.  
  358.  
  359. #suka rabotay!!!
  360. w = World()
  361. run()

Report this snippet  

You need to login to post a comment.