2016-12-06 84 views
0
import pyglet 
from pyglet.window import Window, mouse, gl 
from pyglet.image.codecs.png import PNGImageDecoder 




window = pyglet.window.Window(
       790, 640, 
       resizable=False,             # Make sure it is not resizable 
       caption="Something",          # Caption of window 
       config=pyglet.gl.Config(double_buffer=True),      # Avoids flickers 
       vsync=False) 

kitten = pyglet.image.load('bar.png', decoder=PNGImageDecoder()) 
image_part = kitten.get_region(x=0, y=0, width=400, height=40) 
ball = pyglet.sprite.Sprite(image_part, x=50, y=20+50) 
ball.scale = 0.25 

image = kitten.get_region(x=0, y=40, width=400, height=40) 
lol = pyglet.sprite.Sprite(image, x=50, y=30+50) 
lol.scale = 0.25 

a = kitten.get_region(x=0, y=80, width=200, height=40) 
ab = pyglet.sprite.Sprite(a, x=50, y=40+50) 
ab.scale = 0.25 

def update(self, dt): 
    on_draw() 

@window.event 
def on_draw(): 
    window.clear() 
    pyglet.gl.glClearColor(255,255,255,255) 
    lol.draw() 
    ball.draw() 
    ab.draw() 

def update(dt): 
    on_draw() 
pyglet.clock.schedule_interval(update, 1/60) 


pyglet.app.run() 

我想製作2d動畫的排序算法,並不知道如何動畫圖像區域。 運行此代碼時,它會在屏幕上顯示三個靜態欄,我所需要的只是切換其位置。 謝謝你的幫助動畫Pyglet使用圖像區域

+0

你爲什麼要定義'update'兩次?在'update'裏面,你應該修改你將在'on_draw'中顯示的元素。 – furas

回答

0

你必須改變update的東西來看動畫 - 即。你可以移動物體

簡單的例子。

import pyglet 

window = pyglet.window.WWindow(
       790, 640, 
       resizable=False,             # Make sure it is not resizable 
       caption="Something",          # Caption of window 
       config=pyglet.gl.Config(double_buffer=True),      # Avoids flickers 
       vsync=False) 

image = pyglet.image.load('bar.png') 

region = image.get_region(x=0, y=0, width=400, height=40) 
ball = pyglet.sprite.Sprite(region, x=50, y=20+50) 
ball.scale = 0.25 

region = image.get_region(x=0, y=40, width=400, height=40) 
lol = pyglet.sprite.Sprite(region, x=50, y=30+50) 
lol.scale = 0.25 

region = image.get_region(x=0, y=80, width=200, height=40) 
ab = pyglet.sprite.Sprite(region, x=50, y=40+50) 
ab.scale = 0.25 

@window.event 
def on_draw(): 
    window.clear() 
    pyglet.gl.glClearColor(255, 255, 255, 255) 
    ball.draw() 
    lol.draw() 
    ab.draw() 

def update(dt): 
    # change something 
    ball.x += 1 
    lol.y += 1 
    ab.scale += 0.1 

    #on_draw() # you don't need it - pyglet will do it 

pyglet.clock.schedule_interval(update, 1/60) 

pyglet.app.run() 
1

你根本就不會更新lol.x = <new pos>
這應該在你以後的更新來完成:

def update(dt): 
    ball.x += 10 

大多數時候,你不需要擔心任何更新的圖形,但在on_draw()你不妨呼籲通過更新的屏幕:

def on_draw(): 
    window.clear() 
    lol.draw() 
    window.flip() 

正如有人指出,命名兩個函數def update()將導致後者更換第一個。

既然你正在使用精靈,我想我會給你一個整潔的小雪碧類,可能比靜態圖像更適合你。

import pyglet 
from pyglet.gl import * 

class Bar(pyglet.sprite.Sprite): 
    def __init__(self, width=20, height=200, color="#C2C2C2", x=0, y=0): 
     # == Must generate a texture before initialization of Sprite() 
     self.texture = self.gen_solid_img(width, height, color) 

     super(Bar, self).__init__(self.texture) 

     self.y = y 
     self.x = x 

    def gen_solid_img(self, width, height, c, alpha=255): 
     c = c.lstrip("#") 
     c = max(6-len(c),0)*"0" + c 
     r = int(c[:2], 16) 
     g = int(c[2:4], 16) 
     b = int(c[4:], 16) 
     c = (r,g,b,int(alpha)) 
     return pyglet.image.SolidColorImagePattern(c).create_image(width,height) 

    def draw_border(self, color=(0.2, 0.2, 0.2, 0.5)): 
     self.draw_line((self.x, self.y), (self.x, self.y+self.height), color) 
     self.draw_line((self.x, self.y+self.height), (self.x+self.width, self.y+self.height), color) 
     self.draw_line((self.x+self.width, self.y+self.height), (self.x+self.width, self.y), color) 
     self.draw_line((self.x+self.width, self.y), (self.x, self.y), color) 

