泽尔的碰撞图形.py

2024-04-26 05:17:50 发布

您现在位置:Python中文网/ 问答频道 /正文

我试着用Zelle使我的圆圈从矩形反弹图形.py. 一旦圆从矩形反弹出去,我希望它继续随机移动。这是我目前为止的代码,它正在工作! 我也知道,每一个圆图形技术上都可以使用最小的正方形的点来进行碰撞,但我做这件事有困难。在

from graphics import *
import random

def delay(d):
    for i in range(d):
        for i in range(50):
            pass
#-------------------------------------------------
def main():


    win=GraphWin("Moving Circle",500,400)
    win.setBackground('white')
    pt= Point(100,200)
    cir=Circle(pt,30)
    #changes the color of the circle for each game
    r = random.randrange(256)
    b = random.randrange(256)
    g = random.randrange(256)
    color = color_rgb(r, g, b)
    cir.setFill(color)
    cir.draw(win)
#rectangle
    rec = Rectangle(Point(450,450), Point(275, 425))
    rec.draw(win)
    rec.setFill('black')
#-------------------------------------------------
    pt5 = Point(250,30)
    instruct1=Text(pt5, "click multiple times to start(rectangle can take multiple clicks to move)")
    instruct1.setTextColor('black')
    instruct1.draw(win)


#-------------------------------------------------
    p=cir.getCenter()
    p2=win.getMouse()

    dx=1
    dy=1

    keepGoing=True

    while keepGoing:
        d = 100
        delay(d)
        cir.move(dx,dy)
        p=cir.getCenter()
        p2=win.checkMouse()
        instruct1.setText("")


#rectanlge
        isClicked= win.checkMouse()
        if isClicked:
            rp = isClicked
            rc = rec.getCenter()
            rdx = rp.getX() - rc.getX()
            rdy = rp.getY() - rc.getY()
            rec.move(rdx,rdy)

#circle
        if((p.getX()-30)<=0.0) or ((p.getX()+30)>=500):
            dx= -dx

        if((p.getY()-30)<=0.0) or ((p.getY()+30)>=400):
            dy=-dy
        p3=win.checkMouse()



main()

Tags: formoverandomwincolorpointdrawrec
1条回答
网友
1楼 · 发布于 2024-04-26 05:17:50

I know that each circle graphics technically can use the points of the smallest possible square that would fir around the circle to do the collision

我在考虑另一个想法,我们可以考虑一个围绕矩形的圆,而不是一个围绕圆的正方形。对我来说,问题是我们不仅需要检测碰撞,还需要知道从另一个物体移开的方法。它不仅仅是TrueFalse,而是(dx, dy)类型的结果。在

显然,一个围绕矩形的圆太粗糙了,但是假设它是由许多较小的圆组成的矩形,我们测量圆的中心到中心的距离来检测命中:

enter image description here

击中一个中心(绿色)矩形圆圈意味着反转大圆的垂直方向。只在末端(红色)的圆圈上击中意味着与大圆的水平方向相反。我们可以检测到这两种类型的撞击并完全扭转大圈。在

下面是我对您的代码进行的修改,我还修复了您的多次单击问题,并进行了许多样式更改:

from random import randrange
from graphics import *

WIDTH, HEIGHT = 500, 400

RADIUS = 30

def delay(d):
    for _ in range(d):
        for _ in range(50):
            pass

def distance(p1, p2):
    return ((p2.getX() - p1.getX()) ** 2 + (p2.getY() - p1.getY()) ** 2) ** 0.5

def intersects(circle, rectangle):

    dx, dy = 1, 1  # no change

    center = circle.getCenter()

    rectangle_radius = (rectangle.p2.getY() - rectangle.p1.getY()) / 2
    rectangle_width = rectangle.p2.getX() - rectangle.p1.getX()

    y = rectangle.getCenter().getY()

    for x in range(int(rectangle_radius * 2), int(rectangle_width - rectangle_radius * 2) + 1, int(rectangle_radius)):
        if distance(center, Point(rectangle.p1.getX() + x, y)) <= rectangle_radius + RADIUS:
            dy = -dy  # reverse vertical
            break

    if distance(center, Point(rectangle.p1.getX() + rectangle_radius, y)) <= rectangle_radius + RADIUS:
            dx = -dx  # reverse horizontal
    elif distance(center, Point(rectangle.p2.getX() - rectangle_radius, y)) <= rectangle_radius + RADIUS:
            dx = -dx  # reverse horizontal

    return (dx, dy)

def main():
    win = GraphWin("Moving Circle", WIDTH, HEIGHT)

    circle = Circle(Point(WIDTH / 5, HEIGHT / 2), RADIUS)

    # change the color of the circle for each game
    color = color_rgb(randrange(256), randrange(256), randrange(256))
    circle.setFill(color)

    circle.draw(win)

    # rectangle
    rectangle = Rectangle(Point(275, 425), Point(450, 450))  # off screen
    rectangle.setFill('black')
    rectangle.draw(win)

    dx, dy = 1, 1

    while True:
        delay(100)
        circle.move(dx, dy)

        # rectangle
        isClicked = win.checkMouse()

        if isClicked:
            point = isClicked
            center = rectangle.getCenter()
            rectangle.move(point.getX() - center.getX(), point.getY() - center.getY())

        # circle
        center = circle.getCenter()

        if (center.getX() - RADIUS) <= 0.0 or (center.getX() + RADIUS) >= WIDTH:
            dx = -dx

        if (center.getY() - RADIUS) <= 0.0 or (center.getY() + RADIUS) >= HEIGHT:
            dy = -dy

        # collision bounce

        x, y = intersects(circle, rectangle)
        dx *= x
        dy *= y

main()

不是完美的,但是有一些东西可以玩,可能插入一个更好的intersects()实现。在

相关问题 更多 >