【问题标题】:How do I determine if my mouse is over randomly spawning objects如何确定我的鼠标是否在随机生成的对象上
【发布时间】:2020-06-01 09:22:29
【问题描述】:

我正在尝试实现一个游戏,它允许点击随机生成的圆圈,每次点击它都会给你积分。

import pygame
import time
import random

pygame.init()
window = pygame.display.set_mode((800,600))

class Circle():

    def __init__(self, color, x, y, radius, width):
        self.color = color
        self.x = x
        self.y = y
        self.radius = radius
        self.width = width

    def draw(self, win, outline=None):
        pygame.draw.circle(win, self.color, (self.x, self.y), self.radius, self.width)

    def isOver(self, mouse):

        mouse = pygame.mouse.get_pos()
        # Pos is the mouse position or a tuple of (x,y) coordinates
        if mouse[0] > self.x and mouse[0] < self.x + self.radius:
            if mouse[1] > self.y and mouse[1] < self.y + self.width:
                return True

        return False

circles = []

clock = pygame.time.Clock()
FPS = 60

current_time = 0
next_circle_time = 0

run=True
while run:
    delta_ms = clock.tick()

    current_time += delta_ms
    if  current_time > next_circle_time:
        next_circle_time = current_time + 1000 # 1000 milliseconds (1 second)
        r = 20
        new_circle = Circle((255, 255, 255), random.randint(r, 800-r), random.randint(r, 600-r), r, r)
        circles.append(new_circle)
        print()

    window.fill((0, 0, 0))
    for c in circles:
        c.draw(window)
    pygame.display.update()

    for event in pygame.event.get():

        if event.type == pygame.QUIT:
            run=False
            pygame.quit()
            quit()

        if event.type == pygame.MOUSEBUTTONDOWN:
            if Circle.isOver(mouse):
                print('Clicked the circle')

但是,当我尝试实现最后一个条件时,如果 Circle.isOver(mouse):... 我收到此错误

TypeError: isOver() missing 1 required positional argument: 'mouse'

有谁知道这个问题的解决方案?非常感谢任何帮助!

【问题讨论】:

    标签: python oop pygame attributes


    【解决方案1】:

    您必须遍历列表circles 中包含的圆形对象。与绘制圆圈时类似。您必须评估 Circle 类的每个实例的鼠标是否打开,而不是 Class 本身。请注意,isOverMethod Object,必须由 Instance Objects 调用。
    由于该方法在MOUSEBUTTONDOWN事件发生时被调用,所以当前鼠标位置在event.pos属性中提供(见pygame.event):

    run=True
    while run:
        # [...]
    
        for event in pygame.event.get():
    
            if event.type == pygame.QUIT:
                run=False
                pygame.quit()
                quit()
    
            if event.type == pygame.MOUSEBUTTONDOWN:
                for c in circles:
                    if c.isOver(event.pos):
                        print('Clicked the circle')
    

    通过isOver中的pygame.mouse.get_pos()获取鼠标位置是多余的,因为当前鼠标位置是该方法的参数。
    我建议通过评估Euclidean distance与圆心的平方是否小于或等于圆半径的平方来评估是否单击了圆:

    class Circle():
    
        # [...]
    
        def isOver(self, mouse):
            dx, dy = mouse[0] - self.x, mouse[1] - self.y
            return (dx*dx + dy*dy) <= self.radius*self.radius 
    

    【讨论】:

    • "您必须遍历圆形对象...您必须评估鼠标是否为 Circle 类的每个实例打开,而不是针对 Class 本身。"我有点困惑,为什么我的原始代码不起作用,我认为在类中定义 isOver 使它成为一个类方法,它已经适用于类的所有实例?所以不会调用类(并通过逻辑扩展类的所有实例)并询问计算机它是否在任何圆实例上执行该功能。
    • @awesomelej Circle 不是实例对象。 Circle 只是一个定义圆的行为的类。 new_circleCircle 的实例对象。 new_circle 包含 Circle 对象的数据。所有圈子都包含在列表circles 中。但是Circle 类没有关于特定圈子的任何信息。阅读Classes
    • @awesomelej "[..] 已经适用于类的所有实例了吗?" 是的方法。但是您必须分别为每个实例调用它。 Class 不会神奇地将方法调用委托给它的所有实例。
    【解决方案2】:

    mouse 在传递给您的函数时未定义。还有其他问题,但这些是分开的。

    if event.type == pygame.MOUSEBUTTONDOWN:
            mouse = pygame.mouse.get_pos()
            for circle in circles: 
                if circle.isOver(mouse):
                    print('Clicked the circle')
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-12-02
      • 1970-01-01
      • 2010-12-16
      • 1970-01-01
      • 1970-01-01
      • 2014-05-13
      • 1970-01-01
      相关资源
      最近更新 更多