Creating A Grid of Images

Started by
3 comments, last by Wyrframe 5 years, 9 months ago

Hello

I am trying to create a grid of images in pyglet and python and I am not sure where exactly I am going wrong.

The goal is for it to be a Breakout/Arkanoid clone. The problem I am having is getting the brick images to display in a grid.

Here is the code that as far as I can tell, should place the bricks in the correct position.

 


class Brick():
    def __init__(self, space):
      	# Create the list to hold different sprite bricks and load images
        self.batch = pyglet.graphics.Batch()
        self.brick_images = ['brick1.png', 'brick2.png']
        self.brick_sprites = []

        # 1 out of 5 chance to drop a power pill
        self.chance_to_drop = 1

        # Set the images anchor point to its center and create sprites
        for i in range(len(self.brick_images)):
            img = pyglet.image.load(self.brick_images[i])
            img.anchor_x = img.width // 2
            img.anchor_y = img.height // 2
            self.brick_sprites.append(pyglet.sprite.Sprite(img))

        
        for x in range(7):
            for y in range(7):
                self.body = pymunk.Body(body_type=pymunk.Body.KINEMATIC)
                # The position where each pymunk body will be placed
                self.body.position = x * 100 + 75, y * 30 + 340

                self.brick_type = random.randint(0, len(self.brick_sprites) - 1)

                if self.brick_type == 0:
                    sprite = self.brick_sprites[0]
                    # Set the sprite to the same position as the pymunk body
                    sprite.set_position(self.body.position.x, self.body.position.y)
                    sprite.batch = self.batch
                elif self.brick_type == 1:
                    sprite = self.brick_sprites[1]
                    sprite.set_position(self.body.position.x, self.body.position.y)
                    sprite.batch = self.batch

                self.shape = pymunk.Segment(self.body, (0, 0), (50, 0), 6)
                self.shape.elasticity = 0.80
                self.shape.collision_type = collision_types['brick']
                space.add(self.body, self.shape)

        handler = space.add_collision_handler(collision_types['brick'], collision_types['ball'])
        handler.separate = self.remove_brick

 

So what I am trying to accomplish is have 7 rows of 7 bricks. As far as I can see the sprites are being created in the loop, but when I run the program only 2 bricks are being displayed. I am sure there is something wrong with the way I am looping but honestly just cannot see where I am going wrong. I have spent some time, trying to see the error but simply cannot see where I am going wrong.

I can see that the pyglet brick sprites are NOT being set to the correct x, y of the pymunk body, even though, using the same formula for the player paddle object lines up the sprite perfectly.

 


#Set the sprite to pymunk object position
self.image = pyglet.image.load('paddle.png')
self.image.anchor_x = self.image.width // 2
self.image.anchor_y = self.image.height // 2
self.sprite = pyglet.sprite.Sprite(self.image, x=self.position.x, y=self.position.y)

 

I am very confused with this one and I just hope I have explained everything clearly enough. Thank you for any help or assistance in any way.

Advertisement

Doesn't look like you're creating a sprite for each brick; you're iterating over a range, moving one of two randomly picked sprites (and only two sprites ever exist, mind you) to the corresponding position on the grid, and then moving on.

Also, does `space.add()` copy its arguments and create a new rigid body as described, or does it add a new body which uses those arguments are its position-and-shape parameters (so if you update them later, it updates that body's position and shape)? Either way, I suspect `space.add()` should be returning something you should store in Brick somewhere.

RIP GameDev.net: launched 2 unusably-broken forum engines in as many years, and now has ceased operating as a forum at all, happy to remain naught but an advertising platform with an attached social media presense, headed by a staff who by their own admission have no idea what their userbase wants or expects.Here's to the good times; shame they exist in the past.

Thank you Wyreframe for the advice.  To be perfectly honest I am not sure how the mechanics of pymunks space.add() works so I cannot give a definitive answer on that. As far as I am aware, from the tutorials I have seen it simply adds pymunk bodies and shapes to the pymunk space, which you should only need to do once.

On the other hand, I thought about what you said with there only ever being 2 sprites being drawn.

I have readjusted the code as such:


class Brick():
    def __init__(self, space):
        self.batch = pyglet.graphics.Batch()
        self.brick_images = ['brick1.png', 'brick2.png']
        self.sprite_list= []

        for x in range(7):
            for y in range(7):
                body = pymunk.Body(body_type=pymunk.Body.KINEMATIC)
                body.position = x * 100 + 75, y * 30 + 340

                image_index = random.randint(0, len(self.brick_images) - 1)
                image = pyglet.image.load(self.brick_images[image_index])
                sprite = pyglet.sprite.Sprite(image, x=body.position.x, y=body.position.y, batch=self.batch)
                self.sprite_list.append(sprite)

                shape = pymunk.Segment(body, (0, 0), (50, 0), 6)
                shape.elasticity = 0.80
                shape.collision_type = collision_types['brick']
                space.add(body, shape)

 

This creates the grid as I intended. But I am still not sure if it is correct as pyglet as a built in fps display. With the previous code (with the grid not showing) it showed a constant 60fps. After changing it to this, it creates the grid but the fps now sits and around 25fps

I am assuming it has something to do with the loading of the images in a loop, although I could be mistaken. Thanks for the help of spotting only 2 sprites, which has at least helped me move forward a little bit more. 

You don't need to load a separate Image for every Sprite. You can load your two brick images once each, and then create any number of Sprites which all use one or the other of those Images. That's the difference between an Image and a Sprite; the first is just simple bitmap data, and the other is a scene graph element which describes what to draw and where.

For that sharp of a drop, I bed there's something odd about how you're creating and using Brick. I'm guessing you're instantiating a Brick once per frame, instead of once per scene reset?

 


class BrickGrid():
    def __init__(self, space):
        self.batch = pyglet.graphics.Batch()
        self.sprite_list= []

        # I really don't know Python, there must be a better way to do this:
        # Create a list of brick images, and load each file in turn.
        brick_images = ['brick1.png', 'brick2.png']
        for index in range(len(self.brick_images)):
            brick_images[index] = pyglet.image.load(brick_images[index])

        for x in range(7):
            for y in range(7):
                body = pymunk.Body(body_type=pymunk.Body.KINEMATIC)
                body.position = x * 100 + 75, y * 30 + 340

                image = brick_images[random.randint(0, len(brick_images) - 1)]
                sprite = pyglet.sprite.Sprite(image, x=body.position.x, y=body.position.y, batch=self.batch)
                self.sprite_list.append(sprite)

                shape = pymunk.Segment(body, (0, 0), (50, 0), 6)
                shape.elasticity = 0.80
                shape.collision_type = collision_types['brick']
                space.add(body, shape)

 

RIP GameDev.net: launched 2 unusably-broken forum engines in as many years, and now has ceased operating as a forum at all, happy to remain naught but an advertising platform with an attached social media presense, headed by a staff who by their own admission have no idea what their userbase wants or expects.Here's to the good times; shame they exist in the past.

This topic is closed to new replies.

Advertisement