LoginSignup

This article is a Private article. Only a writer and users who know the URL can access it.
Please change open range to public in publish setting if you want to share this article with other users.

More than 3 years have passed since last update.

7章 クラスとオブジェクト

Last updated at Posted at 2020-06-06

後半

前半はこちら →前半

斜めに動かす

# x座標を動かす
    x = x + dx
    # y座標も動かす
    y = y + dy
    # 次の位置に円を描く
    canvas.create_oval(x - 20, y - 20, x + 20, y + 20, fill="red",width=0)
    # 端を越えていたら反対向きにする
    if x >= canvas.winfo_width():
        dx = -1
    if x <= 0:
        dx = +1
    # y座標も同様
    if y >= canvas.winfo_height():
        dy = -1
    if y <= 0:
        dy = +1

    # 再びタイマー
    root.after(10, move)

横に動かすときはx座標に移動量を足すことで動かしていた
そのためこの横の動きに縦の動き、つまりy座標に移動量を加えることで斜めの動きを実現できる
winfo_heightメソッドを使うことで高さを取得できる

結果

動かす円を増やす

# 円をリストで用意する
balls = [{"x" : 400, "y" : 300, "dx" : 1, "dy" : 1, "color":"red"},
         {"x" : 200, "y" : 100, "dx" : -1, "dy" : 1, "color":"green"},
         {"x" : 100, "y" : 200, "dx" : 1, "dy" : -1, "color":"blue"}]

def move():
    global balls
    for b in balls:
        # 今の円を消す
        canvas.create_oval(b["x"] - 20, b["y"] - 20,
                           b["x"] + 20, b["y"] + 20,
                           fill="white",width=0)
        # x座標を動かす
        b["x"] = b["x"] + b["dx"]
        # y座標も動かす
        b["y"] = b["y"] + b["dy"]
        # 次の位置に円を描く
        canvas.create_oval(b["x"] - 20, b["y"] - 20, 
                           b["x"] + 20, b["y"] + 20, 
                           fill=b["color"],width=0)
        # 端を越えていたら反対向きにする
        if b["x"] >= canvas.winfo_width():
           b["dx"] = -1
        if b["x"] <= 0:
           b["dx"] = +1
        # y座標も同様
        if b["y"] >= canvas.winfo_height():
           b["dy"] = -1
        if b["y"] <= 0:
           b["dy"] = +1

    # 再びタイマー
    root.after(10, move)

複数個の円を動かすためにはリストを使う
balls = [
{"x" : 400, "y" : 300, "dx" : 1, "dy" : 1, "color":"red"},
{"x" : 200, "y" : 100, "dx" : -1, "dy" : 1, "color":"green"},
{"x" : 100, "y" : 200, "dx" : 1, "dy" : -1, "color":"blue"}]

このようにリストにすることで行数を少なくすることができる
そして円に関するデータをまとめるためにディクショナリ(Dictionary)という機能を使う
今回はballを変数名とした
ball = {"x" : 400, "y" : 300, "dx" : 1, "dy" : 1, "color":"red"}
(ディクショナリ)
変数名 = { キー名: 値, キー名: 値, ・・・}

プログラムをブロック化する

今度はディクショナリとリストを使わずに行う
オブジェクトを使用する

class Ball:
    def __init__(self, x, y, dx, dy, color):
        self.x = x
        self.y = y
        self.dx = dx
        self.dy = dy
        self.color = color

    def move(self, canvas):
        # 今の円を消す
        canvas.create_oval(self.x - 20, self.y - 20,
                           self.x + 20, self.y + 20,
                           fill="white",width=0)
        # x座標を動かす
        self.x = self.x + self.dx
        self.y = self.y + self.dy
        # 次の位置に円を描く
        canvas.create_oval(self.x - 20, self.y - 20,
                           self.x + 20, self.y + 20, 
                           fill=self.color, width=0)
        # 端を越えていたら反対向きにする
        if self.x >= canvas.winfo_width():
           self.dx = -1
        if self.x <= 0:
           self.dx = +1
        if self.y >= canvas.winfo_height():
           self.dy = -1
        if self.y <= 0:
           self.dy = +1

# 円をひとつ作る
b = Ball(400, 300, 1, 1, "red")

def loop():

オブジェクトを使う場合にはクラスをプログラムしなければならない
こうしてクラスから作ったオブジェクトのことをインスタンスと言う
(クラス)
class クラス名:
    クラスの定義内容

今回ではこの部分
class Ball:
def _init_(self, x, y, dx, dy, color):
self.x = x
self.y = y
self.dx = dx
self.dy = dy
self.color = color

ここにでてくる_init_というのは最初にオブジェクトを作るときに呼び出される特殊な関数であり、コンストラクタ(constructor)と呼ばれている
オブジェクトのなかにあるxやyなどの変数をインスタンス変数という

結果


スピードを速くするために先生のサイトを参照しました→クリック

円以外も動かす

 def erase(self, canvas):
        canvas.create_oval(self.x - 20, self.y - 20,
                           self.x + 20, self.y + 20,
                           fill="white",width=0)

    def draw(self, canvas):
        canvas.create_oval(self.x - 20, self.y - 20,
                           self.x + 20, self.y + 20, 
                           fill=self.color, width=0)

class Rectangle(Ball):
    def erase(self, canvas):
        canvas.create_rectangle(self.x - 20, self.y - 20,
                           self.x + 20, self.y + 20,
                           fill="white",width=0)

    def draw(self, canvas):
        canvas.create_rectangle(self.x - 20, self.y - 20,
                           self.x + 20, self.y + 20, 
                           fill=self.color, width=0)

class Triangle(Ball):
    def erase(self, canvas):
        canvas.create_polygon(self.x, self.y - 20,
                           self.x + 20, self.y + 20,
                           self.x - 20, self.y + 20,
                           fill="white",width=0)

    def draw(self, canvas):
        canvas.create_polygon(self.x, self.y - 20,
                           self.x + 20, self.y + 20,
                           self.x - 20, self.y + 20,
                           fill=self.color, width=0)

# 円、四角形、三角形を用意
balls = [Ball(400, 300, 1, 1, "red"),
         Rectangle (200, 100, -1, 1, "green"),
         Triangle(100, 200, 1, -1, "blue")]

def loop():

クラスにはメソッド単位で処理を変更する機能があり、これをオーバーライド(override)という
さらに既存のクラスを基に新しいクラスを作ることを継承という
(継承)
class新しいクラス名(基のクラス名):
クラス名
三角形→Triangle
四角形→Rectangle

結果


完成!!

最後に

今回使ったgifは「Gif Maker」というアプリでつくりました
画面録画したものを編集するだけなのでとても簡単です
スクリーンショット (33).png

1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up