我是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
答案 0 :(得分:6)
创建圆圈(点击时),生成2个随机数。这些是二维Euclidean velocity向量的(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的速度,请对矢量进行标准化:
要向量normalize,您可以将其除以magnitude:
所以在你的情况下:
因此:
所以在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
变量相乘,以获得可靠的速度。
一旦你开始让多个物体四处移动并且可能在屏幕外移动,移除不可能再回来的屏幕外物体并且与你的程序无关,这是很有用的。否则,如果您在创建更多内容时继续跟踪所有这些屏幕外对象,则会导致内存泄漏,并且在给定足够时间/操作的情况下将耗尽内存。
虽然你现在正在做的事情很简单,假设你还没有,学习一些基本的矢量数学将很快就能收回成功。最终你可能需要进行一些矩阵数学来进行某些变换。如果你是新手,它并不像它最初看起来那么难。如果你开始尝试做更多雄心勃勃的事情,你可能会在没有学习的情况下逃脱,但如果你开始尝试做更多雄心勃勃的事情,你将在以后节省你的努
答案 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的答案,看看是否有帮助。在几何和三角学的背景下,真正的理解更容易(尽管如果你找到一个好的资源,你可能会没有它)。
您需要记住的其他一些事情:
现在,我们正在使用“与帧速率相关”的代码。也就是说,圆圈在屏幕上移动的速度完全取决于计算机的运行速度;较慢的计算机会看到圆圈像蜗牛一样移动,而更快的计算机在离开屏幕之前几乎看不到圆圈!有一些方法可以解决这个问题,您可以自己查找(搜索“帧率依赖”或您喜欢的搜索引擎中的其他术语)。
现在,你有screen.lock()和screen.unlock()。你不需要这些。如果表面需要锁定/解锁屏幕表面(某些表面不需要),并且您打算手动访问像素数据,则只需要锁定/解锁屏幕表面。做一些事情,比如在屏幕上绘制圆圈,pygame自动锁定/解锁表面。简而言之,您现在无需处理锁定/解锁。