Advertisement
Guest User

python space game 4-20-2018

a guest
Apr 20th, 2018
76
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 9.51 KB | None | 0 0
  1. import math
  2.  
  3. class Field:
  4. def __init__(self, width, height):
  5. self.width, self.height = width, height
  6. self.chars = [[' '] * height for i in range(width)]
  7.  
  8. def fill(self, x1=' ', x2=-1, y1=-1, y2=-1, char=' '):
  9. if(type(x1) is str):
  10. self.chars = [[x1] * self.height for i in range(self.width)]
  11. elif(x2 > x1 and y2 > y1):
  12. for x in range(x1, x2):
  13. for y in range(y1, y2):
  14. self.chars[x][y] = char
  15.  
  16. def overlay(self, x, y, source):
  17. for tx in range(x, min(self.width, source.width + x)):
  18. for ty in range(y, min(self.height, source.height + y)):
  19. if(source.chars[tx-x][ty-y] != ' '):
  20. self.chars[tx][ty] = source.chars[tx-x][ty-y]
  21.  
  22. def draw(self, x, y, source):
  23. for tx in range(x, min(self.width, source.width + x)):
  24. for ty in range(y, min(self.height, source.height + y)):
  25. self.chars[tx][ty] = source.chars[tx-x][ty-y]
  26.  
  27. def draw_string(self, x, y, string):
  28. for tx in range(x, min(x + len(string), self.width)):
  29. self.chars[tx][y] = string[tx-x]
  30.  
  31. def draw_string_centered(self, x1, x2, y, string):
  32. x = (x2 - x1 - len(string)) // 2 + x1
  33. for tx in range(x, min(x + len(string), self.width - x)):
  34. self.chars[tx][y] = string[tx-x]
  35.  
  36. def draw_box(self, x1, x2, y1, y2, charset='-|O'):
  37. if(len(charset) == 2):
  38. charset = charset[0] + charset[0] + charset[1]
  39. self.fill(x1, x2, y1, y1+1, charset[0])
  40. self.fill(x1, x2, y2, y2+1, charset[0])
  41. self.fill(x1, x1+1, y1, y2, charset[1])
  42. self.fill(x2, x2+1, y1, y2, charset[1])
  43. for cp in [(x1, y1), (x1, y2), (x2, y1), (x2, y2)]:
  44. self.draw_string(cp[0], cp[1], charset[2])
  45.  
  46. def __str__(self):
  47. output = ''
  48. for y in range(self.height):
  49. output += ''.join([self.chars[i][y] for i in range(self.width)]) + '\n'
  50. return '\n' * 40 + output[:-1]
  51.  
  52. def create_coordinate_border(in_width, in_height=0, title='', content=None):
  53. if(type(in_width) is Field):
  54. if(type(in_height) is str):
  55. title = in_height
  56. return create_coordinate_border(in_width.width, in_width.height, title=title, content=in_width)
  57.  
  58. SPACING = 5
  59.  
  60. side_margin = len(str(in_height)) + 1
  61. width = side_margin * 2 + in_width
  62. height = 4 + in_height
  63. if(title):
  64. height += 2
  65. output = Field(width, height)
  66. output.fill(' ')
  67.  
  68. top_start = 0
  69. if(title):
  70. output.draw_box(side_margin-1, side_margin+in_width, 0, 2)
  71. output.draw_string_centered(side_margin, side_margin + in_width, 1, title)
  72. top_start += 2
  73.  
  74. output.draw_box(side_margin-1, side_margin+in_width, top_start, top_start+2)
  75. output.draw_box(side_margin-1, side_margin+in_width, top_start+2, height-1)
  76. for x in range(0, in_width, SPACING):
  77. output.draw_string(x - len(str(x)) + side_margin + 1, top_start + 1, str(x))
  78. output.draw_string(x + side_margin, top_start + 2, '+')
  79.  
  80. for y in range(0, in_height, SPACING):
  81. output.draw_string(side_margin - len(str(y)) - 1, y + top_start + 3, str(y))
  82. output.draw_string(side_margin + in_width + 1, y + top_start + 3, str(y))
  83. output.draw_string(side_margin - 1, y + top_start + 3, '+')
  84. output.draw_string(side_margin + in_width, y + top_start + 3, '+')
  85.  
  86. if(content):
  87. output.draw(side_margin, 3 + top_start, content)
  88.  
  89. return output
  90.  
  91. from math import ceil
  92.  
  93. def render_tabulated_grid(width, items=[]):
  94. if(len(items) == 0):
  95. return Field(width, 0)
  96. maxlen = max([len(i) + 2 for i in items])
  97. tablen = min([i for i in range(maxlen, width) if width % i <= 4])
  98. columns = width // tablen
  99. height = ceil(len(items) / columns)
  100. output = Field(width, height)
  101. for y in range(0, height):
  102. for x in range(0, columns):
  103. index = x + y * columns
  104. if(index < len(items)):
  105. output.draw_string(x * tablen, y, items[index])
  106. return output
  107.  
  108. class Interface:
  109. def __init__(self):
  110. self.output = None
  111.  
  112. def get_controls(self):
  113. return []
  114.  
  115. def get_title(self):
  116. return ''
  117.  
  118. def get_status(self):
  119. return Field(0, 0)
  120.  
  121. def render(self):
  122. window_content = self.get_main()
  123. title = self.get_title()
  124. controls = self.get_controls()
  125. status_content = self.get_status()
  126.  
  127. width = window_content.width + 2
  128. inset = 0
  129. height = window_content.height + 2
  130. if(title):
  131. height += 2
  132. control_pane = render_tabulated_grid(width - 2, controls)
  133. height += status_content.height + 1 + control_pane.height + 1
  134. output = Field(width, height)
  135.  
  136. y = 0
  137. if(title):
  138. output.draw_box(0, width-1, y, y+2)
  139. output.draw_string((width - len(title)) // 2, 1, title)
  140. y += 2
  141. output.draw_box(0, width-1, y, window_content.height+1+y)
  142. output.draw(1, y+1, window_content)
  143. y += window_content.height + 1
  144. output.draw_box(0, width-1, y, y+status_content.height+1)
  145. output.draw(1, y + 1, status_content)
  146. y += status_content.height + 1
  147. output.draw_box(0, width-1, y, y+control_pane.height+1)
  148. output.draw(1, y + 1, control_pane)
  149.  
  150. self.output = output
  151.  
  152. def update(self, delta_time):
  153. pass
  154.  
  155. def on_key(self, key_code):
  156. pass
  157.  
  158. def __str__(self):
  159. if(not self.output):
  160. self.render()
  161. return str(self.output)
  162.  
  163. from random import randint
  164.  
  165. '''
  166. useful unicode characters:
  167. ֍ ܔ ௬ ௐ ౠ གྷ ࿐ ᑐ ᗘ
  168. '''
  169.  
  170. class UniverseObject:
  171. def __init__(self, char):
  172. self.char = char
  173. self.explored = False
  174.  
  175. def __str__(self):
  176. if(self.explored):
  177. return self.char
  178. else:
  179. return '?'
  180.  
  181. class EmptySpace(UniverseObject):
  182. def __init__(self):
  183. super().__init__(' ')
  184.  
  185. class Star(UniverseObject):
  186. def __init__(self):
  187. super().__init__('*')
  188.  
  189. UNIVERSE_WIDTH = 121
  190. UNIVERSE_HEIGHT = 41
  191. universe = [[EmptySpace() for j in range(UNIVERSE_HEIGHT)] for i in range(UNIVERSE_WIDTH)]
  192. for x in range(UNIVERSE_WIDTH):
  193. for y in range(UNIVERSE_HEIGHT):
  194. # 30% chance of a star
  195. if(randint(0, 100) <= 10):
  196. universe[x][y] = Star()
  197.  
  198. class Ship:
  199. def __init__(self, x, y):
  200. self.x, self.y = x, y
  201.  
  202. def __str__(self):
  203. return '+'
  204.  
  205. def explore(self, radius):
  206. ir = int(radius)
  207. for x in range(-ir*2, ir*2+1):
  208. for y in range(-ir, ir+1):
  209. if(math.sqrt((x/2)**2 + y**2) <= radius + 0.5):
  210. print(x, y)
  211. print(x + self.x, y + self.y)
  212. universe[x+self.x][y+self.y].explored = True
  213.  
  214. def short_range_scan(self):
  215. self.explore(1)
  216.  
  217. def long_range_scan(self):
  218. self.explore(6)
  219.  
  220. def fly_to(self, x, y):
  221. self.x, self.y = x, y
  222. print(x, y)
  223. self.short_range_scan()
  224.  
  225. ship = Ship(60, 20)
  226. ship.long_range_scan()
  227.  
  228. crosshair = Field(3, 3)
  229. crosshair.draw_string(0, 0, '\\ /')
  230. crosshair.draw_string(0, 2, '/ \\')
  231.  
  232. SCREEN_WIDTH = 121
  233. SCREEN_HEIGHT = 41
  234. class StarMap(Interface):
  235. def __init__(self):
  236. super().__init__()
  237. self.cx, self.cy = 0, 0
  238.  
  239. def get_title(self):
  240. return 'UNIVERSE MAP'
  241.  
  242. def get_controls(self):
  243. return ['WASD: Navigate', 'SHIFT: Navigate Faster', 'SPACE: Fly To', 'Z: Long Range Scan', 'Q: Exit Game']
  244.  
  245. def get_main(self):
  246. global universe
  247. f = Field(SCREEN_WIDTH, SCREEN_HEIGHT)
  248. for y in range(SCREEN_HEIGHT):
  249. for x in range(SCREEN_WIDTH):
  250. ux = (x + self.cx + UNIVERSE_WIDTH) % UNIVERSE_WIDTH
  251. uy = (y + self.cy + UNIVERSE_HEIGHT) % UNIVERSE_HEIGHT
  252. if(universe[ux][uy]):
  253. f.draw_string(x, y, str(universe[ux][uy]))
  254. f.overlay(SCREEN_WIDTH // 2 - 1, SCREEN_HEIGHT // 2 - 1, crosshair)
  255. f.draw_string(ship.x - self.cx, ship.y - self.cy, str(ship))
  256. return f
  257.  
  258. def on_key(self, key):
  259. global going, ship
  260. key = key.decode('ascii')
  261. amount = [1, 10][key != key.lower()]
  262. key = key.lower()
  263. if(key == 'w'):
  264. self.cy -= amount
  265. elif(key == 'a'):
  266. self.cx -= amount
  267. elif(key == 's'):
  268. self.cy += amount
  269. elif(key == 'd'):
  270. self.cx += amount
  271. elif(key == ' '):
  272. ship.fly_to(self.cx + SCREEN_WIDTH // 2, self.cy + SCREEN_HEIGHT // 2)
  273. elif(key == 'z'):
  274. ship.long_range_scan()
  275. elif(key == 'q'):
  276. going = False
  277. self.cx = (self.cx + UNIVERSE_WIDTH) % UNIVERSE_WIDTH
  278. self.cy = (self.cy + UNIVERSE_HEIGHT) % UNIVERSE_HEIGHT
  279.  
  280. def get_status(self):
  281. return render_tabulated_grid(81, ['Hull: 100%', 'Fuel: 100%'])
  282.  
  283. from msvcrt import getch as getkey
  284. from time import sleep, time
  285.  
  286. cint = StarMap()
  287. print(cint)
  288. last = time()
  289.  
  290. going = True
  291. while going:
  292. kc = getkey()
  293. #print(kc)
  294. #continue
  295. if(kc == b'\xff'):
  296. sleep(0.02)
  297. continue
  298. else:
  299. cint.on_key(kc)
  300. cint.update(time() - last)
  301. last = time()
  302. cint.render()
  303. print(cint)
  304. sleep(0.02)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement