I am very new to python and I have this code that I wrote... I am trying to make it so the turtle will bounce if it touches any of the box.. but somehow the turtle does not fuction the way it suppose.. I wonder can anyone give me a hand?

Thanks.

Recommended Answers

All 18 Replies

Hi!

Your if's in bounce() are not doing what you want ;) Try this:

if (-150 <=  x <= -110) and (80 >= y >= 40):
    turtle.left(40)
elif (-90 <= x <= -50) and (30 >= y >= -10):
    turtle.left(40)
elif (-30 <= x <= 10) and (-20 >= y >= -60):
    turtle.left(40)
elif (30 <= x <= 70) and (-80 >= y >= -120):
    turtle.left(40)
...

This does also not work properly, but looks a bit better :)

Regards, mawe

I changed the thing to this

if (-150 <=  x <= -110) and (80 >= y >= 40):
			turtle.left(40)
		elif (-90 <= x <= -50) and (30 >= y >= -10):
			turtle.left(40)
		elif (-30 <= x <= 10) and (-20 >= y >= -60):
			turtle.left(40)
		elif (30 <= x <= 70) and (-80 >= y >= -120):
			turtle.left(40)
		elif (90 <= x <= 130) and (-120 >= y >= -160):
			turtle.left(40)
		elif (-150 <=  x <= -110) and (-120 >= y >= -160):
			turtle.left(40)
		elif (90 <= x <= 130) and (80 >= y >= 40):
			turtle.left(40)

but it is bouncing out of range..

Hi Skyline_GTR,

It looks like the second y-coordinate for each of your if-elifs is off by 80, because you told the turtle to walk 40 steps in the wrong direction. In other words, change your polygon() function to look like this:

def polygon(sides,length):
     for step in range(sides):
          print turtle.position()
          turtle.forward(length)
          turtle.left(360/sides)

All this does is print out the turtle's location at the four corners of each box. Check the y-coordinates against the ones in your if-elifs, and I think you'll find that they don't quite match up. I suspect this is because you thought that saying turtle.down() actually makes the turtle point downwards, in addition to setting it down on the canvas - unfortunately, it doesn't!

Hi Skyline_GTR,

It looks like the second y-coordinate for each of your if-elifs is off by 80, because you told the turtle to walk 40 steps in the wrong direction. In other words, change your polygon() function to look like this:

def polygon(sides,length):
for step in range(sides):
print turtle.position()
turtle.forward(length)
turtle.left(360/sides)

All this does is print out the turtle's location at the four corners of each box. Check the y-coordinates against the ones in your if-elifs, and I think you'll find that they don't quite match up. I suspect this is because you thought that saying turtle.down() actually makes the turtle point downwards, in addition to setting it down on the canvas - unfortunately, it doesn't!

Ok, I fixed the coordinates. but I want to ask a question. When it touches the y coordinates, it will bounce correctly.. but when it bounce on the the top or the bottom of the box, it doesn't bounce it suppose to be..
the code is like this

if (-150 <=  x <= -110) and (120 >= y >= 80):
   turtle.left(180 - 2*angle)

I wonder how do you make it so when it bounce on the on the top or the bottom of the box, it will bounce like "turtle.right(2*angle)" using this code.

Thanks.

Ok, I fixed the coordinates. but I want to ask a question. When it touches the y coordinates, it will bounce correctly.. but when it bounce on the the top or the bottom of the box, it doesn't bounce it suppose to be..
the code is like this

if (-150 <= x <= -110) and (120 >= y >= 80):
turtle.left(180 - 2*angle)

I wonder how do you make it so when it bounce on the on the top or the bottom of the box, it will bounce like "turtle.right(2*angle)" using this code.

Thanks.

anyone can give me a hand on this?

Nice little game program! Could you gives us your latest project zip file? Makes it easier to look at and help you!

here you go I really hope you can give me a hand here.. because I don't know why the if statment is so werid... it will not bounce correctly.

I have uploaded two version of the bounce.. the project1 bounce is so werid that I have no clue how to fix..
the second file is semi working when it bounce the left or the right side of the box, it will bounce correctly... but when it bounces up or down, it will just go straight down...I know that I should use

