[pygame]画像が分割して表示されない…。

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら

トピックに返信する


答えを正確にご入力ください。答えられるかどうかでスパムボットか否かを判定します。

BBCode: ON
[img]: ON
[flash]: OFF
[url]: ON
スマイリー: OFF

トピックのレビュー
   

展開ビュー トピックのレビュー: [pygame]画像が分割して表示されない…。

Re: [pygame]画像が分割して表示されない…。

#31

by asd » 6年前

解決したようでよかったです。
今後もエラーが出てきたり、期待した動作にならないことが多々あるかと思いますが、
このトピックで沖さんやshira221さん、私が提示した情報やデバッグ方法を活用して、
「エラーが出た!」で終わらせずに「なぜ、どこで、どうすれば、これでいいか、これで大丈夫」と原因と解決まで持っていけるように頑張ってもらえればと。

特に今回のようにエラーが出る場合は原因箇所の特定は容易ですが、期待した動作をしない場合(エラーにならないけどあたり判定がおかしいとか)は
原因箇所を自分で見つけ出す必要があります。
その場合にはプログラムの処理を追いかけて、問題となる場所を特定しなければならないので今以上に地道な作業が続きます。

いずれにせよゲームが完成するよう応援しています(*´ヮ`)

Re: [pygame]画像が分割して表示されない…。

#30

by 沖 滉均 » 6年前

はい、正解です。
エラーが出たら、まずどういうエラーなのかを確認する
英語で書かれてはいますがself.imageはwidthという変数を持っていないよというのがわかります。
今回はsplit_image_loadで取得した場合はエラーが発生していなかった
では、何か違うことをやっていないだろうか?
width = self.imageList[0].get_width()
width = self.image.width
違うことをやっているのがわかりますね

self.imageList[0]はSurfaceクラスのインスタンス
self.imageもSurfaceクラスのインスタンス
Surfaceクラスのドキュメントを確認すると、どうやらwidthなんていうメンバ変数はない(またはアクセスできない)
get_width()というクラスメソッドでwidthが取得できることを確認する
width = self.image.get_width()
に修正する

期待通り動作するか確認をする
期待の動作:framexまたはframeyがセットされていないときは、画像が分割されずに画像全体が表示される
動作確認:framexまたはframeyがセットされていないときは、画像が分割されず画像全体が表示された
ここまで行ってデバッグが部分的に完了です

framexとframey両方がNoneの場合ではなく、framexだけがNone、frameyだけがNone、両方に数値が入っている場合(可変部分の確認)
同じように期待する動作はどういう状況なのか
動作確認で期待する動作をするか

ゲームはツールなどと違ってリアルタイムに動いている部分が多く、止めて確認が難しい場合もあります。
printデバッグにしても大量にログが出てしまって特定しにくい場合もあります

なので、小さな問題から少しずつ解決していく癖をつけましょう
ちょっと問題があったけど他は動いてるからいいよね?
と進めていってしまうと、原因を特定するにも時間がかかりますし、そこを直したらまた別の問題が発生したとなってしまう場合もあります。

前にも書いたけどもデバッグ自体は非常に地道で面倒な作業ですが、ゲームを完成させるには避けて通れない作業です。
ドキュメントを読むのも英語だと難しく感じる場合があるでしょう
その場合は、参照したドキュメントをここの掲示板にリンクでも貼って尋ねてみてはいかがですか?
こういうこと(明示必須)をやりたいけど、期待した動作(明示必須)にならなかったんだけどどうしてかな?

今回は最後までゲームが完成すると良いですね。
パックマン風ゲームをつくるのであれば最後までがんばってください。
その際に、わからないことがあればこのトピのasdさんやshira221さんの返信もよく読んで、しっかりと質問をしてください。

Re: [pygame]画像が分割して表示されない…。

#29

by keito94 » 6年前

オフトピック
今回の質問で得た教訓。Pygameで画像サイズを獲得する時は

コード:

def image(imagename):
    image = image_load(imagename)
    width = image.width
    height = image.height
ではなく、

コード:

def image(imagename):
    image = image_load(imagename)
    width = image.get_width()
    height = image.get_height()
にすべし。
image.width(または、height)だと存在しないのでエラーが発生する。

Re: [pygame]画像が分割して表示されない…。

#28

by keito94 » 6年前

>>asdさん
丁度それに気づいていた頃です。
本来、あなたの考えていることはここで明示してない以上、あなたにしかわからないのでコードとエラーだけ出しても質問になっていないことをいい加減理解してください。
わ、分かりました…。簡単に説明しますね。
①freamxとfreamyの引数は、画像をfreamxXfreamyサイズに分割するという意味である。(ここはOK)
②freamxとfreamyの引数がない時は画像全体をスプライトとして判定する。
③のだが、画像全体を読み込もうとすると、No.22のエラーが出てしまう。
ということなら、わかると思いますが…。
沖 滉均 さんが書きました: framexもframeyも値がセットされている場合は、split_image_loadを呼んでいますね?
その場合、self.imageListにはSurfaceのインスタンスが入っています。
そして、width, heightにはどうやって取得した値を入れているでしょう?

コード:

            width = self.imageList[0].get_width()
            height = self.imageList[0].get_height()
Surfaceクラスのメンバ関数であるget_widthとget_heightで獲得しています。
そして、width, heightにはどうやって値を入れようとしているでしょう?
あなたの発言を聞いて、まさかと思い、コードを以下の通りにしてみました。

コード:

        if (framex and framey) is None:
            width = self.image.get_width()
            height = self.image.get_height()
            transColor = self.image.get_at((0, 0))
            self.image.set_colorkey(transColor, RLEACCEL)
その後、Pacman.drawの部分を以下のようにすると、

コード:

    def draw(self, screen):
        self.playerImg = self.image# List[self.freamnum]
        screen.blit(self.playerImg, self.rect)
エラーログが出ずに画像全体が表示されるようになりました。Pygameのドキュメントをちゃんと読むべきでした…。
どうもありがとうございました。
オフトピック
脳内で完結させず、ちゃんと説明できるようにならないとな…。

Re: [pygame]画像が分割して表示されない…。

#27

by asd » 6年前

keito94 さんが書きました:>>asdさん

でも、freamxとfreamyをNoneにすると、No.22のエラーが出るとという意味で言ったのですが…。
えっ、それを直すためのヒントはすでに書き記しているのですが…
と、思ったらすでにその部分は直されていたみたいですね。
keito94さんの手元で直されていても、私はエスパーではないのでそれを透視することができません。
なのでここに明言してくれないと直されていることは分かりようがありません

それで、if判定は直ったものの今度は別のエラーが出ているのでkeito94さんはそのエラーを直したいんですよね?

であれば、考えるべきことは沖さんも提示も参考にしていただければと思いますが、

1.framex = None, framey = Noneの時にどこの処理を行っているのか
 →エラーログにヒントというか答え(エラー発生場所)があります

コード:

  File "C:/Users/keito940/PycharmProjects/PacMan/PacMan.py", line 49, in __init__
    width = self.image.width
2.1の場所でなぜエラーとなるのか
 →同じくエラーログに答えがあります

コード:

AttributeError: 'pygame.Surface' object has no attribute 'width'
英語で書かれていますが、「pygame.Surfaceオブジェクトにwitdhなんて属性はないよ」と言われています。

if判定でelse節に分岐した際はこんなエラーは出なかったのに、なぜでしょうね?
同じwidthを指定しているはずなのに…お?

-if節のwidth指定部分

コード:

        self.image = image_load(filename)
        # 画像を分割するかどうかをチェックする。
        if (framex and framey) is None:
            width = self.image.width
-else節のwidth指定部分

コード:

        else:
            self.imageList = split_image_load(self.image,framex,framey)
            width = self.imageList[0].get_width()
並べてみるとwidthの指定部分が違っていませんか?
そもそもif節ではimage、else節ではimageList[0]を対象に処理しているので対象となるオブジェクトも別物のようですね?
この違いを基にどうすればよいのかを考え、調べ、試してみてください。
オフトピック
沖さんも記載している通り、デバッグとはエラーや期待した動作と違う動作があった場合に、
・どこがその原因になっているのか
・なぜその部分が原因になっているのか
・ではどのように直したら期待した動作になってくれるのか
・直してみて期待した動作になっているか
・可変部分がある場合、他の条件でも問題がないか
を繰り返し行うことを言います。

なので前の投稿のように「エラーになった!」の報告だけではデバッグにはならないのです。
エラーが出たら上記の「なんで?どうして?どうしたらいいのかな?」を自分なりに考えてみてください。
そのうえで直してもうまくいかない場合は上記の内容を提示した上で質問してみるとよいと思います。

Re: [pygame]画像が分割して表示されない…。

#26

by 沖 滉均 » 6年前

keito94 さんが書きました:>>沖さん
実はこっちでもそれへの回答をしていました。
していました?何を言っているのですか?
あなたは何に対して返信しているのでしょう
回答は今したんですよね
自分のなかで解決していたのならなぜ最初から書かないのですか?

条件式を直した結果エラーしたことを推測しろなんていうのは無理な話で、変えたのなら変えたでなぜそれを書かないんですか?

さて、エラーが発生する原因はご自分でドキュメントを読んできてください。

ヒントとなるのは以下の通り
framexもframeyも値がセットされている場合は、split_image_loadを呼んでいますね?
その場合、self.imageListにはSurfaceのインスタンスが入っています。
そして、width, heightにはどうやって取得した値を入れているでしょう?

framexかframeyがNoneの場合は、image_loadを呼んでいます。
この場合、self.imageには何が入っていますか?
そして、width, heightにはどうやって値を入れようとしているでしょう?

そして、この2つを比べた場合にwidth, heightへ代入している部分がおかしいとは思いませんか?
オフトピック
デバッグをするというのは、このようにエラーの原因をひとつひとつ自分で探して潰していく地道でつまらない作業です。
本来、あなたの考えていることはここで明示してない以上、あなたにしかわからないのでコードとエラーだけ出しても質問になっていないことをいい加減理解してください。

Re: [pygame]画像が分割して表示されない…。

#25

by keito94 » 6年前

>>asdさん
…実はこれは冗談で、Aの方なんですが…。
新しく追加した部分を見てください。

コード:

print("オーバーロードのデバッグ")
print("パターンその1")
# 省略
print("(None and None) is None  :{}".format(bool((None and None) is None)))
print("パターンその2")
print("framex = 32, framey = None")
# 省略
print("(32 and None) is None    :{}".format(bool((32 and None) is None)))
print("パターンその3")
print("framex = 32, framey = 32")
# 省略
print("(32 and 32) is None      :{}".format(bool((32 and 32) is None)))
print("パターンその4")
print("framex = None, framey = 32")
# 省略
print("(None and 32) is None    :{}".format(bool((None and 32) is None)))
なので、スプライトのクラスはこうなります。

コード:

class Sprite(pygame.sprite.Sprite):
    def __init__(self, filename, x, y,framex=None,framey=None):
        pygame.sprite.Sprite.__init__(self)
        self.image = image_load(filename)
        # 画像を分割するかどうかをチェックする。
        if (framex and framey) is None:
            width = self.image.width
            height = self.image.height
            transColor = self.image.get_at((0, 0))
            self.image.set_colorkey(transColor, RLEACCEL)
            self.imageList = split_image_load(self.image, width, height)
        else:
            self.imageList = split_image_load(self.image,framex,framey)
            width = self.imageList[0].get_width()
            height = self.imageList[0].get_height()
            transColor = self.imageList[0].get_at((0, 0))
            self.imageList[0].set_colorkey(transColor, RLEACCEL)

        self.rect = Rect(x, y, width, height)

        # 浮動小数点に変換
        self.fpx = float(self.rect.x)
        self.fpy = float(self.rect.y)
        # 移動量
        self.fpvx = 0.0
        self.fpvy = 0.0

でも、freamxとfreamyをNoneにすると、No.22のエラーが出るとという意味で言ったのですが…。

>>沖さん
実はこっちでもそれへの回答をしていました。

Re: [pygame]画像が分割して表示されない…。

#24

by asd » 6年前

keito94 さんが書きました:やっぱり演算子の問題だったのですが…。
以下のようなエラーログが出ました。

コード:

Traceback (most recent call last):
  File "C:/Users/keito940/PycharmProjects/PacMan/PacMan.py", line 277, in <module>
    Main()
  File "C:/Users/keito940/PycharmProjects/PacMan/PacMan.py", line 251, in Main
    pacman = Player()
  File "C:/Users/keito940/PycharmProjects/PacMan/PacMan.py", line 72, in __init__
    Sprite.__init__(self, "PacMan.bmp", 304, 258)
  File "C:/Users/keito940/PycharmProjects/PacMan/PacMan.py", line 49, in __init__
    width = self.image.width
AttributeError: 'pygame.Surface' object has no attribute 'width'

上記のようなエラーが出て、パックマンの画像全体を写すことができません。
はい、エラー報告ありがとうございました!…と言えば満足なのでしょうか?
そのエラーが出ないように原因を突き止めて修正するのが”デバッグ”だと思います。

そしてそれが直近で解決する問題だと思っていたのですが違うのでしょうか。

「エラーが出ました」の報告で終わるのはデバッグではないです。
それともそのエラーを直すのは目的ではないのでしょうか。

A.エラーが出るので直したい、助けて!
 →エラーを直すのが目的
B.エラーが出てたのに関連して面白い課題を投稿してくれました、みんな見て!
 →エラーはどうでもよくて、雑談するのが目的

沖さんも指摘してくれていますが、やりたいことがAなのであれば、なぜエラーになるのか、本来はどうしたいのかを考えてみませんか?
現状ではオフトピックで囲まれてはいますが、それが本題になっているBになっているように感じます。

本来の目的に戻って考えませんか?

Re: [pygame]画像が分割して表示されない…。

#23

by 沖 滉均 » 6年前

簡単な問題を作ってみました?
そうじゃないでしょう

asdさんや、shira211さんがデバッグ方法なりヒントなりを出してくれています。
なぜ自分で考えようとしないんですか?
エラーログが表示されました。そりゃそうです、エラーが発生するコードを書いているのですから当然エラーログが出るでしょう
asd さんが書きました:○考えるべきこと
・framexがNone(未指定)またはframeyがNone(未指定)だった場合にエラーなく処理されるようにしたい
 →問題となっている箇所がTrueになるようにしたい

あとはshira211さんが提示されているようにPythonインタプリタ上で適合するif文の条件式を探し出せばよいです。
以前提示したパターン1~4それぞれのパターンを確認するだけのコードです。

コード:

print("if framex and framey is None")
print("---- pattern 1 ----")
print("framex = None, framey = None")
print("None and None is None:{}".format(bool(None and None is None)))
print("None                 :{}".format(bool(None)))
print("None is None         :{}".format(bool(None is None)))
print("---- pattern 2 ----")
print("framex = 32, framey = None")
print("32 and None is None  :{}".format(bool(32 and None is None)))
print("32                   :{}".format(bool(32)))
print("None is None         :{}".format(bool(None is None)))
print("---- pattern 3 ----")
print("framex = 32, framey = 32")
print("32 and 32 is None    :{}".format(bool(32 and 32 is None)))
print("32                   :{}".format(bool(32)))
print("32 is None           :{}".format(bool(32 is None)))
print("---- pattern 4 ----")
print("framex = None, framey = 32")
print("None and 32 is None  :{}".format(bool(None and 32 is None)))
print("None                 :{}".format(bool(None)))
print("32 is None           :{}".format(bool(32 is None)))
これを実行すると本来意図しない結果が見つかるはずです。
その点については、asdさんが○考えるべきこととして日本語で条件を書いてくれています。
それをそのままPythonで書いてみることから始めませんか?

C言語、Python、その他の言語、もちろん演算子や条件演算子など違いはありますが基本的な考え方は一緒です。

Re: [pygame]画像が分割して表示されない…。

#22

by keito94 » 6年前

やっぱり演算子の問題だったのですが…。
以下のようなエラーログが出ました。

コード:

Traceback (most recent call last):
  File "C:/Users/keito940/PycharmProjects/PacMan/PacMan.py", line 277, in <module>
    Main()
  File "C:/Users/keito940/PycharmProjects/PacMan/PacMan.py", line 251, in Main
    pacman = Player()
  File "C:/Users/keito940/PycharmProjects/PacMan/PacMan.py", line 72, in __init__
    Sprite.__init__(self, "PacMan.bmp", 304, 258)
  File "C:/Users/keito940/PycharmProjects/PacMan/PacMan.py", line 49, in __init__
    width = self.image.width
AttributeError: 'pygame.Surface' object has no attribute 'width'

上記のようなエラーが出て、パックマンの画像全体を写すことができません。
オフトピック
shira211さんが出した課題がなんか面白そうでしたから、NaNiNETという簡単な問題を作ってみました。
http://dixq.net/forum/blog.php?u=2409&b=6672
ぜひご覧ください。

Re: [pygame]画像が分割して表示されない…。

#21

by asd » 6年前

更に横から失礼します。
あまり助言しすぎるのもと思いましたが、道筋を書き残してみたいと思います。
参考になればと思います。

○問題となっている箇所

コード:

if framex and framey is None:
○問題が発生する条件(沖さん指摘とkeito94さんのテスト結果から)
沖 滉均 さんが書きました: 1. framex = None, framey = None
2. framex = 数値, framey = None
○考えるべきこと
・framexがNone(未指定)またはframeyがNone(未指定)だった場合にエラーなく処理されるようにしたい
 →問題となっている箇所がTrueになるようにしたい

あとはshira211さんが提示されているようにPythonインタプリタ上で適合するif文の条件式を探し出せばよいです。

以前にC言語は向いていないからPythonを頑張ると宣言されておりましたが、演算子や条件分岐は言語に依らない基本的な要素です。
言語によって書式や用意されている演算子に違いはあるものの、考え方は言語によりません。
よって、ここで正しく考え方を身につけておかないとどの言語でプログラムを組んだとしても必ずと言っていいほどつまづくことになります。

Re: [pygame]画像が分割して表示されない…。

#20

by shira211 » 6年前

横から失礼します

こういう時もprint関数でいろいろ試してみましょう

コード:

print(None and None is None)
これをPythonインタプリタで実行すると結果はNoneです。これはFalseと解釈されるので、求める結果ではありません。どう変えればTrueになるのか、項の数を変えてみたり、順番を変えたり、かっこをいろんな位置に入れたり、いろいろ試してみましょう。
今はC言語から離れているようですが、ぜひC言語でも同じようなことをやってみてください。

Re: [pygame]画像が分割して表示されない…。

#19

by keito94 » 6年前

Pythonの演算子の優先順位を見てみたのですが…。
C言語とは違って、andはisより優先順位が低いですね…。
つまり、何が言いたいのですか?

Re: [pygame]画像が分割して表示されない…。

#18

by 沖 滉均 » 6年前

指摘内容について検索内容を想像することはできませんか?
面倒なのでとりあえず下記辺りを参照して考えてみてください。

条件について
https://docs.python.jp/3/tutorial/datas ... conditions

演算子の優先順位
http://www.pythonweb.jp/tutorial/num/index3.html

どちらも基本的なことです。

Re: [pygame]画像が分割して表示されない…。

#17

by keito94 » 6年前

>>沖 滉均 さん
if文の条件の書き方が原因であることはわかりました。
ですが、Pythonの条件式やそれらしいエラーログをいくら調べても、その原因らしい物を見つけられません。
どの単語を調べれば、あなたが考えている答えに近いのでしょうか?

Re: [pygame]画像が分割して表示されない…。

#16

by 沖 滉均 » 6年前

動かして動かなかったで終わってしまうのですか?
なぜ動かないのかそこまで突き止めましょう

そもそも今回はオーバーロードが難しいという問題ではなく、if文の条件の書き方に問題があるということを認識してください。
そうでなければ、他でまた同じ書き方をして問題が発生しますよ
答えを教えるのは簡単ですが、答えを教えると以前のトピでもあったようにわかったふりをして同じことを繰り返す原因になります。

なので、動かなかったのはなぜか
どうしてそうなったのか
ここをしっかり自分で調べてみてください。

Re: [pygame]画像が分割して表示されない…。

#15

by keito94 » 6年前

1.は以下のようなエラーログが出ます。

コード:

Traceback (most recent call last):
  File "C:/Users/keito940/PycharmProjects/PacMan/PacMan.py", line 276, in <module>
    Main()
  File "C:/Users/keito940/PycharmProjects/PacMan/PacMan.py", line 250, in Main
    pacman = Player()
  File "C:/Users/keito940/PycharmProjects/PacMan/PacMan.py", line 71, in __init__
    Sprite.__init__(self, "PacMan.bmp", 304, 258)
  File "C:/Users/keito940/PycharmProjects/PacMan/PacMan.py", line 54, in __init__
    self.imageList = split_image_load(self.image,framex,framey)
  File "C:/Users/keito940/PycharmProjects/PacMan/PacMan.py", line 206, in split_image_load
    for j in range(0, size_y, frame_y):
TypeError: 'NoneType' object cannot be interpreted as an integer
2.の場合は…

コード:

Traceback (most recent call last):
  File "C:/Users/keito940/PycharmProjects/PacMan/PacMan.py", line 276, in <module>
    Main()
  File "C:/Users/keito940/PycharmProjects/PacMan/PacMan.py", line 250, in Main
    pacman = Player()
  File "C:/Users/keito940/PycharmProjects/PacMan/PacMan.py", line 71, in __init__
    Sprite.__init__(self, "PacMan.bmp", 304, 258,32)
  File "C:/Users/keito940/PycharmProjects/PacMan/PacMan.py", line 49, in __init__
    width = self.image.width
AttributeError: 'pygame.Surface' object has no attribute 'width'
となると、3.のコードでないと必然的に動かないということになりますね…。
ちゃんと、オーバーロードできていたつもりなのに…。
オフトピック
Pythonでのメゾットのオーバーロードって難しいもんだな…。

Re: [pygame]画像が分割して表示されない…。

#14

by 沖 滉均 » 6年前

理由として貼り付けられているリンクは何の理由にもなっていないですよ?
framex及びframeyがNoneの場合と書いているつもりであれば大きな間違いです。

デフォルト引数を使ってオーバーロードのように扱いたいということなのでしょうから、発生し得る状況は基本的には下記の3パターンでしょうが
1. framex = None, framey = None
2. framex = 数値, framey = None
3. framex = 数値, framey = 数値
4. framex = None, framey = 数値←これは意図的にセットしないとならないはずなのでとりあえずは考えなくても良いでしょう

上記それぞれのパターン時の動作を把握できていますか?

Re: [pygame]画像が分割して表示されない…。

#13

by keito94 » 6年前

沖 滉均 さんが書きました:解決済みにしているから見てないかもしれないけども、コード中のif文には問題があることに気がついていますかね?
https://docs.python.jp/3/faq/programmin ... -in-python
実はこれには理由がありまして…。

Re: [pygame]画像が分割して表示されない…。

#12

by 沖 滉均 » 6年前

オフトピック
解決済みにしているから見てないかもしれないけども、コード中のif文には問題があることに気がついていますかね?
意図しているとしたら危険な設計ですし、どういう動きになるか把握しているのですかね

Re: [pygame]画像が分割して表示されない…。

#11

by shira211 » 6年前

オフトピック
スプライトに自分自身を描画する動作を実装する方法と、スプライトを管理するsprite.Groupに描画を任せる方法をごちゃまぜにしていたのが原因で、pygame.sprite.RenderUpdate.draw()は何も悪くありませんよ。あなたが参考にしているサイトにもきちんと書いてあります。
http://aidiary.hatenablog.com/entry/20080517/1275700731
サンプルでは、描画関数 draw()も実装していますが、これはスプライトグループを使うと必要なくなります。

Re: [pygame]画像が分割して表示されない…。

#10

by keito94 » 6年前

shira211さんに言われてPygameのリファレンスを見ました。
RenderUpdates.draw
Spriteの画像のコピー描写を行い、描写先となった範囲の情報を取得します。
RenderUpdates.draw(surface): return Rect_list

格納している全てのSpriteの画像を指定surface上に描写します。Group.drawと同じ動きですが、この命令では画面上で描写が行われた範囲の一覧を戻り値として返します。Group.clear命令でクリアした範囲も描写先範囲に含まれるので、戻り値として取得されます。

戻り値として得られた Rect 値はpygame.display.update命令実行時に引数として設定するとよいでしょう。そうすることで、ソフトウェア駆動モードでのパフォーマンスが向上します。こうした画面更新の速度を向上させる手法は、描写先の背景が静止画の場合にのみ有効です。
なるほど、難しそうで実は簡単なミスだったんですね…。(自分がpygame.sprite.RenderUpdate.drawで分割されて表示されると思いこんでいたこともある
ちなみにコードの方ですが、Hiragiさんに言われて以下のようにしたら、あっけなく治りました。

コード:

# メイン関数。
def Main():
    pygame.init()
    screen = pygame.display.set_mode((640, 480))
    all = pygame.sprite.RenderUpdates()
    blocks = pygame.sprite.Group()
    pacman = Player()
    maze = Map()
    all.add(pacman)
    clock = pygame.time.Clock()
    # メインループ
    while True:
        clock.tick(60)

        screen.fill((0, 0, 0))

        maze.draw(screen,blocks)

        all.update(blocks)

        pacman.draw(screen)

        pygame.display.update()  # 画面を更新

        # イベント処理
        for event in pygame.event.get():
            if event.type == QUIT:  # 閉じるボタンが押されたら終了
                pygame.quit()  # Pygameの終了(画面閉じられる)
                sys.exit()

あと、自作したSpriteのプロトタイプも少し変えてあります。(理由は、分割していない画像のときに不具合が起こると判断したからです。)

コード:

    def __init__(self, filename, x, y,framex=None,framey=None):
        pygame.sprite.Sprite.__init__(self)
        self.image = image_load(filename)
        # 画像を分割するかどうかをチェックする。
        if framex and framey is None:
            width = self.image.width
            height = self.image.height
            transColor = self.image.get_at((0, 0))
            self.image.set_colorkey(transColor, RLEACCEL)
        else:
            self.imageList = split_image_load(self.image,framex,framey)
            width = self.imageList[0].get_width()
            height = self.imageList[0].get_height()
            transColor = self.imageList[0].get_at((0, 0))
            self.imageList[0].set_colorkey(transColor, RLEACCEL)

        self.rect = Rect(x, y, width, height)

        # 浮動小数点に変換
        self.fpx = float(self.rect.x)
        self.fpy = float(self.rect.y)
        # 移動量
        self.fpvx = 0.0
        self.fpvy = 0.0

どうもありがとうございました。
オフトピック
みんなもPygameでゲームを作る時は、画像を表示するときに、pygame.sprite.RenderUpdate.draw()は使わないように!!
でないと、こんなことになるからね!!

Re: [pygame]画像が分割して表示されない…。

#9

by shira211 » 6年前

printデバッグはやってみましたか?

プログラムは上から順番に実行されるものですが、例外がありますよね。ループとか関数の呼び出しです。

n回ループさせたくてfor文を書いたけど本当にぴったりn回ループしてるのか(この前もfor文が間違っていたからマップが表示されなかったですよね)
関数の呼び出しは考えたとおりの順番で行われているのか

そういうのを要所要所にprint文を入れて確認するのです。
で、Hiragiさんが指摘しているように、実はPlayer.drawは実行されていなくて、別の何者かがパックマンの画像をscreenに張り付けていることに気づくのです。ここまではpygameに詳しい必要はない、それ以前の問題だったのです。

では、次にいったい誰がパックマンを描画しているのか確認しましょう。パックマンを描画するのは

コード:

all.draw(screen)
ですね。allを書き直すと

コード:

pygame.sprite.RenderUpdates().draw(screen)
です。
ここまでわかったらリファレンスを見に行きましょう
https://www.pygame.org/docs/ref/sprite. ... derUpdates
ありますね、pygame.sprite.RenderUpdates.draw()こいつが分割されていないパックマンを描画しています。Spriteクラスで読み込んだ直後の分割されていない画像にself.imageと名付けてしまったのでこんなことになったんですね。これはちょっと運が悪かったかもしれません。

もう一つ指摘させていただくと、hideさんに言われて今回使っているpygameの機能を説明していますが、読み込みに関する部分だけで表示に関する説明をしていません。その部分をしっかり書いていれば自分の力で原因を見つけられたのではと思います。

Re: [pygame]画像が分割して表示されない…。

#8

by Hiragi(GKUTH) » 6年前

コードを見ましたが、Playerクラスのdraw関数の内容をコメントアウトしてもパックマンが描画されているため、意図していない位置でパックマンが描画されているように思います。

Re: [pygame]画像が分割して表示されない…。

#7

by keito94 » 6年前

>>hideさん
わかりました。簡単に説明しますね。
split_image_loadという関数で、pygame.imageとして読み込んだ画像を
freamx(ここでは32)×freamy(ここでは32)のサイズのpygame.Surfaceのリスト(self.playerImg)に分割してセットします。
本来は、プレイヤーとして右向きのパックマンが表示されるべきなのですが、最初に投稿した画像のように、パックマンの画像全体が表示されてしまいます。

Re: [pygame]画像が分割して表示されない…。

#6

by hide » 6年前

Pygameについて調べてみてから回答をどうぞ。
質問するときに使っているPygameの機能とそれに期待している動作を質問者が書くほうが数億倍効率いいですよ。

Re: [pygame]画像が分割して表示されない…。

#5

by keito94 » 6年前

すいませんでした…。
ちょっとした勘違いでした。
あれこれ考えてみた結果、表示の部分に原因があるかもしれないということがわかりました。
Pygameについて調べてみてから回答をどうぞ。

Re: [pygame]画像が分割して表示されない…。

#4

by shira211 » 6年前

こんにちは

不具合の原因が画像を読み込む部分でも表示する部分でもないということをどのように確かめたのか、書いてみてください。
もちろん目で見ただけでは不十分ですよ。

あなたが以前教えてもらったptintデバッグを活用しましょう
オフトピック
Pythonには便利なデバッグ機能が標準で組み込まれているようですね。こちらも勉強してみると面白いかもしれません。
ですが、右も左もわからない初心者ならば、まずはprintデバッグです

Re: [pygame]画像が分割して表示されない…。

#3

by keito94 » 6年前

>>purin52002さん
不具合の原因のご推測、ありがとうございます!!
ですが、この不具合の原因はご推測の通りではないようです…。
Pygameについて詳しく調べてみて、何かそれらしいヒントがあったらご回答ください!!
オフトピック

コード:

が、自分を駄目にしていることに気づいた件について。[/offtopic]

Re: [pygame]画像が分割して表示されない…。

#2

by purin52002 » 6年前

デバッグしてみましょう。

大雑把に悪そうなところを推測すると、
・画像を表示する部分
・画像を読み込む部分
だと思います。

あくまで推測に過ぎないので自分で悪さをしていそうなところを見つけてみてください。
れっつとれいにんぐ^p^

[pygame]画像が分割して表示されない…。

#1

by keito94 » 6年前

どうも、日記での報告に引き続いて、質問をさせていただくことになりました。
Pygame関係の記事を参考にしながら、Pythonでゲームを作っているのですが、どうも困った点があり、質問させて頂きます。
パックマンをアニメーションさせようと、画像を分割させたまではいいのですが、分割されて表示されず、プレイヤーが画像のようになってしまいます。
ソースコードを添付しましたのでPygameに詳しい方ご回答お願いします。
添付ファイル
Question.zip
(2.84 KiB) ダウンロード数: 330 回
Q.PNG
Q.PNG (12.38 KiB) 閲覧数: 27571 回

ページトップ