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

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

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

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

Q&A

1回答

1611閲覧

【python】'Nonetype' object has no attribute ~~の直し方が分からない

ramurezun

総合スコア5

Python

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

0グッド

0クリップ

投稿2020/05/19 13:46

前提・実現したいこと

小林 郁夫・佐々木 晃共著の「Pythonによるプログラミング」p160の練習問題6.4に取り組んでいます。最終的にボールがブロックで跳ね返りブロックが消えるアニメーションを作成したいです。しかし、check_blocksのblockが正しく反映されません。自分でも挑戦してみましたが、上手くいきません。ご教授願います。

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

Traceback (most recent call last):
File "C:\Users\user\Desktop\python\ex06-block.py", line 182, in <module>
box.animate()
File "C:\Users\user\Desktop\python\ex06-block.py", line 162, in animate
self.check_blocks(self.ball,self.block)
File "C:\Users\user\Desktop\python\ex06-block.py", line 145, in check_blocks
if(block.y<ball.y+ball.d/2<block.y+block.h
AttributeError: 'NoneType' object has no attribute 'y'

該当のソースコード

from tkinter import *
from dataclasses import dataclass,field
import time

@dataclass
class Ball:
id:int
x:int
y:int
d:int
vx:int
vy:int
c:str="black"

def move(self): self.x=self.x+self.vx self.y=self.y+self.vy def redraw(self): d=self.d canvas.coords(self.id,self.x,self.y, self.x+d,self.y+d)

@dataclass
class Paddle:
id:int
x:int
y:int
w:int
h:int
vy:int = field(init=False,default=0)
c:str="green"

def move(self): self.y=self.y+self.vy def redraw(self): canvas.coords(self.id,self.x,self.y, self.x+self.w,self.y+self.h) def set_v(self,v): self.vy=v def stop(self): self.vy=0

@dataclass
class Block:
id:int
x:int
y:int
w:int
h:int
c:str

def redraw(self): canvas.coords(self.id,self.x,self.y, self.x+self.w,self.y+self.h) def delete(self): canvas.delete(self.id)

@dataclass
class Box:
id:int
west:int
north:int
east:int
south:int
ball:Ball
paddle:Paddle
block:Block
paddle_v:int
duration:float

def __init__(self,x,y,w,h,duration): self.west,self.north=(x,y) self.east,self.south=(x+w,y+h) self.ball=None self.paddle=None self.block=None self.blocks=[] self.duration=duration self.paddle_v=5 def make_ball(self,x,y,d,vx,vy): id=canvas.create_oval(x,y,x+d,y+d, fill="black",outline="black") return Ball(id,x,y,d,vx,vy) def make_walls(self): canvas.create_rectangle(self.west,self.north,self.east,self.south) def check_wall(self,ball): if ball.x+ball.vx<=self.west or ball.x+ball.d+ball.vx>=self.east: ball.vx=-ball.vx if ball.y+ball.vy<=self.north or ball.y+ball.d+ball.vy>=self.south: ball.vy=-ball.vy def set_ball(self): self.ball=self.make_ball(self.west+10,self.north+10,10,4,2) def make_paddle(self,x,y,w,h,c): id=canvas.create_rectangle(x,y,x+w,y+h, fill=c,outline=c) return Paddle(id,x,y,w,h) def check_paddle(self,ball,paddle): if(ball.y+ball.d/2>=paddle.y and paddle.x<=ball.x+ball.d and ball.y+ball.d/2<=paddle.y+paddle.h): ball.vx=-ball.vx def set_paddle(self): self.paddle=self.make_paddle(self.east-20,(self.north+self.south)/2-10, 10,20, "green") def up_paddle(self,event): self.paddle.set_v(-self.paddle_v) def down_paddle(self,event): self.paddle.set_v(self.paddle_v) def stop_paddle(self,event): self.paddle.stop() def make_block(self,x,y,w,h,c): id=canvas.create_rectangle(x,y,x+w,y+h, fill=c,outline=c) return Block(id,x,y,w,h,c) def set_blocks(self,n,s): for x in range(n): block=self.make_block(self.west+10*x,self.south-30, 5,20,"red") for x in range(s): block=self.make_block(self.west+10*x,self.south-60, 5,20,"blue") self.blocks.append(block) def check_blocks(self,ball,block): if(block.y<ball.y+ball.d/2<block.y+block.h and(block.x<=ball.x<=block.x+block.w or block.x<=ball.x+ball.d<=block.x+block.w)): ball.vx=-ball.vx self.block.delete() self.blocks.remove() def animate(self): while True: self.ball.move() self.paddle.move() self.check_wall(self.ball) self.check_paddle(self.ball,self.paddle) self.ball.redraw() self.paddle.redraw() for block in self.blocks: self.check_blocks(self.ball,self.block) self.block.redraw() time.sleep(self.duration) tk.update()

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

box=Box(100,100,300,200,0.05)
box.make_walls()
canvas.bind_all("<KeyPress-Up>",box.up_paddle)
canvas.bind_all("<KeyPress-Down>",box.down_paddle)
canvas.bind_all("<KeyRelease-Up>",box.stop_paddle)
canvas.bind_all("<KeyRelease-Down>",box.stop_paddle)
box.set_ball()
box.set_paddle()
box.set_blocks(4,4)
box.animate()

試したこと

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

以下、該当ページを掲載します。
https://books.google.co.jp/books?id=sOKxDwAAQBAJ&pg=PA161&lpg=PA161&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%E3%83%97%E3%83%AD%E3%83%88%E3%82%B3%E3%83%AB&source=bl&ots=nzXmB2DTmb&sig=ACfU3U1g0d42R2WQQ01Qg8LVyYfn6I3iKg&hl=ja&sa=X&ved=2ahUKEwjA1dXmh8DpAhW_x4sBHbmRB9wQ6AEwBXoECAkQAQ#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%E3%83%97%E3%83%AD%E3%83%88%E3%82%B3%E3%83%AB&f=false

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

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

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

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

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

y_waiwai

2020/05/19 13:49

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

回答1

0

def check_blocks(self,ball,block):

if(block.y<ball.y+ball.d/2<block.y+block.h

ここで、block がNoneのため、block.yがエラーとなってます。
これをどーにかしましょう

投稿2020/05/19 13:58

y_waiwai

総合スコア87749

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

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

ramurezun

2020/05/19 14:42

blockをNoneにしない方法を自分では見つけることができませんでした。 ご教授お願いします。
y_waiwai

2020/05/19 14:44

このままではコードが読めません。 修正依頼に書いてあるように編集してください
ramurezun

2020/05/19 15:03

すみません。なぜか質問を編集してもその内容が反映されないので、新たに質問ページを作ります。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問