Advertisement
Guest User

Untitled

a guest
May 24th, 2019
58
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.06 KB | None | 0 0
  1. #!/usr/bin/python3
  2. import time, math, random
  3. import sense_hat
  4.  
  5. """
  6.  
  7. Astro Bug!
  8.  
  9. A bug game. Eat the food! Avoid the enemies!
  10.  
  11. Modify the starting state in the `state` dict.
  12.  
  13. Note: Requires sense_hat version 2.2.0 or later.
  14.  
  15. """
  16.  
  17. starting_enemies = [ [4,6], [0,4] ]
  18.  
  19. state = { "bug_x" : 4,
  20. "bug_y" : 4,
  21. "bug_rgb" : (250,250,250),
  22. "food_x" : 2,
  23. "food_y" : 7,
  24. "food_rgb" : (0,255,50),
  25. "level" : 1,
  26. "enemies" : starting_enemies,
  27. "enemy_rgb" : (255,50,0) }
  28.  
  29. start_over_state = dict(state)
  30.  
  31. sense = sense_hat.SenseHat()
  32. sense.low_light = True
  33.  
  34. def setscreen():
  35. """Takes x and y vales and alters screen state. Does not
  36. modify state."""
  37. bug_x = state["bug_x"]
  38. bug_y = state["bug_y"]
  39. bug_rgb = state["bug_rgb"]
  40. food_x = state["food_x"]
  41. food_y = state["food_y"]
  42. food_rgb = state["food_rgb"]
  43. enemies = state["enemies"]
  44. enemy_rgb = state["enemy_rgb"]
  45.  
  46. if sense.low_light:
  47. zero = 8
  48. else:
  49. zero = 48
  50. brightness = 255 -zero
  51. sense.clear((50,100,150))
  52. sense.set_pixel(food_x, food_y, food_rgb)
  53. sense.set_pixel(bug_x, bug_y, bug_rgb)
  54. for e in enemies:
  55. sense.set_pixel(e[0], e[1], enemy_rgb)
  56.  
  57. def distance(x1, y1, x2, y2):
  58. """returns distance of two points"""
  59. return math.hypot(x2 - x1, y2 - y1)
  60.  
  61. def clip(pixels, nmin = 0, nmax = 255):
  62. """Ensures rgb values are between 0 and 255"""
  63. return tuple(max(min(nmax, n), nmin) for n in pixels)
  64.  
  65. def check_pos():
  66. """Checks for eating food and hitting enemies. Alters state but
  67. does not redraw screen. Call setscreen() after this."""
  68. global state
  69. bug_x = state["bug_x"]
  70. bug_y = state["bug_y"]
  71. food_x = state["food_x"]
  72. food_y = state["food_y"]
  73. level = state["level"]
  74. enemies = state["enemies"]
  75.  
  76. weaker = int(10 * (level/2))
  77. stronger = 10
  78. radius = 2.5
  79. fdist = distance(bug_x, bug_y, food_x, food_y)
  80.  
  81. for e in enemies:
  82. edist = distance(bug_x, bug_y, e[0], e[1])
  83. if edist == 0:
  84. # Hit an enemy; game over & reset
  85. sense.show_message("R.I.P. Bug, Level {0}".format(state["level"]))
  86. state = dict(start_over_state)
  87. return
  88.  
  89. if fdist > radius:
  90. # Bug is far away; grow weaker
  91. state["bug_rgb"] = clip([abs(i - weaker) for i in state["bug_rgb"]])
  92. elif fdist == 0.0:
  93. # Bug ate food and is healthy again
  94. state["bug_rgb"] = (255,255,255)
  95. state["level"] += 1
  96. state["enemies"] += [[random.randint(0,7), random.randint(0,7)]]
  97. sense.show_message(str(state["level"]))
  98. time.sleep(1)
  99. # Set food to new location that's not under the bug
  100. while True:
  101. state["food_x"] = random.randint(0,7)
  102. if state["food_x"] != state["bug_x"]:
  103. break
  104. while True:
  105. state["food_y"] = random.randint(0,7)
  106. if state["food_y"] != state["bug_y"]:
  107. break
  108. elif fdist < radius:
  109. # Bug is close; grow a little stronger
  110. state["bug_rgb"] = clip([abs(i + stronger) for i in state["bug_rgb"]])
  111.  
  112. def rand_step(xy):
  113. """Returns one iteration of a random walk of x,y coordinates"""
  114. x, y = xy
  115.  
  116. new_x = x + random.choice([-1,0,1])
  117. new_y = y + random.choice([-1,0,1])
  118. return [ 0 if new_x == 8 else 7 if new_x == -1 else new_x,\
  119. 0 if new_y == 8 else 7 if new_y == -1 else new_y]
  120.  
  121. def move_enemies():
  122. global state
  123. enemies = state["enemies"]
  124. reserved = [[state["bug_x"], state["bug_y"]],[state["food_x"], state["food_y"]]]
  125. new_enemies = []
  126. for e in enemies:
  127. while True:
  128. new_e = rand_step(e)
  129. if new_e not in reserved:
  130. break
  131. new_enemies.append(new_e)
  132. state["enemies"] = new_enemies
  133. setscreen()
  134.  
  135. def draw_bug(event):
  136. """Takes a keypress and redraws the screen"""
  137. global state
  138. if event.action == sense_hat.ACTION_RELEASED:
  139. # Ignore releases
  140. return
  141. elif event.direction == sense_hat.DIRECTION_UP:
  142. state["bug_x"] = state["bug_x"]
  143. state["bug_y"] = 7 if state["bug_y"] == 0 else state["bug_y"] - 1
  144. elif event.direction == sense_hat.DIRECTION_DOWN:
  145. state["bug_x"] = state["bug_x"]
  146. state["bug_y"] = 0 if state["bug_y"] == 7 else state["bug_y"] + 1
  147. elif event.direction == sense_hat.DIRECTION_RIGHT:
  148. state["bug_x"] = 0 if state["bug_x"] == 7 else state["bug_x"] + 1
  149. state["bug_y"] = state["bug_y"]
  150. elif event.direction == sense_hat.DIRECTION_LEFT:
  151. state["bug_x"] = 7 if state["bug_x"] == 0 else state["bug_x"] - 1
  152. state["bug_y"] = state["bug_y"]
  153.  
  154. # Check to see if anything should happen
  155. setscreen()
  156. check_pos()
  157. setscreen()
  158.  
  159. # Initial state
  160. setscreen()
  161. sense.set_pixel(state["bug_x"], state["bug_y"], state["bug_rgb"])
  162.  
  163. last_tick = round(time.time(),1) * 10
  164.  
  165. while True:
  166. # Enemies move faster in higher levels
  167. timer = 20 - (state["level"] % 20)
  168.  
  169. # Every so often, move enemies
  170. tick = round(time.time(),1) * 10
  171. if (tick % timer == 0) and (tick > last_tick):
  172. move_enemies()
  173. last_tick = tick
  174.  
  175. # Poll joystick for events. When they happen, redraw screen.
  176. for event in sense.stick.get_events():
  177. draw_bug(event)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement