pygame动画演示小球碰撞

使用pygame实现动量定理的小球碰撞演示动画

动量定理我们在高中的时候就已经接触过了,是十分重要的物理定理。其中的完全弹性碰撞(机械能守恒)是十分典型的例子,机械能守恒和动量定理两个公式就可以推出小球碰撞之后的速度,依据这个公式,我们就可以完成我们的动画演示了。
m 1 v 1 + m 2 v 2 = m 1 v 1 ′ + m 2 v 2 ′ m_1v_1+m_2v_2=m_1v_1'+m_2v_2' m1v1+m2v2=m1v1+m2v2

1 2 m 1 v 1 2 + 1 2 m 2 v 2 2 = 1 2 m 1 v 1 ′ 2 + 1 2 m 2 v 2 ′ 2 \frac{1}{2}m_1v_1^2+\frac{1}{2}m_2v_2^2=\frac{1}{2}m_1v_1'^2+\frac{1}{2}m_2v_2'^2 21m1v12+21m2v22=21m1v12+21m2v22
根据这两个式子,可以得出碰撞之后的 v 1 ’ v_1’ v1 v 2 ′ v_2' v2的速度:
v 1 ′ = 2 m 2 m 1 + m 2 v 2 + m 1 − m 2 m 1 + m 2 v 1 v_1'=\frac{2m_2}{m_1+m_2}v_2+\frac{m_1-m_2}{m_1+m_2}v_1 v1=m1+m22m2v2+m1+m2m1m2v1

v 2 ′ = 2 m 1 m 1 + m 2 v 1 + m 2 − m 1 m 1 + m 2 v 2 v_2'=\frac{2m_1}{m_1+m_2}v_1+\frac{m_2-m_1}{m_1+m_2}v_2 v2=m1+m22m1v1+m1+m2m2m1v2

然后就可以写代码了

源代码

# color.py
# 需要用到的颜色
RED = (255,0,0)
GREEN = (0,255,0)
BLUE = (0,0,255)
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
YELLOW = (255,255,0)
UNKNOWN = (0, 255,255)
import pygame
from pygame.locals import *
from color import *

# 精灵类
class ball(pygame.sprite.Sprite):
    def __init__(self, mass, position, velocity, color): # position 为左下角的坐标
        self.mass = mass
        self.image = pygame.Surface((40, 40))
        self.rect = self.image.get_rect()
        # pygame.draw.rect(self.image, BLACK, self.rect, 1)
        self.image.fill(WHITE)
        pygame.draw.circle(self.image, color, (20, 20), 20)
        self.rect.bottomleft = position
        self.velocity = velocity
# 主函数
import pygame, sys
from pygame.locals import *
from color import *
from ball import ball

