2

我是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

4

2 回答 2

7

创建圆圈时(单击),生成 2 个随机数。这些将是二维欧几里得 速度矢量的 (x,y) 分量:

在此处输入图像描述

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

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

在此处输入图像描述

posx, posy = posx + vx, posy + vy

请注意,整体速度可能是可变的。如果您希望始终保持每秒 1.0 的速度,请对向量进行归一化:

要对向量进行归一化,请将其除以其幅度

在此处输入图像描述

所以在你的情况下:

在此处输入图像描述

因此:

在此处输入图像描述

所以在 Python 中,在导入math之后import math

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

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


一旦你让多个对象四处移动并可能离开屏幕,删除那些没有机会回来并且与你的程序无关的屏幕外对象是很有用的。否则,如果您在创建更多对象的同时继续跟踪所有这些屏幕外对象,则本质上会出现内存泄漏,并且在足够的时间/操作下会耗尽内存。


虽然你现在做的事情很简单,假设你还没有,学习一些基本的向量数学很快就会得到回报。最终,您可能需要涉足一些矩阵数学来进行某些转换。如果您是新手,它并不像最初看起来那么难。你可能不去研究它而侥幸逃脱,但如果你开始尝试做更有野心的事情,你以后会省力。

于 2012-08-11T03:35:25.407 回答
5

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

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 会自动为你锁定/解锁表面。简而言之,您现在不需要处理锁定/解锁。

于 2012-08-12T18:25:17.017 回答