I made a Christmas tree lighting game with Python

What I made

xmastree_s.gif

environment

Python 3.6.8 on linux Dependent packages: PIL (Pillow 5.1.0)

Source code

It is available on GitHub. Only the points will be introduced below.

UI creation points

Image display

Use the Image and ImageTk modules from the PIL package to display PNG images. First, I'm loading a set of images with ʻImage.open (). The reason for resize ()` is that I want to move it on the Raspberry Pi's touch display in the future, so I can flexibly change the display size.

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)

The loaded image is displayed on Tkinter's canvas. At this time, use the PhotoImage () constructor. It seems that the PhotoImage object needs to be retained. It was not displayed when using a local variable. The return value of create_image () is the ID of the object on the canvas. You will need it to switch images and display rotation animations during the game.

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)

To change the image, create a new PhotoImage and use the 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)

Rotation animation

There is no such convenience as an animation method in Tkinter, so you can update the image on your own to achieve the animation. To call the process periodically, you can use Tkinter's common widget method ʻafter ()`.

app_tk.py


def rotate_cell(self, x, y):
    info = self.img_info[x][y]
    info.angle -= 15   #15 degree rotation
    info.photo_img = ImageTk.PhotoImage(info.img.rotate(info.angle))   #Create rotated PhotoImage
    self.canvas.itemconfigure(info.id, image = info.photo_img)   #Replace image
    if info.angle % 90 == 0:
        #Animation complete
        #Game status update process, etc.
    else:
        self.after(15, self.rotate_cell, x, y)   #Update the image again after 15ms

Place widget on canvas

You can place the widget with the canvas's create_window () method. If you want to handle multiple widgets at once, use 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)

Click event on canvas

Assign a callback method with bind (). The event is passed as an argument to the callback method, and you can get the coordinates where the click event occurred in .x, .y.

app_tk.py


self.canvas.bind('<ButtonRelease-1>', self.on_click_canvas)

def on_click_canvas(self, event):
    # event.x, event.Get coordinates with y
    x = (event.x - TREE_OFFSET_X) // CELL_LENGTH
    y = (event.y - TREE_OFFSET_Y) // CELL_LENGTH
    #processing

Maze algorithm

The electrical path can be described as a maze starting at the base of the tree. There are various algorithms for creating a maze, but I made it in my own way. The algorithm is as follows in simple terms.

I think that you will make a maze route by connecting the squares of the graph paper.

  1. Mark the starting cell as used.
  2. List all combinations of used cells and adjacent unused cells.
  3. Randomly select one from the list, connect the selected squares with a passage, and mark the selected squares as used. ..
  4. Repeat 2-3 until all cells are used up.

It looks like this when you make a video of how the maze is completed.

tree_build.gif

bonus

I wanted to play Christmas-like BGM, and when I looked up how to play mp3 files in Python, I found out that there is Pygame. Of course it seems that you can also display images, so maybe you should have used this from the beginning ...

Recommended Posts

I made a Christmas tree lighting game with Python
I made a roguelike game with Python
I made a bin picking game with Python
I made a fortune with Python.
I made a daemon with Python
I made a simple typing game with tkinter in Python
I made a puzzle game (like) with Tkinter in Python
I made a character counter with Python
I made a Hex map with Python
I made a life game with Numpy
I made a simple blackjack with Python
I made a configuration file with Python
I made a neuron simulator with Python
〇✕ I made a game
I made a poker game server chat-holdem using websocket with python
I made a segment tree with python, so I will introduce it
I made a competitive programming glossary with Python
I made a weather forecast bot-like with Python.
I made a GUI application with Python + PyQt5
I made a Twitter fujoshi blocker with Python ①
I want to make a game with Python
[Python] I made a Youtube Downloader with Tkinter.
I made a Mattermost bot with Python (+ Flask)
I made blackjack with python!
I made a python text
I made blackjack with Python.
I made wordcloud with Python.
I made a Twitter BOT with GAE (python) (with a reference)
I made a vim learning game "PacVim" with Go
I made a net news notification app with Python
I made a Python3 environment on Ubuntu with direnv.
I made a LINE BOT with Python and Heroku
I made a falling block game with Sense HAT
I made a Line-bot using Python!
Othello game development made with Python
I made a package to filter time series with python
I made a simple book application with python + Flask ~ Introduction ~
I tried a stochastic simulation of a bingo game with Python
Life game with Python [I made it] (on the terminal & Tkinter)
I made a simple circuit with Python (AND, OR, NOR, etc.)
I made a library to easily read config files with Python
Let's make a shiritori game with Python
I made a package that can compare morphological analyzers with Python
I made a payroll program in Python!
I drew a heatmap with seaborn [Python]
I made a Nyanko tweet form with Python, Flask and Heroku
Christmas classic (?) Lighting a Christmas tree with Raspberry Pi and Philips Hue
I made a lot of files for RDP connection with Python
[Python] I made an image viewer with a simple sorting function.
I tried a functional language with Python
I made a shuffle that can be reset (reverted) with Python
What I did with a Python array
I made a stamp generator with GAN
After studying Python3, I made a Slackbot
[python] I made a class that can write a file tree quickly
I made a WEB application with Django
I made a tool to automatically browse multiple sites with Selenium (Python)
I tried to discriminate a 6-digit number with a number discrimination application made with python
I made a tool that makes decompression a little easier with CLI (Python3)
I made a module PyNanaco that can charge nanaco credit with python
I made a stamp substitute bot with line