How would you get turtle to overlap certain areas of squares? - python

So I had to get familiar with turtle for a project with school. I got basically everything my professor asked besides for overlapping the squares.
However he would like the squares to overlap like this
I haven't been able to replicate this at all. I am wondering if their is something I need to throw into my code to easily solve it.
Here is my code
import turtle #Imports the 'turtle module' which allows intricate shapes and pictures to be drawn
my_turtle_pos = (10 , 10)
def square(my_turtle,x,y,length) : #I set up a function that helps me determine the square
my_turtle.penup() #Picks 'up' the turtle pen
my_turtle.setposition(x-length/2,y-length/2) #Helps set positon
my_turtle.pendown() #Puts 'down' the turtle pen
my_turtle.color('black','red') #Allows black outline, with red filling
my_turtle.begin_fill() #Starts the filling of red and helps remember the starting point for a filled area
my_turtle.forward(length) #Moves the turtle by the specified amount 'length'
my_turtle.left(90) #Moves the turtle by given amount '90'
my_turtle.forward(length)
my_turtle.left(90)
my_turtle.forward(length)
my_turtle.left(90)
my_turtle.forward(length)
my_turtle.left(90)
my_turtle.end_fill() #Stops filling with red, which will close with the current color
def graphic_pattern(my_turtle,x,y,length,times): #recursive function
if times <= 0: #This just tells us how many 'times' it needs to repeat till given amount
return
newSize = length/2.2 #This will grab the new size
graphic_pattern(my_turtle,x-length/2,y-length/2,newSize,times-1) #Functions to help with writing 'smaller' squares
graphic_pattern(my_turtle,x-length/2,y+length/2,newSize,times-1)
graphic_pattern(my_turtle,x+length/2,y-length/2,newSize,times-1)
graphic_pattern(my_turtle,x+length/2,y+length/2,newSize,times-1)
square(my_turtle,x,y,length)
my_turtle = turtle.Turtle(shape="arrow") #You can use differen't shapes for the turtle, I chose arrow, though the turtle was cool :)
my_turtle.speed(100) #I am not sure how fast the turtle can go, I just chose 100 cause it went by quicker.
graphic_pattern(my_turtle,3,0,300,4) #Example pattern stated from homework assignment.
I think it's something to do with where the pen draws the squares first. Thanks for any input!

Sounds like it's a simple sequencing of your graphic_pattern() and square() methods. It seems you would want to draw the top right graphic_pattern() first, followed by the middle square, and then followed by the rest of the graphic_pattern() calls:
import turtle #Imports the 'turtle module' which allows intricate shapes and pictures to be drawn
my_turtle_pos = (10 , 10)
def square(my_turtle,x,y,length) : #I set up a function that helps me determine the square
my_turtle.penup() #Picks 'up' the turtle pen
my_turtle.setposition(x-length/2,y-length/2) #Helps set positon
my_turtle.pendown() #Puts 'down' the turtle pen
my_turtle.color('black','red') #Allows black outline, with red filling
my_turtle.begin_fill() #Starts the filling of red and helps remember the starting point for a filled area
my_turtle.forward(length) #Moves the turtle by the specified amount 'length'
my_turtle.left(90) #Moves the turtle by given amount '90'
my_turtle.forward(length)
my_turtle.left(90)
my_turtle.forward(length)
my_turtle.left(90)
my_turtle.forward(length)
my_turtle.left(90)
my_turtle.end_fill() #Stops filling with red, which will close with the current color
def graphic_pattern(my_turtle,x,y,length,times): #recursive function
if times <= 0: #This just tells us how many 'times' it needs to repeat till given amount
return
newSize = length/2.2 #This will grab the new size
graphic_pattern(my_turtle,x+length/2,y+length/2,newSize,times-1)
square(my_turtle,x,y,length)
graphic_pattern(my_turtle,x-length/2,y-length/2,newSize,times-1)
graphic_pattern(my_turtle,x-length/2,y+length/2,newSize,times-1)
graphic_pattern(my_turtle,x+length/2,y-length/2,newSize,times-1)
my_turtle = turtle.Turtle(shape="arrow") #You can use differen't shapes for the turtle, I chose arrow, though the turtle was cool :)
my_turtle.speed(100) #I am not sure how fast the turtle can go, I just chose 100 cause it went by quicker.
graphic_pattern(my_turtle,3,0,300,4) #Example pattern stated from homework assignment.

