파이썬으로 크리스마스 트리 조명 게임을 만들었습니다.
만든 것
※비디오는 2배속입니다.
전기 거리를 연결하고 크리스마스 트리 전구를 켜는 게임을 파이썬으로 만들었습니다. GUI는 Tkinter를 사용합니다.
전 자료는 몇 년 전에 NORAD의 산타 추적 웹사이트에 나와 있던 게임이다. 이것을 사랑하고 쭉 하고 있었던 것을 기억해, 최근 공부해 사용할 수 있게 된 Python으로 만들어 보기로 했습니다.
환경
파이썬 3.6.8 on linux
종속 패키지: PIL (Pillow 5.1.0)
소스 코드
GitHub에서 게시 중입니다. 이하에서는 포인트만 소개합니다.
UI 작성 포인트
이미지 표시
PNG 이미지를 표시하기 위해 PIL 패키지의 Image 모듈과 ImageTk 모듈을 사용합니다.
시작하기 전에 이미지를 Image.open()
로 가져옵니다.resize()
왜냐하면 향후 라즈파이의 터치 디스플레이에서도 움직이고 싶기 때문에 표시 크기를 유연하게 바꿀 수 있기 때문입니다.
app_tk.pyIMG_STAR_OFF = Image.open('image/star_off.png').resize(STAR_SIZE, Image.BILINEAR)
IMG_STAR_ON = Image.open('image/star_on.png').resize(STAR_SIZE, Image.BILINEAR)
가져온 이미지는 Tkinter의 캔버스에 표시됩니다. 이 때 PhotoImage()
생성자를 사용합니다.
PhotoImage 객체는 유지해야 하는 것 같습니다. 로컬 변수를 사용하면 표시되지 않았습니다.create_image()
의 반환 값은 canvas의 오브젝트 ID입니다. 게임 중에 이미지를 전환하거나 회전 애니메이션을 표시할 때 필요합니다.
app_tk.pyself.canvas = tk.Canvas(self, width=w, height=h)
self.star_img = ImageTk.PhotoImage(IMG_STAR_ON)
self.star_id = self.canvas.create_image(STAR_OFFSET_X,
STAR_OFFSET_Y,
image=self.star_img,
anchor=tk.NW)
이미지를 변경하려면 새 PhotoImage를 만들고 canvas itemcomfigure()
를 사용합니다.
app_tk.pyif tree.is_complete():
self.star_img = ImageTk.PhotoImage(IMG_STAR_ON)
else:
self.star_img = ImageTk.PhotoImage(IMG_STAR_OFF)
self.canvas.itemconfigure(self.star_id, image=self.star_img)
회전 애니메이션
Tkinter에는 애니메이션 메소드와 같은 편리한 것이 없기 때문에, 스스로 정기적으로 이미지를 갱신해 애니메이션을 실현합니다.
주기적으로 처리를 호출하려면 Tkinter widget 공통 메소드 after()
를 사용할 수 있습니다.
app_tk.pydef rotate_cell(self, x, y):
info = self.img_info[x][y]
info.angle -= 15 # 15度回転
info.photo_img = ImageTk.PhotoImage(info.img.rotate(info.angle)) # 回転したPhotoImage作成
self.canvas.itemconfigure(info.id, image = info.photo_img) # 画像を差し替え
if info.angle % 90 == 0:
# アニメーション完了
# ゲームの状態更新処理など
else:
self.after(15, self.rotate_cell, x, y) # 15ミリ秒後に再度画像を更新する
canvas에 widget 배치
canvas의 create_window()
메서드로 widget을 배치할 수 있습니다. 여러 widget을 함께 취급하고 싶다면 Frame을 사용합니다.
app_tk.pyframe = tk.Frame(self, bg='#e5f8cf', padx=5)
start = tk.Button(frame, text='Start', command=self.start_new_game,
fg='#345834', font=('', 22, 'bold'))
start.pack(side=tk.LEFT, padx=5, pady=10)
self.counter_text = tk.StringVar()
self.counter_text.set('00:00')
self.counter_label = tk.Label(frame, textvariable=self.counter_text,
bg='#e5f8cf', fg='#345834',
font=('', 22, 'bold'))
self.counter_label.pack(side=tk.LEFT, padx=5, pady=10)
self.canvas.create_window(20, 20, window=frame, anchor=tk.NW)
캔버스의 클릭 이벤트
bind()
에서 콜백 메서드를 할당합니다. 콜백 메소드에는 인수로 이벤트가 건네받아, .x, .y로 클릭 이벤트가 발생한 좌표를 취득할 수 있습니다.
app_tk.pyself.canvas.bind('<ButtonRelease-1>', self.on_click_canvas)
def on_click_canvas(self, event):
# event.x, event.yで座標を取得
x = (event.x - TREE_OFFSET_X) // CELL_LENGTH
y = (event.y - TREE_OFFSET_Y) // CELL_LENGTH
# 処理
미로 알고리즘
전기의 거리는 나무의 뿌리를 시작으로 미로로 표현할 수 있습니다.
미로 작성의 알고리즘은 조사하면 여러 가지 있는 것입니다만, 가류로 만들었습니다. 간단히 쓰면 다음과 같은 알고리즘입니다.
방안지의 매스 눈을 연결하여 미로의 경로를 만들 것이라고 생각합니다.
파이썬 3.6.8 on linux
종속 패키지: PIL (Pillow 5.1.0)
소스 코드
GitHub에서 게시 중입니다. 이하에서는 포인트만 소개합니다.
UI 작성 포인트
이미지 표시
PNG 이미지를 표시하기 위해 PIL 패키지의 Image 모듈과 ImageTk 모듈을 사용합니다.
시작하기 전에 이미지를 Image.open()
로 가져옵니다.resize()
왜냐하면 향후 라즈파이의 터치 디스플레이에서도 움직이고 싶기 때문에 표시 크기를 유연하게 바꿀 수 있기 때문입니다.
app_tk.pyIMG_STAR_OFF = Image.open('image/star_off.png').resize(STAR_SIZE, Image.BILINEAR)
IMG_STAR_ON = Image.open('image/star_on.png').resize(STAR_SIZE, Image.BILINEAR)
가져온 이미지는 Tkinter의 캔버스에 표시됩니다. 이 때 PhotoImage()
생성자를 사용합니다.
PhotoImage 객체는 유지해야 하는 것 같습니다. 로컬 변수를 사용하면 표시되지 않았습니다.create_image()
의 반환 값은 canvas의 오브젝트 ID입니다. 게임 중에 이미지를 전환하거나 회전 애니메이션을 표시할 때 필요합니다.
app_tk.pyself.canvas = tk.Canvas(self, width=w, height=h)
self.star_img = ImageTk.PhotoImage(IMG_STAR_ON)
self.star_id = self.canvas.create_image(STAR_OFFSET_X,
STAR_OFFSET_Y,
image=self.star_img,
anchor=tk.NW)
이미지를 변경하려면 새 PhotoImage를 만들고 canvas itemcomfigure()
를 사용합니다.
app_tk.pyif tree.is_complete():
self.star_img = ImageTk.PhotoImage(IMG_STAR_ON)
else:
self.star_img = ImageTk.PhotoImage(IMG_STAR_OFF)
self.canvas.itemconfigure(self.star_id, image=self.star_img)
회전 애니메이션
Tkinter에는 애니메이션 메소드와 같은 편리한 것이 없기 때문에, 스스로 정기적으로 이미지를 갱신해 애니메이션을 실현합니다.
주기적으로 처리를 호출하려면 Tkinter widget 공통 메소드 after()
를 사용할 수 있습니다.
app_tk.pydef rotate_cell(self, x, y):
info = self.img_info[x][y]
info.angle -= 15 # 15度回転
info.photo_img = ImageTk.PhotoImage(info.img.rotate(info.angle)) # 回転したPhotoImage作成
self.canvas.itemconfigure(info.id, image = info.photo_img) # 画像を差し替え
if info.angle % 90 == 0:
# アニメーション完了
# ゲームの状態更新処理など
else:
self.after(15, self.rotate_cell, x, y) # 15ミリ秒後に再度画像を更新する
canvas에 widget 배치
canvas의 create_window()
메서드로 widget을 배치할 수 있습니다. 여러 widget을 함께 취급하고 싶다면 Frame을 사용합니다.
app_tk.pyframe = tk.Frame(self, bg='#e5f8cf', padx=5)
start = tk.Button(frame, text='Start', command=self.start_new_game,
fg='#345834', font=('', 22, 'bold'))
start.pack(side=tk.LEFT, padx=5, pady=10)
self.counter_text = tk.StringVar()
self.counter_text.set('00:00')
self.counter_label = tk.Label(frame, textvariable=self.counter_text,
bg='#e5f8cf', fg='#345834',
font=('', 22, 'bold'))
self.counter_label.pack(side=tk.LEFT, padx=5, pady=10)
self.canvas.create_window(20, 20, window=frame, anchor=tk.NW)
캔버스의 클릭 이벤트
bind()
에서 콜백 메서드를 할당합니다. 콜백 메소드에는 인수로 이벤트가 건네받아, .x, .y로 클릭 이벤트가 발생한 좌표를 취득할 수 있습니다.
app_tk.pyself.canvas.bind('<ButtonRelease-1>', self.on_click_canvas)
def on_click_canvas(self, event):
# event.x, event.yで座標を取得
x = (event.x - TREE_OFFSET_X) // CELL_LENGTH
y = (event.y - TREE_OFFSET_Y) // CELL_LENGTH
# 処理
미로 알고리즘
전기의 거리는 나무의 뿌리를 시작으로 미로로 표현할 수 있습니다.
미로 작성의 알고리즘은 조사하면 여러 가지 있는 것입니다만, 가류로 만들었습니다. 간단히 쓰면 다음과 같은 알고리즘입니다.
방안지의 매스 눈을 연결하여 미로의 경로를 만들 것이라고 생각합니다.
이미지 표시
PNG 이미지를 표시하기 위해 PIL 패키지의 Image 모듈과 ImageTk 모듈을 사용합니다.
시작하기 전에 이미지를
Image.open()
로 가져옵니다.resize()
왜냐하면 향후 라즈파이의 터치 디스플레이에서도 움직이고 싶기 때문에 표시 크기를 유연하게 바꿀 수 있기 때문입니다.app_tk.py
IMG_STAR_OFF = Image.open('image/star_off.png').resize(STAR_SIZE, Image.BILINEAR)
IMG_STAR_ON = Image.open('image/star_on.png').resize(STAR_SIZE, Image.BILINEAR)
가져온 이미지는 Tkinter의 캔버스에 표시됩니다. 이 때
PhotoImage()
생성자를 사용합니다.PhotoImage 객체는 유지해야 하는 것 같습니다. 로컬 변수를 사용하면 표시되지 않았습니다.
create_image()
의 반환 값은 canvas의 오브젝트 ID입니다. 게임 중에 이미지를 전환하거나 회전 애니메이션을 표시할 때 필요합니다.app_tk.py
self.canvas = tk.Canvas(self, width=w, height=h)
self.star_img = ImageTk.PhotoImage(IMG_STAR_ON)
self.star_id = self.canvas.create_image(STAR_OFFSET_X,
STAR_OFFSET_Y,
image=self.star_img,
anchor=tk.NW)
이미지를 변경하려면 새 PhotoImage를 만들고 canvas
itemcomfigure()
를 사용합니다.app_tk.py
if tree.is_complete():
self.star_img = ImageTk.PhotoImage(IMG_STAR_ON)
else:
self.star_img = ImageTk.PhotoImage(IMG_STAR_OFF)
self.canvas.itemconfigure(self.star_id, image=self.star_img)
회전 애니메이션
Tkinter에는 애니메이션 메소드와 같은 편리한 것이 없기 때문에, 스스로 정기적으로 이미지를 갱신해 애니메이션을 실현합니다.
주기적으로 처리를 호출하려면 Tkinter widget 공통 메소드
after()
를 사용할 수 있습니다.app_tk.py
def rotate_cell(self, x, y):
info = self.img_info[x][y]
info.angle -= 15 # 15度回転
info.photo_img = ImageTk.PhotoImage(info.img.rotate(info.angle)) # 回転したPhotoImage作成
self.canvas.itemconfigure(info.id, image = info.photo_img) # 画像を差し替え
if info.angle % 90 == 0:
# アニメーション完了
# ゲームの状態更新処理など
else:
self.after(15, self.rotate_cell, x, y) # 15ミリ秒後に再度画像を更新する
canvas에 widget 배치
canvas의
create_window()
메서드로 widget을 배치할 수 있습니다. 여러 widget을 함께 취급하고 싶다면 Frame을 사용합니다.app_tk.py
frame = tk.Frame(self, bg='#e5f8cf', padx=5)
start = tk.Button(frame, text='Start', command=self.start_new_game,
fg='#345834', font=('', 22, 'bold'))
start.pack(side=tk.LEFT, padx=5, pady=10)
self.counter_text = tk.StringVar()
self.counter_text.set('00:00')
self.counter_label = tk.Label(frame, textvariable=self.counter_text,
bg='#e5f8cf', fg='#345834',
font=('', 22, 'bold'))
self.counter_label.pack(side=tk.LEFT, padx=5, pady=10)
self.canvas.create_window(20, 20, window=frame, anchor=tk.NW)
캔버스의 클릭 이벤트
bind()
에서 콜백 메서드를 할당합니다. 콜백 메소드에는 인수로 이벤트가 건네받아, .x, .y로 클릭 이벤트가 발생한 좌표를 취득할 수 있습니다.app_tk.py
self.canvas.bind('<ButtonRelease-1>', self.on_click_canvas)
def on_click_canvas(self, event):
# event.x, event.yで座標を取得
x = (event.x - TREE_OFFSET_X) // CELL_LENGTH
y = (event.y - TREE_OFFSET_Y) // CELL_LENGTH
# 処理
미로 알고리즘
전기의 거리는 나무의 뿌리를 시작으로 미로로 표현할 수 있습니다.
미로 작성의 알고리즘은 조사하면 여러 가지 있는 것입니다만, 가류로 만들었습니다. 간단히 쓰면 다음과 같은 알고리즘입니다.
방안지의 매스 눈을 연결하여 미로의 경로를 만들 것이라고 생각합니다.
미로가 완성되어 가는 모습을 동영상으로 하면 이런 느낌입니다.
덤
크리스마스 같은 BGM을 흘리고 싶었고 파이썬에서 mp3 파일을 재생하는 방법을 살펴보면 파이게임이 있다는 것을 알았습니다. 화상의 표시라든지 당연히 할 수 있는 것 같기 때문에, 처음부터 이것을 사용하면 좋았을지도・・・
Reference
이 문제에 관하여(파이썬으로 크리스마스 트리 조명 게임을 만들었습니다.), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/usuiat/items/3ee278abbf8702a5e728
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
Reference
이 문제에 관하여(파이썬으로 크리스마스 트리 조명 게임을 만들었습니다.), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/usuiat/items/3ee278abbf8702a5e728텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)