2012-07-06 57 views
1

此代碼在靜止在位置(50,80)的黑色屏幕上顯示圖像assassin1.pngpyglet使用pymunk比重

目標是誘導寶寶重力在該圖像,以便它下降。我遵循了使用pygame編寫的pymunk tutorial,並試圖去適應它。我不知道爲什麼我的代碼不會對我的圖像施加重力。有人能告訴我我做錯了什麼,爲了使它正常工作我應該改變什麼?

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() 

回答

5

的問題是,您將Sprite一次的位置:

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) 

,但這個位置永遠不會被更新。

另一個問題是,在pygame示例中,space.step(1/50.0)被稱爲主循環的每一次迭代,而您的只在窗口繪製時被調用。

所以,首先,你應該確保space.step被調用每一幀。通過使用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) 

下一步是確保子畫面的位置與所述對象pyglet同步被依然古色古香。

改變你的刺客類:

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 

創建刺客情況是這樣的:

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) 

,並在您的新update方法調用self.player1.update()

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

    def on_draw(self): 
     ... 

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

(你應該可能會擺脫一些不需要的實例成員,但是另一個主題)

+1

注意:您仍然希望將一個常數dt發送到space.step方法中,因爲在固定的時間步長下,仿真將表現得更加穩定和快速。 – viblo 2012-07-06 14:12:58

+1

@viblo是的,文檔是這樣說的,但我從未發現這是一個問題。 – sloth 2012-07-06 14:17:58

+0

很好的解釋,謝謝!關於你對這些不需要的實例成員的評論:我假設你正在談論的事實是,我把'assassin_space'的代碼放在一個'PymunkSpace'類的下面,而不僅僅是一個函數中?在這種情況下,它肯定是不需要的,但是使用一個類來封裝所有類似assassin_space的函數是否適用於我在遊戲中實現的其他角色(具有不同的大小)?我也想稍後實施碰撞。 – Bentley4 2012-07-06 14:28:43