python - Pygame中的动画故障
问题描述
我正在使用pygame 创建两个质量比为 100 次方的块的碰撞模拟,要清楚这意味着较大块与较小块的比率可以是100**0
, 100**1
,100**2
等等。我在必要的地方添加了注释和文档字符串,以使逻辑易于理解。
import pygame
# from collisions import *
pygame.init()
s1, s2 = 100, 50 # block sides
x1, y1 = 1000, 250 # bigger block coords
x2, y2 = 500, y1 + s1 - s2 # smaller block coords
power = int(input('enter: ')) # mass ratio
v1 = (-0.5) # initial velocity of block 1
m1, m2 = 100 ** (power - 1), 1 # mass of blocks
v2 = 0 # initial velocity of block 2
# temp_x1 = 0
red = (255, 0, 0)
blue = (0, 0, 255)
def message_to_print(msg, color):
font = pygame.font.SysFont(None, 40)
text = font.render(msg, True, color)
win.blit(text, [10, 10])
def reverse_vel(vel):
'''
reversing velocity of block
'''
vel *= -1
return vel
def exchange_vel(v1, m1, v2, m2):
'''
this function is calculating the new velocity of the block after collision,
based on law of conservation of momentum and kinetic energy
'''
v1 = ((m1 - m2) / (m1 + m2)) * v1 + ((2 * m2) / (m1 + m2)) * v2
return v1 # returning new velocity after collision
win = pygame.display.set_mode((1200, 500))
win.fill((255, 255, 255))
pygame.display.set_caption('simulation')
Collisions = 0 # counting number of collisions
run = True
while run:
# click_sound = pygame.mixer.Sound("rss/click.wav")
# pygame.time.delay(10)
# sound_collide, sound_reverse = True, True
message_to_print('collision ' + str(Collisions), (0, 0, 0))
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
# biger block
x1 += v1 # changing block coordinates according to velocity
if x1 > s2: # this prevents block 1 from moving out of window
t = x1
if not x2 + s2 < x1 or x1 + s1 < x2:
'''
changing velocity after collision,
storing them in temp variable for each block,
then assiging new velocity
'''
v2_temp = exchange_vel(v2, m2, v1, m1)
v1_temp = exchange_vel(v1, m1, v2, m2)
# if sound_collide:
# click_sound.play()
# sound = False
v2, v1 = v2_temp, v1_temp # assigning new velocities
Collisions += 1
# smaller Block
x2 += v2
if x2 <= 0:
'''
if block 1 touch left wall, its velocity reverses,
'''
v2 = reverse_vel(v2)
# if sound_reverse:
# click_sound.play()
# sound_reverse = False
Collisions += 1
pygame.draw.rect(win, blue, (x2, y2, s2, s2))
pygame.draw.rect(win, red, (t, y1, s1, s1))
pygame.display.update()
win.fill((255, 255, 255))
pygame.quit()
问题1:
对于较小的power
模拟值,效果很好。但是对于power>=3
块 2(蓝色块)的动画值变得很奇怪(如图所示),我无法找到原因并修复它。
如图所示,蓝色块始终是这个位置,不断消失和出现。
更新:发生的碰撞次数是该程序的组成部分。在任何情况下,发生的碰撞次数都不应受到影响
解决方案
我明白你在做什么。您可以通过在阻止块 1 移出窗口时简单地添加 else 语句来实现这一点。
if x1 >= s2:
t = x1
t2 = x2
else:
t2 = 0
和改变
pygame.draw.rect(win, blue, (t2, y2, s2, s2)) # x2-> t2
解释 : 当你的 block1 坐标大于 s2 时,它们会正常移动,但如果不是这种情况,只需将较小块的坐标固定为 0。
建议:由于实际上在此期间会发生碰撞,为了在模拟中显示这一点,您可以执行类似的操作。
if x1 >= s2 +2: # this prevents block 1 from moving out of window
t = x1
t2 = x2
else:
t2 = z%2
z+=1
这将创建一个迷你碰撞效果。我用2
的是任意选择。z=0
也在主循环之前初始化
推荐阅读
- android - 如何减少在 Android RecyclerVIew 中单击项目时的操作延迟?
- c++ - Vim 缩进 C++11 lambda,在新行上有左大括号
- javascript - JavaScript - 从“for”循环中选择最后一项
- python - 获取作为序列化对象发送的所请求用户的配置文件
- java - JSON解析时这段代码有什么问题?
- c# - 为什么在使用 fluent-nhibernate 配置 nhibernate 时出现 MissingMethodException?
- javascript - 无法使用 JavaScript 计算时差
- c++ - 擦除后重构列表迭代器
- java - 当我尝试使用 Hibernate 删除实体时,没有错误消息但不会删除
- linux - 如何在没有用户交互的情况下创建用户并设置密码?