python-如何使球在pygame中从三角形弹回?

前端之家收集整理的这篇文章主要介绍了python-如何使球在pygame中从三角形弹回? 前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

您好,我是一个非常新的程序员,我正在尝试使球从45度三角形弹起.这是我的代码

这个程序使球碰到窗户的侧面时会弹跳,但是我不知道如何使它弹起三角形.

  1. import pygame # importing the pygame
  2. import sys # importing the system libraries
  3. import time # importing timer
  4. import random
  5. from pygame.locals import * # importing the locals functions from the pygame library set
  6. pygame.init() # the function from pygame that initializes all relevant variable
  7. # setting length and width
  8. width = 500
  9. length = 300
  10. # colour variables
  11. WHITE = (255,255,255)
  12. BLUE = (0,255)
  13. # importing ball image
  14. ball = pygame.image.load('ball.png')
  15. ballRect = ball.get_rect()
  16. ballRect.left = 300
  17. ballRect.right = 300
  18. # setting speed
  19. x_speed = 2
  20. y_speed = 2
  21. # setting window size
  22. WINDOW = pygame.display.set_mode((width,length))# setting the size of the window
  23. pygame.display.update()
  24. # loop
  25. while True:
  26. for event in pygame.event.get():
  27. if event.type == QUIT:
  28. pygame.quit()
  29. sys.exit()
  30. ballRect = ballRect.move(x_speed,y_speed)
  31. WINDOW.fill(WHITE) # changing screen colour to white
  32. WINDOW.blit(ball,ballRect) # printing the ball to screen
  33. pygame.display.update()
  34. pygame.display.flip()
  35. time.sleep(0.002) # to slow down the speed of bouncing
  36. pygame.display.update()
  37. # if the left side of ballRect is in a position less than 0,or the right side of ballRect is greater than 500
  38. if ballRect.left < 0 or ballRect.right > (width):
  39. x_speed = x_speed * -1
  40. # if the top of ballRect is in a position less than 0,or the bottom of ballRect is greater than the length
  41. elif ballRect.top < 0 or ballRect.bottom > (length):
  42. y_speed = y_speed * -1
  43. pygame.display.update()

我没有画三角形,因为我不知道要去哪里,但是我希望球会像碰到窗户两侧时那样从三角形弹起.任何帮助将是巨大的!

最佳答案
有趣的任务.可以通过一个简单的列表定义一个三角形:

  1. triangle = [(250,220),(400,300),(100,300)]

三角形可以由pygame.draw.polygon()绘制

  1. pygame.draw.polygon(WINDOW,RED,triangle,0)

使用pygame.math.Vector2定义球的位置和运动矢量:

  1. ballvec = pygame.math.Vector2(1,1)
  2. ballpos = pygame.math.Vector2(150,250)
  3. balldiameter = 64

创建一个函数,执行碰撞检测.该功能必须检测球是否命中线.如果击中线,则球的运动矢量将反映在线上.
该线由2个点(lp0,lp1)表示,它们是pygame.math.Vector2对象.
球的位置(pt)和运动矢量(dir)也是pygame.math.Vector2个对象:

  1. def isect(lp0,lp1,pt,dir,radius):
  2. # direction vector of the line
  3. l_dir = (lp1 - lp0).normalize()
  4. # normal vector to the line
  5. nv = pygame.math.Vector2(-l_dir[1],l_dir[0])
  6. # distance to line
  7. d = (lp0-pt).dot(nv)
  8. # intersection point on endless line
  9. ptX = pt + nv * d
  10. # test if the ball hits the line
  11. if abs(d) > radius or dir.dot(ptX-pt) <= 0:
  12. return dir
  13. if (ptX-lp0).dot(l_dir) < 0 or (ptX-lp1).dot(l_dir) > 0:
  14. return dir
  15. # reflect the direction vector on the line (like a billiard ball)
  16. r_dir = dir.reflect(nv)
  17. return r_dir

将窗口矩形和三角形追加到线列表中.蚀刻线由2 pygame.math.Vector2个对象的元组表示:

  1. # add screen rect
  2. screen_rect = [(0,0),(0,(500,0)]
  3. for i in range(len(screen_rect)):
  4. p0,p1 = screen_rect[i],screen_rect[(i+1) % len(screen_rect)]
  5. line_list.append((pygame.math.Vector2(p0[0],p0[1]),pygame.math.Vector2(p1[0],p1[1])))
  6. # add red trianlge
  7. triangle = [(250,300)]
  8. for i in range(len(triangle)):
  9. p0,p1 = triangle[i],triangle[(i+1) % len(triangle)]
  10. line_list.append((pygame.math.Vector2(p0[0],p1[1])))

遍历直线的循环中进行碰撞检测.如果球撞到线,则运动矢量将替换为反射的运动矢量:

  1. for line in line_list:
  2. ballvec = isect(*line,ballpos,ballvec,balldiameter/2)

最后更新球的位置和球矩形:

  1. ballpos = ballpos + ballvec
  2. ballRect.x,ballRect.y = ballpos[0]-ballRect.width/2,ballpos[1]-ballRect.height/2

请参阅示例代码,在该示例中,我将建议的更改应用于原始代码.我的球图像的尺寸为64×64.球直径必须设置为此尺寸(球直径= 64):

  1. import pygame # importing the pygame
  2. import sys # importing the system libraries
  3. import time # importing timer
  4. import random
  5. from pygame.locals import * # importing the locals functions from the pygame library set
  6. pygame.init() # the function from pygame that initializes all relevant variable
  7. # setting length and width
  8. width = 500
  9. length = 300
  10. # colour variables
  11. WHITE = (255,255)
  12. RED = (255,0)
  13. GRAY = (128,128,128)
  14. # importing ball image
  15. ball = pygame.image.load("ball.png")
  16. ballRect = ball.get_rect()
  17. # setting ball data
  18. ballvec = pygame.math.Vector2(1.5,1.5)
  19. ballpos = pygame.math.Vector2(150,250)
  20. balldiameter = 64
  21. # setting window size
  22. WINDOW = pygame.display.set_mode((width,length))# setting the size of the window
  23. def isect(lp0,l_dir[0])
  24. # distance to line
  25. d = (lp0-pt).dot(nv)
  26. # intersection point on endless line
  27. ptX = pt + nv * d
  28. # test if the ball hits the line
  29. if abs(d) > radius or dir.dot(ptX-pt) <= 0:
  30. return dir
  31. if (ptX-lp0).dot(l_dir) < 0 or (ptX-lp1).dot(l_dir) > 0:
  32. return dir
  33. # reflect the direction vector on the line (like a billiard ball)
  34. r_dir = dir.reflect(nv)
  35. return r_dir
  36. line_list = []
  37. # add screen rect
  38. screen_rect = [(0,p1[1])))
  39. # add blue triangle
  40. triangle2 = [(250,80),0)]
  41. for i in range(len(triangle2)):
  42. p0,p1 = triangle2[i],triangle2[(i+1) % len(triangle2)]
  43. line_list.append((pygame.math.Vector2(p0[0],p1[1])))
  44. # loop
  45. while True:
  46. for event in pygame.event.get():
  47. if event.type == QUIT:
  48. pygame.quit()
  49. sys.exit()
  50. WINDOW.fill(GRAY)
  51. pygame.draw.polygon(WINDOW,0)
  52. pygame.draw.polygon(WINDOW,BLUE,triangle2,0)
  53. WINDOW.blit(ball,ballRect)
  54. pygame.display.update()
  55. pygame.display.flip()
  56. time.sleep(0.002) # to slow down the speed of bouncing
  57. pygame.display.update()
  58. for line in line_list:
  59. ballvec = isect(*line,balldiameter/2)
  60. ballpos = ballpos + ballvec
  61. ballRect.x,ballpos[1]-ballRect.height/2
  62. pygame.display.update()

猜你在找的Python相关文章