turtle.right(2*angle)

for the top and bottom bounce.. but I don't know how do to make it so when it touches the top and bottom of the box, it will use this bounce

turtle.right(2*angle)

and when it touches left or right, it will use this bounce

turtle.left(180 - 2*angle)

Thanks.

I looked at you updated project2.py.
Looks like you mixed space and tabs, got that fixed.
Random is imported but never used.
Don't you need line to start program?
What is range of steps, 1000 to 5000?

sorry for double post.. I thought I clicked the edit button..

to start the program, you type play_bounce()
then after it draws the layout, it will ask your the angle you want to shoot and the number of steps. but it will just not bounce corectly..if you read my last post, that is the specific problem that I have..

This is your problem:

When the turtle collides with a box, you want to detect whether the collision happened because the turtle bumped into a vertical side (left, right) or a horizontal side (top, bottom). Depending on how the collision occurred, you do different things.

Correct?

Okay, let's think about this. There are three ways the turtle can collide with a box:

i) it crosses the left or right side (the vertical case),
ii) it crosses the top or bottom (the horizontal case), or
iii) it crosses at a corner (the corner case).

At any given iteration of the loop, all we know is the turtle's current position. This tells us nothing about which side the turtle collided with, especially near the corners, or if the step size is large. However, if we keep track of the last position the turtle was in for each step, we can draw a line segment between the turtle's current position and the turtle's last position. Then we can test for our three conditions by doing this:

If the line segment contains any box's corner points it is the corner case.
Otherwise, if the line segment intersects with the left or right sides, it is a vertical case.
Otherwise, it is a horizontal case.

How do we test for line segment intersection?

Suppose the line segment goes from (x1,y1) to (x2,y2) and there is a vertical box side going from (xb,yb1) to (xb,yb2). In other words, the turtle's last position was (x1,y1) and the turtle's current position is (x2,y2). Also, note that because the box side is a vertical line the x-coordinates of its endpoints are the same. Now, if x1 < xb < x2 and the y-coordinate of the line segment at xb is between yb1 and yb2, the line segments intersect.

How do you find the y-coordinate of the line segment at xb? Get the slope of the line segment by dividing:

(y2-y1) / (x2-x1)

Then multiply this by (x1-xb) and add y1. This should give you the y-coordinate of the line segment at xb. Make sense?

As another aside, you really shouldn't move the turtle until you're sure you're not going to collide with anything. I guess it doesn't matter in this case, because you're taking very small steps, but if you were taking larger steps you would have to check for collisions before moving.

this sound complicate to me. when you said the line segment. So what you said it is possible to do what I want right?

the part that I am comfused with is when you talk about the current position and the last position. How do I find the last position? Can you give me a hint?

Prepare yourself for a long post.

The turtle makes a step at the beginning of every iteration of the loop. Then, you check to see if the step has caused a collision.

Suppose that we're in the middle of the program, and the turtle has made N steps with no collisions.

If the N+1st step causes a collision, then we can draw a line segment between the position of the turtle at the Nth step and the position of the turtle at the N+1st step. This line segment should cut across, or "intersect" the side or corner of a box, because the Nth step was outside of the box, and the N+1st step is inside the box.

Is that clear? That's kind of the crux of it.

Here are some numbers to make this example concrete. Imagine that we have just one box with coordinates (0,90),(0,120),(30,120),(30,90). Imagine that our turtle starts at (-10.5,100) and travels in the direction of the x-axis (angle=0) and each step moves it forward by +1.

So, let's do a "trace" of the program:

N is the step we're currently on:

N     Turtle Position     Collision?
1     (-10.5,100)         No
2     (-9.5,100)          No
3     (-8.5,100)          No
4     (-7.5,100)          No
5     (-6.5,100)          No
6     (-5.5,100)          No
7     (-4.5,100)          No
8     (-3.5,100)          No
9     (-2.5,100)          No
10    (-1.5,100)          No
11    (-0.5,100)          No
12    (0.5,100)           YES

