Advertisement
Guest User

Untitled

a guest
Jan 27th, 2025
26
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.51 KB | None | 0 0
  1. import pygame
  2. import math
  3.  
  4. # Initialize Pygame
  5. pygame.init()
  6.  
  7. # Screen dimensions
  8. screen_width = 800
  9. screen_height = 600
  10. screen = pygame.display.set_mode((screen_width, screen_height))
  11. pygame.display.set_caption("Bouncing Yellow Ball in Rotating Square")
  12.  
  13. # Colors
  14. black = (0, 0, 0)
  15. white = (255, 255, 255)
  16. yellow = (255, 255, 0)
  17. light_gray = (200, 200, 200)
  18.  
  19. # Ball properties
  20. ball_radius = 20
  21. ball_x = screen_width // 2
  22. ball_y = screen_height // 2
  23. ball_speed_x = 5
  24. ball_speed_y = 3
  25.  
  26. # Square properties
  27. square_size = 300
  28. square_center_x = screen_width // 2
  29. square_center_y = screen_height // 2
  30. square_rotation_angle = 0
  31. square_rotation_speed = 0.5 # Degrees per frame
  32.  
  33. # Function to rotate a point around a center
  34. def rotate_point(point, center, angle_degrees):
  35. angle_radians = math.radians(angle_degrees)
  36. cos_theta = math.cos(angle_radians)
  37. sin_theta = math.sin(angle_radians)
  38. x = point[0] - center[0]
  39. y = point[1] - center[1]
  40. rotated_x = x * cos_theta - y * sin_theta
  41. rotated_y = x * sin_theta + y * cos_theta
  42. return [rotated_x + center[0], rotated_y + center[1]]
  43.  
  44. # Function to get square vertices based on rotation
  45. def get_square_vertices(center_x, center_y, size, angle):
  46. half_size = size / 2
  47. vertices = [
  48. [-half_size, -half_size],
  49. [half_size, -half_size],
  50. [half_size, half_size],
  51. [-half_size, half_size]
  52. ]
  53. rotated_vertices = []
  54. for vertex in vertices:
  55. rotated_vertices.append(rotate_point([vertex[0] + center_x, vertex[1] + center_y], [center_x, center_y], angle))
  56. return rotated_vertices
  57.  
  58. # Function to check collision with a square edge and bounce (more robust and no sticking)
  59. def check_square_collision_and_bounce(ball_x, ball_y, ball_radius, ball_speed_x, ball_speed_y, vertices):
  60. next_ball_x = ball_x + ball_speed_x
  61. next_ball_y = ball_y + ball_speed_y
  62. new_ball_speed_x = ball_speed_x
  63. new_ball_speed_y = ball_speed_y
  64.  
  65. for i in range(4):
  66. p1 = vertices[i]
  67. p2 = vertices[(i + 1) % 4]
  68.  
  69. dx = p2[0] - p1[0]
  70. dy = p2[1] - p1[1]
  71.  
  72. # Vector from p1 to ball center
  73. ball_vec_x = next_ball_x - p1[0]
  74. ball_vec_y = next_ball_y - p1[1]
  75.  
  76. # Project ball vector onto edge normal (normalized perpendicular vector)
  77. edge_length_sq = dx*dx + dy*dy
  78. if edge_length_sq == 0: # Handle degenerate edge
  79. continue
  80.  
  81. normal_x = -dy
  82. normal_y = dx
  83. normal_length = math.sqrt(normal_x*normal_x + normal_y*normal_y)
  84. normal_x /= normal_length
  85. normal_y /= normal_length
  86.  
  87. projection = (ball_vec_x * normal_x + ball_vec_y * normal_y)
  88.  
  89. # Closest point on the edge to the ball center
  90. closest_x = next_ball_x - projection * normal_x
  91. closest_y = next_ball_y - projection * normal_y
  92.  
  93. # Check if closest point is on the segment
  94. on_segment = True
  95. dot_product1 = (closest_x - p1[0]) * dx + (closest_y - p1[1]) * dy
  96. dot_product2 = (closest_x - p2[0]) * dx + (closest_y - p2[1]) * dy
  97. if dot_product1 < 0 or dot_product2 > 0:
  98. on_segment = False
  99.  
  100. if on_segment:
  101. distance_sq = (next_ball_x - closest_x)**2 + (next_ball_y - closest_y)**2
  102. if distance_sq <= ball_radius**2: # Collision!
  103. if projection < 0: # Ball moving towards the edge
  104. dot_product_vel = ball_speed_x * normal_x + ball_speed_y * normal_y
  105. new_ball_speed_x -= 2 * dot_product_vel * normal_x
  106. new_ball_speed_y -= 2 * dot_product_vel * normal_y
  107. # Slightly push ball away to prevent sticking
  108. next_ball_x += normal_x * 0.1
  109. next_ball_y += normal_y * 0.1
  110. return next_ball_x - ball_speed_x, next_ball_y - ball_speed_y, new_ball_speed_x, new_ball_speed_y
  111.  
  112. return next_ball_x - ball_speed_x, next_ball_y - ball_speed_y, new_ball_speed_x, new_ball_speed_y
  113.  
  114.  
  115. # Game loop
  116. running = True
  117. clock = pygame.time.Clock()
  118.  
  119. while running:
  120. for event in pygame.event.get():
  121. if event.type == pygame.QUIT:
  122. running = False
  123.  
  124. # Update square rotation
  125. square_rotation_angle += square_rotation_speed
  126.  
  127. # Get rotated square vertices
  128. square_vertices = get_square_vertices(square_center_x, square_center_y, square_size, square_rotation_angle)
  129.  
  130. # Ball movement and collision detection
  131. ball_x, ball_y, ball_speed_x, ball_speed_y = check_square_collision_and_bounce(ball_x, ball_y, ball_radius, ball_speed_x, ball_speed_y, square_vertices)
  132.  
  133. ball_x += ball_speed_x
  134. ball_y += ball_speed_y
  135.  
  136.  
  137. # Keep ball within screen bounds (fallback, but square collision is primary)
  138. if ball_x - ball_radius < 0:
  139. ball_x = ball_radius
  140. ball_speed_x *= -1
  141. if ball_x + ball_radius > screen_width:
  142. ball_x = screen_width - ball_radius
  143. ball_speed_x *= -1
  144. if ball_y - ball_radius < 0:
  145. ball_y = ball_radius
  146. ball_speed_y *= -1
  147. if ball_y + ball_radius > screen_height:
  148. ball_y = screen_height - ball_radius
  149. ball_speed_y *= -1
  150.  
  151.  
  152. # Drawing
  153. screen.fill(black)
  154.  
  155. # Draw rotating square
  156. pygame.draw.polygon(screen, light_gray, square_vertices, 2) # 2 is line thickness
  157.  
  158. # Draw ball
  159. pygame.draw.circle(screen, yellow, (int(ball_x), int(ball_y)), ball_radius)
  160.  
  161. pygame.display.flip()
  162.  
  163. clock.tick(60) # Limit frame rate to 60 FPS
  164.  
  165. pygame.quit()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement