简体   繁体   中英

Using pymunk gravity with pyglet

This code displays the image assassin1.png on a black screen standing still at position (50, 80).

The goal is to induce the pymunk gravity on that image so that it falls down. I followed the pymunk tutorial which is written using pygame and tried to adapt that. I don't know why my code isn't applying gravity to the my image. Could someone tell me what I am doing wrong and what I should change to make it work properly?

import pyglet
import pymunk

class PymunkSpace(object):
    def assassin_space(self, space):
        self.space = space
        self.mass = 91
        self.radius = 14
        self.inertia = pymunk.moment_for_circle(self.mass, 0, self.radius) 
        self.body = pymunk.Body(self.mass, self.inertia) 
        self.body.position = 50, 80 
        self.shape = pymunk.Circle(self.body, self.radius) 
        self.space.add(self.body, self.shape) 
        return self.shape 

class Assassin(pyglet.sprite.Sprite):
    def __init__(self, batch, img, x, y):
        pyglet.sprite.Sprite.__init__(self, img, x , y )

class Game(pyglet.window.Window):
    def __init__(self):
        pyglet.window.Window.__init__(self, width = 315, height = 220)
        self.batch_draw = pyglet.graphics.Batch()
        self.a_space = PymunkSpace().assassin_space(space)
        self.player1 = Assassin(batch = self.batch_draw, img = pyglet.image.load("assassin1.png"), x = self.a_space.body.position.x ,y = self.a_space.body.position.y )

    def on_draw(self):
        self.clear()
        self.batch_draw.draw()
        self.player1.draw()
        space.step(1/50.0) 

if __name__ == "__main__":
    space = pymunk.Space() 
    space.gravity = (0.0, -900.) 
    window = Game()
    pyglet.app.run()

The problem is that you set the location of your Sprite once:

self.player1 = Assassin(batch = self.batch_draw, img = pyglet.image.load("assassin1.png"), x = self.a_space.body.position.x ,y = self.a_space.body.position.y )

class Assassin(pyglet.sprite.Sprite):
  def __init__(self, batch, img, x, y):
      pyglet.sprite.Sprite.__init__(self, img, x , y )

but this location never gets updated.

Another problem is that in the pygame example, space.step(1/50.0) is called every iteration of the main loop, while your's only gets called when the window is drawn.

So, first, you should ensure space.step gets called every frame. Do so by using a clock :

class Game(pyglet.window.Window):
    def __init__(self):
        ...
        pyglet.clock.schedule(self.update)

    def on_draw(self):
        self.clear()
        self.batch_draw.draw()
        self.player1.draw()

    def update(self, dt):
        space.step(dt)

The next step is ensuring the location of the sprite is keeped in sync with the pyglet object.

Change your Assassin class:

class Assassin(pyglet.sprite.Sprite):
    def __init__(self, batch, img, space):
        self.space = space
        pyglet.sprite.Sprite.__init__(self, img, self.space.body.position.x , self.space.body.position.y)

    def update(self):
        self.x = self.space.body.position.x
        self.y = self.space.body.position.y

Create your Assassin instance like this:

class Game(pyglet.window.Window):
    def __init__(self):
        pyglet.window.Window.__init__(self, width = 315, height = 220)
        self.batch_draw = pyglet.graphics.Batch()
        self.a_space = PymunkSpace().assassin_space(space)
        self.player1 = Assassin(batch = self.batch_draw, img = pyglet.image.load("assassin1.png"), space = self.a_space)
        pyglet.clock.schedule(self.update)

and call self.player1.update() in your new update method:

class Game(pyglet.window.Window):
    def __init__(self):
        ...

    def on_draw(self):
        ...

    def update(self, dt):
        self.player1.update()
        space.step(dt)

(And you should probably get rid of some unneeded instance members, but that's another topic)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM