It is currently Fri Sep 10, 2010 1:23 am




Post new topic Reply to topic  [ 16 posts ]  Go to page 1, 2  Next
Sprite groups 
Author Message

Joined: Fri Feb 05, 2010 4:30 am
Posts: 60
Post Sprite groups
Work on my project continues.. now I'm trying to implement bullets into my game. Two problems arise, though:

First, the bullets are supposed to disappear when they collide with blocks, which are in the form of a list. I'm not really sure if they do, but they tend to disappear at weird places.

Second, if I scroll the screen while the bullet is in the air, it appears to bend to where I'm scrolling. Any help would be appreciated, as always :D

Check out my project at http://code.google.com/p/strikecraft/downloads/list if you want to test it for yourself.

Here's the code for my shoot class:
Code:
class Shoot(pygame.sprite.Sprite):
    def __init__(self, speed, location, image):
        pygame.sprite.Sprite.__init__(self)
        self.image = load_image("%s.png" %image)
        self.rect = self.image.get_rect()
        self.rect.center = player.rect.move(level.scroll_x, level.scroll_y).center
        self.speed = speed

    def update(self):
        self.rect.move_ip(self.speed, 0)
        for block in blocks:
            if self.rect.colliderect(block.rect):
                self.kill()


Sun Mar 14, 2010 9:18 am
Profile

Joined: Sun Jan 31, 2010 9:39 am
Posts: 95
Post Re: Sprite groups
nivekuil wrote:
Work on my project continues.. now I'm trying to implement bullets into my game. Two problems arise, though:

First, the bullets are supposed to disappear when they collide with blocks, which are in the form of a list. I'm not really sure if they do, but they tend to disappear at weird places.


Looking briefly at the code, it seems like the bullets are processed before the blocks. This means the bullets move, hit the blocks, get deleted, and then the blocks move, so when you render the blocks will have moved from where they hit the blocks, which could cause the effect you're noticing.


Sun Mar 14, 2010 8:48 pm
Profile

Joined: Fri Feb 05, 2010 4:30 am
Posts: 60
Post Re: Sprite groups
Nope, changing the order of the processing doesn't help. I wish there were a way to render multiple entities without using a spritegroup, though.


Mon Mar 15, 2010 5:23 am
Profile

Joined: Thu Aug 27, 2009 11:10 am
Posts: 65
Post Re: Sprite groups
I've never actually used a sprite group before. You can just put all of your objects into a list and then loop through that calling update/render on each. That's what I usually do.

_________________
Check out my latest project: http://pyedpypers.org/index.php?page=project&projectid=44 - Cat And Mouse

Please let me know if you make any levels for it, I'd love to include them in the next release.


Mon Mar 15, 2010 10:43 am
Profile

Joined: Fri Feb 05, 2010 4:30 am
Posts: 60
Post Re: Sprite groups
Yeah, I prefer lists too. I got it to shoot nicely, but it doesn't detect collision with blocks. Also, it lags massively after a few shots, on my 2.5gz 6gb RAM computer.
Code:
class Shoot():
    def __init__(self):
        self.shootTime = 0
        self.shootSpeed = 8
        self.rounds = 30
        self.maxRounds = 30
        self.clips = 50

        self.reloading = False
        self.reloadTime = 0
        self.reloadSpeed = 60
        self.add = 0

    def process(self):
        if player.leftClick == True and self.shootTime >= self.shootSpeed and self.rounds > 0 and self.reloading == False:
            print "pew pew! %s" %int(self.add)
            self.shootTime = 0
            self.rounds -= 1
            self.add += 1

            bullets.append(Bullet(10, player.rect.center, "bullet1"))
        self.shootTime += 1

        for bullet in bullets:
            bullet.rect.move_ip(bullet.speed, 0)
            for block in blocks:
                for bullet in bullets:
                    if bullet.rect.colliderect(block.rect):
                        del bullet

        if self.reloading == True and self.reloadTime <= self.reloadSpeed:
            self.reloadTime += 1
            if self.reloadTime == self.reloadSpeed:
                self.reloading = False
                self.reloadTime = 0
                self.rounds = self.maxRounds
                self.clips -= 1

        keyPress = pygame.key.get_pressed()
        for key in keyPress:
            if keyPress[K_r] and self.reloading == False:
                self.reloading = True

    def render(self):
        for bullet in bullets:
            screen.blit(bullet.sprite, bullet.rect.move(level.scroll_x, level.scroll_y), level.rect)

class Bullet(object):
    def __init__(self, speed, location, image):
        self.sprite = load_image("%s.png" %image)
        self.rect = self.sprite.get_rect()
        self.rect.center = player.rect.center
        self.speed = speed


Tue Mar 16, 2010 10:12 pm
Profile

Joined: Thu Aug 27, 2009 11:10 am
Posts: 65
Post Re: Sprite groups
The lag could be this loop:
Code:
for bullet in bullets:
            bullet.rect.move_ip(bullet.speed, 0)
            for block in blocks:
                for bullet in bullets:
                    if bullet.rect.colliderect(block.rect):
                        del bullet


