2009-09-21 6 views
1

Donc, j'essaie de faire une fonction de rebond réaliste, où la tortue frappe un mur et rebondit à l'angle correspondant. Mon code ressemble à ceci:TurtleGraphics Python: Tortue qui rebondit sur les murs?

def bounce(num_steps, step_size, initial_heading): 
    turtle.reset() 
    top = turtle.window_height()/2 
    bottom = -top 
    right = turtle.window_width()/2 
    left = -right 

    turtle.left(initial_heading) 
    for step in range(num_steps): 
     turtle.forward(step_size) 
     x, y = turtle.position() 
     if left <= x <= right and bottom <= y <= top: 
     pass 
     else: 
     turtle.left(180-2 * (turtle.heading())) 

Ainsi, cela fonctionne pour les parois latérales, mais je ne comprends pas comment le faire rebondir correctement sur le haut/bas. Aucune suggestion?

Répondre

1

Essayez quelque chose comme ceci:

if not (left <= x <= right): 
    turtle.left(180 - 2 * turtle.heading()) 
elif not (bottom <= y <= top): 
    turtle.left(-2 * turtle.heading()) 
else: 
    pass 

Ma syntaxe python est un peu rouillé, désolé: P. Mais le calcul est un peu différent pour un retournement horizontal ou vertical.

EDIT:

Je soupçonne que ce qui se passe est votre tortue est d'entrer dans une situation où il pointe vers le haut et collé au-dessus de la paroi supérieure. Cela l'amènerait à retourner indéfiniment. Vous pouvez essayer d'ajouter les conditions suivantes:

if (x <= left and 90 <= turtle.heading() <= 270) or (right <= x and not 90 <= turtle.heading() <= 270): 
    turtle.left(180 - 2 * turtle.heading()) 
elif (y <= bottom and turtle.heading() >= 180) or (top <= y and turtle.heading <= 180): 
    turtle.left(-2 * turtle.heading()) 
else: 
    pass 

Si cela fonctionne, il y a probablement un bug ailleurs dans votre code. La manipulation des arêtes est difficile à obtenir. Je suppose que turtle.heading() retournera toujours quelque chose entre 0 et 360 - sinon, il sera encore plus difficile de faire mieux.

+0

La tortue reste accrochée sur le mur supérieur, mais merci d'avoir essayé. –

+0

Oh, mise à jour: j'ai changé le -2 dans turtle.left sous elif pas à 2 et il semble rebondir correctement. Merci encore. –

+0

+1: La solution originale fonctionne bien pour moi. Agréable! –

0

Gday,

Votre problème semble être que vous utilisez le même trigonométrie pour calculer les parois droite et à gauche, comme vous êtes en haut et en bas. Un morceau de papier et un crayon devraient suffire pour calculer les déviations requises.

def inbounds(limit, value): 
    'returns boolean answer to question "is turtle position within my axis limits"' 
    return -limit < value * 2 < limit 

def bounce(num_steps, step_size, initial_heading): 
    '''given the number of steps, the size of the steps 
     and an initial heading in degrees, plot the resultant course 
     on a turtle window, taking into account elastic collisions 
     with window borders. 
    ''' 

    turtle.reset() 
    height = turtle.window_height() 
    width = turtle.window_width() 
    turtle.left(initial_heading) 

    for step in xrange(num_steps): 
     turtle.forward(step_size) 
     x, y = turtle.position() 

     if not inbounds(height, y): 
      turtle.setheading(-turtle.heading()) 

     if not inbounds(width, x): 
      turtle.setheading(180 - turtle.heading()) 

Je l'ai utilisé la fonction setheading et une fonction d'assistance (inbounds) de déclarer encore l'intention du code ici. Fournir une sorte de chaîne de doc est aussi une bonne pratique dans tout code que vous écrivez (à condition que le message qu'il indique est exact !!)

Votre kilométrage peut varier sur l'utilisation de xrange, Python 3.0+ rebaptise simplement range .

Questions connexes