I'm working on a code that draws a spirograph and moves circles depending on its color towards the sides of the screen. What I mean is, for example, there are 7 colors starting from white, blue, green, etc. I want to move all the circles that are white to the sides of the screen together, every white circle moving at once. Then every blue circle to the sides of the screen together, then, etc. This is what I mean:
import turtle
import random
import math
listCircleColor = ("red", "blue", "green", "orange", "yellow", "purple", "white")
listCircleObjects = list()
intGroup = 5
angleleft = 360/(intGroup*len(listCircleColor))
# make screen object
# and set size
sc = turtle.Screen()
sc.bgcolor("black")
sc.tracer(5)
# make turlte object
turtle.hideturtle()
turtle.speed(0)
def moveanddraw(oneturtle):
oneturtle.left(90)
oneturtle.penup()
oneturtle.forward(20)
oneturtle.right(90)
oneturtle.pendown()
oneturtle.circle(100)
def movesamecolorcircle():
for cls in listCircleColor:
for tur in listCircleObjects:
objcrlcolor = tur.color()
if objcrlcolor == (cls, cls):
tur.undo()
for i in range(1, 6):
moveanddraw(tur)
if i < 5:
tur.undo()
headangle = 0
for i in range(intGroup):
for cl in listCircleColor:
tur = turtle.Turtle()
tur.hideturtle()
tur.setheading(headangle)
tur.color(cl)
tur.pencolor(cl)
tur.speed(0)
tur.pensize(2)
tur.circle(100)
headangle = headangle angleleft
listCircleObjects.append(tur)
sc.ontimer(movesamecolorcircle, 50)
print(len(listCircleObjects))
sc.exitonclick()
This is what I want, except that all the circles are moving together, as you can see that they don't move together in the code. So instead of using turtle, I used pygame to try to make the effect of circles moving together better. This is my current code:
import pygame
import math
import sys
import time
#setting colors
WHITE = (255, 255, 255)
BLUE = (0, 0, 255)
GREEN = (0, 255, 0)
RED = (255, 0, 0)
ORANGE = (255, 127, 0)
YELLOW = (255, 255, 0)
PURPLE = (160, 32, 240)
#setting what order the colors go in
listCircleColor = (RED, BLUE, GREEN, ORANGE, YELLOW, PURPLE, WHITE)
#how many circles per color
intGroup = 5
#the space between each circle
turnangle = 360/35
#width of screen
width = 600
#height of screen
height = 600
#radius of circles
radius = 100
#making the screen
screen = pygame.display.set_mode((width, height))
#if the code is running, then continue
running = True
##.draw.circle(screen, BLUE, (0, 0), radius, width=2)
circles = []
circles_rect = []
#draw
#draw
alpha = turnangle
for i in range(intGroup):
for cl in listCircleColor:
surfacetemp = pygame.Surface((width, height))
surfacetemp = surfacetemp.convert_alpha()
surfacetemp.fill((0, 0, 0, 0))
##circlerect = pygame.rect
if alpha > 0 and alpha < 90:
circlerect = pygame.draw.circle(surfacetemp, cl, (300 radius *
math.cos(math.radians(alpha)), 300 radius * math.sin(math.radians(alpha))), radius, width=2)
# second quarter of circles
if alpha > 90 and alpha < 180:
circlerect = pygame.draw.circle(surfacetemp, cl, (300 - radius *
math.cos(math.radians(180 - alpha)), 300 radius * math.sin(math.radians(180 - alpha))),
radius, width=2)
# third quarter of circles
if alpha > 180 and alpha < 270:
circlerect = pygame.draw.circle(surfacetemp, cl, (300 - radius *
math.cos(math.radians(270 - alpha)), 300 - radius * math.sin(math.radians(270 - alpha))),
radius, width=2)
# last quarter of circles
if alpha > 270 and alpha < 360:
circlerect = pygame.draw.circle(surfacetemp, cl, (300 radius *
math.cos(math.radians(360 - alpha)), 300 - radius * math.sin(math.radians(360 - alpha))),
radius, width=2)
alpha = alpha turnangle
##circles.append(circlerect)
circles.append(surfacetemp)
circles_rect.append(surfacetemp.get_rect())
#move"
#exit only when user clicks on exit button
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
exit()
screen.fill((0, 0, 0))
for crect, ret in zip(circles, circles_rect):
ret.right = 5
ret.left = 5
screen.blit(crect, ret)
screen.blit(crect, ret)
##screen.blit(crect,crect)
pygame.time.Clock().tick(20)
pygame.display.update()
##for center, color in circles:
## pygame.draw.circle(screen, color, center, radius, 2)
##pygame.display.flip()
I've been told to put each circle into multiple screens and then move them, but I have no idea how to move them simultaneously. Please help me.
CodePudding user response:
pygame.time.Clock().tick(20)
is useless. pygame.time.Clock.tick
measures the time between two calls to a method of an object instance. You must create the instance before the application loop, but call tick
in the loop.
The Indentation is completely wrong. The display must be updated in the application instead of after the application loop. However, the scene must be drawn in the application loop instead of the event loop:
clock = pygame.time.Clock() # <-- create pygame.time.Clock instance
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
runnning = False
# INDENTATION
#<--|
screen.fill((0, 0, 0))
for crect, ret in zip(circles, circles_rect):
ret.right = 5
ret.left = 5
screen.blit(crect, ret)
#INDENTATION
#-->|
pygame.display.update()
clock.tick(20) # <--- use instance object
pygame.quit()
exit()
Notice, that the typical PyGame application loop has to:
- limit the frames per second to limit CPU usage with
pygame.time.Clock.tick
- handle the events by calling either
pygame.event.pump()
orpygame.event.get()
. - update the game states and positions of objects dependent on the input events and time (respectively frames)
- clear the entire display or draw the background
- draw the entire scene (
blit
all the objects) - update the display by calling either
pygame.display.update()
orpygame.display.flip()
CodePudding user response:
Let's try fixing your original turtle code. The two problems I see are: first, your movesamecolorcircle()
function's loops are nested in the wrong order. Second, you're using tracer()
but not using update()
effectively. Let's rework the code to address the above and some style issues:
from turtle import Screen, Turtle
listCircleColors = ['red', 'blue', 'green', 'orange', 'yellow', 'purple', 'white']
intGroup = 5
angleLeft = 360 / (intGroup * len(listCircleColors))
def moveAndDraw(turtle):
turtle.left(90)
turtle.penup()
turtle.forward(15)
turtle.pendown()
turtle.right(90)
turtle.circle(100)
def moveSameColorCircle():
for color in listCircleColors:
for _ in range(12):
for turtle in listCircleObjects:
if turtle.pencolor() == color:
turtle.undo()
moveAndDraw(turtle)
screen.update()
screen = Screen()
screen.setup(900, 900)
screen.bgcolor('black')
screen.tracer(False)
headAngle = 0
listCircleObjects = list()
for _ in range(intGroup):
for color in listCircleColors:
turtle = Turtle()
turtle.hideturtle()
turtle.setheading(headAngle)
turtle.color(color)
turtle.pensize(2)
turtle.circle(100)
headAngle = angleLeft
listCircleObjects.append(turtle)
screen.ontimer(moveSameColorCircle, 50)
screen.exitonclick()