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

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

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

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

Q&A

解決済

1回答

1679閲覧

Pythonで複数の車をX方向に動かしたい

ramurezun

総合スコア5

Python

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

0グッド

0クリップ

投稿2020/05/15 16:21

前提・実現したいこと

小林 郁夫・佐々木 晃共著「Pythonによるプログラミング」p58練習問題2.1に取り組んでいます。複数の車を同時にx方向に動かし、左右の壁で反転させるようにしたいです。自分でも挑戦してみましたが、エラーメッセージが出てうまくいきません。解決法をご教授願います。

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

 以下、下記のプログラムを実行したときに出るエラーメッセージです。車は出現するが動かないという状況です。
Traceback (most recent call last):
File "C:\Users\user\Desktop\python\ex02-1-cars.py", line 81, in <module>
redraw_car(car)
File "C:\Users\user\Desktop\python\ex02-1-cars.py", line 50, in redraw_car
canvas.coords(car.ids,car.x,car.y,car.x+car.l,car.y+car.h)
File "C:\Users\user\AppData\Local\Programs\Python\Python38\lib\tkinter_init_.py", line 2761, in coords
self.tk.call((self._w, 'coords') + args))]
_tkinter.TclError: invalid command name ".!canvas"

該当のソースコード

from tkinter import *
from dataclasses import dataclass
import time

DURATION=0.001
X0=150
Y0=150
D=15
VX0=2

@dataclass
class Car:
ids:str
x:int
y:int
l:int
h:int
wd:int
vx:int
bcolor:str

@dataclass
class Border:
left:int
right:int
top:int
bottom:int

def make_car(x, y, l, h, wd=30,vx=4,bcolor="green"):
w_1_x=x+l/4-wd
w_2_x=x+l*3/4-wd
w_y=y+h-wd

id0=canvas.create_rectangle(x, y,x+l,y+h, outline=bcolor, fill=bcolor) id1=canvas.create_oval(w_1_x, w_y, w_1_x+2*wd, w_y+2*wd, outline="black", fill="black") id2=canvas.create_oval(w_2_x, w_y, w_2_x+2*wd, w_y+2*wd, outline="black", fill="black") ids=[id0,id1,id2] return Car(ids,x,y,l,h,wd,vx,bcolor)

def move_car(car):
car.x=car.x+car.vx

def make_walls(ox,oy,width,height):
canvas.create_rectangle(ox,oy,ox+width,oy+height)

def redraw_car(car):
canvas.coords(car.ids,car.x,car.y,car.x+car.l,car.y+car.h)
canvas.coords(car.ids,car.x+car.l/4-car.wd,car.y+car.h-car.wd,car.x+car.l/4+car.wd,car.y+car.h+car.wd)
canvas.coords(car.ids,car.x+car.l3/4-car.wd,car.y+car.h-car.wd,car.x+car.l3/4+car.wd,car.y+car.h+car.wd)

tk=Tk()
canvas=Canvas(tk,width=2000,height=2000,bd=0)
canvas.pack()
tk.update()

border=Border(100,1000,100,800)

make_walls(
border.left,
border.top,
border.right-border.left,
border.bottom-border.top
)

cars=[
make_car(100,150,200,100,30,2,"green"),
make_car(200,250,150,50,30,-4,"red"),
make_car(300,350,400,100,60,-2,"yellow"),
make_car(400,450,200,300,15,4,"gold")
]

while True:
for car in cars:
move_car(car)
if(car.x+car.vx<border.left
or car.x+car.l>=border.right):
car.vx=-car.vx
redraw_car(car)
tk.update()
time.sleep(DURATION)

試したこと

補足情報(FW/ツールのバージョンなど)

該当ページです。ご参照ください。
https://books.google.co.jp/books?id=sOKxDwAAQBAJ&pg=PA56&lpg=PA56&dq=python%E3%81%AB%E3%82%88%E3%82%8B%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0%E3%80%80%EF%BC%95%EF%BC%98&source=bl&ots=nzXmy_HQt5&sig=ACfU3U17hWqsA6mVz12YVH8oVSoC5yYWqA&hl=ja&sa=X&ved=2ahUKEwinkICdo7bpAhWaFogKHbrgBiIQ6AEwAHoECAcQAQ#v=onepage&q=python%E3%81%AB%E3%82%88%E3%82%8B%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0%E3%80%80%EF%BC%95%EF%BC%98&f=false

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

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

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

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

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

Yasumichi

2020/05/15 16:24

Python はインデントが意味を持つのでコードを以下のように囲んでください。 ```python ここにコードを入れる ``` 対応しているMarkdownの記法を知りたい https://teratail.com/help#about-markdown
guest

