当前位置:   article > 正文

球球大作战(Python)_python球球大作战

python球球大作战
  1. import pygame,random,sys,time,math
  2. from pygame.locals import *
  3. #定义窗口变量
  4. WORLDWIDTH =2500 #世界宽度
  5. WORLDHEIGHT =2500 #世界高度
  6. HALFWWIDTH = int(WORLDWIDTH//2)
  7. HALFWHEIGHT = int(WORLDHEIGHT//2)
  8. WIDTH = 500 #窗口宽度
  9. HEIGHT =500 #窗口高度
  10. CENTERWIDTH = int(WIDTH//2)
  11. CENTERHEIGHT = int(HEIGHT//2)
  12. FPS = 30 #帧率
  13. SPLITBASE = 0.5 #分裂基数
  14. pi = math.pi
  15. INITIALWEIGHT = 300 #初始重量
  16. #定义颜色变量
  17. LIGHTBLACK = (10,51,71)
  18. LIGHTBLUE = (51,102,205)
  19. WHITE = (255,255,255)
  20. BLACK = (0,0,0)
  21. RED = (255,0,0)
  22. #定义方向变量
  23. UP = 'up'
  24. DOWN = 'down'
  25. LEFT = 'left'
  26. RIGHT = 'right'
  27. #定义球球类
  28. class Ball():
  29. def __init__(self,xpos,ypos,weight,color): #定义球的x,y,重量,颜色
  30. self.xpos = xpos
  31. self.ypos = ypos
  32. self.radius = weightToRadius(weight)
  33. self.weight = weight
  34. self.speed = weightToSpeed(weight)
  35. self.color = color
  36. def move(self,direction): #小球移动
  37. rec = pygame.Rect(-HALFWWIDTH, -HALFWHEIGHT, WORLDWIDTH, WORLDHEIGHT)
  38. if direction == UP:
  39. if rec.top < self.ypos - self.radius: #限制在上边界以下
  40. self.ypos -= int(self.speed//20)
  41. elif direction == DOWN:
  42. if rec.bottom > self.ypos +self.radius:
  43. self.ypos += int(self.speed//20)
  44. elif direction == RIGHT:
  45. if rec.right > self.xpos + self.radius:
  46. self.xpos += int(self.speed//20)
  47. elif direction == LEFT:
  48. if rec.left < self.xpos - self.radius:
  49. self.xpos -= int(self.speed//20)
  50. def split(self,direction): #分裂小球函数
  51. newweight = math.floor((self.weight // 2) * SPLITBASE)
  52. newball = Ball(self.xpos, self.ypos, newweight, self.color)
  53. if direction == UP:
  54. #分裂流畅动画
  55. for i in range(10):
  56. newball.ypos -= round(0.2*self.radius)
  57. drawBall(newball)
  58. pygame.display.update()
  59. elif direction == DOWN:
  60. for i in range(10):
  61. newball.ypos += round(0.2*self.radius)
  62. drawBall(newball)
  63. pygame.display.update()
  64. elif direction == LEFT:
  65. for i in range(10):
  66. newball.xpos -= round(0.2*self.radius)
  67. drawBall(newball)
  68. pygame.display.update()
  69. elif direction == RIGHT:
  70. for i in range(10):
  71. newball.xpos += round(0.2*self.radius)
  72. drawBall(newball)
  73. pygame.display.update()
  74. self.setWeight(newweight) #分裂完后设置球的重量
  75. selfBalls.append(newball)
  76. def setWeight(self,newweight):
  77. self.weight = newweight
  78. self.speed = weightToSpeed(newweight)
  79. self.radius = weightToRadius(newweight)
  80. def eatFood(self): #吃食物
  81. global foodlist
  82. selfworldx = self.xpos
  83. selfworldy = self.ypos
  84. for food in foodlist:
  85. distance = math.sqrt((selfworldx-food.xpos)*(selfworldx-food.xpos)+(selfworldy-food.ypos)*(selfworldy-food.ypos))
  86. if distance < self.radius:
  87. self.setWeight(self.weight+food.weight)
  88. foodlist.remove(food)
  89. #食物类
  90. class Food():
  91. def __init__(self,xpos,ypos,weight,color,radius):
  92. self.xpos = xpos
  93. self.ypos = ypos
  94. self.weight = weight
  95. self.color = color
  96. self.radius = radius
  97. #其他球类
  98. class OtherBall():
  99. def __init__(self,xpos,ypos,weight,color):
  100. self.xpos = xpos
  101. self.ypos = ypos
  102. self.weight = weight
  103. self.radius = weightToRadius(weight)
  104. self.speed = weightToSpeed(weight)
  105. self.color = color
  106. self.direction = random.uniform(0,2*pi) #方向角度
  107. def eatFood(self):
  108. global foodlist
  109. for food in foodlist:
  110. distance = math.sqrt((self.xpos-food.xpos)**2+(self.ypos-food.ypos)**2)
  111. if distance < self.radius:
  112. self.setWeight(self.weight+food.weight)
  113. foodlist.remove(food)
  114. def setWeight(self,newweight):
  115. self.weight = newweight
  116. self.speed = weightToSpeed(newweight)
  117. self.radius = weightToRadius(newweight)
  118. def move(self):#使小球能在方框内移动
  119. rec = pygame.Rect(-HALFWWIDTH,-HALFWHEIGHT,WORLDWIDTH,WORLDHEIGHT)
  120. if rec.left>self.xpos:
  121. self.direction = pi - self.direction
  122. self.xpos += self.speed//10 #之前没有这句,小球在碰撞几次墙壁之后就会跳动着出界
  123. if rec.right<self.xpos:
  124. self.direction = pi - self.direction
  125. self.xpos -= self.speed//10
  126. if rec.top >self.ypos:
  127. self.direction = 2*pi-self.direction
  128. self.ypos += self.speed//10
  129. if rec.bottom < self.ypos:
  130. self.direction = 2*pi-self.direction
  131. self.ypos -= self.speed//10
  132. self.xpos += math.floor(math.cos(self.direction)*self.speed//40)
  133. self.ypos -= math.floor(math.sin(self.direction)*self.speed//40)
  134. def main():
  135. global FPSCLOCK,DISPLAYSURF,cameray,camerax,selfBalls,otherBalls,foodlist,rec #设置全局变量
  136. pygame.init()
  137. FPSCLOCK = pygame.time.Clock()
  138. DISPLAYSURF = pygame.display.set_mode((WIDTH,HEIGHT))
  139. camerax = -CENTERWIDTH
  140. cameray = -CENTERHEIGHT
  141. dirction = ''
  142. #定义小球列表
  143. selfBalls = []
  144. otherBalls = []
  145. foodlist = []
  146. for i in range(100): #创建其他小球
  147. xpos = random.randint(-HALFWWIDTH, HALFWWIDTH)
  148. ypos = random.randint(-HALFWHEIGHT, HALFWHEIGHT)
  149. otherb = OtherBall(xpos,ypos,INITIALWEIGHT*1.1,randomColor())
  150. otherBalls.append(otherb)
  151. for i in range(1000): #初始化创建100个食物
  152. createFood(foodlist)
  153. ball = Ball(0, 0, INITIALWEIGHT, randomColor()) #建立第一个小球
  154. selfBalls.append(ball)
  155. fontObj = pygame.font.Font('C:/Windows/Fonts/msyh.ttc',20) #字体对象,我用的是系统字体
  156. winfont = pygame.font.Font('C:/Windows/Fonts/msyh.ttc',36)
  157. allweight = 0
  158. while True:
  159. for event in pygame.event.get():
  160. if event.type == QUIT:
  161. time.sleep(3)
  162. exit()
  163. if event.type == KEYUP: #响应键盘
  164. if event.key == K_w:
  165. dirction = UP
  166. elif event.key == K_s:
  167. dirction = DOWN
  168. elif event.key == K_d:
  169. dirction = RIGHT
  170. elif event.key == K_a:
  171. dirction = LEFT
  172. elif event.key == K_j: #分裂
  173. count = len(selfBalls)
  174. if count < 16:
  175. for i in range(count):
  176. if selfBalls[i].weight > 20:
  177. selfBalls[i].split(dirction)
  178. DISPLAYSURF.fill(LIGHTBLACK) #背景填充
  179. rec = pygame.Rect(-(camerax + HALFWHEIGHT), -(cameray + HALFWHEIGHT), WORLDWIDTH, WORLDHEIGHT) #边界矩形
  180. drawBorder(rec)
  181. text = '重量为:'+str(allweight)+' 敌人还剩:'+str(len(otherBalls))
  182. displayText(text,fontObj,WHITE,200,20)
  183. if len(foodlist)<500: #当食物数量小于500时,增加食物
  184. createFood(foodlist)
  185. drawFoods(foodlist)
  186. if len(otherBalls)>0: #当其他球还有的时候进行吃球的操作
  187. balleatBall()
  188. if len(otherBalls)==0 or allweight>=1000000: #胜利条件
  189. displayText('恭喜你!最终你胖到了'+str(allweight)+'斤',winfont,RED,CENTERWIDTH,CENTERHEIGHT)
  190. pygame.display.update()
  191. time.sleep(3)
  192. pygame.quit()
  193. if len(selfBalls)==0:
  194. displayText('你被吃了~继续努力吧~',winfont,RED,CENTERWIDTH,CENTERHEIGHT)
  195. pygame.display.update()
  196. time.sleep(3)
  197. pygame.quit()
  198. allweight = 0
  199. for b in selfBalls: #得到所有重量和移动所有球
  200. allweight += b.weight
  201. b.move(dirction)
  202. for b in otherBalls: #移动其他的球
  203. b.move()
  204. b.eatFood()
  205. drawBalls(selfBalls)
  206. camerax = selfBalls[0].xpos - CENTERWIDTH
  207. cameray = selfBalls[0].ypos - CENTERHEIGHT
  208. for ball in selfBalls:
  209. ball.eatFood()
  210. drawBalls(otherBalls)
  211. if len(selfBalls)>=2:
  212. unite()
  213. pygame.display.update()
  214. FPSCLOCK.tick(FPS)
  215. def displayText(text,fontObj,textcolor,xpos,ypos): #显示字函数
  216. textsurf = fontObj.render(text, True, textcolor)
  217. textRect = textsurf.get_rect()
  218. textRect.center = (xpos, ypos)
  219. DISPLAYSURF.blit(textsurf, textRect)
  220. def balleatBall(): #我方球吃其他球,本游戏不设置其他球互吃
  221. global selfBalls,otherBalls
  222. for ball1 in selfBalls:
  223. for ball2 in otherBalls:
  224. distance = math.sqrt((ball1.xpos - ball2.xpos) ** 2 + (ball1.ypos - ball2.ypos) ** 2)
  225. if distance < (ball1.radius + ball2.radius) / 2:
  226. if ball1.radius > ball2.radius + 3:
  227. ball1.setWeight(ball1.weight + ball2.weight)
  228. otherBalls.remove(ball2)
  229. elif ball1.radius+3 < ball2.radius :
  230. ball2.setWeight(ball1.weight + ball2.weight)
  231. selfBalls.remove(ball1)
  232. def unite(): #联合两个小球
  233. global selfBalls
  234. for ball1 in selfBalls:
  235. for ball2 in selfBalls:
  236. if ball1!=ball2:
  237. distance = math.sqrt((ball1.xpos-ball2.xpos)**2+(ball1.ypos-ball2.ypos)**2)
  238. if distance<(ball1.radius+ball2.radius)/2:
  239. ball1.setWeight(ball1.weight+ball2.weight)
  240. selfBalls.remove(ball2)
  241. def createFood(foodlist):
  242. xpos = random.randint(-HALFWWIDTH,HALFWWIDTH)
  243. ypos = random.randint(-HALFWHEIGHT,HALFWHEIGHT)
  244. weight = 10 #每个食物的重量
  245. radius = 3 #每个食物的半径
  246. newfood = Food(xpos,ypos,weight,randomColor(),radius)
  247. foodlist.append(newfood)
  248. def drawFoods(foodlist):
  249. global camerax,cameray
  250. for food in foodlist:
  251. pygame.draw.circle(DISPLAYSURF, food.color, ((food.xpos - camerax), (food.ypos - cameray)), food.radius)
  252. def drawBalls(balls): #画所有球
  253. global camerax,cameray
  254. for ball in balls:
  255. pos = (ball.xpos-camerax,ball.ypos-cameray)
  256. radius = ball.radius
  257. color = ball.color
  258. pygame.draw.circle(DISPLAYSURF,color,pos,radius)
  259. def weightToSpeed(weight):#重量转换为速度
  260. if weight < 8000:
  261. return math.floor(-0.02*weight+200)
  262. elif weight >=8000:
  263. return 40 #最低速度为40
  264. def weightToRadius(weight): #将小球的重量转化为半径
  265. if weight < 100:
  266. return math.floor(0.1*weight + 10)
  267. elif weight>=100:
  268. return math.floor(2*math.sqrt(weight))
  269. def drawBorder(rec): #画边界
  270. borderthick = 5
  271. pygame.draw.rect(DISPLAYSURF,WHITE,rec,borderthick)
  272. recleft = (rec[0]-CENTERWIDTH,rec[1]-CENTERHEIGHT,CENTERWIDTH,WORLDHEIGHT+HEIGHT)
  273. recright = (rec[0]+WORLDWIDTH,rec[1]-CENTERHEIGHT,CENTERWIDTH,WORLDHEIGHT+HEIGHT)
  274. rectop = (rec[0],rec[1]-CENTERHEIGHT,WORLDWIDTH,CENTERHEIGHT)
  275. recbottom = (rec[0],rec[1]+WORLDHEIGHT,WORLDWIDTH,CENTERHEIGHT)
  276. pygame.draw.rect(DISPLAYSURF,BLACK,recleft,0)
  277. pygame.draw.rect(DISPLAYSURF, BLACK, rectop, 0)
  278. pygame.draw.rect(DISPLAYSURF, BLACK, recright, 0)
  279. pygame.draw.rect(DISPLAYSURF, BLACK, recbottom, 0)
  280. def drawBall(Obj):
  281. pygame.draw.circle(DISPLAYSURF,Obj.color,(Obj.xpos,Obj.ypos),Obj.radius)
  282. def randomColor(): #随机获取颜色
  283. return (random.randint(1,255),random.randint(1,255),random.randint(1,255))
  284. if __name__ =="__main__":
  285. main()

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家自动化/article/detail/386670?site
推荐阅读
相关标签
  

闽ICP备14008679号