質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

1回答

1680閲覧

迷路ゲームのアイテム取得時の挙動について

退会済みユーザー

退会済みユーザー

総合スコア0

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

1クリップ

投稿2018/04/15 09:48

編集2018/04/15 13:00

はじめまして。プログラム初心者です。

「12歳から始めるゼロからのpythonゲームプログラミング教室」という初心者向けの本を読みながら勉強しています。
その中の迷路ゲーム製作中によくわからない点があったのお聞かせ願いたいです。

イメージ説明

カーソルをクリックして鍵を取りゴールへ向かうゲームです。支持に従い制作し、プログラム自体は全く問題ありませんでした。
ただその中で鍵に位置が重なると鍵のイメージが消える箇所について、本に以下の文章が書いてあったのですが、理解できませんでした。

鍵を描画するときにタグを付けておいて消す方法もいいのですが、今回はmap_dataを書き換えてからdraw_map関数を呼び出す方法で鍵を消します。

map_data[y][x]に0を代入し、次にdelete関数を使ってキャンバス上のすべての部品を消します。すべての部品を消したいときは"all"という特別なタグを指定します。あとはdraw_map関数を呼び出すだけです。

以下がその部分になります。(コード全文は一番最後に記載します)

# 移動先のチェック def check_move (x, y): global brave_x, brave_y, flag_key if x>=0 and x<MAX_WIDTH and y>=0 and y<MAX_HEIGHT: p = map_data[y][x] if p == 1: return elif p == 3: flag_key = True map_data[y][x] = 0 canvas.delete("all") draw_map() elif p == 2: if flag_key == True: ending() else: return brave_x = x brave_y = y canvas.coords("brave", brave_x*62+31, brave_y*62+31)

素人考えで描画のデータが3(鍵)から0(道)に変わったならそれで消えたことになるのではと思ったので、試しに①「canvas.delete("all") draw_map()」を削除したら鍵は消えませんでした。

次に②「canvas.delete("all")」だけ削除したら主人公がその場から動かなくなりました。

これについて質問です。

①の方は0を代入しても上書きされないものなのでしょうか。
②の方は一度消して再描画はちゃんと動くのにただの再描画では動かなくなるのはなぜなのでしょうか。

本の通り書いてちゃんと動いたのだからそれでいいのかもしれませんが、理解できないまま先に進むといつかぶつかりそうな気がしたので質問させていただきました。
あまりに稚拙な質問で申し訳ありません。どうぞ宜しくお願い致します。

※以下にコード全文を記載しておきます。(下記にエラーはなく問題なくendingを迎えられます)

import tkinter # マップの描画 def draw_map(): for y in range(0, MAX_HEIGHT): for x in range(0, MAX_WIDTH): p = map_data[y][x] canvas.create_image(x*62+31, y*62+31, image=images[p]) # 主人公の表示 canvas.create_image(brave_x*62+31, brave_y*62+31, image=images[4], tag="brave") # 移動先のチェック def check_move (x, y): global brave_x, brave_y, flag_key if x>=0 and x<MAX_WIDTH and y>=0 and y<MAX_HEIGHT: p = map_data[y][x] if p == 1: return elif p == 3: flag_key = True map_data[y][x] = 0 canvas.delete("all") draw_map() elif p == 2: if flag_key == True: ending() else: return brave_x = x brave_y = y canvas.coords("brave", brave_x*62+31, brave_y*62+31) # 上ボタンが押された def click_button_up(): check_move(brave_x, brave_y-1) # 下ボタンが押された def click_button_down(): check_move(brave_x, brave_y+1) # 左ボタンが押された def click_button_left(): check_move(brave_x-1, brave_y) # 右ボタンが押された def click_button_right(): check_move(brave_x+1, brave_y) # エンディング作成 def ending(): canvas.delete("all") canvas.create_rectangle(0, 0, 620, 434, fill="black") canvas.create_text(300, 200, fill="white", font=("MS ゴシック", 15), text="""ゴールおめでとう。 だが、君の戦いはまだ始まったばかりだ。 ………つづく?""") # ボタンを無効化 button_up["state"] = "disabled" button_down["state"] = "disabled" button_left["state"] = "disabled" button_right["state"] = "disabled" # ウィンドウの作成 root = tkinter.Tk() root.title("ダンジョン&パイソン") root.minsize(840, 454) root.option_add("*font", ["メイリオ", 14]) # ボタン配置 button_up = tkinter.Button(text="↑") button_up.place(x=720,y=150) button_up["command"] = click_button_up button_down = tkinter.Button(text="↓") button_down.place(x=720,y=210) button_down["command"] = click_button_down button_left = tkinter.Button(text="←") button_left.place(x=660,y=180) button_left["command"] = click_button_left button_right = tkinter.Button(text="→") button_right.place(x=780,y=180) button_right["command"] = click_button_right #キャンバス作成 canvas =tkinter.Canvas(width=620, height=434) canvas.place(x=10, y=10) canvas.create_rectangle(0, 0, 610, 434, fill="gray",tag="drawField") # 画像データ読み込み images = [tkinter.PhotoImage(file="img6/chap6-mapfield.png"), tkinter.PhotoImage(file="img6/chap6-mapwall.png"), tkinter.PhotoImage(file="img6/chap6-mapgoal.png"), tkinter.PhotoImage(file="img6/chap6-mapkey.png"), tkinter.PhotoImage(file="img6/chap6-mapman.png"),] # マップデータ MAX_WIDTH = 10 MAX_HEIGHT = 7 map_data = [[1, 0, 1, 1, 1, 1, 1, 1, 1, 1], [1, 0, 0, 1, 2, 0, 0, 1, 3, 1], [1, 1, 0, 1, 1, 1, 0, 1, 0, 1], [1, 0, 0, 0, 0, 0, 0, 1, 0, 1], [1, 0, 1, 1, 1, 1, 1, 1, 0, 1], [1, 0, 0, 0, 0, 0, 0, 0, 0, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1]] # 主人公の位置 brave_x = 1 brave_y = 0 flag_key = False draw_map() root.mainloop()

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2018/04/15 10:23

