Shuvit game master repo. http://shuvit.org
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

StatesCar.py 13KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395
  1. import utils
  2. import bge
  3. import random
  4. from mathutils import Vector
  5. #====================================
  6. def mark_path(path, y):
  7. iter_ = 0
  8. for x in path:
  9. pm = bge.logic.getCurrentScene().addObject('path_marker', y.obj, 0)
  10. pm.worldPosition = path[iter_]
  11. iter_ += 1
  12. if iter_ == 1:
  13. pm.color = [0,1,0,.4]
  14. if iter_ == (len(path) ):
  15. pm.color = [1,0,0,.4]
  16. if iter_ == (len(path) +1):
  17. pm.color = [1,0,1,.4]
  18. y.path_display.append(pm)
  19. def clear_markers(self):
  20. for x in self.FSM.owner.path_display:
  21. try:
  22. x.endObject()
  23. except:
  24. pass
  25. def get_ground_ray(self):
  26. Axis = 2
  27. Distance = -10
  28. end = self.obj.worldPosition + (self.obj.worldOrientation.col[Axis]*Distance)
  29. start = self.obj.worldPosition.copy()
  30. ground_ray = self.obj.rayCast(end, start, 6,'', 1, 0)
  31. return ground_ray
  32. def set_height(self):
  33. ground_ray = get_ground_ray(self)
  34. target_height = 0.9
  35. hitpoint = ground_ray[1]
  36. try:
  37. dist = self.obj.getDistanceTo(hitpoint)
  38. if dist < target_height:
  39. self.obj.worldPosition.z += target_height - dist
  40. self.obj.linearVelocity.z = 0
  41. self.obj.linearVelocity.y *= .1
  42. except:
  43. pass
  44. def align_to_road(self):
  45. ground_ray = get_ground_ray(self)
  46. try:
  47. self.obj.alignAxisToVect(ground_ray[2], 2, .15)
  48. except:
  49. pass
  50. def find_new_parking(self):
  51. potentials = []
  52. for x in self.manager.parking_spots:
  53. if x.status == 'available':
  54. potentials.append(x)
  55. for x in potentials:
  56. min_dist = 45
  57. dist = self.obj.getDistanceTo(x.obj)
  58. #print('dist to potential', dist)
  59. if dist < min_dist:
  60. potentials.remove(x)
  61. #print('----removing potential')
  62. if len(potentials) > 0:
  63. new_parking = random.choice(potentials)
  64. #path = self.manager.navmesh.findPath(self.start_empty.obj.worldPosition, new_parking.obj.worldPosition)
  65. path2 = self.manager.navmesh2.queue_path(self.start_empty.obj.worldPosition, new_parking.obj.worldPosition, self)
  66. #print('parking added at', new_parking.obj.worldPosition)
  67. #path.remove(path[0])
  68. #mark_path(path, self)
  69. return new_parking, path2
  70. else:
  71. #print('cant find parking for', self)
  72. self.FSM.FSM.ToTransition('toEnterParallelPark')
  73. def get_lane_point(self):
  74. self.point = self.path[self.path_index]
  75. if self.point != self.last_lane_point:
  76. v = Vector([self.last_lane_point.x - self.point.x, self.last_lane_point.y - self.point.y, 0])
  77. tv = v.normalized()
  78. nv = Vector([-tv.y, tv.x, 0]) #rotate 90 degrees
  79. self.last_lane_point = self.lane_point
  80. self.lane_point = self.point + self.manager.lane_position * nv
  81. else:
  82. pass
  83. #print('skipping lane point')
  84. def update_point(self):
  85. #print(self.path_index, 'path index', len(self.path))
  86. if self.path_index >= (len(self.path) ):
  87. self.FSM.FSM.ToTransition('toEnterParallelPark')
  88. else:
  89. dist = self.obj.getDistanceTo(self.lane_point)
  90. self.point = self.path[self.path_index]
  91. if dist < 2.5:
  92. get_lane_point(self)
  93. if self.path_index > (len(self.path)):
  94. pass
  95. else:
  96. self.path_index += 1
  97. def align_to_point(self):
  98. #print('lane_point', self.lane_point)
  99. v = self.obj.getVectTo(self.lane_point)[1]
  100. v.z = 0
  101. self.obj.alignAxisToVect(v, 0, .1)
  102. def delta_to_vect(self):
  103. v = self.obj.getVectTo(self.lane_point)[1]
  104. delta = self.last_lane_point - self.lane_point
  105. delta = delta.cross(v)
  106. delta_mult = -.1
  107. mult = 1.0
  108. deltamove = delta[2] * delta_mult
  109. #check if in front
  110. local = self.obj.worldOrientation.inverted() * (self.lane_point - self.obj.worldPosition)
  111. f = deltamove * 50
  112. if local < 0:
  113. f *= -1
  114. self.obj.applyForce([0, f, 0], True)
  115. def apply_gas(self):
  116. if self.obj.linearVelocity.x < self.speed_targ:
  117. self.obj.applyForce([self.speed_inc, 0, 0], True)
  118. #====================================
  119. State = type("State", (object,), {})
  120. #====================================
  121. class State(object):
  122. def __init__(self, FSM):
  123. self.FSM = FSM
  124. self.timer = 0
  125. self.startTime = 0
  126. def Enter(self):
  127. self.timer = 0
  128. self.startTime = 0
  129. def Execute(self):
  130. print('Executing')
  131. def Exit(self):
  132. print('Exiting')
  133. #====================================
  134. class Example(State):
  135. def __init__(self,FSM):
  136. super(Example, self).__init__(FSM)
  137. def Enter(self):
  138. self.FSM.stateLife = 1
  139. self.FSM.owner.resumePhysics()
  140. self.FSM.owner.resumeDynamics()
  141. print('physics resumed')
  142. super(Example, self).Enter()
  143. def Execute(self):
  144. self.FSM.stateLife += 1
  145. print('doing example')
  146. def Exit(self):
  147. pass
  148. class ExitParallelPark(State):
  149. def __init__(self,FSM):
  150. super(ExitParallelPark, self).__init__(FSM)
  151. def Enter(self):
  152. self.FSM.stateLife = 1
  153. self.FSM.owner.obj.restorePhysics()
  154. self.FSM.owner.obj.restoreDynamics()
  155. self.FSM.owner.obj.linearVelocity = [0,0,0]
  156. # self.FSM.owner.target, self.FSM.owner.path = find_new_parking(self.FSM.owner)
  157. self.FSM.owner.path_index = 0
  158. self.FSM.owner.point = self.FSM.owner.path[self.FSM.owner.path_index]
  159. self.FSM.owner.target.status = 'targetted'
  160. self.FSM.owner.start_empty.status = 'available'
  161. #mark_path(self.FSM.owner.path, self.FSM.owner)
  162. print('physics resumed')
  163. super(ExitParallelPark, self).Enter()
  164. def Execute(self):
  165. self.FSM.stateLife += 1
  166. v = self.FSM.owner.obj.getVectTo(self.FSM.owner.path[0])
  167. self.FSM.owner.obj.alignAxisToVect(v[1], 0, .01)
  168. self.FSM.owner.obj.alignAxisToVect([0,0,1], 2, 1)
  169. if self.FSM.stateLife > 220:
  170. self.FSM.ToTransition('toNavigateToTarget')
  171. def Exit(self):
  172. pass
  173. #====================================
  174. class EnterParallelPark(State):
  175. def __init__(self,FSM):
  176. super(EnterParallelPark, self).__init__(FSM)
  177. def Enter(self):
  178. self.FSM.stateLife = 1
  179. #print('entering parallel park')
  180. self.FSM.owner.obj.worldPosition = self.FSM.owner.target.obj.worldPosition.copy()
  181. self.FSM.owner.obj.worldOrientation = self.FSM.owner.target.obj.worldOrientation.copy()
  182. self.FSM.owner.obj.applyMovement([0, -6, 0], True)
  183. self.FSM.owner.target.status = 'in_use'
  184. self.FSM.owner.obj.worldPosition.z += .9
  185. self.FSM.owner.active = False
  186. self.FSM.owner.start_empty = self.FSM.owner.target
  187. self.FSM.owner.last_point = self.FSM.owner.target.obj.worldPosition.copy()
  188. self.FSM.owner.lane_point = self.FSM.owner.target.obj.worldPosition.copy()
  189. self.FSM.owner.last_lane_point = self.FSM.owner.target.obj.worldPosition.copy()
  190. self.FSM.owner.point = self.FSM.owner.target.obj.worldPosition.copy()
  191. self.FSM.owner.path_index = 0
  192. self.FSM.owner.path = None
  193. #print('clearning last path')
  194. clear_markers(self)
  195. #self.FSM.owner.obj.suspendDynamics()
  196. #self.FSM.owner.obj.suspendPhysics()
  197. super(EnterParallelPark, self).Enter()
  198. def Execute(self):
  199. self.FSM.stateLife += 1
  200. if self.FSM.stateLife == 2:
  201. self.FSM.owner.manager.cars_active.remove(self.FSM.owner)
  202. self.FSM.owner.obj.suspendDynamics()
  203. self.FSM.owner.obj.suspendPhysics()
  204. def Exit(self):
  205. pass
  206. #====================================
  207. class NavigateToTarget(State):
  208. def __init__(self,FSM):
  209. super(NavigateToTarget, self).__init__(FSM)
  210. def Enter(self):
  211. self.FSM.stateLife = 1
  212. super(NavigateToTarget, self).Enter()
  213. def Execute(self):
  214. self.FSM.stateLife += 1
  215. update_point(self.FSM.owner)
  216. align_to_point(self.FSM.owner)
  217. align_to_road(self.FSM.owner)
  218. set_height(self.FSM.owner)
  219. delta_to_vect(self.FSM.owner)
  220. apply_gas(self.FSM.owner)
  221. #emergency exit
  222. if self.FSM.stateLife > 30 * 60:
  223. self.FSM.ToTransition('toEnterParallelPark')
  224. def Exit(self):
  225. pass
  226. #====================================
  227. class Activate(State):
  228. def __init__(self,FSM):
  229. super(Activate, self).__init__(FSM)
  230. def Enter(self):
  231. self.FSM.stateLife = 1
  232. super(Activate, self).Enter()
  233. def find_target(self):
  234. pass
  235. def drive_to_point(self):
  236. pass
  237. # if self.FSM.path:
  238. # ground_ray = get_ground_ray(self)
  239. # if ground_ray[0]:
  240. # set_height(self, ground_ray)
  241. # align_to_road(self, ground_ray)
  242. # v = self.FSM.owner.getVectTo(self.lane_point)
  243. # speed_force = 800.0
  244. # max_speed = 5.0
  245. # behind = False
  246. # local = self.FSM.owner.worldOrientation.inverted() * (self.lane_point - self.FSM.owner.worldPosition)
  247. # v2 = v[1].copy()
  248. # v2.z = 0
  249. # delta = self.last_lane_point - self.lane_point
  250. # delta = delta.cross(v[1])
  251. # delta_mult = -.1
  252. # mult = 1.0
  253. # backup_time = 20
  254. # #change max speed
  255. # if self.FSM.stateLife % 180 == 0:
  256. # print('change speed force')
  257. # self.speed_force = random.choice([max_speed * 1.3, max_speed * 1.6, max_speed * .8, max_speed * .6, max_speed])
  258. # if local.x > 0 and self.backup == 0:
  259. # if self.FSM.owner.linearVelocity.x < self.max_speed:
  260. # self.FSM.owner.applyForce([speed_force, 0, 0], True)
  261. # deltamove = delta[2] * delta_mult
  262. # #self.FSM.owner.applyMovement([0, deltamove, 0], True)
  263. # f = deltamove * 5000
  264. # self.FSM.owner.applyForce([0, f, 0], True)
  265. # v = self.FSM.owner.getVectTo(self.lane_point)
  266. # v2 = v[1].copy()
  267. # v2.z = 0
  268. # self.FSM.owner.alignAxisToVect(v2, 0, .05)
  269. # else:
  270. # if local.x < 0:
  271. # self.backup = backup_time
  272. # if self.backup > 0:
  273. # print('backing up')
  274. # v = self.FSM.owner.getVectTo(self.FSM.path[0])
  275. # v2 = v[1].copy()
  276. # v2.z = 0
  277. # self.FSM.owner.alignAxisToVect(v2, 0, .02)
  278. # if self.FSM.owner.linearVelocity.x > -max_speed / 2:
  279. # self.FSM.owner.applyForce([-speed_force * .8, 0, 0], True)
  280. # self.backup -= 1
  281. # dist = self.FSM.owner.getDistanceTo(self.lane_point)
  282. # if dist < 2.5 and (len(self.FSM.path) > 0):
  283. # #print(self.FSM.path,'this is the path')
  284. # #print('navmesh point removed')
  285. # self.last_point = self.point
  286. # self.last_lane_point = self.lane_point
  287. # self.FSM.path.remove(self.FSM.path[0])
  288. # if len(self.FSM.path) > 0:
  289. # self.point = self.FSM.path[0]
  290. # v = Vector([self.last_point.x - self.point.x, self.last_point.y - self.point.y, 0])
  291. # tv = v.normalized()
  292. # nv = Vector([-tv.y, tv.x, 0]) #rotate 90 degrees
  293. # self.lane_point = self.point + self.lane_position * nv
  294. # else:
  295. # self.point = None
  296. # if self.FSM.path == []:
  297. # self.FSM.curTarget = None
  298. # #progress
  299. # self.pos_his.append(self.FSM.owner.worldPosition.copy())
  300. # pos_his_len = len(self.pos_his)
  301. # if pos_his_len > 200:
  302. # sum_ = abs(self.FSM.owner.worldPosition.x - self.pos_his[0][0]) + abs(self.FSM.owner.worldPosition.y - self.pos_his[0][1])
  303. # #print(sum_, 'sum')
  304. # if sum_ < .05:
  305. # self.backup = backup_time
  306. # print('progress stopped')
  307. # del self.pos_his[0]
  308. def Execute(self):
  309. self.FSM.stateLife += 1
  310. def Exit(self):
  311. pass
  312. #====================================
  313. class RequestPath(State):
  314. def __init__(self,FSM):
  315. super(RequestPath, self).__init__(FSM)
  316. def Enter(self):
  317. self.FSM.stateLife = 1
  318. self.FSM.owner.target, self.FSM.owner.path = find_new_parking(self.FSM.owner)
  319. self.FSM.owner.path_index = 0
  320. super(RequestPath, self).Enter()
  321. def Execute(self):
  322. self.FSM.stateLife += 1
  323. #own['ped_astar'] = Astar('nav_points')
  324. #own['ped_astar'].get_path([5,-12,1] , [16,16,1])
  325. #print('doing example')
  326. def Exit(self):
  327. pass