2013-10-25 2 views
0

나는 미로를 만들 수있는 게임을하고 있습니다. 다양한 블록에서 레벨을 선택하면서 16x16 격자에 블록을 배치합니다. 당신이 블록을 만들 때마다,이 클래스를 추가합니다파이 게임 : 오브젝트/클래스/서페이스 목록 저장

class Block(object): 
    def __init__(self,x,y,spr): 
     self.x=x 
     self.y=y 
     self.sprite=spr 
     self.rect=self.sprite.get_rect(x=self.x,y=self.y) 

instances라는 목록에.

.bin 파일로 쉘빙을 시도했지만 표면 처리 오류가 반환됩니다. 저축 및 적재 수준에 대해서는 어떻게 할 수 있습니까?

도움을 주시면 감사하겠습니다./(적어도 많은 노력없이) 파이 게임의 Surface 객체를 보류

import pygame 
from pygame.locals import * 

#initstuff 
pygame.init() 
screen=pygame.display.set_mode((640,480)) 
pygame.display.set_caption('PiMaze') 
instances=[] 

#loadsprites 
menuspr=pygame.image.load('images/menu.png').convert() 
b1spr=pygame.image.load('images/b1.png').convert() 
b2spr=pygame.image.load('images/b2.png').convert() 
currentbspr=b1spr 
curspr=pygame.image.load('images/curs.png').convert() 
curspr.set_colorkey((0,255,0)) 

#menu 
menuspr.set_alpha(185) 
menurect=menuspr.get_rect(x=-260,y=4) 

class MenuItem(object): 
    def __init__(self,pos,spr): 
     self.x=pos[0] 
     self.y=pos[1] 
     self.sprite=spr 
     self.pos=(self.x,self.y) 
     self.rect=self.sprite.get_rect(x=self.x,y=self.y) 

class Block(object): 
    def __init__(self,x,y,spr): 
     self.x=x 
     self.y=y 
     self.sprite=spr 
     self.rect=self.sprite.get_rect(x=self.x,y=self.y) 

while True: 
    #menu items 
    b1menu=b1spr.get_rect(x=menurect.left+32,y=48) 
    b2menu=b2spr.get_rect(x=menurect.left+64,y=48) 
    menuitems=[MenuItem(b1menu,b1spr),MenuItem(b2menu,b2spr)] 

    screen.fill((20,30,85)) 
    mse=pygame.mouse.get_pos() 
    key=pygame.key.get_pressed() 
    placepos=((mse[0]/16)*16,(mse[1]/16)*16) 
    if key[K_q]: 
     if mse[0]<260: 
      if menurect.right<255: 
       menurect.right+=1 
     else: 
      if menurect.left>-260: 
       menurect.left-=1 
    else: 
     if menurect.left>-260: 
      menurect.left-=1 
    for e in pygame.event.get(): 
     if e.type==QUIT: 
      exit() 

     if menurect.right<100: 
      if e.type==MOUSEBUTTONUP: 
       if e.button==1: 
        to_remove = [i for i in instances if i.rect.collidepoint(placepos)] 
        for i in to_remove: 
         instances.remove(i) 
        if not to_remove: 
         instances.append(Block(placepos[0],placepos[1],currentbspr)) 

    for i in instances: 
     screen.blit(i.sprite,i.rect) 
    if not key[K_q]: 
     screen.blit(curspr,placepos) 

    screen.blit(menuspr,menurect) 

    for item in menuitems: 
     screen.blit(item.sprite,item.pos) 
     if item.rect.collidepoint(mse): 
      if pygame.mouse.get_pressed()==(1,0,0): 
       currentbspr=item.sprite 
      pygame.draw.rect(screen, ((255,0,0)), item, 1) 
    pygame.display.flip() 

답변

2

당신은 직렬화 할 수없는/피클 : :)

여기에 참조 할 수 있도록 전체 코드입니다. 그래서 귀하의 질문에 대한 답변 : 단지 표면을 직렬화하려고하지 마십시오 (그것은 어쨌든 디스크 공간을 낭비 할 것입니다).

당신은 예를 들어 귀하의 표면을 저장하는 간단한 dict를 작성하고 수업 그냥 예를 들어, 키를 저장할 수 있었다 : (

menuspr=pygame.image.load('images/menu.png').convert() 
b1spr=pygame.image.load('images/b1.png').convert() 
b2spr=pygame.image.load('images/b2.png').convert() 
currentbspr=b1spr 
curspr=pygame.image.load('images/curs.png').convert() 
curspr.set_colorkey((0,255,0)) 
# create a dict to store all surfaces 
surf_dict = {'b1spr': b1spr, 
      'b2spr': b2spr, 
      'currentbspr': currentbspr, 
      'curspr': curspr} 

... 
class Block(object): 
    def __init__(self,x,y,spr): 
     self.x=x 
     self.y=y 
     self.sprite=spr 
     # self.sprite is no longer a Surface, but a str 
     self.rect=surf_dict[self.sprite].get_rect(x=self.x,y=self.y) 

... 
    ... 
     # don't pass the surface to the Block, just the key 
     instances.append(Block(placepos[0],placepos[1], 'currentbspr')) 

... 
    for i in instances: 
     # get the Surface from the dict, not from the instance itself 
     screen.blit(surf_dict[i.sprite],i.rect) 

지금 당신이 savely 모든 Block -instances을 보류/피클을 시도 할 수 있습니다 관련 질문 인 here)를 보셨습니다.

