Python 如何在pygame中使我的圆圈飞离屏幕?

Python 如何在pygame中使我的圆圈飞离屏幕?,python,animation,random,pygame,game-loop,Python,Animation,Random,Pygame,Game Loop,我是python的乞丐,我正在尝试做一个圆圈游戏。到目前为止,当你点击时,它会在你的鼠标上画一个带有随机颜色和半径的圆 接下来,我希望圆圈以随机方向飞离屏幕。我该怎么做呢?这是迄今为止我的主要代码块: check1 = None check2 = None while True: for event in pygame.event.get(): if event.type == QUIT: pygame.quit() s

我是python的乞丐,我正在尝试做一个圆圈游戏。到目前为止,当你点击时,它会在你的鼠标上画一个带有随机颜色和半径的圆

接下来,我希望圆圈以随机方向飞离屏幕。我该怎么做呢?这是迄今为止我的主要代码块:

check1 = None
check2 = None

while True:

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

        if event.type == MOUSEBUTTONDOWN:
            last_mouse_pos = pygame.mouse.get_pos()



    if last_mouse_pos:

        global check

        color1 = random.randint(0,255)
        color2 = random.randint(0,255)
        color3 = random.randint(0,255)
        color = (color1,color2,color3)

        radius = random.randint (5,40)
        posx,posy = last_mouse_pos

        if posx != check1 and posy != check2:
            global check1, check2
            screen.lock()
            pygame.draw.circle(screen, color, (posx,posy), radius)
            screen.unlock()
            check1,check2 = posx,posy


    pygame.display.update()
同样,我希望圆圈以随机方向飞离屏幕。 我做了一些尝试,但还没有成功。
另外,感谢jdi在创建圆(单击)时帮助我生成2个随机数。这些将是二维向量的(x,y)分量:

然后在创建球后,在游戏循环的每次迭代中,通过速度向量增加球的位置:

posx, posy = posx + vx, posy + vy


请注意,总体速度可能是可变的。如果希望始终保持每秒1.0的速度,请规范化向量:

对于向量,将其除以其:

因此,在你的情况下:

因此:

因此,在Python中,使用导入数学后:

mag = math.sqrt(vx*vx + vy*vy)
v_norm = vx/mag, vy/mag
# use v_norm instead of your (vx, vy) tuple
然后您可以将其与一些
速度
变量相乘,以获得可靠的速度


一旦你开始让多个对象在屏幕外移动,移除屏幕外的对象是很有用的,因为这些对象没有机会再回来,并且与你的程序没有任何关系。否则,如果您在创建更多对象的同时继续跟踪所有这些屏幕外对象,则实际上会出现内存泄漏,并且如果有足够的时间/操作,将耗尽内存



虽然你现在做的很简单,假设你还没有,学习一些基本的向量数学很快就会有回报。最终,您可能需要尝试一些矩阵数学来进行某些转换。如果你是新来的,它并不像最初看起来那么难。您可能不必学习它,但如果您开始尝试做更雄心勃勃的事情,您将节省自己的精力。

现在,您正在做以下工作(大大简化代码)

让我们让事情变得容易一点,然后逐步建立

从圆圈开始,用户无需单击 为了简单起见,让我们在屏幕左上角附近画一个圆圈,这样我们就可以一直假设会有一个圆圈(使一些逻辑更容易)

为圆设置动画 在讨论太多“随机方向”之前,让我们先简单一点,朝一个方向走(比如说,总是向下向右走)

现在,每次通过循环时,圆心都会移动一点,然后将其绘制到新的位置。请注意,如果圆移动过快,可能需要减少添加到圆x和y(在我的代码中为0.1)中的值

然而,你会注意到你的屏幕现在充满了圆圈!而不是一个“移动”的圆,你只是画了很多次这个圆!为了解决这个问题,我们将在每次绘图之前“清除”屏幕

