Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

I'm drawing a large number of bouncing shapes similar to an old 1990s screensaver. I'm just doing this to study (but not hopework) For some reason my object clearing (simply blitting a black shape over the prior position) is missing parts of the shapes and leaving fragments behind. I could just black the whole screen between each draw cycle and avoid this, but I want to draw over the individual shapes. Why is this periodically missing parts of the shapes?

    from pygame.locals import *
    import pygame as pg
    from random import randint as ri
    import time

    pg.init()
    display_size = (800, 600)
    canvas = pg.display.set_mode(display_size)

    canvobj = []
    running = True

    class circle:
        def __init__(self, xpos, ypos, rad):
            self.type = 'circle'
            self.color = (ri(1,255),ri(1,255),ri(1,255))
            self.posit = (xpos, ypos)
            self.radius = rad
            self.speed = (ri(-5,5),ri(-5,5))
            self.bounce = 0
        def topygame(self):
            return (self.color, self.posit, self.radius)
        def clearit(self):
            return ((0, 0, 0), self.posit, self.radius)
        def moveit(self):
            self.posit = (self.posit[0]+self.speed[0], self.posit[1]+self.speed[1])
            return (self.color, self.posit, self.radius)

    class rect:
        def __init__(self, x, y, width, height):
            self.type = 'rect'
            self.color = (ri(1,255),ri(1,255),ri(1,255))
            self.posit = (x, y, width, height)
            self.speed = (ri(-5,5),ri(-5,5))
            self.bounce = 0
        def topygame(self):
            return (self.color, self.posit)
        def clearit(self):
            return ((0, 0, 0), self.posit)
        def moveit(self):
            self.posit = (self.posit[0]+self.speed[0], self.posit[1]+self.speed[1], self.posit[2], self.posit[3])
            return (self.color, self.posit)


     def addobjs(num, iterable):
        for x in range(num):
            iterable.append(circle(ri(1,800),ri(1,600), ri(1,50)))
        for x in range(num):
            iterable.append(rect(ri(1,800),ri(1,600), ri(1,100), ri(1,100)))

    def clearobjs(obj):
        if obj.speed[0]==0 and obj.speed[1]==0:
            obj.speed=(ri(10,20),ri(10,20))
            obj.bounce=0
        if obj.posit[1] < -100 or obj.posit[1] > 650:
            obj.bounce += 1
            obj.speed = (obj.speed[0], -obj.speed[1])
        if obj.posit[0] < -100 or obj.posit[0] > 850:
            obj.bounce += 1
            obj.speed = (-obj.speed[0], obj.speed[1])
        if x.type == 'circle':
            pg.draw.circle(canvas, *(x.clearit()))
        if x.type == 'rect':
            pg.draw.rect(canvas, *(x.clearit()))
        if x.bounce > 4:
            canvobj.remove(obj)

    def moveobjs(obj):
        if x.type == 'circle':
            pg.draw.circle(canvas, *(x.moveit()))
        if x.type == 'rect':
            pg.draw.rect(canvas, *(x.moveit()))

    starttime = time.time()

    while running:
        pg.display.flip()

        if time.time()-starttime > 1:
             starttime = time.time()
             addobjs(ri(1,3), canvobj)

        for x in canvobj:
             clearobjs(x)

        for x in canvobj:
             moveobjs(x)

        for event in pg.event.get():
            if event.type == QUIT:
                running = False
                break
            else:
                pass

        pg.time.delay(30)

    pg.quit()
share|improve this question
2  
there's a screenshot to show the artifact? –  Gustavo Maciel May 17 '12 at 3:17

1 Answer 1

up vote 2 down vote accepted

Sounds like your shapes have anti-alias around them and plotting black shapes with anti-alias would only semi remove the anti-alias portion of the screen. The way anti-alias work is to read on screen pixels, and apply black to that pixel as a percentage (and not pure black) which is then plotted back to screen. This forumla would leave the kind of behavour you describe.

Your solution is increase the size of the shape a couple of pixels when it comes to wiping them out or turn anti-alias turn off altogether.

If you open up an art package and plot a white anti-alias circle on a black background and then plot a black anti-alias circle of the exact same size in the same position as the white circle, you will see the same issue in that it is not able to fully remove the white circle.

share|improve this answer
    
I increased the radius of the circle object by 2 pixels when blacking out the old objects. Enlarging the size of the blacked out circles didn't seem to have any effect on if they left artifacts or not. It seems like it must be skipping a blackout once every so often, but that doesn't make sense since the blackouts originate from the same list as the colored shapes do. I have to go for a bit but I'll test it with white and stationary objects and get back to you. –  Ceryn May 17 '12 at 4:23
    
This fixed my problem. I will come back and upvote once i get 15 reputation. :) –  Ceryn May 17 '12 at 7:02

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.