Wednesday, September 25, 2013

Hitboxes and you!

Pygame, you did a bad thing.  With sprites, if one wants to position them, they manipulate the rect property.

What do you mean that isn't a bad design move!  Ok, if that was all it was it wouldn't be an issue... except that the rect property is also used in hit detection... and that the sprite image always, and I mean always is redrawn on the top left hand corner of this rect, wherever the rectangle controlling the sprite is located.  Anyone that has ever played or made a bullet-hell shooter can tell you that is a terrible idea.

So, when I set the rect property to allow for things like the sprite of Arianna to nudge up against the wall, well, bad things happen.


Now, fellow reader, do not despair, for I was able to find a reasonable workaround.

First, I made a new property simply known as hitbox.  The hitbox was shaped to my liking.

Next, I had to rewrite the function that checked for collisions.  Before it looked like this:

    def checkCollision (self,sprite):
        level_bumps = spritecollide(sprite,self.sprites,False)
        for items in level_bumps:
            items.onCollision(sprite)



It was using the native function that came with pygame to check for collisions between sprites.  Course, both rely on the sprite's rect property to work, which I am no longer using for collision detection with moving characters like the PC or enemies.

Course, the native function relied on a function that pygame Rectangle objects have: colliderect().  So, I rewrote the function thusly:

    def checkCollision (self,sprite):
        for item in self.sprites:
            if sprite.hitbox.colliderect(item):
                item.onCollision(sprite)


So that the onCollision function would be called right when the one sprite was seen to be in contact with another.

Finally, it would be simply making sure that the hitbox moved with the rest of the sprite.  I put that in the update function, where the last line reads:

self.hitbox.center = self.rect.center

At present that simply means that the hitbox is centered on the sprite.  I could change that later, which I probably will.

The result?


Saturday, September 21, 2013

The world is right now!

Ok, I fixed that bug in the room!

Here's how!

First, I changed the sprites used for the walls and that with DirtySprite as opposed to regular sprites.

Next, I used the OrderedUpdates class, which in Pygame is a subclass of the RenderUpdates class, which is a subclass of the RenderPlain class - the class responsible for redrawing DirtySprites.

And... yes!  No more negaverse!

Tuesday, September 17, 2013

Sprite Groups and You

This is what happens when you don't set a redraw order:
Chaos!  Utter Chaos!
I originally had it so that each sprite was in a separate group for redraw.  Now the sprites are all in the same group.  The code itself for drawing the room hasn't changed much from the last time it was posted, only that its to one group now as opposed to multiple groups.  I think I am going to change that.

Stay tuned for the exciting conclusion to this problem.

Monday, September 16, 2013

I'm still working on it!

The beauty of that video?

Well, there was the problem of figuring out how to divide rooms.  Well, one way might be not to, and to only divide regions of an area as opposed to individual rooms.

Course, one thing at a time.  I need to make sure the doors work.

Friday, August 30, 2013

Finally! She bumps into walls (sorta)!



Would you like to know how I did it?

Ok.

So, in the level class that is being used to hold the level sprites I use the collision detection algorithms that come with Pygame.

level_bumps = spritecollide(sprite,self.walls,False)
 
Now, it isn't quite as simply as it sounds, mostly because all it does is give a list of all the sprites of a given group that intercept with a given sprite (that last argument is whether or not I want to destroy the sprites afterwards... which is no).  While this does make things easier on me (meaning that I don't have to program checking for when one pixel loves another pixel), I still have to program what should be done when two sprites collide.  After all, any sauvy reader should be able to point out that the floor is made up of sprites.

At the moment, the functionality is for walls that are not corners, as the video points out.  Still, there was an interesting way that I achieved this.  Though the power of objects!

So, first, we capture those sprites that meet another sprite:


def checkCollision (self,sprite):  level_bumps = spritecollide(sprite,self.walls,False)  for items in level_bumps:     items.onCollision(sprite) 

Notice that weird function?  Yeah, that doesn't come with Pygame.  I added those using a class that is a subclass of Sprite that I made that simply has that function.  Whether it does anything depends on whether or not I bothered to fill anything in to the overloaded class that would be, say, a wall.

Here is what it looks like for a wall by the way:

def onCollision (self,sprite):
        offset = 5
        if self.orientation == NORTH:
            relocate = self.rect.bottom+offset
            sprite.rect.top = relocate
        elif self.orientation == SOUTH:
            relocate = self.rect.top-offset
            sprite.rect.bottom = relocate
        elif self.orientation == EAST:
            relocate = self.rect.right+offset
            sprite.rect.left = relocate
        elif self.orientation == WEST:
            relocate = self.rect.left-offset
            sprite.rect.right = relocate


The result?  Well, you can see the video, can you?

Tuesday, August 27, 2013

Saturday, August 24, 2013

She's Out!

Well, there was a series of funny problems, starting here:
I swore, I banged my head against the keyboard, and cried.  Then I learn that the fix was only one line long:

pygame.key.set_repeat(100,100)  

Now it works!

It ain't over yet.