PythonでCUIで遊ぼ!
コンソールに表示して楽しいものを動画(Pythonで玉遊び【CUI】)を参考に実際にコードを書いて実行していきます。
まず骨組みは
class Canvas:
class Ball:
class Game:
def main():
game = Game()
game.run()
if __name__ == "__main__":
main()
となっています。
これで最終的には動かします。クラスを作って描画場所の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
このコードではボールの方向、スピード
Canvasの端からはみ出ないように反転させる
これらの判定に結果を最後に座標に代入しています。
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()
更新されるたびに画面を一度クリア
再度描画される仕組みを作ります。描画されるたびにボールの座標が変化するので動いていくボールが描画されるようになります。
今回実行できた全コードです。
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()