Legend of the Gold Box... A game written for the LOWREZJAM 2018 game jam
Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

719 lines
27KB

  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. ovec = self._getOrientVec()
  461. lcell = rcell = None
  462. if ovec[0] == 0: # Facing North/South
  463. lcell = self._getCell(pos[0] + ovec[1], pos[1])
  464. rcell = self._getCell(pos[0] - ovec[1], pos[1])
  465. else: # Facing East/West
  466. lcell = self._getCell(pos[0], pos[1] - ovec[0])
  467. rcell = self._getCell(pos[0], pos[1] + ovec[0])
  468. hsw = int(size[0]*0.5)
  469. hsh = int(size[1]*0.5)
  470. # Render from outside inwards!
  471. if lcell is not None:
  472. if lcell[o][0] >= 0:
  473. rect = wdat["walls"][lcell[o][0]]["f_close"]
  474. hw = int(rect[2]*0.5)
  475. hh = int(rect[3]*0.5)
  476. rw = hsw - hw
  477. self.draw_image(wsurf, (0, hsh-hh), (rect[0]+(rect[2]-rw), rect[1], rw, rect[3]))
  478. if rcell is not None:
  479. if rcell[o][0] >= 0:
  480. rect = wdat["walls"][rcell[o][0]]["f_close"]
  481. hw = int(rect[2]*0.5)
  482. hh = int(rect[3]*0.5)
  483. rw = hsw - hw
  484. self.draw_image(wsurf, (size[0]-rw, hsh-hh), (rect[0], rect[1], rw, rect[3]))
  485. # Rendering the main cell!!
  486. frect = None # This will be used to place walls
  487. if fcell[o][0] >= 0:
  488. idx = fcell[o][0]
  489. frect = wdat["walls"][idx]["f_close"]
  490. hw = int(frect[2]*0.5)
  491. hh = int(frect[3]*0.5)
  492. self.draw_image(wsurf, (hsw-hw, hsh-hh), (frect[0], frect[1], frect[2], frect[3]))
  493. if fcell[orl][0] >= 0:
  494. idx = fcell[orl][0]
  495. rect = wdat["walls"][idx]["s_close"]
  496. if frect is None:
  497. # Kinda cheating in that it's known that all walls are the same size.
  498. frect = wdat["walls"][idx]["f_close"]
  499. hw = int(frect[2]*0.5)
  500. lsurf = pygame.transform.flip(wsurf.subsurface(rect), True, False)
  501. self.draw_image(lsurf, (hsw-(hw+rect[2]), hsh-int(rect[3]*0.5)))
  502. if fcell[orr][0] >= 0:
  503. idx = fcell[orr][0]
  504. rect = wdat["walls"][idx]["s_close"]
  505. if frect is None:
  506. frect = wdat["walls"][idx]["f_close"]
  507. hw = int(frect[2]*0.5)
  508. self.draw_image(wsurf, (hsw+hw, hsh-int(rect[3]*0.5)), (rect[0], rect[1], rect[2], rect[3]))
  509. def _RenderPerspective(self):
  510. # Getting ALL of the core resources
  511. rm = self.resource
  512. edat = self._res["env"]
  513. wdat = self._res["walls"]
  514. if edat is None or wdat is None or edat() is None or wdat() is None:
  515. return
  516. edat = edat().data
  517. wdat = wdat().data
  518. ehsurf = rm.get("graphic", edat["horizon"]["src"])
  519. egsurf = rm.get("graphic", edat["ground"]["src"])
  520. wsurf = rm.get("graphic", wdat["src"])
  521. if ehsurf is None or egsurf is None or wsurf is None:
  522. return
  523. if ehsurf() is None or egsurf() is None or wsurf() is None:
  524. return
  525. oshift = lambda d: d if d >= 0 and d < 4 else (0 if d > 3 else 3)
  526. px = self._cellpos[0]
  527. py = self._cellpos[1]
  528. orl = self._d_n2s(oshift(self._d_s2n(self._orientation) - 1))
  529. orr = self._d_n2s(oshift(self._d_s2n(self._orientation) + 1))
  530. cell = self._getCell(px, py)
  531. # First, output the ground and horizon
  532. # TODO Later, perhaps cut the horizon and ground to represent each possible cell instead of just the current one?
  533. self.draw_image(ehsurf(), (0,0), edat["horizon"]["defs"][cell["h"]]["rect"])
  534. self.draw_image(egsurf(), (0,32), edat["ground"]["defs"][cell["g"]]["rect"])
  535. # Rendering the rest
  536. size = self.resolution
  537. self._RenderPersFar((px, py), size, self._orientation, orr, orl, wdat, wsurf())
  538. self._RenderPersMid((px, py), size, self._orientation, orr, orl, wdat, wsurf())
  539. self._RenderPersClose((px, py), size, self._orientation, orr, orl, cell, wdat, wsurf())
  540. def on_render(self):
  541. if self._renderMode == 0:
  542. self._RenderTopDown()
  543. else:
  544. self._RenderPerspective()
  545. class NodeMapEditor(gbe.nodes.Node2D):
  546. def __init__(self, name="MapEditor", parent=None):
  547. try:
  548. gbe.nodes.Node2D.__init__(self, name, parent)
  549. except gbe.nodes.Node2D as e:
  550. raise e
  551. self._last_orientation = ""
  552. self._size = 0
  553. self._thickness = 1
  554. self._color = pygame.Color(255,255,255)
  555. self._points = None
  556. self.pointer_size = 4
  557. def _getPoints(self, size):
  558. p = self.parent
  559. o = p.orientation
  560. points = self._points[o]
  561. hw = int(size[0]*0.5)
  562. hh = int(size[1]*0.5)
  563. return (
  564. (points[0][0] + hw, points[0][1] + hh),
  565. (points[1][0] + hw, points[1][1] + hh),
  566. (points[2][0] + hw, points[2][1] + hh)
  567. )
  568. @property
  569. def pointer_size(self):
  570. return self._size
  571. @pointer_size.setter
  572. def pointer_size(self, size):
  573. if not isinstance(size, int):
  574. raise TypeError("Size expected to be an integer.")
  575. if size <= 0:
  576. raise ValueError("Size must be greater than zero.")
  577. if size != self._size:
  578. self._size = size
  579. # Now updating all of the pointer... ummm... points
  580. hs = max(1, int(size * 0.5))
  581. self._points = {
  582. "n": ((0,-hs),(hs,hs),(-hs,hs)),
  583. "s": ((0,hs),(hs,-hs),(-hs,-hs)),
  584. "e": ((-hs,hs),(hs,0),(-hs,-hs)),
  585. "w": ((hs,hs),(-hs,0),(hs,-hs))
  586. }
  587. def set_color(self, color):
  588. if isinstance(color, (tuple, list)):
  589. clen = len(color)
  590. if clen == 3 or clen == 4:
  591. iscolor = lambda v : isinstance(v, int) and v >= 0 and v < 256
  592. if iscolor(color[0]) and iscolor(color[1]) and iscolor(color[2]):
  593. if clen == 3:
  594. self._color = pygame.Color(color[0], color[1], color[2])
  595. elif clen == 4 and iscolor(color[3]):
  596. self._color = pygame.Color(color[0], color[1], color[2], color[3])
  597. def get_color(self):
  598. return (self._color.r, self._color.g, self._color.b, self._color.a)
  599. def on_start(self):
  600. self.listen("KEYPRESSED", self.on_keypressed)
  601. def on_pause(self):
  602. self.unlisten("KEYPRESSED", self.on_keypressed)
  603. def on_keypressed(self, event, data):
  604. p = self.parent
  605. if p is None or not isinstance(p, NodeGameMap):
  606. return
  607. if data["key_name"] == "escape":
  608. self.emit("QUIT")
  609. if data["key_name"] == "tab":
  610. p.toggle_render_mode()
  611. elif data["key_name"] == "w":
  612. p.move_forward(True)
  613. elif data["key_name"] == "s":
  614. p.move_backward(True)
  615. elif data["key_name"] == "a":
  616. p.turn_left()
  617. elif data["key_name"] == "d":
  618. p.turn_right()
  619. elif data["key_name"] == "space":
  620. o = p.orientation
  621. cpos = p.cell_position
  622. p.set_cell_face(cpos[0], cpos[1], o)
  623. elif data["key_name"] == "e":
  624. p.next_wall()
  625. elif data["key_name"] == "q":
  626. p.prev_wall()
  627. def on_render(self):
  628. size = self.resolution
  629. self.draw_lines(self._getPoints(size), self._color, self._thickness, True)