pygameでゲームを作成する|セーブの仕方を探す

pygameセーブの仕方で検索してもよくわからなかったので自分で考えてみることにしました。

 

やり方としては、「セーブを押したときに、現在のpythonファイルを丸ごとバックアップをとる」という方法です。

 

  1. セーブをクリックしてイベントを発動
  2. そのファイルに既存のデータがあったら上書き、内場合は新規作成
  3. ファイルをオープン、データをコピー、貼り付け、ファイルをクローズ

ちなみにロードは、元のファイルに上書きで読み込むことです。

 

やって見ましょう。

 

(このやり方はうまくいかなかったので、うまくいった方をみたい方は「重要なデータを他のファイルに書き込む」にとんでください。)

 

セーブをする

 

もとのファイルとして時間が増加するファイルを作成します。

 


#-*- coding:utf-8 -*-
import pygame
from pygame.locals import*
import sys

size=(640,480)	#スクリーンサイズ

pygame.init()
screen=pygame.display.set_mode(size)	#スクリーンの設定
pygame.display.set_caption("台詞を書き出す")	#タイトル

font=pygame.font.Font("JKG-L.ttf",60)	#フォントファイルと文字の大きさ
i=0
clock=pygame.time.Clock()
while(1):
 clock.tick(60)
 i+=1
 kazu=font.render(str(i),False,(255,255,255))	#出力したい文字となめらかさ(Trueだとなめらか)、文字色の設定

 screen.fill((0,0,0))
 screen.blit(kazu,(0,0))	

 pygame.display.update()

 for event in pygame.event.get():
  if event.type==QUIT:
   sys.exit()

これで真っ黒な画面に1秒間に60増えていくゲーム?ができました。

 

今回は、「aでセーブ」「bでロード」というようにします。

 

必要はファイルは

 

  • 最初のデータ(これが消えてしまうとすべてがパアになってしまう可能性がある)
  • 常に入れ替わるデータ
  • セーブしたデータ

結果


#-*- coding:utf-8 -*-
import pygame
from pygame.locals import*
import sys
import codecs

size=(640,480)	#スクリーンサイズ

pygame.init()
screen=pygame.display.set_mode(size)	#スクリーンの設定
pygame.display.set_caption("台詞を書き出す")	#タイトル

font=pygame.font.Font("JKG-L.ttf",60)	#フォントファイルと文字の大きさ
i=0
deta=[]
clock=pygame.time.Clock()
while(1):
 clock.tick(60)
 i+=1
 kazu=font.render(str(i),False,(255,255,255))	#出力したい文字となめらかさ(Trueだとなめらか)、文字色の設定

 screen.fill((0,0,0))
 screen.blit(kazu,(0,0))	

 pygame.display.update()

 for event in pygame.event.get():
  if event.type==QUIT:
   sys.exit()
  if event.type==KEYDOWN:
   if event.key==K_a:	#aでセーブ
    fp=codecs.open("a.py","r",'utf-8-sig')
    for line in fp:
     deta.append(line)
    fp.close()
    fp=codecs.open("c.py","w",'utf-8-sig')
    for line in deta:
     fp.write(line)
    fp.close()

   if event.key==K_z:	#zでロード
    fp=codecs.open("c.py","r",'utf-8-sig')
    for line in fp:
     deta.append(line)
    fp.close()
    fp=codecs.open("a.py","w",'utf-8-sig')
    for line in deta:
     fp.write(line)
    fp.close()

このようなモノを作成しましたが、失敗でした。

 

テキストとして保存しても、その中に格納させているモノまでは保存されないということでした。

あたりまえのことといえばそうですが、実際にやってみてはっきりとわかりました。

重要なデータを他のファイルに書き込む

次は、データをtxtファイルとして直接書き込むことにします。

 


#-*- coding:utf-8 -*-
import pygame
from pygame.locals import*
import sys
import codecs


size=(640,480)	#スクリーンサイズ

pygame.init()
screen=pygame.display.set_mode(size)	#スクリーンの設定
pygame.display.set_caption("台詞を書き出す")	#タイトル

font=pygame.font.Font("JKG-L.ttf",60)	#フォントファイルと文字の大きさ
i=0
pt=0
deta=[]
deta2=[]
clock=pygame.time.Clock()
while(1):
 clock.tick(60)
 i+=1
 kazu=font.render(str(i),False,(255,255,255))	#出力したい文字となめらかさ(Trueだとなめらか)、文字色の設定

 screen.fill((0,0,0))
 screen.blit(kazu,(0,0))	

 pygame.display.update()

 for event in pygame.event.get():
  if event.type==QUIT:
   sys.exit()
  if event.type==KEYDOWN:
   if event.key==K_a:	#aでセーブ
    deta.clear()
    deta.append(str(i))
    fp=open("nihon.txt",mode="w",encoding='utf-8')
    for line in deta:
     fp.write(line)
    fp.close()

   if event.key==K_z:	#zでロード
    fp=codecs.open("nihon.txt","r",'utf-8-sig')
    deta2.clear()
    for line in fp:
     deta2.append(line)
    fp.close()
    i=int(deta[0])

やっとできました。

 


   if event.key==K_a:	#aでセーブ
    deta.clear()
    deta.append(str(i))
    fp=open("nihon.txt",mode="w",encoding='utf-8')
    for line in deta:
     fp.write(line)
    fp.close()

 

ここでは、aが押されたは発動します。

 

まずは配列の中身を空にします。

 

もしカラにしなければ、txtファイルに次々に書き込まれていくことになります。

 


   if event.key==K_z:	#zでロード
    fp=codecs.open("nihon.txt","r",'utf-8-sig')
    deta2.clear()
    for line in fp:
     deta2.append(line)
    fp.close()
    i=int(deta[0])

zが押されるとiにデータが入ります。

ここでも配列の中身を空にしなければ、前のセーブデータもiに入ってしまいます。

 

ファイルのオープンの仕方はaとzで違いますが、気にしないでください。

 

どちらのやり方でもできるのかという実験です。(どちらでもできました。)

 

実際に使うときはどちらかに統一した方がいいです。

 

まとめ

pygameのセーブって本当はどうするのでしょうか。