2013-10-07 4 views
0

저는 Kivy를 골치며 일종의 2D 그리드로 응용 프로그램과 같은 게임을하려고합니다. 내 디자인에서는 각각의 셀 오 그리드는 자체의 그래픽 표현을 가져야하며, 내부의 내용에 따라 다릅니다. 다음은 그리드를 만들고 각 셀에 일부 이미지를 삽입하는 현재 간단한 코드입니다.동일한 이미지의 여러 인스턴스를로드하는 최적의 방법

class MyWidget(Widget): 
    def __init__(self,images,*args, **kwargs): 
     super(MyWidget, self).__init__(*args, **kwargs) 
     self.images = [] 
     for img in images: 
      self.add_image(img) 
     self.bind(pos=self.callback,size=self.callback) 
    def add_image(self,image): 
     self.images.append(Image(source=image,allow_stretch = True,keep_ratio = False)) 
     self.add_widget(self.images[-1]) 
    def callback(self,instance,value): 
     for image in instance.images: 
      image.pos = instance.pos 
      image.size = instance.size 

class StartScreen(Screen): 
    def __init__(self,**kwargs): 
     super(StartScreen, self).__init__(**kwargs) 
     i = 10 
     self.layout = GridLayout(cols=i) 
     self.add_widget(self.layout) 
     for i in range(i*i): 
      self.layout.add_widget(MyWidget(['./images/grass.png','./images/bug1.png'])) 

class TestApp(App): 
    def build(self): 
     return StartScreen() 

문제는 모든 이미지가있는 동안 내가 볼 수있는 것과 같은, 어떤것는 각 셀에 대해 다시 메모리에로드되어 있다는 점이다. 10000 셀 정도가 될 때 특히 효율적이지 않습니다. 동일한 이미지를 각 셀에 추가하려고 시도했지만 각 위젯에는 단 하나의 부모 만있을 수 있습니다. 이미 초기화 된 텍스처로 새 이미지를 초기화하려고 시도했지만 향상되지는 않았습니다. 로드 된 이미지의 텍스처를 얻으려고 시도한 다음 텍스쳐로 사각형을 만듭니다. 이런 식으로 뭔가 :

def add_image(self,texture): 
    with self.canvas: 
     rect = Rectangle(texture=texture,pos=self.pos, size=self.size) 
     self.rects.append(rect) 

질감은 다음과 같습니다

Image(source='./images/grass.png',allow_stretch = True,keep_ratio = False).texture 

그것은 향상 메모리 사용 (4백30메가바이트에서는 200KB의 이미지 만 개 세포 160MB합니다하지만 여전히,이 두 가지 이미지를 아주 많이.. :)

내 질문 : Kivy에서 많은 반복 이미지로 2D 그리드를 만드는 더 효율적인 방법이 있습니까? 아마 문제에 대한 나의 접근 방식은 결함이 - 내가 만드는 게임에 정말 아무의 expirence이 없다 ...

표시되는 메모리 문제가 위젯에서입니다
+1

나는 완전히 확신 할 수는 없지만 ['Atlas'] (http://kivy.org/docs/api-kivy.atlas.html)를 사용해 볼 수 있습니다. 그것은 귀하의 경우 2 대신 하나의 이미지를로드하여 서버 또는 하드 드라이브에 대한 통화의 양을 줄이기위한 것입니다. 그러나, 나는 또한 약간의 메모리 관리가있을 것이라고 생각하고 싶다. 확실하지는 않지만 시험해 볼 가치가 있습니다. –

답변

1

는 텍스처의 그릇된 판단에서, kivy의 이미지 텍스처 kivy의 내부 cache를 사용하여 캐시하지 메커니즘을 사용하면 1 분 안에 이미지를 100 번로드하면 kivy는 캐시에서 기존 텍스처를 다시 사용합니다.

이 캐시는 설정된 시간이 지나면 시간 초과되며이 시간 초과 후 디스크에서 다시로드됩니다. 이러한 이유로 Image 위젯에는 reload 메소드와 설정할 수있는 nocache 속성이 있습니다. 하나는 항상 시도하고 Atlas를 사용해야하지만 당신은 캐시가 전체 메커니즘이 더 나은 성능과 텍스처 관리를 허용하는쪽으로되지 제한 시간 기어드 않습니다이다, 게임의 수동 캐시 ::

from kivy.cache import Cache 
Cache._categories['kv.image']['limit'] = 0 
Cache._categories['kv.texture']['limit'] = 0 

을 설정할 수 있습니다. 다른 장점으로는 gpu에 업로드 할 단일 텍스처가 포함되며 업로드 시간이 크게 향상되고 디스크 시간에서 읽기가 상당히 감소됩니다.

모든 위젯은 오버 헤드가 크지 않고 같은 위젯의 10,000 회 이상의 반복을 처리 할 때에도 마찬가지입니다. 메모리 사용 문제가 발생합니다. 위젯은 이러한 용도에 적합하지 않습니다. 텍스처 반복 좌표 인 을 사용하여 위젯을 사용하지 않고 캔버스 위로 직접 그려야합니다. (테스트되지 않은) 같은 것을 : 당신은 당신이 쓰는 게임에 관심이 있다면 물리 엔진으로 KivEnt 및 cymunk보고 할 수 있습니다

texture = Image('grid.jpg').texture 
texture.wrap = 'repeat' 
texture.uvsize = (20, 20) 
with self.canvas: 
    Color(1, 1, 1) 
    Rectangle(pos=(0, 0), size=(2000, 2000), texture=texture) 

.

관련 문제