ending をむかえたから動けないんじゃ?
退会済みユーザー

退会済みユーザー

2018/04/15 12:57

回答ありがとうございます。 書き忘れましたが、プログラム自体は全く問題なく、最期まで迎えられますが、なぜ一度消して再描画が必要なのがわからなかったので質問させてもらいました。 疑問の時点ではゴールのフラグが立っていないのでendingを迎えているわけではないようです。
guest

回答1

0

ベストアンサー

回答します
ソースを読ませていただきました。

canvasの仕組みがわかりませんので
憶測で説明します。

たぶんですがアイテムや背景の画像データの”canvas”からの消去は

マップデータ配列にある画像データ(アイテムや背景)の更新
に加えて
「 canvas.create_image(x62+31, y62+31, image=images[p])」の実行が必要です。

実際、ソースのマップ作成メソッドでは

p = map_data[y][x] canvas.create_image(x*62+31, y*62+31, image=images[p])

しています。

描画のデータが3(鍵)から0(道)に変わったならそれで消えたことになる

では

map_data[y][x] = p

を実行しただけでデータを上書きしただけす

これに加えて

canvas.create_image(x*62+31, y*62+31, image=images[0])

でpを0に指定しなおす処理までしないといけないと思います。

投稿2018/04/15 13:36

編集2018/04/15 13:43
kawakawa2018

総合スコア1195

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2018/04/15 14:02

回答ありがとうございます。 なるほど、人間から見えれば更新で変わるものの、プログラム的に画像が更新されるということは内部で1.更新2.実行の過程が必要なのですね。 プログラム勉強し始めで、こういうことまで頭が回らなかったです。今後勉強するにあたって非常に重要なことを聞けた気がします。 ありがとうございました。
kawakawa2018

2018/04/15 14:15

こちらこそお役に立ててよかったです。 Tkinterのドキュメントを一度お読みになり さらにライブラリの.pyソースも目を通すと そちらの本よりも良いゲームが作れるかもしれませんね。 一般のゲームプログラミング理論 ・アイテムの描画、更新 ・画面シーンの切り替え ・LOOPと割り込み処理、←マルチスレッド処理も関係? このあたりを知っていたら、PythonでもC#でも 3Dライブラリ利用ソフトでも簡単にゲームが作れそうですね。 Tkinterを使って2Dゲーム、ロールプレーイングを作る ですか この変わった利用方法? は自分には驚きでしたね。 いずれにしてもいい意味で知識がつきました。
退会済みユーザー

退会済みユーザー

2018/04/15 14:29

御返事ありがとうございます。 tkinterを使ってゲームを作るのは変わった方法なのですね。私はまだ入門したてのため、それすら知りませんでした。もしかしたら正規の覚え方とか少し違うのかもしれませんね。現在はどこから勉強すれば良いのかも見えていないですし、せっかく始めたので進めてみたいと思います。 その後、おすすめしてくださった辺りも含めて本格的に勉強してみたいと思います。その過程でつまづいたら、またどこかでお目にかかるかもしれません。その時お暇でしたらアドバイスいただけたら幸いです。 ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問