You can see this, right? If not, try graphing it out with paper and pencil!

Now, if we draw a line segment between the position at step 11 (-0.5,100) and the position at step 12 (0.5,100), we will see that the line segment crosses the side of the box, because when the turtle was at (-0.5,100) it was outside of the box, and now it is inside the box at (0.5,100). Is this part clear?

Okay. Before we go any further, let's talk about how to get that line segment in the first place. To form that line segment, we need two things: the turtle's current position, which you already know how to get, and the turtle's previous position. So you need to save the turtle's previous position somehow. Here's one way to do it, but very simplified:

x_previous = -10.5
y_previous = 100
for step in range(number_of_steps):
     # Move the turtle
     # Check for box collisions
     # If there is a collision, do what I described above
     # Now we are at the end of the loop
     x_previous = x
     y_previous = y

Let's look at what this code does for the first two steps. We set x_previous and y_previous to -10.5 and 100, respectively, outside the loop. Then we do the major part of the loop - remember, during the first step the turtle moves from (-10.5,100) to (-9.5,100). At the end of the loop, x_previous gets set equal to -9.5 and y_previous gets set equal to 100. What this means is that at any step of the loop, (x_previous,y_previous) is the position the turtle was just at one step ago.

Is it getting clearer now?

Okay, so, what do you do with that line segment? Imagine that your turtle has caused a collision. Your current collision-detection code will work for this. We would like to know whether the collision happened because the turtle entered the box from a vertical side (left or right) or from a horizontal side (top or bottom).

If the line segment intersects any of these sides, that was the side which caused the collision. Therefore, we will test all four sides for intersection with the line segment. But how do we detect intersection between a line segment and the side of a box? Let's look at our example above.

Suppose we want to test the intersection of the line segment that goes between (-0.5,100) and (0.5,100) with the left side of the box, which is goes between (0,90) and (0,120). You do this by asking two questions:

Is the x-coordinate of the left side of the box (which is 0) between the x-coordinates of the endpoints of the line segment (which are -0.5 and 0.5)? In other words, is 0 between x_previous and x? In this case, it is.

Now, if that is true, we answer a second question. First, find the point on the line segment that shares an x-coordinate with the side of the box. This is essentially the point where the two intersect. We observe that a vertical side has only one x-coordinate - in this case, it's 0, but we will call it xb in general. You can find the y-coordinate of that point using the slope of the line segment:

y_coord = ((y-y_previous)/(x-x_previous))*(xb-x_previous)+y_previous

The second question is "is y_coord between the y-coordinates of the left side of the box?"

If y_coord is between the y-coordinates of the left side of the box (between 90 and 120, in this case), there is an intersection, and you have just figured out which side caused the collision. So let's try this with our example. In our case:

y_coord = ((100-100)/(0.5--0.5))*(0--0.5)+100 = 100

Is 100 between 90 and 120? Why yes, it is. This means that the turtle definitely just crossed the left side, and we should use whatever angle change we need to use for collisions with the left and right side of a box.

This whole setup inverts itself for the horizontal lines. However, you really don't need to check those - for each box, just check the top and the bottom. If neither the top nor the bottom caused the collision, the left or the right side must have.

Is this clear?

Thanks for you long explaination. but I think I am too dumb for this...The part where you said to draw a line segment, I am lost already..I am not sure where I should put the codes.

Looks like your turtle figures out the left and right side of box, but not top and bottom. Could this be because the way if evaluates your and statement? If y is false it doesn't bother with x.

it is because if you bounce top and down, you should use

turtle.right(2*angle)

but if you bounce left and right, you should use

turtle.left(180 - 2*angle)

Skyline_GTR,

You're not using turtle to draw a line segment - the line segment is imaginary. It lets you figure out which side of the box got breached.

The code I described would go inside the if-elif statements. You would have something like:

if (-150 <= x <= -110) and (120 >= y >= 80):
     # Here is where you put my method

I would like to help you further, but you're going to have to meet me half-way, here. Please tell me what you understand and what you don't.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.