🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
canvas

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

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Tkinter

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

Python

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

Q&A

解決済

1回答

1783閲覧

bindメソッドで弾を出す(ゲームプログラム)

SkeletonFarts

総合スコア3

canvas

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

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Tkinter

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

Python

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

0グッド

0クリップ

投稿2020/12/02 05:49

前提・実現したいこと

Pythonのtkinterを用い、インベーダーゲームをベースに勉強がてら改良をしています。

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

イベントシーケンスの部分、"<ButtonPress-3>"が初期値だったのですが、スペースキーにすることで
自機が打つ弾をスペースキーで出すプログラムにしたく、"<space>"にしたのですが、
スペースキーを押しても弾が出ず、エラーメッセージも出ません。

def bind(self): #canvas内で動作させる canvas.tag_bind(self.id,"<space>", self.pressed)

全体のソースコード

import tkinter as tk from tkinter import messagebox import random from PIL import Image, ImageTk import os WINDOW_HEIGHT = 600 # ウィンドウの高さ WINDOW_WIDTH = 600 # ウィンドウの幅 CANNON_Y = 550 # 自機のy座標 ENEMY_SPACE_X = 100 # 敵の間隔(x座標) ENEMY_SPACE_Y = 60 # 敵の間隔(y座標) ENEMY_MOVE_SPACE_X = 2 # 敵の移動間隔(x座標) ENEMY_MOVE_SPEED = 15 # 敵の移動スピード(2000 ms) NUMBER_OF_ENEMY = 2 # 敵の数 ENEMY_SHOOT_INTERVAL = 100 # 敵がランダムに弾を打ってくる間隔 COLLISION_DETECTION = 300 # 当たり判定 BULLET_HEIGHT = 10 # 弾の縦幅 BULLET_WIDTH = 2 # 弾の横幅 BULLET_SPEED = 50 # 弾のスピード(10 ms) TEXT_GOOD_SIZE = 10 # goodのサイズ TEXT_CONGRATULATIONS_SIZE = 50 # congratularionsのサイズ TEXT_GAMECLEAR_SIZE = 60 # gameclearのサイズ TEXT_GAMEOVER_SIZE = 90 # gameoverのサイズ class Cannon: # 自機 def __init__(self, x, y=CANNON_Y): #x座標は中心に固定, y座標は"CANNON_Y"で変更 self.x = x self.y = y self.draw() self.bind() def draw(self): #自機の画像を配置(完了) self.id = canvas.create_image( self.x, self.y, image=cannon_tkimg, tag="cannon") def bind(self): #canvas内で動作させる canvas.tag_bind(self.id,"<space>", self.pressed) canvas.tag_bind(self.id, "<Button1-Motion>", self.dragged) #自機の移動 def pressed(self, event=None): #弾 mybullet = MyBullet(event.x, self.y) mybullet.draw() mybullet.shoot() def dragged(self, event): dx = event.x - self.x self.x, self.y = canvas.coords(self.id) canvas.coords(self.id, self.x+dx, self.y) self.x = event.x def destroy(self): canvas.delete(self.id) class MyBullet: # 自分の弾 def __init__(self, x, y): self.x = x self.y = y def draw(self): #弾の描写 self.id = canvas.create_rectangle( self.x-BULLET_WIDTH, self.y+BULLET_HEIGHT, self.x+BULLET_WIDTH, self.y-BULLET_HEIGHT, fill="blue") #fill関数で弾の色を変更する def shoot(self): if self.y >= 0: canvas.move(self.id, 0, -BULLET_HEIGHT) self.y -= BULLET_HEIGHT self.defeat() root.after(BULLET_SPEED, self.shoot) def defeat(self): for enemy in enemies: if ((self.x-enemy.x)**2+(self.y-enemy.y)**2) < COLLISION_DETECTION: enemy.exist = False enemy.destroy() canvas.create_text(enemy.x, enemy.y, text="good!", fill="cyan", font=( "System", TEXT_GOOD_SIZE), tag="good") def destroy(self): canvas.delete(self.id) class Enemy: # 敵 def __init__(self, x, y): self.x = x % WINDOW_WIDTH self.y = y+x//WINDOW_WIDTH*ENEMY_SPACE_Y self.exist = True self.draw() self.move() def draw(self): self.id = canvas.create_image( self.x, self.y, image=crab_tkimg, tag="enemy") def enemy_shoot(self): if self.exist: enemybullet = EnemyBullet(self.x, self.y) enemybullet.draw() enemybullet.shoot() def move(self): if self.exist: if self.x > WINDOW_WIDTH: self.x -= ENEMY_MOVE_SPACE_X self.y += ENEMY_SPACE_Y elif self.x < 0: self.x += ENEMY_MOVE_SPACE_X self.y += ENEMY_SPACE_Y if self.y % (ENEMY_SPACE_Y*2) == ENEMY_SPACE_Y: self.x += ENEMY_MOVE_SPACE_X else: self.x -= ENEMY_MOVE_SPACE_X canvas.coords(self.id, self.x, self.y) root.after(ENEMY_MOVE_SPEED, self.move) def destroy(self): canvas.delete(self.id) class EnemyBullet: # 敵の弾 def __init__(self, x, y): self.x = x self.y = y def draw(self): self.id = canvas.create_rectangle( self.x-BULLET_WIDTH, self.y+BULLET_HEIGHT, self.x+BULLET_WIDTH, self.y-BULLET_HEIGHT, fill="red") def shoot(self): if self.y <= WINDOW_HEIGHT: canvas.move(self.id, 0, BULLET_HEIGHT) self.y += BULLET_HEIGHT self.collision() root.after(BULLET_SPEED, self.shoot) def collision(self): if ((self.x-cannon.x)**2+(self.y-cannon.y)**2) < COLLISION_DETECTION: gameover() def destroy(self): canvas.delete(self.id) def gameclear(): # ゲームクリア判定 winflag = 0 for enemy in enemies: if enemy.exist == False: winflag += 1 if winflag == NUMBER_OF_ENEMY: canvas.delete("good") canvas.create_text(WINDOW_WIDTH//2, WINDOW_HEIGHT//2-80, text="Congratulations!", fill="lime", font=("System", TEXT_CONGRATULATIONS_SIZE)) canvas.create_text(WINDOW_WIDTH//2, WINDOW_HEIGHT//2+20, text="GAME CLEAR!", fill="lime", font=("System", TEXT_GAMECLEAR_SIZE)) root.after(1000, gameclear) def gameover(): # ゲームオーバー判定 canvas.delete("cannon", "good") canvas.create_text(WINDOW_WIDTH//2, WINDOW_HEIGHT//2, text="GAME OVER", fill="red", font=("System", TEXT_GAMEOVER_SIZE)) def enemy_randomshoot(): # ランダムに敵の弾が発射 enemy = random.choice(enemies) enemy.enemy_shoot() root.after(ENEMY_SHOOT_INTERVAL, enemy_randomshoot) def comming_soon(): messagebox.showinfo("準備中です!", "只今リセットボタン実装に向けて準備中です!") if __name__ == "__main__": # 初期描画 root = tk.Tk() root.title("invader") canvas = tk.Canvas(root, width=WINDOW_WIDTH, height=WINDOW_HEIGHT, bg="black") canvas.focus_set() canvas.pack() # 画像の読み込み cannon_img = Image.open("data/cannon.jpeg") cannon_tkimg = ImageTk.PhotoImage(cannon_img) crab_img = Image.open("data/crab.jpeg") crab_tkimg = ImageTk.PhotoImage(crab_img) # メニューバー menubar = tk.Menu(root) root.configure(menu=menubar) menubar.add_command(label="QUIT", underline=0, command=root.quit) #QUITメニューの配置 menubar.add_command(label="RESET", command=comming_soon) #RESETメニューの配置 # インスタンス生成 cannon = Cannon(WINDOW_WIDTH//2, CANNON_Y) enemies = [] for i in range(NUMBER_OF_ENEMY): enemy_i = Enemy(i*ENEMY_SPACE_X+50, ENEMY_SPACE_Y) enemies.append(enemy_i) enemy_randomshoot() gameclear() root.mainloop()

"<ButtonPress-3>"に戻したら、右クリックで弾を打てることができました。
ご迷惑をおかけしますが、宜しくお願い致します。

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

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

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

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

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

K_Y_M

2020/12/02 07:48

"<Key-space>"に変更してみて頂けますでしょうか
guest

回答1

0

ベストアンサー

canvas.tag_bind(self.id,"<space>", self.pressed)

tag_bind ではなく、bind を使います

python

1canvas.bind("<space>", self.pressed)

投稿2020/12/03 00:03

teamikl

総合スコア8738

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

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

SkeletonFarts

2020/12/03 13:25

無事、問題解決できました 誠にありがとうございますm(__)m
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問