def main():
    pygame.init()
    screen = pygame.display.set_mode((800, 600))
    pygame.display.set_caption('动量定理动画')
    FPSCLOCK = pygame.time.Clock()
    floor1 = 200
    floor2 = 400
    floor3 = 600
    # 初始化小球
    ball1 = ball(10, (0, floor1), 10,RED)
    ball2 = ball(20, (760, floor1), -5,BLACK)
    ball3 = ball(10, (0, floor2), 10,GREEN)
    ball4 = ball(10, (760, floor2), -10,BLUE)
    ball5 = ball(1, (0, floor3), 10, YELLOW)
    ball6 = ball(1000000000000000000000, (400, floor3), 0, UNKNOWN)
    # 绘制两个小球
    screen.fill(WHITE)
    pygame.draw.line(screen, BLACK,(0, floor1), (800, floor1), 1)
    pygame.draw.line(screen, BLACK,(0, floor2), (800, floor2), 1)
    pygame.draw.line(screen, BLACK,(0, floor3), (800, floor3), 1)
    screen.blit(ball1.image, ball1.rect)
    screen.blit(ball2.image, ball2.rect)
    screen.blit(ball3.image, ball3.rect)
    screen.blit(ball4.image, ball4.rect)
    screen.blit(ball5.image, ball5.rect)
    screen.blit(ball6.image, ball6.rect)

    while True:
        for event in pygame.event.get():
            if event.type == QUIT:
                pygame.quit()
                sys.exit()

        if collision_check(ball1.rect, ball2.rect):
            v1 = ball1.velocity
            v2 = ball2.velocity
            m1 = ball1.mass
            m2 = ball2.mass
            ball1.velocity = int(2*m2*v2/(m1+m2)+((m1-m2)/(m1+m2))*v1)
            ball2.velocity = int(2*m1*v1/(m1+m2)+((m2-m1)/(m1+m2))*v2)

        if ball3.rect.right > ball4.rect.left and ball3.rect.right - ball3.velocity <= ball4.rect.left - ball4.velocity:
            v1 = ball3.velocity
            v2 = ball4.velocity
            m1 = ball3.mass
            m2 = ball4.mass
            ball3.velocity = int(2*m2*v2/(m1+m2)+((m1-m2)/(m1+m2))*v1)
            ball4.velocity = int(2*m1*v1/(m1+m2)+((m2-m1)/(m1+m2))*v2)

        if ball5.rect.right > ball6.rect.left and ball5.rect.right - ball5.velocity <= ball6.rect.left - ball6.velocity:
            v1 = ball5.velocity
            v2 = ball6.velocity
            m1 = ball5.mass
            m2 = ball6.mass
            print(ball5.velocity)
            ball5.velocity = int(2*m2*v2/(m1+m2)+((m1-m2)/(m1+m2))*v1)
            ball6.velocity = int(2*m1*v1/(m1+m2)+((m2-m1)/(m1+m2))*v2)

        if ball1.rect.left < 0 or ball1.rect.right > 800:
            ball1.velocity = -ball1.velocity
            if (ball1.rect.left < 0 and ball1.velocity < 0) or (ball1.rect.right > 800 and ball1.velocity > 0):
                ball1.velocity = -ball1.velocity

        if ball2.rect.left < 0 or ball2.rect.right > 800:
            ball2.velocity = -ball2.velocity
            if (ball2.rect.left < 0 and ball2.velocity < 0) or (ball2.rect.right > 800 and ball2.velocity > 0):
                ball2.velocity = -ball2.velocity

        if ball3.rect.left < 0 or ball3.rect.right > 800:
            ball3.velocity = -ball3.velocity
            if (ball3.rect.left < 0 and ball3.velocity < 0) or (ball3.rect.right > 800 and ball3.velocity > 0):
                ball3.velocity = -ball3.velocity

        if ball4.rect.left < 0 or ball4.rect.right > 800:
            ball4.velocity = -ball4.velocity
            if (ball4.rect.left < 0 and ball4.velocity < 0) or (ball4.rect.right > 800 and ball4.velocity > 0):
                ball4.velocity = -ball4.velocity

        if ball5.rect.left < 0 or ball5.rect.right > 800:
            ball5.velocity = -ball5.velocity
            if (ball5.rect.left < 0 and ball5.velocity < 0) or (ball5.rect.right > 800 and ball5.velocity > 0):
                ball5.velocity = -ball5.velocity

        if ball6.rect.left < 0 or ball6.rect.right > 800:
            ball6.velocity = -ball6.velocity
            if (ball6.rect.left < 0 and ball6.velocity < 0) or (ball6.rect.right > 800 and ball6.velocity > 0):
                ball6.velocity = -ball6.velocity

        ball1.rect.left += ball1.velocity
        ball2.rect.left += ball2.velocity
        ball3.rect.left += ball3.velocity
        ball4.rect.left += ball4.velocity
        ball5.rect.left += ball5.velocity
        ball6.rect.left += ball6.velocity

        screen.fill(WHITE)
        pygame.draw.line(screen, BLACK,(0, floor1), (800, floor1), 1)
        pygame.draw.line(screen, BLACK,(0, floor2), (800, floor2), 1)
        pygame.draw.line(screen, BLACK,(0, floor3), (800, floor3), 1)
        screen.blit(ball1.image, ball1.rect)
        screen.blit(ball2.image, ball2.rect)
        screen.blit(ball3.image, ball3.rect)
        screen.blit(ball4.image, ball4.rect)
        screen.blit(ball5.image, ball5.rect)
        screen.blit(ball6.image, ball6.rect)
        pygame.display.update()
        FPSCLOCK.tick(60)

if __name__ == '__main__':
    main()

效果

效果

  • 2
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
Pygame是一个用于开发2D游戏的Python库,可以实现小球碰撞效果。下面是一个简单的示例代码来演示如何使用Pygame实现小球碰撞: ```python import pygame import random # 初始化Pygame pygame.init() # 设置窗口大小和标题 width, height = 800, 600 screen = pygame.display.set_mode((width, height)) pygame.display.set_caption("Ball Collision") # 定义颜色 BLACK = (0, 0, 0) WHITE = (255, 255, 255) # 定义小球类 class Ball: def __init__(self, x, y, radius, color): self.x = x self.y = y self.radius = radius self.color = color self.dx = random.randint(-5, 5) # 随机生成小球的水平速度 self.dy = random.randint(-5, 5) # 随机生成小球的垂直速度 def move(self): self.x += self.dx self.y += self.dy def draw(self): pygame.draw.circle(screen, self.color, (self.x, self.y), self.radius) def check_collision(self, other_ball): distance = ((self.x - other_ball.x) ** 2 + (self.y - other_ball.y) ** 2) ** 0.5 if distance <= self.radius + other_ball.radius: return True else: return False # 创建小球对象列表 balls = [] for _ in range(10): x = random.randint(0, width) y = random.randint(0, height) radius = random.randint(10, 50) color = (random.randint(0, 255), random.randint(0, 255), random.randint(0, 255)) ball = Ball(x, y, radius, color) balls.append(ball) # 游戏主循环 running = True clock = pygame.time.Clock() while running: for event in pygame.event.get(): if event.type == pygame.QUIT: running = False screen.fill(BLACK) # 移动和绘制小球 for ball in balls: ball.move() ball.draw() # 检测小球碰撞 for i in range(len(balls)): for j in range(i + 1, len(balls)): if balls[i].check_collision(balls[j]): balls[i].dx *= -1 balls[i].dy *= -1 balls[j].dx *= -1 balls[j].dy *= -1 pygame.display.flip() clock.tick(60) # 退出游戏 pygame.quit() ``` 这段代码创建了一个窗口,生成了一些随机大小和颜色的小球,并且让它们在窗口中移动。当两个小球碰撞时,它们的速度会反向改变,从而实现了小球碰撞效果。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值