-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpygame-claude-3.7-v2.py
171 lines (138 loc) · 5.48 KB
/
pygame-claude-3.7-v2.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
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
import pygame
import sys
import math
# Initialize pygame
pygame.init()
# Constants
SCREEN_WIDTH = 800
SCREEN_HEIGHT = 600
FPS = 60
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
RED = (255, 0, 0)
BLUE = (0, 0, 255)
GREEN = (0, 255, 0)
# Create the screen
screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
pygame.display.set_caption("Concentric Circles Animation")
clock = pygame.time.Clock()
class OuterCircle:
def __init__(self, x, y, radius, color=WHITE):
self.x = x
self.y = y
self.radius = radius
self.color = color
self.angular_velocity = 1.0 # degrees per frame
self.angle = 0
def update(self):
self.angle += self.angular_velocity
if self.angle >= 360:
self.angle -= 360
def draw(self, screen):
# Draw the outer circle
pygame.draw.circle(screen, self.color, (self.x, self.y), self.radius, 2)
# Draw a marker on the circle to visualize rotation
marker_x = self.x + int(self.radius * math.cos(math.radians(self.angle)))
marker_y = self.y + int(self.radius * math.sin(math.radians(self.angle)))
pygame.draw.circle(screen, RED, (marker_x, marker_y), 8)
class InnerCircle:
def __init__(self, x, y, radius, outer_circle, color=BLUE):
self.x = x
self.y = y
self.radius = radius
self.color = color
self.outer_circle = outer_circle
# Initial velocity (px per frame)
self.vx = 2.0
self.vy = 1.5
# Trail effect
self.trail = []
self.max_trail_length = 50
def update(self):
# Move the inner circle
self.x += self.vx
self.y += self.vy
# Add current position to trail
self.trail.append((self.x, self.y))
if len(self.trail) > self.max_trail_length:
self.trail.pop(0)
# Calculate distance from center of outer circle
dx = self.x - self.outer_circle.x
dy = self.y - self.outer_circle.y
distance = math.sqrt(dx*dx + dy*dy)
# Check collision with outer circle (accounting for inner circle radius)
max_distance = self.outer_circle.radius - self.radius
if distance > max_distance:
# Normalize the direction vector
nx = dx / distance
ny = dy / distance
# Reflect velocity vector off the tangent at the collision point
dot_product = self.vx * nx + self.vy * ny
# Basic reflection
self.vx -= 2 * dot_product * nx
self.vy -= 2 * dot_product * ny
# Apply a slight influence from the outer circle's rotation
rotation_influence = self.outer_circle.angular_velocity / 10.0
perpendicular_x = -ny
perpendicular_y = nx
self.vx += rotation_influence * perpendicular_x
self.vy += rotation_influence * perpendicular_y
# Damping (slight energy loss)
dampening = 0.98
self.vx *= dampening
self.vy *= dampening
# Reposition circle to be exactly on the boundary to prevent sticking
self.x = self.outer_circle.x + nx * max_distance
self.y = self.outer_circle.y + ny * max_distance
def draw(self, screen):
# Draw the trail
for i in range(1, len(self.trail)):
alpha = int(255 * i / len(self.trail))
color = (0, 0, min(255, alpha + 100))
pygame.draw.line(screen, color, self.trail[i-1], self.trail[i], 2)
# Draw the inner circle
pygame.draw.circle(screen, self.color, (int(self.x), int(self.y)), self.radius)
def draw_info_text(screen, outer_circle):
font = pygame.font.SysFont(None, 24)
# Render instructions
instructions = [
"UP/DOWN arrows: Adjust rotation speed",
f"Current rotation speed: {outer_circle.angular_velocity:.1f}°/frame",
"SPACE: Reset animation"
]
for i, text in enumerate(instructions):
text_surface = font.render(text, True, WHITE)
screen.blit(text_surface, (10, 10 + i * 25))
def main():
# Create the circles
center_x, center_y = SCREEN_WIDTH // 2, SCREEN_HEIGHT // 2
outer_circle = OuterCircle(center_x, center_y, 200)
inner_circle = InnerCircle(center_x, center_y - 100, 20, outer_circle)
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_UP:
outer_circle.angular_velocity += 0.2
elif event.key == pygame.K_DOWN:
outer_circle.angular_velocity = max(0, outer_circle.angular_velocity - 0.2)
elif event.key == pygame.K_SPACE:
# Reset the animation
outer_circle.angular_velocity = 1.0
inner_circle = InnerCircle(center_x, center_y - 100, 20, outer_circle)
# Update
outer_circle.update()
inner_circle.update()
# Draw
screen.fill(BLACK)
outer_circle.draw(screen)
inner_circle.draw(screen)
draw_info_text(screen, outer_circle)
pygame.display.flip()
clock.tick(FPS)
pygame.quit()
sys.exit()
if __name__ == "__main__":
main()