pygame.draw.circle causing lag

Started by
5 comments, last by Facehat 14 years, 2 months ago
Im drawing a range around a tower in a tower defense game and its not going good. tower_selected is True when you have clicked on a tower

if tower_selected:
            pygame.draw.circle(screen, (0, 0, 0), tower_selected.rect.center, tower_selected.range, 1)
the circle is being drawn every frame there are no problems with the actual drawing of the range (it shows up fine) but it is just slowing my game down by i would say about 1/2 of the normal frame rate. so is draw.circle just expensive ( and how could i use it better) or is it more likely that something else is going wrong. And what is the best way to figure out? would it help to post all of the relevant code for you guys to look over? If i delete those two lines that tell it to draw then the game runs fine. also I am using some vector movement calculations and other stuff that maybe could be taking up alot of processing power, so maybe the draw.circle is just pushing it over the edge. thanks for any help.
Advertisement
Circles can be expensive if implemented using square roots, but not the extent that it halves your frame rate. Post your code. Are you using pygame.draw on an opengl surface or a software one? If its the former, try drawing the circle manually using opengl calls.
I dont even know what an opengl surface is so im going to guess that im not using one.

The game is pretty far into development and there are alot of modules/image files so here is just the stuff that should be most useful. i could pm a link to the source code zip file download if thats necessary.

this is the code for the circle drawing and other things that might be useful
import a bunch of stuff thats importantfrom Values import *######main game loop#######def main():    '''Display settings'''    screen = pygame.display.set_mode((750, 600)) #Resolution of screen ((x, y))    clock = pygame.time.Clock() #opens clock for fps##### the group all the turrets are being held in    turrets = pygame.sprite.Group()# stuff goes into groups    TurretSprites.Turret.groups = turrets, all # same as above    turret_selected = None # nothing is selected    while running:        all.update()        ##### Events #####        for event in pygame.event.get():            elif event.type == pygame.MOUSEBUTTONDOWN: # all the mouse events                if event.button == 1:                    click = pygame.mouse.get_pos() # gets position of mouse when clicked                    ##### check if a turret was clicked #####                    else:                        for t in turrets:                            if t.rect.collidepoint(click):                                turret_selected = t  # so we can draw the tower stats down later                            else: # if we did not click on anykind of object                                turret_selected = None # deselect everything#skiping abunch of stuff        ##### Update and draw everything #####        map1.draw(screen) # DO WORK SON! draws the tiled map background        dirty = all.draw(screen)        pygame.display.update(dirty)         if turret_selected:            pygame.draw.circle(screen, (0, 0, 0), turret_selected.rect.center, turret_selected.range, 1) # THE PROBLEM        pygame.display.flip()        clock.tick(50) #setting frame rate number = fps


here is the turret module the only data that draw.circle uses from here is the range and rect center
so i dont see how this could be a problem

import pygameclass Turret(pygame.sprite.Sprite):    def __init__(self, position):        pygame.sprite.Sprite.__init__(self, self.groups)        self.image = pygame.image.load("Images/Towers/Basic Gun.png").convert() # get image        self.image.set_colorkey(self.image.get_at((0, 0))) # transparent        self.rect = self.image.get_rect() # get it, just get it        self.rect.center = (position) # where should i go dear slavelord        self.SHOOTING_TIMER = 100 # time between shots        self.shooting_timer = 0 # start at 0 so we are loaded when tower is placed        self.pick_target = False # not picking a target right now        self.range = 100 # range in pixels        #bunch of other turret stuff that isnt related to the issue


if you would like to download the whole running source code then i can post it and send you a link, just say so. it would be very appreciated!

thanks so much to anyone who can help with this circle.draw problem
It's very slow to draw pixel by pixel on modern graphics hardware. If you can, draw the circle just once to a new surface and blit that each time you need it.
sorry but could someone please give me an example of the best way to do this, im stumped.
turret_radius_image = pygame.Surface((turret_radius*2, turret_radius*2))turret_radius_image.draw.circle(params)...other code stuff...for t in turrets:    if t.turret_selected:        screen.blit(turret_radius_image, (turret_x, turret_y)
Another thing to consider with pygame (or really, anything based on SDL), is that it tends to be really really slow when hardware acceleration isn't on (or at least that was the case when I used it). You might check to make sure it's using DirectX instead of windib. Also, check if running in fullscreen with the pygame.HARDWARE flag is faster.

Also, vsync or imprecise timing code might be the cause -- are you dropping from 60fps to 30?

This topic is closed to new replies.

Advertisement