Legend of the Gold Box... A game written for the LOWREZJAM 2018 game jam
No puede seleccionar más de 25 temas Los temas deben comenzar con una letra o número, pueden incluir guiones ('-') y pueden tener hasta 35 caracteres de largo.

690 líneas
26KB

  1. from . import gbe
  2. import pygame
  3. class NodeInterface(gbe.nodes.NodeSurface):
  4. def __init__(self, name="Interface", parent=None):
  5. try:
  6. gbe.nodes.NodeSurface.__init__(self, name, parent)
  7. except gbe.nodes.NodeError as e:
  8. raise e
  9. def on_render(self):
  10. size = self.resolution
  11. self.draw_rect((0, 0, size[0], 10), pygame.Color(255,0,0,128), 1)
  12. self.draw_circle((int(size[0]/2), int(size[1]/2)), 16, pygame.Color(255,0,0,255), 2, pygame.Color(0,255,0,255))
  13. class NodeGameMap(gbe.nodes.Node2D):
  14. def __init__(self, name="GameMap", parent=None):
  15. try:
  16. gbe.nodes.Node2D.__init__(self, name, parent)
  17. except gbe.nodes.NodeError as e:
  18. raise e
  19. self._renderMode = 0 # 0 = Top-down | 1 = Perspective
  20. self._layer = {}
  21. self._currentLayer = ""
  22. self._res = {
  23. "env_src":"",
  24. "env":None,
  25. "h_index":0,
  26. "g_index":0,
  27. "wall_src":"",
  28. "walls":None,
  29. "wall_index":-1,
  30. "door_index":-1
  31. }
  32. self._topdown = {
  33. "size":8, # Pixels square
  34. "wall_color":pygame.Color(255, 255, 255),
  35. "blocked_color":pygame.Color(255, 0, 0)
  36. }
  37. self._cellpos = [0,0]
  38. self._orientation = "n"
  39. @property
  40. def environment_source(self):
  41. return self._res["env_src"]
  42. @property
  43. def wall_source(self):
  44. return self._res["wall_src"]
  45. @property
  46. def layer_count(self):
  47. return len(self._layer)
  48. @property
  49. def current_layer(self):
  50. return self._currentLayer
  51. @property
  52. def current_layer_width(self):
  53. if self._currentLayer != "":
  54. return self._layer[self._currentLayer]["w"]
  55. return 0
  56. @property
  57. def current_layer_height(self):
  58. if self._currentLayer != "":
  59. return self._layer[self._currentLayer]["h"]
  60. return 0
  61. @property
  62. def layer_names(self):
  63. names = []
  64. for key in self._layer:
  65. names.append(names)
  66. return names
  67. @property
  68. def orientation(self):
  69. return self._orientation
  70. @property
  71. def cell_position(self):
  72. return (self._cellpos[0], self._cellpos[1])
  73. def set_resources(self, env_src, wall_src):
  74. res = self.resource
  75. if env_src != "" and env_src != self._res["env_src"]:
  76. if res.is_valid("json", env_src):
  77. if not res.has("json", env_src):
  78. res.store("json", env_src)
  79. e = res.get("json", env_src)
  80. if e is not None and e() is not None:
  81. self._res["env_src"] = env_src
  82. self._res["env"] = e
  83. # NOTE: Making a lot of assumptions to the structural validity of the data file.
  84. isrc1 = e().data["horizon"]["src"]
  85. isrc2 = e().data["ground"]["src"]
  86. if res.is_valid("graphic", isrc1) and res.is_valid("graphic", isrc2):
  87. if not res.has("graphic", isrc1):
  88. res.store("graphic", isrc1)
  89. if not res.has("graphic", isrc2):
  90. res.store("graphic", isrc2)
  91. if wall_src != "" and wall_src != self._res["wall_src"]:
  92. if res.is_valid("json", wall_src):
  93. if not res.has("json", wall_src):
  94. print("Storing resource {}".format(wall_src))
  95. res.store("json", wall_src)
  96. w = res.get("json", wall_src)
  97. if w is not None and w() is not None:
  98. self._res["wall_src"] = wall_src
  99. self._res["walls"] = w
  100. # NOTE: I'm making a lot of assumptions to the structural validity of the data file, but...
  101. imgsrc = w().data["src"]
  102. if res.is_valid("graphic", imgsrc):
  103. if not res.has("graphic", imgsrc):
  104. res.store("graphic", imgsrc)
  105. else:
  106. print("Failed to get JSON instance {}".format(wall_src))
  107. else:
  108. print("Invalid JSON {}".format(wall_src))
  109. def add_layer(self, name, w, h):
  110. if name == "" or name in self._layer:
  111. return
  112. self._layer[name] = {
  113. "w":w,
  114. "h":h,
  115. "cells":[]
  116. }
  117. for c in range(0, w*h):
  118. self._layer[name]["cells"].append({
  119. "h":0, # Horizon
  120. "g":0, # Ground
  121. "n":[-1, False, -1, None], # North Wall | [<graphic index, -1 = None>, <blocking>, <door index, -1 = None, 0 = closed, 1=open>, <door target>]
  122. "s":[-1, False, -1, None], # South Wall
  123. "e":[-1, False, -1, None], # East Wall
  124. "w":[-1, False, -1, None], # West Wall
  125. })
  126. if self._currentLayer == "":
  127. self._currentLayer = name
  128. def set_active_layer(self, name, x=0, y=0):
  129. if name == "" or not (name in self._layers):
  130. return
  131. layer = self._layers[name]
  132. if x >= 0 and x < layer["w"] and y >= 0 and y < layer["h"]:
  133. self._currentLayer = name
  134. self._cellpos = [x,y]
  135. def set_cell_env(self, x, y, ceiling=-1, ground=-1):
  136. if self._currentLayer == "":
  137. return
  138. layer = self._layer[self._currentLayer]
  139. if x >= 0 and x < layer["w"] and y >= 0 and y < layer["h"]:
  140. index = (y * layer["w"]) + x
  141. cell = layer["cells"]
  142. if ceiling >= 0:
  143. cell[index]["c"] = ceiling
  144. if ground >= 0:
  145. cell[index]["g"] = ground
  146. def fill_cell_env(self, x1, y1, x2, y2, ceiling=-1, ground=-1):
  147. if self._currentLayer == "":
  148. return
  149. for y in range(y1, y2+1):
  150. for x in range(x1, x2+1):
  151. self.set_cell_env(x, y, ceiling, ground)
  152. def set_cell_face(self, x, y, face, gi=-2, blocking=None):
  153. if self._currentLayer == "" or not (face == "n" or face == "s" or face == "w" or face == "e"):
  154. return
  155. layer = self._layer[self._currentLayer]
  156. if x >= 0 and x < layer["w"] and y >= 0 and y < layer["h"]:
  157. index = (y * layer["w"]) + x
  158. cell = layer["cells"]
  159. if gi <= -2:
  160. gi = self._res["wall_index"]
  161. if gi >= -1:
  162. cell[index][face][0] = gi
  163. if blocking is not None:
  164. cell[index][face][1] = (blocking == True)
  165. else:
  166. if gi == -1: # If gi = -1, there is no wall, so, by default, there is no blocking.
  167. cell[index][face][1] = False
  168. else: # Otherwise, blocking is assumed :)
  169. cell[index][face][1] = True
  170. elif blocking is not None:
  171. blocking = (blocking == True) # Forcing a boolean
  172. cell[index][face][1] = blocking
  173. def next_wall(self):
  174. if self._res["walls"] is not None:
  175. w = self._res["walls"]()
  176. if w is not None:
  177. windex = self._res["wall_index"] + 1
  178. if windex >= len(w.data["walls"]):
  179. windex = -1
  180. self._res["wall_index"] = windex
  181. print("Next Wall Index: {}".format(windex))
  182. def prev_wall(self):
  183. if self._res["walls"] is not None:
  184. w = self._res["walls"]()
  185. if w is not None:
  186. windex = self._res["wall_index"] - 1
  187. if windex < -1:
  188. windex = len(w.data["walls"]) - 1
  189. self._res["wall_index"] = windex
  190. print("Prev Wall Index: {}".format(windex))
  191. def turn_left(self):
  192. onum = self._d_s2n(self._orientation)
  193. onum -= 1
  194. if onum < 0:
  195. onum = 3
  196. self._orientation = self._d_n2s(onum)
  197. def turn_right(self):
  198. onum = self._d_s2n(self._orientation)
  199. onum += 1
  200. if onum > 3:
  201. onum = 0
  202. self._orientation = self._d_n2s(onum)
  203. def move_to(self, x, y):
  204. if x >= 0 and x < self.current_layer_width and y >= 0 and y < self.current_layer_height:
  205. self._cellpos = [x, y]
  206. def move_forward(self, ignore_passible=False):
  207. if ignore_passible or self.is_passible(self._cellpos[0], self._cellpos[1], self._orientation):
  208. x = self._cellpos[0]
  209. y = self._cellpos[1]
  210. if self._orientation == "n":
  211. y -= 1
  212. elif self._orientation == "e":
  213. x += 1
  214. elif self._orientation == "s":
  215. y += 1
  216. elif self._orientation == "w":
  217. x -= 1
  218. self.move_to(x, y)
  219. def move_backward(self, ignore_passible=False):
  220. orient = self._orientation
  221. if self._orientation == "n":
  222. self._orientation = "s"
  223. elif self._orientation == "s":
  224. self._orientation = "n"
  225. elif self._orientation == "e":
  226. self._orientation = "w"
  227. elif self._orientation == "w":
  228. self._orientation = "e"
  229. self.move_forward(ignore_passible)
  230. self._orientation = orient
  231. def is_passible(self, x, y, d):
  232. """
  233. Returns true if it's possible to move forward from the x, y map position in the direction given.
  234. d - 0 = North, 1 = East, 2 = South, 3 = West
  235. """
  236. if self._currentLayer == "" or d < 0 or d >= 4:
  237. return False
  238. layer = self._layer[self._currentLayer]
  239. if x >= 0 and x < layer["w"] and y >= 0 and y < layer["h"]:
  240. index = (y * layer["w"]) + x
  241. d = self._d_n2s(d)
  242. return not layer["cells"][index][d][1]
  243. return False
  244. def toggle_render_mode(self):
  245. if self._renderMode == 0:
  246. self._renderMode = 1
  247. else:
  248. self._renderMode = 0
  249. def set_render_mode(self, mode):
  250. if mode <= 0:
  251. self._renderMode = 0
  252. else:
  253. self._renderMode = 1
  254. def get_render_mode(self):
  255. return self._renderMode
  256. def _d_n2s(self, d): # _(d)irection_(n)umber_to_(s)tring
  257. if d == 0:
  258. return "n"
  259. elif d == 1:
  260. return "e"
  261. elif d == 2:
  262. return "s"
  263. elif d == 3:
  264. return "w"
  265. return ""
  266. def _d_s2n(self, d):
  267. if d == "n":
  268. return 0
  269. elif d == "e":
  270. return 1
  271. elif d == "s":
  272. return 2
  273. elif d == "w":
  274. return 3
  275. return -1
  276. def _indexFromPos(self, x, y):
  277. if x >= 0 and x < self.current_layer_width and y >= 0 and y < self.current_layer_height:
  278. return (y * self.current_layer_width) + x
  279. return -1
  280. def _getCell(self, x, y):
  281. if x >=- 0 and x < self.current_layer_width and y >= 0 and y < self.current_layer_height:
  282. index = self._indexFromPos(x, y)
  283. return self._layer[self._currentLayer]["cells"][index]
  284. return None
  285. def _getOrientVec(self):
  286. if self._orientation == "n":
  287. return (0, -1)
  288. elif self._orientation == "s":
  289. return (0, 1)
  290. elif self._orientation == "e":
  291. return (1, 0)
  292. elif self._orientation == "w":
  293. return (-1, 0)
  294. return (0,0)
  295. def _RenderTopDown(self):
  296. cell_size = self._topdown["size"]
  297. size = self.resolution
  298. pos = self._cellpos
  299. lsize = (self.current_layer_width, self.current_layer_height)
  300. hcells = int(size[0] / cell_size)
  301. vcells = int(size[1] / cell_size)
  302. cx = pos[0] - int(hcells * 0.5)
  303. cy = pos[1] - int(vcells * 0.5)
  304. ry = -int(cell_size*0.5)
  305. for j in range(0, vcells+1):
  306. y = cy + j
  307. if y >= 0 and y < lsize[1]:
  308. rx = -int(cell_size*0.5)
  309. for i in range(0, hcells+1):
  310. x = cx + i
  311. if x >= 0 and x < lsize[0]:
  312. cell = self._getCell(x, y)
  313. if cell["n"][0] >= 0:
  314. self.draw_rect((rx, ry, cell_size, 2), self._topdown["wall_color"], 0, self._topdown["wall_color"])
  315. if cell["e"][0] >= 0:
  316. self.draw_rect((rx+(cell_size-2), ry, 2, cell_size), self._topdown["wall_color"], 0, self._topdown["wall_color"])
  317. if cell["s"][0] >= 0:
  318. self.draw_rect((rx, ry+(cell_size-2), cell_size, 2), self._topdown["wall_color"], 0, self._topdown["wall_color"])
  319. if cell["w"][0] >= 0:
  320. self.draw_rect((rx, ry, 2, cell_size), self._topdown["wall_color"], 0, self._topdown["wall_color"])
  321. if cell["n"][1] == True:
  322. self.draw_lines([(rx+1, ry+1), (rx+(cell_size-2), ry+1)], self._topdown["blocked_color"], 1)
  323. if cell["e"][1] == True:
  324. self.draw_lines([(rx+(cell_size-2), ry+1), (rx+(cell_size-2), ry+(cell_size-2))], self._topdown["blocked_color"], 1)
  325. if cell["s"][1] == True:
  326. self.draw_lines([(rx+1, ry+(cell_size-2)), (rx+(cell_size-2), ry+(cell_size-2))], self._topdown["blocked_color"], 1)
  327. if cell["w"][1] == True:
  328. self.draw_lines([(rx+1, ry+1), (rx+1, ry+(cell_size-2))], self._topdown["blocked_color"], 1)
  329. rx += cell_size
  330. ry += cell_size
  331. def _RenderPersFar(self, pos, size, o, orr, orl, wdat, wsurf):
  332. ovec = self._getOrientVec()
  333. fx = pos[0] + (ovec[0]*2)
  334. fy = pos[1] + (ovec[1]*2)
  335. fcell = self._getCell(fx, fy)
  336. if fcell == None:
  337. return # If we can't see the cell directly ahead, the other's won't be visible either!
  338. lcell = llcell = rcell = rrcell = None
  339. if ovec[0] == 0: # Facing North/South
  340. lcell = self._getCell(fx + ovec[1], fy)
  341. llcell = self._getCell(fx + (ovec[1]*2), fy)
  342. rcell = self._getCell(fx - ovec[1], fy)
  343. rrcell = self._getCell(fx - (ovec[1]*2), fy)
  344. else: # Facing East/West
  345. lcell = self._getCell(fx, fy + ovec[0])
  346. llcell = self._getCell(fx, fy + (ovec[0]*2))
  347. rcell = self._getCell(fx, fy - ovec[0])
  348. rrcell = self._getCell(fx, fy - (ovec[0]*2))
  349. hsw = int(size[0]*0.5)
  350. hsh = int(size[1]*0.5)
  351. # Rendering from edges to center
  352. if llcell is not None:
  353. if llcell[o][0] >= 0:
  354. rect = wdat["walls"][llcell[o][0]]["f_far"]
  355. hw = int(rect[2]*0.5)
  356. hh = int(rect[3]*0.5)
  357. self.draw_image(wsurf, (0, hsh-hh), (rect[0], rect[1], hw, rect[3]))
  358. if rrcell is not None:
  359. if rrcell[o][0] >= 0:
  360. rect = wdat["walls"][rrcell[o][0]]["f_far"]
  361. hw = int(rect[2]*0.5)
  362. hh = int(rect[3]*0.5)
  363. self.draw_image(wsurf, (size[0]-hw, hsh-hh), (rect[0]+hw, rect[1], hw, rect[3]))
  364. if lcell is not None:
  365. if lcell[o][0] >= 0:
  366. rect = wdat["walls"][lcell[o][0]]["f_far"]
  367. hw = int(rect[2]*0.5)
  368. hh = int(rect[3]*0.5)
  369. self.draw_image(wsurf, (hw, hsh-hh), (rect[0], rect[1], rect[2], rect[3]))
  370. if lcell[orl][0] >= 0:
  371. rect = wdat["walls"][lcell[orl][0]]["s_far"]
  372. lsurf = pygame.transform.flip(wsurf.subsurface(rect), True, False)
  373. hh = int(rect[3]*0.5)
  374. self.draw_image(lsurf, (0, hsh-hh))
  375. if rcell is not None:
  376. if rcell[o][0] >= 0:
  377. rect = wdat["walls"][rcell[o][0]]["f_far"]
  378. hw = int(rect[2]*0.5)
  379. hh = int(rect[3]*0.5)
  380. self.draw_image(wsurf, (size[0]-(rect[2]+hw), hsh-hh), (rect[0], rect[1], rect[2], rect[3]))
  381. if rcell[orr][0] >= 0:
  382. rect = wdat["walls"][rcell[orr][0]]["s_far"]
  383. hh = int(rect[3]*0.5)
  384. self.draw_image(wsurf, (size[0]-rect[2], hsh-hh), (rect[0], rect[1], rect[2], rect[3]))
  385. # Rendering the main cell!!
  386. frect = None # This will be used to place walls
  387. if fcell[o][0] >= 0:
  388. frect = wdat["walls"][fcell[o][0]]["f_far"]
  389. hw = int(frect[2]*0.5)
  390. hh = int(frect[3]*0.5)
  391. self.draw_image(wsurf, (hsw-hw, hsh-hh), (frect[0], frect[1], frect[2], frect[3]))
  392. if fcell[orl][0] >= 0:
  393. rect = wdat["walls"][fcell[orl][0]]["s_far"]
  394. if frect is None:
  395. # Kinda cheating in that it's known that all walls are the same size.
  396. frect = wdat["walls"][fcell[orl][0]]["f_far"]
  397. hw = int(frect[2]*0.5)
  398. lsurf = pygame.transform.flip(wsurf.subsurface(rect), True, False)
  399. self.draw_image(lsurf, (hsw-(hw+rect[2]), hsh-int(rect[3]*0.5)))
  400. if fcell[orr][0] >= 0:
  401. rect = wdat["walls"][fcell[orr][0]]["s_far"]
  402. if frect is None:
  403. frect = wdat["walls"][fcell[orr][0]]["f_far"]
  404. hw = int(frect[2]*0.5)
  405. self.draw_image(wsurf, (hsw+hw, hsh-int(rect[3]*0.5)), (rect[0], rect[1], rect[2], rect[3]))
  406. def _RenderPersMid(self, pos, size, o, orr, orl, wdat, wsurf):
  407. ovec = self._getOrientVec()
  408. fx = pos[0] + ovec[0]
  409. fy = pos[1] + ovec[1]
  410. fcell = self._getCell(fx, fy)
  411. if fcell == None:
  412. return # If we can't see the cell directly ahead, the other's won't be visible either!
  413. lcell = rcell = None
  414. if ovec[0] == 0: # Facing North/South
  415. lcell = self._getCell(fx + ovec[1], fy)
  416. rcell = self._getCell(fx - ovec[1], fy)
  417. else: # Facing East/West
  418. lcell = self._getCell(fx, fy + ovec[0])
  419. rcell = self._getCell(fx, fy - ovec[0])
  420. hsw = int(size[0]*0.5)
  421. hsh = int(size[1]*0.5)
  422. # Render from outside inwards!
  423. if lcell is not None:
  424. if lcell[o][0] >= 0:
  425. rect = wdat["walls"][lcell[o][0]]["f_mid"]
  426. hw = int(rect[2]*0.5)
  427. hh = int(rect[3]*0.5)
  428. self.draw_image(wsurf, (0, hsh-hh), (rect[0]+hw, rect[1], int(rect[2]*0.5), rect[3]))
  429. if rcell is not None:
  430. if rcell[o][0] >= 0:
  431. rect = wdat["walls"][rcell[o][0]]["f_mid"]
  432. hw = int(rect[2]*0.5)
  433. hh = int(rect[3]*0.5)
  434. self.draw_image(wsurf, (size[0]-hw, hsh-hh), (rect[0], rect[1], hw, rect[3]))
  435. # Rendering the main cell!!
  436. frect = None # This will be used to place walls
  437. if fcell[o][0] >= 0:
  438. frect = wdat["walls"][fcell[o][0]]["f_mid"]
  439. hw = int(frect[2]*0.5)
  440. hh = int(frect[3]*0.5)
  441. self.draw_image(wsurf, (hsw-hw, hsh-hh), (frect[0], frect[1], frect[2], frect[3]))
  442. if fcell[orl][0] >= 0:
  443. rect = wdat["walls"][fcell[orl][0]]["s_mid"]
  444. if frect is None:
  445. # Kinda cheating in that it's known that all walls are the same size.
  446. frect = wdat["walls"][fcell[orl][0]]["f_mid"]
  447. hw = int(frect[2]*0.5)
  448. lsurf = pygame.transform.flip(wsurf.subsurface(rect), True, False)
  449. self.draw_image(lsurf, (hsw-(hw+rect[2]), hsh-int(rect[3]*0.5)))
  450. if fcell[orr][0] >= 0:
  451. rect = wdat["walls"][fcell[orr][0]]["s_mid"]
  452. if frect is None:
  453. frect = wdat["walls"][fcell[orr][0]]["f_mid"]
  454. hw = int(frect[2]*0.5)
  455. self.draw_image(wsurf, (hsw+hw, hsh-int(rect[3]*0.5)), (rect[0], rect[1], rect[2], rect[3]))
  456. def _RenderPersClose(self, pos, size, o, orr, orl, cell, wdat, wsurf):
  457. fcell = self._getCell(pos[0], pos[1])
  458. hsw = int(size[0]*0.5)
  459. hsh = int(size[1]*0.5)
  460. # Rendering the main cell!!
  461. frect = None # This will be used to place walls
  462. if fcell[o][0] >= 0:
  463. idx = fcell[o][0]
  464. frect = wdat["walls"][idx]["f_close"]
  465. hw = int(frect[2]*0.5)
  466. hh = int(frect[3]*0.5)
  467. self.draw_image(wsurf, (hsw-hw, hsh-hh), (frect[0], frect[1], frect[2], frect[3]))
  468. if fcell[orl][0] >= 0:
  469. idx = fcell[orl][0]
  470. rect = wdat["walls"][idx]["s_close"]
  471. if frect is None:
  472. # Kinda cheating in that it's known that all walls are the same size.
  473. frect = wdat["walls"][idx]["f_close"]
  474. hw = int(frect[2]*0.5)
  475. lsurf = pygame.transform.flip(wsurf.subsurface(rect), True, False)
  476. self.draw_image(lsurf, (hsw-(hw+rect[2]), hsh-int(rect[3]*0.5)))
  477. if fcell[orr][0] >= 0:
  478. idx = fcell[orr][0]
  479. rect = wdat["walls"][idx]["s_close"]
  480. if frect is None:
  481. frect = wdat["walls"][idx]["f_close"]
  482. hw = int(frect[2]*0.5)
  483. self.draw_image(wsurf, (hsw+hw, hsh-int(rect[3]*0.5)), (rect[0], rect[1], rect[2], rect[3]))
  484. def _RenderPerspective(self):
  485. # Getting ALL of the core resources
  486. rm = self.resource
  487. edat = self._res["env"]
  488. wdat = self._res["walls"]
  489. if edat is None or wdat is None or edat() is None or wdat() is None:
  490. return
  491. edat = edat().data
  492. wdat = wdat().data
  493. ehsurf = rm.get("graphic", edat["horizon"]["src"])
  494. egsurf = rm.get("graphic", edat["ground"]["src"])
  495. wsurf = rm.get("graphic", wdat["src"])
  496. if ehsurf is None or egsurf is None or wsurf is None:
  497. return
  498. if ehsurf() is None or egsurf() is None or wsurf() is None:
  499. return
  500. px = self._cellpos[0]
  501. py = self._cellpos[1]
  502. orl = self._d_n2s(max(0, self._d_s2n(self._orientation) - 1))
  503. orr = self._d_n2s((self._d_s2n(self._orientation) + 1)%4)
  504. cell = self._getCell(px, py)
  505. # First, output the ground and horizon
  506. # TODO Later, perhaps cut the horizon and ground to represent each possible cell instead of just the current one?
  507. self.draw_image(ehsurf(), (0,0), edat["horizon"]["defs"][cell["h"]]["rect"])
  508. self.draw_image(egsurf(), (0,32), edat["ground"]["defs"][cell["g"]]["rect"])
  509. # Rendering the rest
  510. size = self.resolution
  511. self._RenderPersFar((px, py), size, self._orientation, orr, orl, wdat, wsurf())
  512. self._RenderPersMid((px, py), size, self._orientation, orr, orl, wdat, wsurf())
  513. self._RenderPersClose((px, py), size, self._orientation, orr, orl, cell, wdat, wsurf())
  514. def on_render(self):
  515. if self._renderMode == 0:
  516. self._RenderTopDown()
  517. else:
  518. self._RenderPerspective()
  519. class NodeMapEditor(gbe.nodes.Node2D):
  520. def __init__(self, name="MapEditor", parent=None):
  521. try:
  522. gbe.nodes.Node2D.__init__(self, name, parent)
  523. except gbe.nodes.Node2D as e:
  524. raise e
  525. self._last_orientation = ""
  526. self._size = 0
  527. self._thickness = 1
  528. self._color = pygame.Color(255,255,255)
  529. self._points = None
  530. self.pointer_size = 4
  531. def _getPoints(self, size):
  532. p = self.parent
  533. o = p.orientation
  534. points = self._points[o]
  535. hw = int(size[0]*0.5)
  536. hh = int(size[1]*0.5)
  537. return (
  538. (points[0][0] + hw, points[0][1] + hh),
  539. (points[1][0] + hw, points[1][1] + hh),
  540. (points[2][0] + hw, points[2][1] + hh)
  541. )
  542. @property
  543. def pointer_size(self):
  544. return self._size
  545. @pointer_size.setter
  546. def pointer_size(self, size):
  547. if not isinstance(size, int):
  548. raise TypeError("Size expected to be an integer.")
  549. if size <= 0:
  550. raise ValueError("Size must be greater than zero.")
  551. if size != self._size:
  552. self._size = size
  553. # Now updating all of the pointer... ummm... points
  554. hs = max(1, int(size * 0.5))
  555. self._points = {
  556. "n": ((0,-hs),(hs,hs),(-hs,hs)),
  557. "s": ((0,hs),(hs,-hs),(-hs,-hs)),
  558. "e": ((-hs,hs),(hs,0),(-hs,-hs)),
  559. "w": ((hs,hs),(-hs,0),(hs,-hs))
  560. }
  561. def set_color(self, color):
  562. if isinstance(color, (tuple, list)):
  563. clen = len(color)
  564. if clen == 3 or clen == 4:
  565. iscolor = lambda v : isinstance(v, int) and v >= 0 and v < 256
  566. if iscolor(color[0]) and iscolor(color[1]) and iscolor(color[2]):
  567. if clen == 3:
  568. self._color = pygame.Color(color[0], color[1], color[2])
  569. elif clen == 4 and iscolor(color[3]):
  570. self._color = pygame.Color(color[0], color[1], color[2], color[3])
  571. def get_color(self):
  572. return (self._color.r, self._color.g, self._color.b, self._color.a)
  573. def on_start(self):
  574. self.listen("KEYPRESSED", self.on_keypressed)
  575. def on_pause(self):
  576. self.unlisten("KEYPRESSED", self.on_keypressed)
  577. def on_keypressed(self, event, data):
  578. p = self.parent
  579. if p is None or not isinstance(p, NodeGameMap):
  580. return
  581. if data["key_name"] == "escape":
  582. self.emit("QUIT")
  583. if data["key_name"] == "tab":
  584. p.toggle_render_mode()
  585. elif data["key_name"] == "w":
  586. p.move_forward(True)
  587. elif data["key_name"] == "s":
  588. p.move_backward(True)
  589. elif data["key_name"] == "a":
  590. p.turn_left()
  591. elif data["key_name"] == "d":
  592. p.turn_right()
  593. elif data["key_name"] == "space":
  594. o = p.orientation
  595. cpos = p.cell_position
  596. p.set_cell_face(cpos[0], cpos[1], o)
  597. elif data["key_name"] == "e":
  598. p.next_wall()
  599. elif data["key_name"] == "q":
  600. p.prev_wall()
  601. def on_render(self):
  602. size = self.resolution
  603. self.draw_lines(self._getPoints(size), self._color, self._thickness, True)