Robert.H
Robert.H

Reputation: 31

In Pyglet is there way to bring sprites to foreground

I am trying to bring sprites to the foreground so that they are on the top layer of an image. This is the line i am using to assign the value of the image

ball = pyglet.sprite.Sprite(ball_image, 50, 50)

Is there a property that i can add to this line that will draw the image on the foreground ?

edit: I am trying to keep the first image stay in the foreground regardless if its drawn before or after the second image.

Upvotes: 2

Views: 1062

Answers (2)

Torxed
Torxed

Reputation: 23480

What both you (OP) and two commenters fail to realize is that GKBRK's answer is actually an applicable solution to your question. Because rendering the thing you want on top - last - will actually solve this problem.

OpenGL doesn't have "layers" predefined. This is up to the developer to solve. OpenGL's sole purpose is to communicate with the graphics card in a predefined set of rules. You use these rules to create something you understand, pass it to OpenGL and it converts it to something the graphics card understands.

You simply have to create a placeholder (a variable) containing the foreground, and render that last in the chain of objects to be rendered.

Normally this placeholder is a Pyglet Batch.

How it works is:

import pyglet

key = pyglet.window.key

class main(pyglet.window.Window):
    def __init__ (self, width=800, height=600, fps=False, *args, **kwargs):
        super(main, self).__init__(width, height, *args, **kwargs)
        self.x, self.y = 0, 0

        ## == an example of batched rendering:
        self.main_batch = pyglet.graphics.Batch()

        ## == Set up two ordered groups.
        ##    Again, you still have to place the foreground LAST in the queue.
        self.background = pyglet.graphics.OrderedGroup(0)
        self.foreground = pyglet.graphics.OrderedGroup(1)

        self.bg = pyglet.sprite.Sprite(pyglet.image.load('background.png'), batch=self.main_batch, group=self.background)

        self.sprites = {}
        self.sprites['player'] = pyglet.sprite.Sprite(pyglet.image.load('player.png'), batch=self.main_batch, group=self.foreground, x = 10, y = 50)
        self.sprites['enemy'] = pyglet.sprite.Sprite(pyglet.image.load('foe.png'), batch=self.main_batch, group=self.foreground, x = 50, y = 200)

        self.x = pyglet.sprite.Sprite(pyglet.image.load('foreground.png'), batch=self.main_batch, group=self.foreground, x=200, y=400)

        self.alive = 1

    def on_draw(self):
        self.render()

    def on_close(self):
        self.alive = 0

    def on_key_press(self, symbol, modifiers):
        if symbol == key.ESCAPE: # [ESC]
            self.alive = 0

    def render(self):
        ## == Clear the frame
        self.clear()

        self.main_batch.draw()

        ## == And flip the current buffer to become the active viewed buffer.
        self.flip()

    def run(self):
        while self.alive == 1:
            self.render()

            # -----------> This is key <----------
            # This is what replaces pyglet.app.run()
            # but is required for the GUI to not freeze
            #
            event = self.dispatch_events()

x = main()
x.run()

But you could also just do:

def render():
    self.clear()
    self.bg.draw()
    for s_name, sprite_object in self.sprites.items():
        sprite_object.draw()
    self.foreground.draw()
    self.flip()

It's essentially the same thing.. but a LOT slower.

But I stand by GKBRK's answer; it is correct.. And with the absolute lack of code from the OP - it's hard to give any code as a example unless you happen to sit on some (as I do).

My code is not necessarily applicable to the OP's code - so this will most likely just be confusing or not a good match of code style. But this is how it works at least.

Upvotes: 5

Leo
Leo

Reputation: 1303

Drawing the sprite you want to be on the top later than the bottom sprites should accomplish what you want.

Upvotes: 2

Related Questions