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

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

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

HTML5の<canvas>要素用のタグです。CanvasはHTML5から導入された、二次元の図形描写が可能な要素です。

Tkinter

Tkinterは、GUIツールキットである“Tk”をPythonから利用できるようにした標準ライブラリである。

Python

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

Q&A

解決済

1回答

676閲覧

ゲームを正しく動作させたい

Simonde

総合スコア7

canvas

HTML5の<canvas>要素用のタグです。CanvasはHTML5から導入された、二次元の図形描写が可能な要素です。

Tkinter

Tkinterは、GUIツールキットである“Tk”をPythonから利用できるようにした標準ライブラリである。

Python

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

0グッド

1クリップ

投稿2020/10/19 08:27

編集2020/10/19 08:39

前提・実現したいこと

今、ブロック崩しゲームを作っています。ただのブロック崩しゲームに追加して、ブロックにあたったらスコアが10増える、ブロックは三回あたったらなくなる、途中槍(としている物)にあたったらGameover、お金(としているもの)にあたったらスコアが50増えるという設定で作りました。しかし、「発生している問題」で書いたような問題が発生してしまいます。どこがおかしいから正しく動作しないのか教えていただきたいです。

発生している問題・エラーメッセージ

お金にあたったらスコアが50増えるとプログラムしたのですがなぜか50ではなく、1450ほど増えてしまいます、またすべてではないですがブロックが1回で消えてしまうことがあります。
エラーメッセージは特に検出されていません

