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.

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)