見出し画像

PythonでCUIで遊ぼ!

コンソールに表示して楽しいものを動画(Pythonで玉遊び【CUI】)を参考に実際にコードを書いて実行していきます。

まず骨組みは

class Canvas:

class Ball:

class Game:

def main():
        game = Game()
        game.run()

if __name__ == "__main__":
     main()

となっています。

def main():
  game = Game()
  game.run()

これで最終的には動かします。クラスを作って描画場所のCanvas、動かしていくBall、それをまとめ、実際に動くようにしていくGameクラスを作っていきます。

そしてmain()関数でGameクラスを利用し、実行することで全体を動かします。

動かす仕組みは

import time
import os

sum = 0

while True:
    # os.system("clear")
    sum += 1
    print("Hello World ", sum)
    time.sleep(1)

これを実行すると1秒ごとに"Hello world"が出力されます。

普通にwhileを使うと一瞬で処理してしまします。

while i < 1000000:  # 100万回ループ
    sum += i
    i += 1

end_time = time.time()  # 処理終了後の時刻を取得
print(f"実行時間: {end_time - start_time}秒")

実行時間: 0.08872580528259277秒

なので自分の実行したいスピードを調整する必要があります。動かしていく部分はwahileの中に書きます。

   def run(self):
        try:
            while True:
                self.update()
                self.draw()
        except KeyboardInterrupt:
            return

実際に動かす命令としては

def main():
        game = Game()
        game.run()

" game.run()"が全ての起点になります。

  self.update()
  self.draw()

実際の関数は

  def update(self):
        time.sleep(0.33)
        self.ball.auto_move(self.canvas)    

def draw(self):
        self.canvas.draw(self.ball)

を実行することになっています。

update()

ここでclass Ballで作ってるある"ball.auto_move(self.canvas)"を使ってあります。

 def auto_move(self,canvas):
        x = self.x + self.vx
        y = self.y + self.vy     

        if x >= canvas.width or x < 0:
            self.vx = -self.vx
            return self.auto_move(canvas)
        
        if y >= canvas.height or y < 0:
            self.vy = -self.vy
            return self.auto_move(canvas)

        self.x = x
        self.y = y

このコードではボールの方向、スピード

x = self.x + self.vx
y = self.y + self.vy    

Canvasの端からはみ出ないように反転させる

if x >= canvas.width or x < 0:
  self.vx = -self.vx
  return self.auto_move(canvas)

if y >= canvas.height or y < 0:
  self.vy = -self.vy
  return self.auto_move(canvas)

これらの判定に結果を最後に座標に代入しています。

self.x = x
self.y = y

draw()

二次元配列で描画するCanvasにボールを表示します。

def draw(self):
        self.canvas.draw(self.ball)

中身はclass Canvasで定義され

   def draw(self, ball):
        os.system('clear')
        for y in range(self.height):
            for x in range(self.width):
                if y == ball.y and x == ball.x:
                    c = ball.char
                else:
                    c = self.matrix[y][x]
                print(c, end='')             
            print()

更新されるたびに画面を一度クリア

os.system('clear')

再度描画される仕組みを作ります。描画されるたびにボールの座標が変化するので動いていくボールが描画されるようになります。

for y in range(self.height):
  for x in range(self.width):
   if y == ball.y and x == ball.x:
    c = ball.char
    else:
    c = self.matrix[y][x]
    print(c, end='')
  print()


今回実行できた全コードです。

import time
import os

class Canvas:
    def __init__(self, width, height):
        self.width = width
        self.height = height
        self.matrix = []
        for y in range(height):
            row = []
            for x in range(width):
                row.append('.')
            self.matrix.append(row)

    def draw(self, ball):
        os.system('clear')
        for y in range(self.height):
            for x in range(self.width):
                if y == ball.y and x == ball.x:
                    c = ball.char
                else:
                    c = self.matrix[y][x]
                print(c, end='')             
            print()

class Ball:
    def __init__(self):
        self.x = 0
        self.y = 0
        self.char = '@'

    def setvec(self,vx,vy):
        self.vx = vx
        self.vy = vy

    def set_pos(self,x,y):
        self.x = x
        self.y = y

    def move(self, addx,addy):
        self.x += addx
        self.y += addy

    def auto_move(self,canvas):
        x = self.x + self.vx
        y = self.y + self.vy

        if x >= canvas.width or x < 0:
            self.vx = -self.vx
            return self.auto_move(canvas)
        
        if y >= canvas.height or y < 0:
            self.vy = -self.vy
            return self.auto_move(canvas)
        
        self.x = x
        self.y = y

class Game:
    def __init__(self):
        self.canvas_width = 40
        self.canvas_height = 20
        self.canvas = Canvas(self.canvas_width, self.canvas_height)
        self.ball = Ball()
        self.ball.set_pos(self.canvas_width // 2, self.canvas_height // 2)
        self.ball.setvec(1, 1)
    
    def run(self):
        try:
            while True:
                self.update()
                self.draw()
        except KeyboardInterrupt:
            return
    
    def update(self):
        time.sleep(0.33)
        self.ball.auto_move(self.canvas)
    
    def draw(self):
        self.canvas.draw(self.ball)
      
def main():
        game = Game()
        game.run()

if __name__ == "__main__":
     main()

いいなと思ったら応援しよう!