You have to change the visit order of your recursive calls.
Now the order is post-order (visit all children, then visit the node).
With this particular order (visit upper right child, visit the node, visit the remaining children):
def graphic_pattern(my_turtle,x,y,length,times): #recursive function
if times <= 0: #This just tells us how many 'times' it needs to repeat till given amount
return
newSize = length/2.2 #This will grab the new size
graphic_pattern(my_turtle,x+length/2,y+length/2,newSize,times-1)
square(my_turtle,x,y,length)
graphic_pattern(my_turtle,x-length/2,y-length/2,newSize,times-1) #Functions to help with writing 'smaller' squares
graphic_pattern(my_turtle,x-length/2,y+length/2,newSize,times-1)
graphic_pattern(my_turtle,x+length/2,y-length/2,newSize,times-1)
you can obtain the desired pattern.

Related

Turtle Collision Python

I am creating a snake game and I want an action to happen if I touch another turtle on my screen?
fruit = turtle.Turtle()
fruit.penup()
fruit.size = 45
fruit.color("Black")
fruit.shape("circle")
fruit.goto(randint(-180,0),randint(0,180))
That is the fruit code so you know what I have.
Unfortunately the Turtle package doesn't have a built-in collision mechanism, so you will have to define what a collision is, and repeatedly check for a collision yourself.
You can define a "collision" checking function using whatever definiton of collision you want.
For example if the distance between the centers of the two fruits is less than the combined radii of the turtles, that means the edges of the circles are overlapping. (For more complex shape a custom box or shape could be used to detect collisions)
Turtles' shapesize gives a multiplier on the default turtle size of 20, which we half to get the radius:
def is_collided(a, b):
distance = b.distance(a.pos())
radius_a = a.shapesize()[0] * 10
radius_b = b.shapesize()[0] * 10
return radius_a + radius_b >= distance
You can then define a list of different turtles, and loop through them to check whether any of them have collided with your fruit, and print if so:
other_turtles = [turtle1, turtle2, turtle3]
for t in other_turtles:
if is_collided(fruit, t):
# can define other actions here
print(f'collision between fruit and {t}')
If you just copy those two snippets directly below your sample code, and replace turtle1, turtle2 with the names of your other turtles, it should work.
You can also see this in action with different fruits here.

Need help making a drawing using recursion

I need to make a code in python that draws the output below using recursion and a function named drawpoly. drawpoly() will take 6 arguments which include a turtle, the length of a side, the number of sides, red, green & blue. While the number of sides is > 2, drawpoly() will recursively call itself decrementing the number of sides by 1 each call. Red will increment by 10, green by 25 & blue by 35 each call. I need to set fillcolor and begin and end fill. I will also need will need to set the screen colormode to be able to use integers to make your colors.
[![enter image description here][1]][1]
her's the code I have so far It doesn't print out anything but its a rough outline of what I need to use in the program
wn = trtl.Screen()
def drawpoly(trtl, num_sides, side_length,color):
numOfSides=8
num_sides=8
side_length=100
color="blue"
while (numOfSides >2):
trtl.drawpoly(trtl,num_sides,side_length,color)
numOfSides -=1
def main():
return drawpoly
main()
[1]: https://i.stack.imgur.com/65dS4.png

How to keep the random moving enemies inside the screen in pygame?

I want to keep the enemies (red rectangles in my case) inside the rectangle.What happens is that since it's a random function , the enemies keep on moving.But slowly some of my enemies moves outside , I don't want this to happen.I want them to be inside the screen only.
I have tried subtracting the screen width and screen height but was unsuccessful in my attempt to do so.So basically what I am asking is how do I check if rectangle is inside the screen.
EDIT :
This is not a possible duplicate as my enemies are moving randomly.In that the player is controlled by the user whereas my program , the movements of the enemy are totally random.
Here is my random movement for my enemies:
def evilMove(evilGuy):
evilCoords = []
#Returns either -1, 0 or 1
randomMovex=random.randrange(-1,2)
randomMovey=random.randrange(-1,2)
evilMake={'x':evilGuy[0]['x']+randomMovex,'y':evilGuy[0]['y']+randomMovey}
del evilGuy[-1] #Delete the previous spawn of enemy so there is no trail
evilCoords.append(evilMake['x']) #Adds x coordinate
evilCoords.append(evilMake['y']) #Adds y coordinate
deadZones.append(evilCoords) #Adds the enemy coordinates in the list
evilGuy.insert(0,evilMake)
Thanks in advance.
Well, you should really look at other questions similar to this, but you could make an if statement where you test if it is outside the screen.
Lets just say your screen is 500 by 500, you would do,
if coordinatesx < 500:
do this and that
if coordinatesy < 500:
do this and that.
This checks if the coordinates of your bad guy are being checked by the screen by saying if the bad guys coordinates are not larger than the screen, then do what you need to do.
EDIT _________________________________________
def evilMove(evilGuy):
evilCoords = []
#Returns either -1, 0 or 1
if x < 500 and y < 500:
randomMovex=random.randrange(-1,2)
randomMovey=random.randrange(-1,2)
evilMake={'x':evilGuy[0]['x']+randomMovex,'y':evilGuy[0]['y']+randomMovey}
Im not sure what your x and y variable is called, just replace it with that. And replace the 500 with your sreen width.