回答1

0

ベストアンサー

ids = [id0, id1, id2] となっているので、以下のように座標を変更したいオブジェクトの ID をそれぞれ ids[0], ids[1], ids[2] と指定する必要があるのではないでしょうか。

diff

1- canvas.coords(car.ids, car.x, car.y, car.x + car.l, car.y + car.h) 2- canvas.coords(car.ids, car.x + car.l / 4 - car.wd, car.y + car.h - car.wd, car.x + car.l / 4 + car.wd, car.y + car.h + car.wd) 3- canvas.coords(car.ids, car.x + car.l * 3 / 4 - car.wd, car.y + car.h - car.wd, car.x + car.l * 3 / 4 + car.wd, car.y + car.h + car.wd) 4+ canvas.coords(car.ids[0], car.x, car.y, car.x + car.l, car.y + car.h) 5+ canvas.coords(car.ids[1], car.x + car.l / 4 - car.wd, car.y + car.h - car.wd, car.x + car.l / 4 + car.wd, car.y + car.h + car.wd) 6+ canvas.coords(car.ids[2], car.x + car.l * 3 / 4 - car.wd, car.y + car.h - car.wd, car.x + car.l * 3 / 4 + car.wd, car.y + car.h + car.wd)

修正後のコード

python

1from tkinter import * 2from dataclasses import dataclass 3import time 4 5DURATION = 0.001 6X0 = 150 7Y0 = 150 8D = 15 9VX0 = 2 10 11 12@dataclass 13class Car: 14 ids: str 15 x: int 16 y: int 17 l: int 18 h: int 19 wd: int 20 vx: int 21 bcolor: str 22 23 24@dataclass 25class Border: 26 left: int 27 right: int 28 top: int 29 bottom: int 30 31 32def make_car(x, y, l, h, wd=30, vx=4, bcolor="green"): 33 w_1_x = x + l / 4 - wd 34 w_2_x = x + l * 3 / 4 - wd 35 w_y = y + h - wd 36 37 id0 = canvas.create_rectangle(x, y, x + l, y + h, outline=bcolor, fill=bcolor) 38 id1 = canvas.create_oval( 39 w_1_x, w_y, w_1_x + 2 * wd, w_y + 2 * wd, outline="black", fill="black" 40 ) 41 id2 = canvas.create_oval( 42 w_2_x, w_y, w_2_x + 2 * wd, w_y + 2 * wd, outline="black", fill="black" 43 ) 44 ids = [id0, id1, id2] 45 return Car(ids, x, y, l, h, wd, vx, bcolor) 46 47 48def move_car(car): 49 car.x = car.x + car.vx 50 51 52def make_walls(ox, oy, width, height): 53 canvas.create_rectangle(ox, oy, ox + width, oy + height) 54 55 56def redraw_car(car): 57 canvas.coords(car.ids[0], car.x, car.y, car.x + car.l, car.y + car.h) 58 canvas.coords( 59 car.ids[1], 60 car.x + car.l / 4 - car.wd, 61 car.y + car.h - car.wd, 62 car.x + car.l / 4 + car.wd, 63 car.y + car.h + car.wd, 64 ) 65 canvas.coords( 66 car.ids[2], 67 car.x + car.l * 3 / 4 - car.wd, 68 car.y + car.h - car.wd, 69 car.x + car.l * 3 / 4 + car.wd, 70 car.y + car.h + car.wd, 71 ) 72 73 74tk = Tk() 75canvas = Canvas(tk, width=2000, height=2000, bd=0) 76canvas.pack() 77tk.update() 78 79border = Border(100, 1000, 100, 800) 80 81make_walls( 82 border.left, border.top, border.right - border.left, border.bottom - border.top 83) 84 85cars = [ 86 make_car(100, 150, 200, 100, 30, 2, "green"), 87 make_car(200, 250, 150, 50, 30, -4, "red"), 88 make_car(300, 350, 400, 100, 60, -2, "yellow"), 89 make_car(400, 450, 200, 300, 15, 4, "gold"), 90] 91 92while True: 93 for car in cars: 94 move_car(car) 95 if car.x + car.vx < border.left or car.x + car.l >= border.right: 96 car.vx = -car.vx 97 redraw_car(car) 98 tk.update() 99 time.sleep(DURATION)

投稿2020/05/15 16:44

編集2020/05/15 16:45
tiitoi

総合スコア21956

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

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

ramurezun

2020/05/17 12:11

回答いただきありがとうございます。 正常に作動しました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問