0

주위를 둘러 보았습니다. 나는 파이썬을 open(fname,mode)에 내장하여 레벨 파일을 만들었습니다.

블록이 생성 될 때마다

, 그것은 스프라이트 이름과 블록의 좌표를 가져 와서 .BIN 형식으로 저장 파일에 추가한다 : (I)이 함수를 생성

이어서

f.write('Block('+str(placepos[0])+','+str(placepos[1])+',b1spr).')

이것을 읽고 그에 따라 레벨을 만드십시오.

def CreateLevel(levelname): 
    f=open(levelname,'r') 
    obj=f.read() 
    f.close() 
    obj=obj.split('.') 
    for b in obj: 
     instances.append(eval(b)) 

비행 색상으로 작동했습니다.

전체 코드는 다음과 같습니다. 도움을 주셔서 감사합니다.

import pygame 
from pygame.locals import * 

#initstuff 
pygame.init() 
screen=pygame.display.set_mode((640,480)) 
pygame.display.set_caption('PiMaze') 
instances=[] 
level='save.bin' 

#loadsprites 
menuspr=pygame.image.load('images/menu.png').convert() 
b1spr=pygame.image.load('images/b1.png').convert() 
b2spr=pygame.image.load('images/b2.png').convert() 
b3spr=pygame.image.load('images/b3.png').convert() 
currentbspr=b1spr 
curspr=pygame.image.load('images/curs.png').convert() 
curspr.set_colorkey((0,255,0)) 

#menu 
menuspr.set_alpha(185) 
menurect=menuspr.get_rect(x=-260,y=4) 

class MenuItem(object): 
    def __init__(self,pos,spr): 
     self.x=pos[0] 
     self.y=pos[1] 
     self.sprite=spr 
     self.pos=(self.x,self.y) 
     self.rect=self.sprite.get_rect(x=self.x,y=self.y) 

class Block(object): 
    def __init__(self,x,y,spr): 
     self.x=x 
     self.y=y 
     self.sprite=spr 
     self.rect=self.sprite.get_rect(x=self.x,y=self.y) 

def CreateLevel(levelname): 
    f=open(levelname,'r') 
    obj=f.read() 
    f.close() 
    obj=obj.split('.') 
    for b in obj: 
     instances.append(eval(b)) 

try: 
    CreateLevel(level) 
except: 
    pass 

f=open(level,'a+') 

while True: 
    #menu items 
    b1menu=b1spr.get_rect(x=menurect.left+32,y=48) 
    b2menu=b2spr.get_rect(x=menurect.left+64,y=48) 
    b3menu=b3spr.get_rect(x=menurect.left+96,y=48) 
    menuitems=[MenuItem(b1menu,b1spr),MenuItem(b2menu,b2spr),MenuItem(b3menu,b3spr)] 

    screen.fill((20,30,85)) 
    mse=pygame.mouse.get_pos() 
    key=pygame.key.get_pressed() 
    placepos=((mse[0]/16)*16,(mse[1]/16)*16) 
    if key[K_q]: 
     if mse[0]<260: 
      if menurect.right<255: 
       menurect.right+=1 
     else: 
      if menurect.left>-260: 
       menurect.left-=1 
    else: 
     if menurect.left>-260: 
      menurect.left-=1 
    for e in pygame.event.get(): 
     if e.type==QUIT: 
      f.close() 
      exit() 

     if menurect.right<100: 
      if key[K_LSHIFT]: 
       if pygame.mouse.get_pressed()==(1,0,0): 
        to_remove = [i for i in instances if i.rect.collidepoint(placepos)] 
        if not to_remove: 
         instances.append(Block(placepos[0],placepos[1],currentbspr)) 
         f.write('Block('+str(placepos[0])+','+str(placepos[1])+',b1spr).') 
        to_remove = [] 

      if not key[K_LSHIFT] or key[K_RSHIFT]:  
       if e.type==MOUSEBUTTONUP: 
        if e.button==1: 
         to_remove = [i for i in instances if i.rect.collidepoint(placepos)] 
         for i in to_remove: 
          instances.remove(i) 
         if not to_remove: 
          instances.append(Block(placepos[0],placepos[1],currentbspr)) 
          f.write('Block('+str(placepos[0])+','+str(placepos[1])+',b1spr).') 

      if key[K_RSHIFT]: 
       if pygame.mouse.get_pressed()==(1,0,0): 
        to_remove = [i for i in instances if i.rect.collidepoint(placepos)] 
        for i in to_remove: 
           instances.remove(i) 
        to_remove=[] 

    for i in instances: 
     screen.blit(i.sprite,i.rect) 
    if not key[K_q]: 
     screen.blit(curspr,placepos) 

    screen.blit(menuspr,menurect) 

    for item in menuitems: 
     screen.blit(item.sprite,item.pos) 
     if item.rect.collidepoint(mse): 
      if pygame.mouse.get_pressed()==(1,0,0): 
       currentbspr=item.sprite 
      pygame.draw.rect(screen, ((255,0,0)), item, 1) 
    pygame.display.flip()