from tkinter import * from dataclasses import dataclass import time import random import math DURATION = 0.01 PADDLE_X0 = 200 PADDLE_Y0 = 550 BALL_Y0 = 300 PAD_VX = 10 BALL_VX = 5 BALL_VY = 5 BLOCK_X = 0 BLOCK_Y = 100 BLOCK_W = 100 BLOCK_H = 20 NUM_BLOCKS = 7 score = 0 ADD_SCORE = 10 MONEY_BONUS = 50 COLORS = ["blue", "red", "black", "white", "green", "pink", "orange"] @dataclass class Paddle: id: int x : int y : int w : int h : int v : int c : str @dataclass class Ball: id: int x : int y : int d : int vx: int vy: int c : str @dataclass class Block: id: int x : int y : int w : int h : int bc: int c : str @dataclass class Game: start: int @dataclass class Spear: id: int x : int y : int w : int h : int vy: int c : str @dataclass class Money: id: int x : int y : int w : int h : int vy: int c : str def make_ball(x, y, d, vx, vy, c="black"): id = canvas.create_oval(x, y, x + d, y + d, fill=c, outline=c) return Ball(id, x, y, d, vx, vy, c) def move_ball(ball): ball.x += ball.vx ball.y += ball.vy def redraw_ball(ball): canvas.coords(ball.id, ball.x, ball.y, ball.x + ball.d, ball.y + ball.d) def make_paddle(x, y, w , v, h, c="blue"): id = canvas.create_rectangle(x, y, x + w, y + h, fill=c, outline=c) return Paddle(id, x, y, w, h, v, c) def move_paddle(pad): pad.x += pad.v def redraw_paddle(pad): canvas.coords(pad.id, pad.x, pad.y, pad.x + pad.w, pad.y + pad.h) def make_block(x, y, m=40, n=300, bc=3, c="green"): id = canvas.create_rectangle(x, y, x + m, y + n, fill=c, outline=c) return Block(id, x, y, m, n, bc, c) def make_blocks(n_rows, x0, y0, w, h, pad=10): blocks = [] for x in range(n_rows): blocks.append(make_block(x0, y0, w, h)) x0 = x0 + w + pad return blocks def delete_block(block): canvas.delete(block.id) def game_start(event): game.start = True def game_over(): canvas.create_text(400, 200, text="Game Over!", font=('FixedSys', 16)) def make_spear(x, y, w=1, h=40, vy=5, c="red"): id = canvas.create_rectangle(x, y, x + w, y + h, fill=c, outline=c) return Spear(id, x, y, w, h, vy, c) def delete_spear(spear): canvas.delete(spear.id) def move_spear(spear): spear.y += spear.vy def redraw_spear(spear): canvas.coords(spear.id, spear.x, spear.y, spear.x + spear.w, spear.y + spear.h) def make_money(x, y, w=10, h=4, vy=3, c="gold"): id = canvas.create_rectangle(x, y, x + w, y + h, fill=c, outline=c) return Money(id, x, y, w, h, vy, c) def delete_money(money): canvas.delete(money.id) def move_money(money): money.y += money.vy def redraw_money(money): canvas.coords(money.id, money.x, money.y, money.x + money.w, money.y + money.h) def make_walls(ox, oy, width, height): canvas.create_rectangle(ox, oy, ox + width, oy + height) def left_paddle(event): paddle.v = -PAD_VX def right_paddle(event): paddle.v = PAD_VX def stop_paddle(event): paddle.v = 0 def change_paddle_color(pad, c="red"): canvas.itemconfigure(pad.id, fill=c) canvas.itemconfigure(pad.id, outline=c) redraw_paddle(pad) tk = Tk() tk.title("Game") WALL_EAST = 800 WALL_SOUTH = 600 canvas = Canvas(tk, width=WALL_EAST, height=WALL_SOUTH, bd=0, highlightthickness=0) canvas.pack() tk.update() BALL_X0 = WALL_EAST/2 PADDLE_X0 = WALL_EAST/2-50 PADDLE_Y0 = WALL_SOUTH-100 paddle = make_paddle(PADDLE_X0, PADDLE_Y0, 100, PAD_VX, 10) ball = make_ball(200, BALL_Y0, 10, BALL_VX, BALL_VX) make_walls(0, 0, WALL_EAST, WALL_SOUTH) blocks = make_blocks(NUM_BLOCKS, BLOCK_X, BLOCK_Y, BLOCK_W, BLOCK_H) game = Game(False) spear = None money = None canvas.bind_all('<KeyPress-Left>', left_paddle) canvas.bind_all('<KeyPress-Right>', right_paddle) canvas.bind_all('<KeyRelease-Left>', stop_paddle) canvas.bind_all('<KeyRelease-Right>', stop_paddle) canvas.bind_all('<KeyPress-space>', game_start) id_score = canvas.create_text(10, 10, text=("score:" + str(score)), font=("FixedSys", 16), justify="left", anchor=NW) id_text = canvas.create_text(WALL_EAST/2, 200, text = "Press 'SPACE' to start", font = ('FixedSys', 16)) tk.update() while not game.start: tk.update() time.sleep(DURATION) canvas.delete(id_text) tk.update() while True: move_paddle(paddle) move_ball(ball) if money : move_money(money) if money == None and random.random() < 0.1: money = make_money(random.randint(100, WALL_EAST - 100), 10) if money and money.y + money.h >= WALL_SOUTH: delete_money(money) money = None if spear : move_spear(spear) if spear == None and random.random() < 0.7: spear = make_spear(random.randint(100, WALL_EAST - 100), 10) if spear and spear.y + spear.h >= WALL_SOUTH: delete_spear(spear) spear = None if ball.y + ball.vy <= 100: ball.vy = -ball.vy if ball.y + ball.d >= WALL_SOUTH: game_over() break if money: if (paddle.x <= money.x <= paddle.x + paddle.w \ and money.y + money.h >= paddle.y): redraw_paddle(paddle) redraw_money score += MONEY_BONUS canvas.itemconfigure(id_score, text="score:" + str(score)) delete_money if spear: if (paddle.x <= spear.x <= paddle.x + paddle.w \ and spear.y + spear.h >= paddle.y \ and spear.y <= paddle.y + paddle.h): redraw_paddle(paddle) redraw_spear(spear) game_over() break if (ball.x + ball.vx < 0 \ or ball.x + ball.d >= WALL_EAST): ball.vx = -ball.vx for block in blocks: if ( block.x < ball.x + ball.d/2 < block.x + block.w and (block.y <= ball.y <= block.y + block.h or block.y <= ball.y + ball.d <= block.y + block.h)): ball.vy = -ball.vy score += ADD_SCORE canvas.itemconfigure(id_score, text="score:" + str(score)) block.bc -= 1 if block.bc == 0: delete_block(block) blocks.remove(block) if blocks == []:break if len(blocks) == 0: canvas.create_text(WALL_EAST/2, 200, text="Clear!", font=('FixedSys', 16)) break if (ball.y + ball.d >= paddle.y \ and paddle.x <= ball.x <= paddle.x + paddle.w): ball.vy = -ball.vy ball.vx = int(6 * (ball.x + ball.d/2 - paddle.x) / paddle.w)- 3 redraw_paddle(paddle) redraw_ball(ball) if money : redraw_money(money) if spear : redraw_spear(spear) tk.update() time.sleep(DURATION) ```ここに言語を入力 コード

試したこと

if money:
の部分をいじってみたのですが狙ったような変化を得られませんでした。

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

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

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

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

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

y_waiwai

2020/10/19 08:28

このままではコードが読めないので、質問を編集し、<code>ボタンを押し、出てくる’’’の枠の中にコードを貼り付けてください
Simonde

2020/10/19 08:56

訂正しました。
guest

回答1

0

ベストアンサー

お金にあたったらスコアが50増えるとプログラムしたのですがなぜか50ではなく、1450ほど増えてしまいます

print(score) としてみましょう、
お金が当たり続けてる間加算されているようです。

原因は、「お金に当たった」判定を何度も行われる為。
また、redraw_money, delete_money 関数も呼び出されてないようです。

diff

1- redraw_money 2+ redraw_money(money) 3 score += MONEY_BONUS 4 canvas.itemconfigure(id_score, text="score:" + str(score)) 5- delete_money 6+ delete_money(money) 7+ money = None

またすべてではないですがブロックが1回で消えてしまうことがあります。

再現条件がわからないので、どの場合かわかりませんが、
横からボールが当たった時でしょうか?

横から当たった場合の反転が、壁に当たった時しかない為、
ブロックに当たり続けていると判定され、カウントが一気に減っているのだと思います。


参考: 著者のGithub にソースコードがあるようです。

投稿2020/10/19 09:56

teamikl

総合スコア8664

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

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

Simonde

2020/10/20 02:01

ありがとうございます!! お金のカウントが正常に作動しました! 正面?からあたっても1回で消えてしまうことがあります。
teamikl

2020/10/20 02:19

正面からについては、再現条件が解らないですね。 デバッグの方法としては、 ブロックのカウントが減った時にprint(block.bc) として、 意図しないタイミングでカウントが減っていないか確認して見ましょう。 例えば、他のブロックに当たったはずなのに 意図しないブロックのカウントが減ってるようなことがないか。 →衝突判定の条件式に漏れがないかを確認する ---- もしくは、正解のコードと見比べてみる。 まずは、インデントやコーディングスタイルも含めて模写すると良いです。 diff というツールを使うと、差分をハイライト表示してくれるので、 間違い箇所がわかりやすくなります。 学習目的であれば、出来れば、前者の自力でのデバッグをお勧めします。 後者は正解のコードがないと応用が利きません。
Simonde

2020/10/20 07:39

わかりましたトライしてみます! ありがとうございます!!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問