如何让我的圈子在pygame中飞出屏幕?

时间:2012-08-11 03:21:38

标签: 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()
            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 个答案:

答案 0 :(得分:6)

创建圆圈(点击时),生成2个随机数。这些是二维Euclidean velocity向量的(x,y)分量:

enter image description here

# interval -1.0 to 1.0, adjust as necessary
vx, vy = ( (random.random()*2) -1, (random.random()*2) - 1 )

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

enter image description here

posx, posy = posx + vx, posy + vy

请注意,整体速度可能会有所变化。如果您希望始终具有每秒1.0的速度,请对矢量进行标准化:

要向量normalize,您可以将其除以magnitude

enter image description here

所以在你的情况下:

enter image description here

因此:

enter image description here

所以在Python中,导入mathimport math

mag = math.sqrt(vx*vx + vy*vy)
v_norm = vx/mag, vy/mag
# use v_norm instead of your (vx, vy) tuple

然后你可以将它与一些speed变量相乘,以获得可靠的速度。


一旦你开始让多个物体四处移动并且可能在屏幕外移动,移除不可能再回来的屏幕外物体并且与你的程序无关,这是很有用的。否则,如果您在创建更多内容时继续跟踪所有这些屏幕外对象,则会导致内存泄漏,并且在给定足够时间/操作的情况下将耗尽内存。


虽然你现在正在做的事情很简单,假设你还没有,学习一些基本的矢量数学将很快就能收回成功。最终你可能需要进行一些矩阵数学来进行某些变换。如果你是新手,它并不像它最初看起来那么难。如果你开始尝试做更多雄心勃勃的事情,你可能会在没有学习的情况下逃脱,但如果你开始尝试做更多雄心勃勃的事情,你将在以后节省你的努

答案 1 :(得分:3)

目前,您正在执行以下操作(大幅简化您的代码)...

while True:
    if the mouse was clicked:
        draw a circle on the screen where the mouse was clicked

让我们让事情变得更容易,并逐渐建立起来。

在没有用户点击

的情况下从圆圈开始

为了简单起见,让我们在屏幕的左上角附近制作圆圈,这样我们就可以假设有一个圆圈(使一些逻辑变得更容易)

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

现在,每次循环时,圆圈的中心移动一点,然后将其绘制到新的位置。请注意,如果圆圈移动得太快,您可能需要减少添加到circle_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类,并使用它来跟踪与您的圈子相关的数据。否则,您可以为每个循环创建一个更新坐标列表。

用户点击

时添加圈子
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

让圆圈随机移动

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

我不确定你的数学背景是什么,所以你可能需要学习一些知识,以便理解如何在一个“方向”(有时称为“向量”)中存储一些数学程序。您可以尝试Preet的答案,看看是否有帮助。在几何和三角学的背景下,真正的理解更容易(尽管如果你找到一个好的资源,你可能会没有它)。

其他一些想法

您需要记住的其他一些事情:

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

  2. 现在,你有screen.lock()和screen.unlock()。你不需要这些。如果表面需要锁定/解锁屏幕表面(某些表面不需要),并且您打算手动访问像素数据,则只需要锁定/解锁屏幕表面。做一些事情,比如在屏幕上绘制圆圈,pygame自动锁定/解锁表面。简而言之,您现在无需处理锁定/解锁。