screen = ....
BLACK = (0,0,0) # Defines the "black" color
circle_x, circle_y = 0,0
while True:
    # Update
    circle_x += 0.1
    circle_y += 0.1

    # Draw
    screen.fill(BLACK)
    draw the circle at circle_x, circle_y
    update the display
请注意,在画圆之前,我们通过将整个物体涂成黑色来“清除”屏幕

现在,您可以开始将希望返回到代码中的其余部分工作

跟踪多个圆圈 可以通过使用圆列表而不是两个圆变量来实现这一点

circles = [...list of circle positions...]
while True:
    # Update
    for circle in circles:
        ... Update the circle position...


    # Draw
    screen.fill(BLACK)
    for circle in circles:
        draw the circle at circle position # This will occur once for each circle
    update the display
需要注意的一点是,如果跟踪元组中的圆位置,则无法更改它们的值。如果您熟悉面向对象编程,您可以创建一个Circle类,并使用它跟踪与您的圆相关的数据。否则,您可以为每个循环创建每个圆的更新坐标列表

当用户单击时添加圆圈 让圆沿随机方向移动 这是一个很好的数学帮助发挥作用。基本上,您需要一种方法来确定通过每个循环更新圆的x和y坐标。请记住,完全可以说您希望它在每个轴(X,y)的-1和1之间移动,但这并不一定正确。有可能X和Y都为零,在这种情况下,圆根本不会移动!下一个圆圈可能是1和1,这将比其他圆圈走得更快

我不确定你的数学背景是什么,所以你可能需要学习一些知识来理解如何在程序中存储“方向”(有时称为“向量”)背后的数学。你可以试试普里特的答案,看看是否有帮助。有了几何学和三角学的背景,真正的理解就容易多了(尽管如果你找到一个好的资源,你可能没有它也能过得去)

其他一些想法 您还需要记住一些其他事项:

  • 现在,我们正在玩的代码是“帧速率相关”。也就是说,圆圈在屏幕上移动的速度完全取决于计算机的运行速度;较慢的计算机会看到圆圈像蜗牛一样移动,而较快的计算机在圆圈飞离屏幕之前几乎看不到它们!有几种方法可以解决这个问题,你可以自己查找(在你最喜欢的搜索引擎中搜索“帧速率相关性”或其他术语)

  • 现在,您有screen.lock()和screen.unlock()。你不需要这些。如果屏幕表面需要锁定/解锁屏幕表面(某些表面不需要),并且要手动访问像素数据,则只需锁定/解锁屏幕表面。在屏幕上画圆圈,pygame会自动为您锁定/解锁曲面。简而言之,您现在不需要处理锁定/解锁


  • 你必须编写一个函数,每帧改变一点圆圈的位置。我有一个用HTML5和JavaScript开发的演示,可以在随机方向上为许多球设置动画。巴尔
    circle_x, circle_y = 10,10
    while True:
        draw the circle at circle_x, circle_y
    
        pygame.display.update()
    
    circle_x, circle_y = 0,0
    while True:
        # Update
        circle_x += 0.1
        circle_y += 0.1
    
        # Draw
        draw the circle at circle_x, circle_y
        update the display
    
    screen = ....
    BLACK = (0,0,0) # Defines the "black" color
    circle_x, circle_y = 0,0
    while True:
        # Update
        circle_x += 0.1
        circle_y += 0.1
    
        # Draw
        screen.fill(BLACK)
        draw the circle at circle_x, circle_y
        update the display
    
    circles = [...list of circle positions...]
    while True:
        # Update
        for circle in circles:
            ... Update the circle position...
    
    
        # Draw
        screen.fill(BLACK)
        for circle in circles:
            draw the circle at circle position # This will occur once for each circle
        update the display
    
    circles = []
    while True:
        # event handling
        for event in pygame.event.get():
            if event.type == MOUSEBUTTONDOWN:
                pos = pygame.mouse.get_pos()
                circles.append( pos ) # Add a new circle to the list
    
        # Update all the circles
        # ....
    
        # Draw
        clear the screen
        for circle_position in circles:
            draw the circle at circle_position # This will occur once for each circle
        update the display