Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python Pygame中的动画故障_Python_Algorithm_Animation_Pygame - Fatal编程技术网

Python Pygame中的动画故障

Python Pygame中的动画故障,python,algorithm,animation,pygame,Python,Algorithm,Animation,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 =

我正在使用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>=3的值,block 2blue block的动画变得异常,如图所示,我无法找到原因并修复它

如图所示,蓝色块始终是这个位置,并不断消失和接近


更新:发生的碰撞数量是该计划的组成部分。在任何情况下,发生的碰撞次数都不应受到影响

我理解你在做什么。当阻止块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,我理解你在做什么。当阻止块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

如果速度v1、v2大于1,则在将v1、v2分别添加到该位置后,碰撞不会精确地发生在对象的新位置。碰撞发生在从x1到x1+v1的轨道上的某个地方,分别是x2到x2+v2

拆分计算int步,其中每个步小于1像素,并在循环中进行计算。注意:计算是用浮点值而不是整数值进行的:

步骤=maxabsintv1+1,intabsv2+1 对于我,请按步骤: 大块头 步骤1=步骤1/步骤 x1+=步骤v1 [...] 小砌块 步骤2=步骤2/步骤 x2+=步骤2 [...] 碰撞后限制小砌块的位置:

如果x1如果速度v1、v2大于1,则在将v1、v2分别添加到该位置后,碰撞不会精确地发生在对象的新位置。碰撞发生在从x1到x1+v1的轨道上的某个地方,分别是x2到x2+v2

拆分计算int步,其中每个步小于1像素,并在循环中进行计算。注意:计算是用浮点值而不是整数值进行的:

步骤=maxabsintv1+1,intabsv2+1 对于我,请按步骤: 大块头 步骤1=步骤1/步骤 x1+=步骤v1 [...] 小砌块 步骤2=步骤2/步骤 x2+=步骤2 [...] 碰撞后限制小砌块的位置:


如果我真的喜欢这个解释,它解决了我提到的问题。但这造成了一个巨大的问题。如果没有,碰撞的数量等于π的位数。但是这个解决方案会给enter:5及以后发生的碰撞次数带来误差。@p.ram当您说给碰撞次数带来误差时,您的意思是计算不正确?预期结果是什么?当输入为5时,预期碰撞数为31415,但根据您的解决方案,碰撞数为283567。为了确认我没有犯任何错误,请您确认解决方案中输入5的碰撞次数。Thanks@p.ram我很惊讶。当我输入:5时,我得到31417。可能问题在于步数过大。当我执行steps=maxabsintv1+1,intabsv2+1*10时,结果是31415。*10只是一个任意因素。可悲的是,我刚刚发现,应用程序似乎冻结了大量的数字。我还需要做进一步的调查。这个程序在最大8点时不需要太大的输入。我还有一个疑问,你的应用程序怎么能比我的程序执行碰撞的速度更快?例如,当输入为4时,您的解决方案运行得更快。我非常喜欢这个解释,它解决了我提到的问题。但这造成了一个巨大的问题。如果没有,碰撞的数量等于π的位数。但这种解决方案会给co的数量带来误差
enter:5及以后发生碰撞。@p.ram当您说碰撞次数出现错误时,您的意思是计算不正确?预期结果是什么?当输入为5时,预期碰撞数为31415,但根据您的解决方案,碰撞数为283567。为了确认我没有犯任何错误,请您确认解决方案中输入5的碰撞次数。Thanks@p.ram我很惊讶。当我输入:5时,我得到31417。可能问题在于步数过大。当我执行steps=maxabsintv1+1,intabsv2+1*10时,结果是31415。*10只是一个任意因素。可悲的是,我刚刚发现,应用程序似乎冻结了大量的数字。我还需要做进一步的调查。这个程序在最大8点时不需要太大的输入。我还有一个疑问,你的应用程序怎么能比我的程序执行碰撞的速度更快?例如,当输入为4时,您的解决方案运行得更快。