使用,這將是替換的一個例子:

kitten = pyglet.image.load('bar.png', decoder=PNGImageDecoder()) 
image_part = kitten.get_region(x=0, y=0, width=400, height=40) 
ball = pyglet.sprite.Sprite(image_part, x=50, y=20+50) 
ball.scale = 0.25 

有:

ball = Bar(x=0, y=0, width=400, height=40) 

我還建議從裝飾切換到繼承的類結構,只是這樣它更容易隨着代碼的增長與每個對象一起工作。

基本類框架是這樣的:

import pyglet 
from pyglet.gl import * 

key = pyglet.window.key 

class main(pyglet.window.Window): 
    def __init__ (self): 
     super(main, self).__init__(800, 600, fullscreen = False, vsync=False) 
     self.x, self.y = 0, 0 

     self.bg = pyglet.sprite.Sprite(pyglet.image.load('background.jpg')) 
     self.sprites = {} 
     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] is pressed 
      self.alive = 0 

    def render(self): 
     self.clear() 
     self.bg.draw() 

     for sprite_name, sprite_obj in self.sprites.items(): 
      sprite_obj.draw() 

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

現在合併這些基於兩類代碼段,你應該有一些看起來像這樣:

import pyglet 
from pyglet.gl import * 

key = pyglet.window.key 

class Bar(pyglet.sprite.Sprite): 
    def __init__(self, width=20, height=200, color="#C2C2C2", x=0, y=0): 
     # == Must generate a texture before initialization of Sprite() 
     self.texture = self.gen_solid_img(width, height, color) 

     super(Bar, self).__init__(self.texture) 

     self.y = y 
     self.x = x 

    def gen_solid_img(self, width, height, c, alpha=255): 
     c = c.lstrip("#") 
     c = max(6-len(c),0)*"0" + c 
     r = int(c[:2], 16) 
     g = int(c[2:4], 16) 
     b = int(c[4:], 16) 
     c = (r,g,b,int(alpha)) 
     return pyglet.image.SolidColorImagePattern(c).create_image(width,height) 

    def draw_border(self, color=(0.2, 0.2, 0.2, 0.5)): 
     self.draw_line((self.x, self.y), (self.x, self.y+self.height), color) 
     self.draw_line((self.x, self.y+self.height), (self.x+self.width, self.y+self.height), color) 
     self.draw_line((self.x+self.width, self.y+self.height), (self.x+self.width, self.y), color) 
     self.draw_line((self.x+self.width, self.y), (self.x, self.y), color) 

class main(pyglet.window.Window): 
    def __init__ (self): 
     super(main, self).__init__(800, 600, fullscreen = False, vsync=False) 
     self.x, self.y = 0, 0 

     self.bg = pyglet.sprite.Sprite(pyglet.image.load('background.jpg')) 
     self.sprites = {} 
     self.sprites['ball'] = Bar() 
     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] is pressed 
      self.alive = 0 
     elif symbol == key.RIGHT: # [RightArrow] is pressed 
      self.sprites['ball'].x += 10 
     elif symbol == key.LEFT: 
      self.sprites['ball'].x -= 10 
     elif symbol == key.UP: 
      self.sprites['ball'].y += 10 
     elif symbol == key.DOWN: 
      self.sprites['ball'].y -= 10 

    def render(self): 
     self.clear() 
     self.bg.draw() 

     ## == Do some calculations and moving around here maybe. 
     ## Unless you'll be using on_key_press() as I did here. 

     for sprite_name, sprite_obj in self.sprites.items(): 
      sprite_obj.draw() 

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

我添加這樣你就可以按任何箭頭(右,左,上,下)來移動我在這裏創建的簡單欄。

它支持顏色,沒有圖片,但那裏很容易添加,只需更換self.texture = gen_solid_image(...),就完成了。

我也對你在哪裏做了一些計算和移動做了一點點評論。

不要嘗試使用線程,它只會讓你的生活更難。