1

Ich versuche meinen Kreis mit Hilfe von Zelle graphics.py von meinem Rechteck abprallen zu lassen. Sobald der Kreis vom Rechteck abgeprallt ist, wollte ich, dass er sich zufällig weiterbewegt. Hier ist mein Code so weit und es funktioniert! Auch ich weiß, dass jede Kreisgrafik technisch die Punkte des kleinsten möglichen Quadrats verwenden kann, das um den Kreis passen würde, um die Kollision zu tun, aber ich habe Probleme damit.Kollisionen in Zelle graphics.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() 

Antwort

0

Ich weiß, dass jeder Kreis Grafiken technisch die Punkte der kleinstmöglichen Platz verwenden können, um den Kreis zu tun die Kollision

Ich spiele mit einer alternativen Tanne würde Idee - wir könnten einen Kreis um das Rechteck anstelle eines Quadrats um den Kreis betrachten. Das Problem für mich ist, dass wir nicht nur eine Kollision erkennen müssen, sondern mit einem Gefühl, auf welche Weise wir uns von dem anderen Objekt entfernen können. Es ist nicht nur True und False sondern eher eine (dx, dy) Art von Ergebnis.

Offensichtlich ist ein Kreis um das Rechteck ist zu grob, aber angenommen, es viele kleinere Kreise waren das Rechteck bilden und wir messen Kreismittenabstand einen Treffer zu erkennen:

enter image description here

A Wenn Sie nur auf einen zentralen (grünen) Kreis klicken, bedeutet das, dass Sie die vertikale Richtung des großen Kreises umkehren. Ein Treffer am Ende (rot) bedeutet, dass die horizontale Richtung des großen Kreises umgekehrt wird. Und wir können beide Arten von Treffern erkennen und den großen Kreis komplett umkehren.

Hier ist mein Nacharbeiten des Codes mit dem oben im Kopf - Ich reparierte auch Ihr mehrfaches Klicken Problem und machte viele Stiländerungen:

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() 

Nicht perfekt, aber etwas zu spielen, um möglicherweise Verstopfung in einer besseren intersects() Implementierung.

+0

Danke! Das war sehr hilfreich! – jen