3
0

More than 3 years have passed since last update.

ボールを動かしてみた

Last updated at Posted at 2020-07-08
1 / 2

 完成品

 ストーカーボール.gif

 動機

今までの講義を通してpythonのプログラミングを学んだことで簡単な動くものを作りたいと思いこれを制作しました。

 手順

Windowを表示

qiita.rb

import tkinter as tk
import math

class Application(tk.Frame):
    def __init__(self,master):
        super().__init__(master)
        self.pack()

        self.width=self.height=500
        master.geometry(str(self.width)+"x"+str(self.height))
        master.title("追いかけっこゲーム")


def main():
    win = tk.Tk()
    app = Application(master = win)
    app.mainloop()


if __name__ == "__main__":

    main()

もう1つのボールについて

qiita.rb

def enemyVec(self,player,enemy,speed):#敵の動き(x,y)のベクトルを返す
    rad=np.arctan((player.y-enemy.y)/(player.x-enemy.x))#向き(角度の計算)
    if player.x-enemy.x >= 0:
        vx=np.cos()*speed
        vy=np.sin()*speed
    else:
        vx=np.cos()*(-1*speed)
        vy=np.sin()*(-1*speed)
    return [vx,vy]

引数として、playerオブジェクトとenemyオブジェクトを渡しています。それぞれの中心座標を計算で使うためです。ここで、この2つのオブジェクトの向きの計算が少しややこしくなると思います。つまり、2点間の角度の計算です。
2点の座標が分かっているので、ベクトルのx成分とy成分を求めることができます。
(例) A(x1,y1),B(x2,y2)の場合
AB→=x2−x1y2−y1

そして、x軸とベクトルがなす角度θを以下のtanの逆関数を使って表すことができます。
θ=tan−1(yx)
tanθの範囲が-π/2~π/2なので、playerとenemyのx座標の差の正負で場合分けをし、speedに-1をかけて、方向を変えています。     

*分かりやすかったため引用させていただいています【Python】Tkinterによる70行で作るGUIアプリ「追いかけっこゲーム」

ソースコード

qiita.rb
import tkinter as tk
import math

class Circle():
    def __init__(self,canvas,x,y,r,color,tag=None):
        self.canvas = canvas
        self.x = x #円の中心のx座標
        self.y = y #円の中心のy座標
        self.r = r #円の半径
        self.color = color
        self.tag = tag

    def createCircle(self):
        self.canvas.create_oval(self.x-self.r,self.y-self.r,self.x+self.r,self.y+self.r,fill=self.color,tag=self.tag)

class Application(tk.Frame):
    def __init__(self,master):
        super().__init__(master)
        self.pack()

        self.width=self.height=500
        master.geometry(str(self.width)+"x"+str(self.height))
        master.title("追いかけっこゲーム")

        self.canvas = tk.Canvas(master,width=self.width,height=self.height,bg="black")
        self.canvas.pack()

        self.player = Circle(self.canvas,250,250,30,"red","player") #インスタンスplayerの生成
        self.enemy = Circle(self.canvas,0,0,30,"blue","enemy") #インスタンスenemyの生成

        self.canvas.bind("<Motion>",self.mouseEvent)
        self.master.after(50,self.update)

    def update(self):
        if self.judgeflag(self.player,self.enemy):
            eV = self.enemyVec(self.player,self.enemy,10)
            self.enemy.x += eV[0]
            self.enemy.y += eV[1]
            self.canvas.delete("player")
            self.canvas.delete("enemy")
            self.player.createCircle()
            self.enemy.createCircle()

        self.master.after(50,self.update)

    def enemyVec(self,player,enemy,speed): #敵の動き(x,y)のベクトルを返す
        rad=math.atan((player.y-enemy.y)/(player.x-enemy.x)) #向き(角度の計算)
        if player.x-enemy.x >= 0:
            vx=math.cos(rad)*speed
            vy=math.sin(rad)*speed
        else:
            vx=math.cos(rad)*(-1*speed)
            vy=math.sin(rad)*(-1*speed)
        return [vx,vy]

    def judgeflag(self,player,enemy): #当たり判定
        if math.sqrt((player.x-enemy.x)**2+(player.y-enemy.y)**2) > player.r+enemy.r: return True
        else: return False

    def mouseEvent(self,event):
        self.player.x = event.x
        self.player.y = event.y

def main():
    win = tk.Tk()
    app = Application(master=win)
    app.mainloop()

if __name__ == "__main__":
    main()

 感想

元のソースコードでは動かなかったためPython 標準ライブラリを参考に試行錯誤しました。ほぼソースコードは【Python】Tkinterによる70行で作るGUIアプリ「追いかけっこゲーム」を参考にさせていただきました。今回制作するにあったて、このプログラムについて理解を深めることができました。まだ自分で1からものを作るのには多くの時間と経験が必要だと感じたので夏休みに勉強しようと思います。教科書を写していた時には感じられなかった達成感を味わうことができ、これからも達成感をモチベーションに変えて学んでいきたいです。

 今後の目標

私はいつか自分でサイトを作りたいです。最近旅行に行こうと思いサイトを開いて予約しようとしていたのですが、何か間違えるたびに最初に戻ってしまうので使いにくなと感じました。なので今後の学びを通して自分で1から作って多くの人に使ってもらえるようなものを作り上げたいです。

 参考文献

- いちばんやさしいpython入門教室 大澤文孝[著]

3
0
2

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
3
0