用pygame设计两个分子之间进行弹性碰撞,初始界面要能够定义分子的弹性系数的速度
时间: 2024-03-07 08:49:21 浏览: 22
好的,下面是一个简单的例子,使用Pygame设计了两个分子之间的弹性碰撞,并且可以在初始界面中定义分子的弹性系数和速度。
```python
import pygame
import random
import math
# 初始化pygame
pygame.init()
# 设置窗口尺寸
size = width, height = 640, 480
# 创建窗口
screen = pygame.display.set_mode(size)
# 设置窗口标题
pygame.display.set_caption("弹性碰撞")
# 设置颜色
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
# 定义分子类
class Molecule(pygame.sprite.Sprite):
def __init__(self, x, y, radius, speed, angle, elasticity):
super().__init__()
self.x = x
self.y = y
self.radius = radius
self.speed = speed
self.angle = angle
self.elasticity = elasticity
self.image = pygame.Surface((radius*2, radius*2))
self.image.fill(WHITE)
pygame.draw.circle(self.image, BLACK, (radius, radius), radius)
self.rect = self.image.get_rect()
self.rect.center = (x, y)
def update(self):
# 移动分子
self.x += self.speed * math.cos(self.angle)
self.y -= self.speed * math.sin(self.angle)
self.rect.center = (round(self.x), round(self.y))
# 检查分子是否碰到边界
if self.rect.left < 0 or self.rect.right > width:
self.angle = math.pi - self.angle
self.speed *= self.elasticity
if self.rect.top < 0 or self.rect.bottom > height:
self.angle = -self.angle
self.speed *= self.elasticity
# 设置分子初始参数
m1 = Molecule(150, 150, 20, 5, math.pi/6, 0.9)
m2 = Molecule(450, 250, 30, 4, math.pi/4, 0.8)
all_sprites = pygame.sprite.Group(m1, m2)
# 设置时钟
clock = pygame.time.Clock()
# 设置弹性系数滑块
elasticity_slider = pygame.Surface((200, 20))
elasticity_slider.fill(WHITE)
pygame.draw.rect(elasticity_slider, BLACK, elasticity_slider.get_rect(), 2)
elasticity_slider_rect = elasticity_slider.get_rect(center=(320, 380))
# 设置速度滑块
speed_slider = pygame.Surface((200, 20))
speed_slider.fill(WHITE)
pygame.draw.rect(speed_slider, BLACK, speed_slider.get_rect(), 2)
speed_slider_rect = speed_slider.get_rect(center=(320, 430))
# 设置字体
font = pygame.font.Font(None, 30)
# 事件循环
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
if event.type == pygame.MOUSEBUTTONDOWN:
# 点击弹性系数滑块
if elasticity_slider_rect.collidepoint(event.pos):
elasticity_slider.fill(BLACK)
elasticity_slider_rect.move_ip(event.rel)
elasticity = elasticity_slider_rect.centerx / 640
pygame.draw.rect(elasticity_slider, WHITE, elasticity_slider.get_rect().inflate(-4, -4))
pygame.draw.rect(elasticity_slider, BLACK, elasticity_slider.get_rect(), 2)
# 点击速度滑块
elif speed_slider_rect.collidepoint(event.pos):
speed_slider.fill(BLACK)
speed_slider_rect.move_ip(event.rel)
speed = speed_slider_rect.centerx / 640 * 10
pygame.draw.rect(speed_slider, WHITE, speed_slider.get_rect().inflate(-4, -4))
pygame.draw.rect(speed_slider, BLACK, speed_slider.get_rect(), 2)
# 更新分子状态
all_sprites.update()
# 检查分子是否碰撞
if pygame.sprite.collide_circle(m1, m2):
dx = m1.x - m2.x
dy = m1.y - m2.y
distance = math.sqrt(dx**2 + dy**2)
angle = math.atan2(dy, dx)
m1.angle = 2 * angle - m1.angle
m2.angle = 2 * angle - m2.angle
m1.speed, m2.speed = m2.speed, m1.speed
m1.speed *= m1.elasticity
m2.speed *= m2.elasticity
overlap = 0.5 * (m1.radius + m2.radius - distance + 1)
m1.x += overlap * math.cos(angle)
m1.y -= overlap * math.sin(angle)
m2.x -= overlap * math.cos(angle)
m2.y += overlap * math.sin(angle)
m1.rect.center = (round(m1.x), round(m1.y))
m2.rect.center = (round(m2.x), round(m2.y))
# 绘制屏幕
screen.fill(WHITE)
all_sprites.draw(screen)
screen.blit(elasticity_slider, elasticity_slider_rect)
screen.blit(speed_slider, speed_slider_rect)
elasticity_label = font.render("弹性系数: {:.1f}".format(elasticity), True, BLACK)
screen.blit(elasticity_label, (20, 380))
speed_label = font.render("速度: {:.1f}".format(speed), True, BLACK)
screen.blit(speed_label, (20, 430))
pygame.display.flip()
# 设置帧率
clock.tick(60)
```
在这个例子中,我们定义了一个Molecule类,用于表示分子。在初始化时,我们传入分子的位置、半径、速度、角度和弹性系数。在update()方法中,我们使用速度和角度计算分子的新位置,并且检查分子是否碰到边界。如果分子碰到边界,我们会根据碰撞的位置和角度更新分子的速度和角度。
我们还使用Pygame的sprite模块创建了一个all_sprites组,用于管理所有的分子。
在事件循环中,我们检查用户是否点击了弹性系数滑块或速度滑块,并且更新分子的弹性系数和速度。
最后,我们绘制屏幕并更新帧率。