【问题标题】:Bouncing 30 balls around the screen在屏幕上弹跳 30 个球
【发布时间】:2015-11-17 05:59:00
【问题描述】:

我的任务是在创建的窗口上显示 30 个弹跳球。我才刚刚开始学习课程,我似乎无法弄清楚如何显示 30 个要弹跳的球。我可以将一个球从所有四面墙上弹开。

#! /usr/bin/env python3

# Dorthy Petrick
# Display 30 bouncing balls bouncing around the screen

from graphics import *
from time import sleep
from random import *

class Ball:
    def __init__(self):
        self.dx = 1
        self.dy = 1

    def draw(self, win):
        self.ball = Circle(Point(25, 60), 3)
        self.ball.setFill('blue')
        self.ball.draw(win)

    def move(self):
        self.ball.move(self.dx,self.dy)

        xValue = self.ball.getCenter().getX()
        yValue = self.ball.getCenter().getY()

        if 550 < xValue:
            self.dx = -self.dx

        if -xValue > xValue:
            self.dx = -self.dx

        if 500 < yValue:
            self.dy = -self.dy

        if -yValue > yValue:
            self.dy = -self.dy

def main():
    win = GraphWin("bouncy.py", 550, 500)
    ball = Ball()
    ball.draw(win)
    counters = []

    while True:
        for i in range(30):
            ball.move()
            counter = Counter()
            counter.setCounterId(i + 1)
            balls.append(ball)



    win.getMouse()
    win.close()

if __name__ == '__main__':
    main()

【问题讨论】:

  • 您每次都将相同的ball 附加到balls。每次执行 for 循环时,您都需要启动一个新的 Ball() 对象。
  • 在代码审查方面: - 尽量不要硬编码像屏幕宽度这样的值(将它们作为参数传递或将它们声明为全局变量)。 - 不惜一切代价避免from X import *,你的主要功能有点没用(除了C相似性之外没有其他原因改变声明) - 你的sleep(0.05)ball.move()之后会出现问题(移动的球越多睡眠时间!),考虑在主事件循环中移动它。玩得开心:)
  • 另外,Counter.__init__ 中的缩进问题。考虑在 CodeReview 网站上发布成功的代码 =)
  • 我不确定Counter 是干什么用的! :P
  • 那个也是。我刚刚还意识到不管ball.x,你的绘图函数都会在同一个地方绘制:(25, 60)

标签: python class


【解决方案1】:

考虑到你的球类是可以的:

编辑以修复您的 Ball 类:

import random
class Ball:
    def __init__(self):
        self.dx = 1
        self.dy = 1
        self.ball = Circle(Point(random.randint(0, 550), random.randint(0, 500)), 3) # use random to randomly display the balls
        self.ball.setFill('blue')

    def draw(self, win):
        self.ball.draw(win)

    def move(self):
        self.ball.move(self.dx,self.dy)
        #sleep(0.005) #not needed...

        xValue = self.ball.getCenter().getX()
        yValue = self.ball.getCenter().getY()

        if 550 < xValue:
            self.dx = -self.dx

        if -xValue > xValue:
            self.dx = -self.dx

        if 500 < yValue:
            self.dy = -self.dy

    if -yValue > yValue:
        self.dy = -self.dy

def main():
    win = GraphWin("bouncy.py", 550, 500)
    ball_lst = [Ball() for i in range(30)] #Initialize 30 balls
    for ball in ball_lst:
        ball.draw(win)
    while True:
        for ball in ball_lst: # for each ball in our balls list
            ball.move() #move the ball
    win.getMouse()
    win.close()

这应该可以完成工作。

【讨论】:

  • 由于“球”对象没有属性“球”,我似乎得到了一个 AttributeError。
  • @Dorthy 您在Ball.draw 中创建self.ball,因此当您尝试在Ball.move 中调用它时,它还不存在。尝试将其移至 __init__ 方法。
  • 我目前在图形方面遇到了更大的错误。第 396 行,在绘制中如果 self.canvas 而不是 self.canvas.isClosed(): raise GraphicsError(OBJ_ALREADY_DRAWN) graphics.GraphicsError: Object current drawn
  • @Dorthy,试试这个最后一个,似乎draw方法应该只调用一次,无论如何,关心所有球都用相同的值实例化,所以每个球都是一个另一个
  • @DanielSanchez 关于如何为圆圈创建随机点的任何提示?
猜你喜欢
  • 1970-01-01
  • 2022-11-16
  • 1970-01-01
  • 2013-05-23
  • 1970-01-01
  • 1970-01-01
  • 2020-02-22
  • 1970-01-01
  • 2012-10-12
相关资源
最近更新 更多