You're iterating through the bullets list twice.

Try something like:
Code:
for bullet in bullets:
   bullet.rect.move_ip(bullet.speed,0)
   for block in blocks:
      if bullet.rect.colliderect(block.rect):
         bullets.remove(bullet)


Not sure what's causing the collisions to not be detected. Try the code above, and if it still doesn't work put some prints in after the if to see if something's wrong.

_________________
Check out my latest project: http://pyedpypers.org/index.php?page=project&projectid=44 - Cat And Mouse

Please let me know if you make any levels for it, I'd love to include them in the next release.


Tue Mar 16, 2010 10:34 pm
Profile

Joined: Sun Jan 31, 2010 9:39 am
Posts: 95
Post Re: Sprite groups
Be careful about those loops where you remove an item from the list you're iterating on. You want instead to do something like

Code:
for bullet in bullets[:]


which iterates over a copy of the list, then you can remove instances from the real list safely.


Tue Mar 16, 2010 11:21 pm
Profile

Joined: Fri Feb 05, 2010 4:30 am
Posts: 60
Post Re: Sprite groups
Ah, thanks george, its a lot faster now(is still pretty slow with 8+ bullets on screen), and works when you slice the list. Apparently, though, calling your code won't work, since it doesn't recognize anything in "bullets" when "block" is called after it is. So I just had to call bullet again. Pretty strange and sacrifices some speed, but it works so I'm happy. Thanks :):
Code:
    def render(self):
        for bullet in bullets[:]:
            bullet.rect.move_ip(bullet.speed,0)
            screen.blit(bullet.sprite, bullet.rect.move(level.scroll_x, level.scroll_y), level.rect)
            for block in blocks[:]:
                for bullet in bullets[:]:
                    if bullet.rect.colliderect(block.rect):
                        bullets.remove(bullet)


Wed Mar 17, 2010 12:11 am
Profile

Joined: Thu Aug 27, 2009 11:10 am
Posts: 65
Post Re: Sprite groups
george wrote:
Be careful about those loops where you remove an item from the list you're iterating on. You want instead to do something like

Code:
for bullet in bullets[:]


which iterates over a copy of the list, then you can remove instances from the real list safely.


I'm going to go through some of my code because I've been just removing items from the list the lazy way...

I've read on some mailing list that iterating through a list backwards also prevents this problem, without having to copy the entire list.

Does anyone know if this is true?

Edit: Here's a link to the post: http://www.python.org/search/hypermail/ ... /0615.html

Looks like it is safe :)

_________________
Check out my latest project: http://pyedpypers.org/index.php?page=project&projectid=44 - Cat And Mouse

Please let me know if you make any levels for it, I'd love to include them in the next release.


Wed Mar 17, 2010 11:14 am
Profile

Joined: Thu Aug 27, 2009 11:10 am
Posts: 65
Post Re: Sprite groups
nivekuil wrote:
Ah, thanks george, its a lot faster now(is still pretty slow with 8+ bullets on screen), and works when you slice the list. Apparently, though, calling your code won't work, since it doesn't recognize anything in "bullets" when "block" is called after it is. So I just had to call bullet again. Pretty strange and sacrifices some speed, but it works so I'm happy. Thanks :):
Code:
    def render(self):
        for bullet in bullets[:]:
            bullet.rect.move_ip(bullet.speed,0)
            screen.blit(bullet.sprite, bullet.rect.move(level.scroll_x, level.scroll_y), level.rect)
            for block in blocks[:]:
                for bullet in bullets[:]:
                    if bullet.rect.colliderect(block.rect):
                        bullets.remove(bullet)


The reason it slows down is that 3rd loop.

Let's say you have 10 bullets and 50 walls. You will go through the first loop 10 times, and then each time you loop you will go through 50 walls, 10*50 - so 500 iterations. If you then iterate through the bullets list again you're increasing it to 10*50*10 == 5000! So every update you are calling rect.colliderect() 5000 times.

To increase the speed, you could do this:
Code:
#iterate through the bullets backwards
for i in range(len(bullets)-1,-1,-1):
   bullet = bullets[i]
   bullet.rect.move_ip(bullet.speed,0)
   screen.blit(bullet.sprite, bullet.rect.move(level.scroll_x, level.scroll_y), level.rect)
   for block in blocks:
       if bullet.rect.colliderect(block.rect):
          bullets.remove(bullet)
          break #no need to keep checking walls after collision


Try that and let me know if you have any problems.

_________________
Check out my latest project: http://pyedpypers.org/index.php?page=project&projectid=44 - Cat And Mouse

Please let me know if you make any levels for it, I'd love to include them in the next release.


Wed Mar 17, 2010 11:52 am
Profile
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 16 posts ]  Go to page 1, 2  Next


Who is online

Users browsing this forum: Google [Bot] and 2 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
cron
© 2008-2009 PyedPypers.org
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group.
Designed by Vjacheslav Trushkin for Free Forum/DivisionCore.