使用Python Zelle Graphics使圆圈(球)在窗口中反弹

时间:2016-11-16 18:39:38

标签: python zelle-graphics

我有一个Python程序,可以让一个球从窗口的四个侧面反弹,但现在我需要使用一个阵列制作10个球。我对此仍然很陌生,并对如何实现这一点感到困惑。我将发布到目前为止的内容:

#create 10 balls bouncing off all 4 sides of the window (400 x 500)
#The ball must start moving after a click, then stop after a given amount of time
#After a second click, the program ends

#----Algorithm----#

#create screen 400 x 500
#create array of 10 circles in different starting points

#wait for click anywhere on screen 
#click anywhere on screen
#all 10 balls move in different directions bouncing off all 4 walls
    #if ball hits left or right wall
            #dy=dy*-1
    #if ball hits top or bottom
            #dx=dx*-1 

#ball moves for no more than 30 seconds
#ball stops
#wait for next click
#program ends

#----ProgramStarts----#

    from graphics import *
    import time, random 

#create screen
winWidth = 400;
winHeight = 500;
win = GraphWin('Ball Bounce', winWidth, winHeight);
win.setBackground(color_rgb(255,255,255));
win.setCoords(0,0,winWidth, winHeight);
numBalls= 10;

#create 10 balls
def makeBall(center, radius, win):

    balls=[];
    radius=10;

    for i in range (0,numBalls):
        aBall=Circle(center, radius);
        aBall.setFill("red");
        aBall.draw(win);
        balls.append(aBall);


#animate 10 balls bouncing off edges of window
def bounceInWin(shape, dx, dy, xLow, xHigh, yLow, yHigh):
    clickPoint=win.getMouse();   
    delay = .005
    for x in range(900):
        shape.move(dx, dy)
        center = shape.getCenter()
        x = center.getX()
        y = center.getY()
        if x < xLow:
            dx = -dx
        if x > xHigh:
            dx = -dx
        if y < yLow:
            dy = -dy
        if y > yHigh:
            dy = -dy
        time.sleep(delay);


#get a random Point
def getRandomPoint(xLow, xHigh, yLow, yHigh):
    x = random.randrange(xLow, xHigh+1)
    y = random.randrange(yLow, yHigh+1)
    return Point(x, y)   

#make ball bounce
def bounceBall(dx, dy):    
    winWidth = 400
    winHeight = 500
    win = GraphWin('Ball Bounce', winWidth, winHeight);
    win.setCoords(0,0,winWidth, winHeight);

    radius = 10
    xLow = radius
    xHigh = winWidth - radius
    yLow = radius
    yHigh = winHeight - radius

    center = getRandomPoint(xLow, xHigh, yLow, yHigh)
    ball = makeBall(center, radius, win)

    bounceInWin(ball, dx, dy, xLow, xHigh, yLow, yHigh)

bounceBall(3, 5);

#wait for another click to end program
win.getMouse(); #close doesn't work, tried putting in loop 
win.close;

1 个答案:

答案 0 :(得分:0)

您的代码存在特定问题:makeBall()无法返回balls; makeBall()需要生成随机起点,而不是从同一个地方开始; bounceInWin()需要为每个球分别单独更新dx和dy,而不仅仅是一个;代码创建两次主窗口 - 只需一次就可以了;需要添加时间计算来关闭运动而不是固定的迭代次数; win.close()是一种方法,所以它需要括号;避免使用分号&#34;;&#34;在Python代码中。

以下是对代码的修改,包括上述更改和一些样式调整:

# Create 10 balls bouncing off all 4 sides of a window (400 x 500)
# The ball must start moving after a click, then stop after a given
# amount of time.  After a second click, the program ends.

#----Algorithm----#

# create screen 400 x 500
# create array of 10 circles in different starting points

# wait for click anywhere on screen
# all 10 balls move in different directions bouncing off all 4 walls
    # if ball hits left or right wall
        # dx = -dx
    # if ball hits top or bottom
        # dy = -dy

# balls move for no more than 30 seconds
# balls stops
# wait for next click
# program ends

#----ProgramStarts----#

import time
import random
from graphics import *

winWidth, winHeight = 400, 500
ballRadius = 10
ballColor = 'red'
numBalls = 10
delay = .005
runFor = 30  # in seconds

# create 10 balls, randomly located
def makeBalls(xLow, xHigh, yLow, yHigh):

    balls = []

    for _ in range(numBalls):
        center = getRandomPoint(xLow, xHigh, yLow, yHigh)

        aBall = Circle(center, ballRadius)
        aBall.setFill(ballColor)
        aBall.draw(win)
        balls.append(aBall)

    return balls

# animate 10 balls bouncing off edges of window
def bounceInWin(shapes, dx, dy, xLow, xHigh, yLow, yHigh):
    movedShapes = [(getRandomDirection(dx, dy), shape) for shape in shapes]

    start_time = time.time()

    while time.time() < start_time + runFor:
        shapes = movedShapes
        movedShapes = []

        for (dx, dy), shape in shapes:
            shape.move(dx, dy)
            center = shape.getCenter()

            x = center.getX()
            if x < xLow or x > xHigh:
                dx = -dx

            y = center.getY()
            if y < yLow or y > yHigh:
                dy = -dy

            # Could be so much simpler if Point had setX() and setY() methods
            movedShapes.append(((dx, dy), shape))

        time.sleep(delay)

# get a random direction
def getRandomDirection(dx, dy):
    x = random.randrange(-dx, dx)
    y = random.randrange(-dy, dy)

    return x, y

# get a random Point
def getRandomPoint(xLow, xHigh, yLow, yHigh):
    x = random.randrange(xLow, xHigh + 1)
    y = random.randrange(yLow, yHigh + 1)

    return Point(x, y)

# make balls bounce
def bounceBalls(dx, dy):

    xLow = ballRadius * 2
    xHigh = winWidth - ballRadius * 2
    yLow = ballRadius * 2
    yHigh = winHeight - ballRadius * 2

    balls = makeBalls(xLow, xHigh, yLow, yHigh)

    win.getMouse()

    bounceInWin(balls, dx, dy, xLow, xHigh, yLow, yHigh)

# create screen
win = GraphWin('Ball Bounce', winWidth, winHeight)

bounceBalls(3, 5)

# wait for another click to end program
win.getMouse()
win.close()

enter image description here