How to make one cannon instead of multiple?

I am currently in the process of making a new cannon game. How can I make it so that there is just one cannon, on the bottom left hand of the screen?
from graphics import *
from math import sqrt
from math import trunc
def PinR(p,r):
if p.getX()>=r.getP1().getX() and p.getX()<=r.getP2().getX()and p.getY()>=r.getP1().getY() and p.getY()<=r.getP2().getY():
return True;
else:
return False;
def distance(p1,p2):
dx=p1.getX()-p2.getX();
dy=p1.getY()-p2.getY();
dist=sqrt(dx*dx+dy*dy);
return dist;
#parameter
FieldWidth=700;
FieldHeight=700;
GroundDepth=75;
BallSize=10;
OriginalSpeed=4;
FieldBackground="brown";
FieldBorder="brown";
tickLength=800000;
buttonSize=8;
# number of cannons and balls
numBalls=4;
# initial cannon power
explosionStrength=30;
# intial gravitational constant
g=1;
# clock tick delay
delay=0.05;
#Create field
Field=GraphWin("B",FieldWidth,FieldHeight);
Field.setBackground(FieldBackground);
#set of balls
spacing=FieldWidth/(numBalls);
ball=[];
for b in range (0,numBalls):
newball=Circle(Point(spacing*b+spacing//2,FieldHeight-GroundDepth),BallSize);
newball.setFill("black");
newball.draw(Field);
ball.append(newball);
#cannon
cannon=[]
for c in range (0,numBalls):
newCannon=Rectangle(Point(spacing*c+spacing//2-BallSize,FieldHeight-GroundDepth-BallSize*5),
Point(spacing*c+spacing//2+BallSize,FieldHeight-GroundDepth+BallSize));
newCannon.setFill("black");
newCannon.draw(Field);
cannon.append(newCannon);
#set of button groups (fire, powerup, powerdown)
fire=[];
for f in range (0,numBalls):
newbutton=Rectangle(Point(spacing*f+spacing//2-buttonSize//2,FieldHeight-GroundDepth-BallSize),
Point(spacing*f+spacing//2+buttonSize//2,FieldHeight-GroundDepth-BallSize+buttonSize));
newbutton.setFill("red");
newbutton.draw(Field);
fire.append(newbutton);
#wall
#target(red,white,red,white)
balldistance=20;
ball1=Circle(Point(FieldWidth//2-20,FieldHeight//2+20),BallSize);
ball1.setFill("red");
ball1.draw(Field);
The reason you get 4 cannons is that you're doing this:
for c in range (0,numBalls):
… where numBalls is 4, and you create a new cannon each time through the loop.
Presumably with only 1 cannon you also only want one cannon ball and one shot, so just set numBalls = 1 instead of numBalls = 4.
However, it might make more sense to simplify the program while you're at it. Replace the lists of 4 cannons with a single cannon, get rid of the loop, do the same for the 4 balls, etc. Then you can also simplify the layout rules—no need for a spacing variable to configure how far apart the cannons are if there's only 1 of them. And so on. This might make it easier for you to understand how the program works—and figuring out how to simplify it might similarly be beneficial on its own.
And if you want to change its position, that's being set in this line:
newCannon=Rectangle(Point(spacing*c+spacing//2-BallSize,FieldHeight-GroundDepth-BallSize*5),
Point(spacing*c+spacing//2+BallSize,FieldHeight-GroundDepth+BallSize));
So, you can tweak the various constants (which all seem to have pretty reasonable names) to get the result you want—or, of course, just hardcode the position you want instead of calculating it.

Scrolling objects are jerky and sometimes jump to the right a few pixels [pygame]

To create an abstract, scrolling city skyline for a prototype, I created a class that generates random rectangles. These rects are added to a list and items are pulled from that list to be drawn on the screen. The rects begin off screen to the right and scroll across to the left until they leave the view plane and are trashed. The movement of the buildings is oddly jerky and they also shift to the right a few pixels at a specific point on the screen.
This video of the prototype is fairly accurate with very little video capture lag. Pay attention to the gaps between the buildings, as they get within the right most 3rd of the display area, the gap will suddenly shrink as if the building to the left of the gap is suddenly shifting right a few pixels. The smaller the gap, the more noticeable it is. The other anomalies in the video are from the recorder and are not present in the app. Here's a very short video that clearly shows this phenomenon: https://www.youtube.com/watch?v=0cdhrezjcY8
At about 1 second in you'll notice a very narrow gap between buildings in the rear layer. At :04 seconds in the gap is even with the blue player object, the left rectangle shifts and the gap vanishes. There's a second, larger gap to the right of that one that does the same thing but since the gap is larger it doesn't completely vanish. I've looked over the code numerous times but can't see what could be causing this anomaly. I'm hoping someone can tell me if it's something I did or a limitation I'm encountering.
I originally wrote this program linearly, without classes or functions. I rewrote it using a class that generates layer objects and handles all the generating and scrolling. In both cases the problem exists. It's driving me crazy trying to figure out why the buildings do not move smoothly. I've even written a version of this using png images instead of randomly generated rectangles. In that version the pngs scroll smoothly and seamlessly: https://www.youtube.com/watch?v=Uiw_giAvbOo (The video is a bit jerky, but the actual program plays smooth) So the issue is limited to these random rectangles.
Here's the code for the program: https://www.refheap.com/73079
Here's the class code by itself:
class Scroller():
def __init__(self, speed, color, heightMax):
# Speed of the layer scroll, the color of the layer and the maximum height for buildings
# set up the building parameters
self.buildingHeightMax = heightMax
self.buildingHeightMin = 100
self.buildingWidthMax = 125
self.buildingWidthMin = 75
self.buildings = []
self.layerspeed = speed
self.buildTime = True
self.buildCountdown = 10
self.color = color
def update(self):
# Check if it's time to build. If not, decrement counter
if self.buildTime == False:
self.buildCountdown -= 1
# If time is 0, time to build, reset counter to a new random time
if self.buildCountdown <= 0:
self.buildTime = True
self.buildCountdown = random.randint(3, self.layerspeed)
# create building if it's time
if self.buildTime:
# generate random width and height of building
buildingHeight = random.randint(self.buildingHeightMin, self.buildingHeightMax)
buildingWidth = random.randint(self.buildingWidthMin, self.buildingWidthMax)
buildingTop = WINDOWHEIGHT - buildingHeight
# This generates the building object from the above parameters
building = pygame.Rect(WINDOWWIDTH, buildingTop, buildingWidth, WINDOWHEIGHT)
self.buildTime = False
self.buildCountdown = random.randint(3, self.layerspeed * 5)
# add building to buildings list
self.buildings.append(building)
# move all buildings on layer at set speed
for building in self.buildings:
# if the building is off the screen, trash it. If not, move it to the
# right at the objects speed.
if building.right < 0:
self.buildings.remove(building)
else:
building.left -= self.layerspeed
# draw the Front buildings
for i in range(len(self.buildings)):
pygame.draw.rect(windowSurface, self.color, self.buildings[i])
Your problem most likely lies in:
# move all buildings on layer at set speed
for building in self.buildings:
# if the building is off the screen, trash it. If not, move it to the
# right at the objects speed.
if building.right < 0:
self.buildings.remove(building)
else:
building.left -= self.layerspeed
You're using remove on the same list you're iterating from, and this will make it skip the next building. So it's not the building to the right that's moving faster, it's the one to the left that has skipped moving.
You can see it yourself with this simple example:
a = [2, 3, 4, 1.5, 6, 8, 3.2]
for element in a:
if element == 4:
a.remove(element)
else:
print element
Try it and you'll see that not only 4 won't be printed, but also 1.5 will be skipped.
Possibly a good way to do it is to first iterate through all the buildings to see which ones need to be removed, then remove then all, and finally move all the ones that are left.
You might want to check this link for some good suggestions.
You're also updating the countdown twice, first on line 47 and then on line 58. Is there any reason for this?

Categories