-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpygame-claude-3.7.py
142 lines (116 loc) · 5.72 KB
/
pygame-claude-3.7.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
import pygame
import sys
import math
class CircleAnimation:
def __init__(self):
# Initialize Pygame
pygame.init()
# Screen dimensions
self.width, self.height = 800, 600
self.screen = pygame.display.set_mode((self.width, self.height))
pygame.display.set_caption("Concentric Circles Animation")
# Colors
self.background_color = (10, 10, 40)
self.outer_circle_color = (100, 150, 255)
self.inner_circle_color = (255, 100, 100)
self.trail_color = (255, 100, 100, 30) # RGBA with alpha for trail
# Clock for controlling frame rate
self.clock = pygame.time.Clock()
self.fps = 60
# Circles properties
self.center_x, self.center_y = self.width // 2, self.height // 2
self.outer_radius = 200
self.inner_radius = 30
self.contact_radius = self.outer_radius - self.inner_radius
# Physics properties
self.angular_velocity = 0.02 # Radians per frame
self.max_angular_velocity = 0.1
self.min_angular_velocity = 0.005
self.current_angle = 0
# Inner circle properties
self.inner_x = self.center_x + self.contact_radius * math.cos(self.current_angle)
self.inner_y = self.center_y + self.contact_radius * math.sin(self.current_angle)
self.inner_angle_velocity = 0
self.inertia_factor = 0.99 # Controls how quickly the inner circle gains/loses speed
# Trail effect
self.trail_surface = pygame.Surface((self.width, self.height), pygame.SRCALPHA)
self.trail_positions = []
self.max_trail_length = 100
def handle_events(self):
for event in pygame.event.get():
if event.type == pygame.QUIT:
return False
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_UP:
self.angular_velocity = min(self.angular_velocity + 0.005, self.max_angular_velocity)
elif event.key == pygame.K_DOWN:
self.angular_velocity = max(self.angular_velocity - 0.005, self.min_angular_velocity)
elif event.key == pygame.K_SPACE:
# Reset
self.angular_velocity = 0.02
self.current_angle = 0
self.inner_angle_velocity = 0
self.trail_positions.clear()
return True
def update_physics(self):
# Update outer circle angle
self.current_angle += self.angular_velocity
# Calculate new inner circle position based on physics
# As the outer circle rotates, the inner circle tries to maintain its position in space
# due to inertia, but is constrained by the outer circle
# Calculate new inner circle angle (influenced by inertia)
self.inner_angle_velocity = (self.inner_angle_velocity * self.inertia_factor -
self.angular_velocity * (1 - self.inertia_factor))
# Calculate inner circle position, ensuring it stays in contact with outer circle wall
inner_angle = self.current_angle + self.inner_angle_velocity
self.inner_x = self.center_x + self.contact_radius * math.cos(inner_angle)
self.inner_y = self.center_y + self.contact_radius * math.sin(inner_angle)
# Add current position to trail
self.trail_positions.append((self.inner_x, self.inner_y))
if len(self.trail_positions) > self.max_trail_length:
self.trail_positions.pop(0)
def draw(self):
# Clear the screen
self.screen.fill(self.background_color)
# Fade the trail surface for the motion trail effect
self.trail_surface.fill((0, 0, 0, 0))
# Draw the trail
for i, pos in enumerate(self.trail_positions):
# Make later positions more opaque
opacity = int(i * 255 / self.max_trail_length)
pygame.draw.circle(self.trail_surface, (255, 100, 100, opacity),
(int(pos[0]), int(pos[1])),
max(1, int(self.inner_radius * i / self.max_trail_length)))
self.screen.blit(self.trail_surface, (0, 0))
# Draw outer circle
pygame.draw.circle(self.screen, self.outer_circle_color,
(self.center_x, self.center_y),
self.outer_radius, 3)
# Draw line from center to inner circle (optional, helps visualize rotation)
pygame.draw.line(self.screen, (200, 200, 200),
(self.center_x, self.center_y),
(self.inner_x, self.inner_y), 1)
# Draw inner circle
pygame.draw.circle(self.screen, self.inner_circle_color,
(int(self.inner_x), int(self.inner_y)),
self.inner_radius)
# Draw speed info
font = pygame.font.SysFont(None, 24)
speed_text = font.render(f"Angular Velocity: {self.angular_velocity:.3f}", True, (255, 255, 255))
controls_text = font.render("Use UP/DOWN arrows to change speed, SPACE to reset", True, (255, 255, 255))
self.screen.blit(speed_text, (10, 10))
self.screen.blit(controls_text, (10, 40))
# Update the display
pygame.display.flip()
def run(self):
running = True
while running:
running = self.handle_events()
self.update_physics()
self.draw()
self.clock.tick(self.fps)
pygame.quit()
sys.exit()
if __name__ == "__main__":
animation = CircleAnimation()
animation.run()