Legend of the Gold Box... A game written for the LOWREZJAM 2018 game jam
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

690 lines
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)