Sign in to follow this  
blewisjr

Pyglet Sprite rotation issue[Solved]

Recommended Posts

blewisjr    752
Ok I have been scouring the almighty Google and trying to get this to work for over an hour. I just can't get my cannon to rotate when I use the up and down arrow keys. Time for some outside eyes to take a glimpse your time and info will be much appreciated.
import pyglet
from pyglet.gl import *

window = pyglet.window.Window(800, 600)

# Enable Alpha Blending
glEnable(GL_BLEND)
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)

class GraphicsObject(object):
    '''This is the representation of a graphic on the screen.'''
    
    def __init__(self, image_path):
        self._sprite = pyglet.sprite.Sprite(pyglet.image.load(image_path))
        self.center = {'x': self._sprite.image.width/2,
                    'y': self._sprite.image.height/2}
        self._rotation = 0.0
        
    def set_rotation(self, angle_in_degrees, min_rotation, max_rotation):
        '''Set the rotation of the GraphicsObject'''
        self._rotation += angle_in_degrees
        
        if self._rotation > max_rotation:
            self._rotation = max_rotation
        elif self._rotation < min_rotation:
            self._rotation = min_rotation
            
        self._sprite.rotation = -self._rotation
        
    
    def draw(self, position_x, position_y, width=None, height=None,
            anchor_x=None, anchor_y=None):
        '''
            Here we draw the GraphicsObject based off of certain specificatons.
            We take into account the position_x, position_y width,
            height, anchor_x, and anchor_y.
            Of these args only position_x, and position_y are required.
            In order of the method signature:
            position_x is the x coord you want the image drawn at.
            position_y is the y coord you want the image drawn at.
            width is the width you want the image drawn at.
            height is the height you want the image drawn at.
            anchor_x is the x position on the image that specifies where the
                image will be drawn from.
            anchor_y is the y position on the image that specifies where the
                image will be drawn from.
        '''
        
        if (width == None and height == None):
            if (anchor_x == None and anchor_y == None):
                self._sprite.image.blit(position_x, position_y)
            else:
                self._sprite.image.anchor_x = anchor_x
                self._sprite.image.anchor_y = anchor_y
                self._sprite.image.blit(position_x, position_y)
        else:
            if (anchor_x == None and anchor_y == None):
                self._sprite.image.blit(position_x, position_y,
                    width=width, height=height)
            else:
                self._sprite.image.anchor_x = anchor_x
                self._sprite.image.anchor_y = anchor_y
                self._sprite.image.blit(position_x, position_y,
                    width=width, height=height)

# Setup our keyboard handler
keys = pyglet.window.key.KeyStateHandler()
window.push_handlers(keys)

# The actual game
class Game(object):
    def __init__(self):
        self.background = GraphicsObject('Sprites/background.png')
        self.cannon = GraphicsObject('Sprites/cannon.png')
        
    def update(self, dt):
        if keys[pyglet.window.key.ESCAPE]:
            window.pop_handlers()
        if keys[pyglet.window.key.UP]:
            self.cannon.set_rotation(float(0.1 * dt), 0.0, 90.0)
        if keys[pyglet.window.key.DOWN]:
            self.cannon.set_rotation(float(-0.1 * dt), 0.0, 90.0)
            
    def draw(self):
        self.background.draw(0, 0, window.width, window.height)
        self.cannon.draw(110, 75, anchor_x=self.cannon.center['x'],
                        anchor_y=self.cannon.center['y'])

game = Game()

@window.event
def on_draw():
    window.clear()
    game.draw()
    
def update(dt):
    game.update(dt)
    
pyglet.clock.schedule_interval(update, 1.0/60.0)

pyglet.app.run()


[Edited by - blewisjr on June 21, 2009 4:38:04 PM]

Share this post


Link to post
Share on other sites
Oluseyi    2103
The problem is that your code requires that the user be pressing the UP or DOWN keys exactly when the update function is being called. For input handling, it's better to use asynchronous methods - the on_key_press event handler is a good place to address keyboard input.

Share this post


Link to post
Share on other sites
blewisjr    752
The issue there is on_key_press does not repeat fire the event if the button is held down. That is what KeyStateHandler is for. It handles the on_key_press for you apparently.

Share this post


Link to post
Share on other sites
blewisjr    752
Sorry for the double post solved the problem. Rotation does not work when you blit the image that the sprite holds. Just adjusted the blits to draws in my draw method. sprites don't get modified size wise so here is the updated code snippet.



# Changed this if condition the else was left the same
if (width == None and height == None):
if (anchor_x == None and anchor_y == None):
self._sprite.set_position(position_x, position_y)
self._sprite.draw()
else:
self._sprite.image.anchor_x = anchor_x
self._sprite.image.anchor_y = anchor_y
self._sprite.set_position(position_x, position_y)
self._sprite.draw()
else:
if (anchor_x == None and anchor_y == None):
self._sprite.image.blit(position_x, position_y,
width=width, height=height)
else:
self._sprite.image.anchor_x = anchor_x
self._sprite.image.anchor_y = anchor_y
self._sprite.image.blit(position_x, position_y,
width=width, height=height)

Share this post


Link to post
Share on other sites
Oluseyi    2103
Yeah, I had started a post about my discoveries while debugging, but then I got side-tracked by a whole bunch of things - lunch, called dad, etc. I realized that the rotation amount was changing, but the image was being blitted in exactly the same original orientation.

Nice find.

Share this post


Link to post
Share on other sites
swiftcoder    18426
Why not just set the sprite's position, rotation and scale, and then draw it directly? Saves all that mucking around with blitting the sprite's image manually.

You will also want to batch the sprites eventually, and integrating that with your current method won't be straightforward.

Share this post


Link to post
Share on other sites
blewisjr    752
In all honesty not sure why I am not doing it that way. I have been hacking this together to learn pyglet and up my experience with python. It has been working very very well. I don't even need code completion at this point. A debugger would indeed be very nice tho lol.

I am pretty sure I will have to refactor and such once I get to the next step.

I originally switched to Python/Pyglet from C#/XNA because I wanted my games to run on my Linux partition as well. There were no real good Pyglet tutorials around besides the programmers guide and the api docs. So I went back to where I actually learned how to make games which was XNA. That framework taught me how to integrate game features together to make a game. Something no C++ game book or DX/OpenGL game book ever did.

What it comes down to is the code you see here is me porting the Beginner 2D XNA Tutorial videos that got me started from the creators club page to Python/Pyglet.

Share this post


Link to post
Share on other sites
blewisjr    752
Yea I found that while looking around on how to use the KeyStateHandler. That little pong game is a great example. Hopefully once I get this whole game fleshed out I can do a set of video tutorials on it. Should be legal as long as I keep the Microsoft Permissive License intact.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this